root/software/fiemap_testing/extent_test.py @ 0a32526d
| 0a32526d | David Sorber | from multiprocessing import Process
|
|
import datetime
|
|||
import os
|
|||
import subprocess
|
|||
import sys
|
|||
devices = {'/dev/sdb1': {'mount': '/mnt/smc0', 'size': 64},
|
|||
'/dev/sdc1': {'mount': '/mnt/smc1', 'size': 256},
|
|||
'/dev/sdd1': {'mount': '/mnt/smc2', 'size': 1024}}
|
|||
MIN_FILE_SIZE = 10240 # in megabytes
|
|||
MAX_FILE_SIZE = 102400 # in megabytes
|
|||
DRIVE_CAPACITY = int(1.8 * (2**20)) # in megabytes
|
|||
class Tester(Process):
|
|||
"""
|
|||
"""
|
|||
def __init__(self, device, mount_path, chunk_size, fs_name, output_path):
|
|||
Process.__init__(self)
|
|||
self.device = device
|
|||
self.mount_path = mount_path
|
|||
self.chunk_size = chunk_size
|
|||
self.mkfs_cmd = '/sbin/mkfs.{:s}'.format(fs_name)
|
|||
self.output_path = output_path
|
|||
# Build a logfile name for the stdout and stderr of the subprocess calls
|
|||
logname = 'subproc_{:d}.log'.format(self.chunk_size)
|
|||
self.subproclog = open(os.path.join(self.output_path, logname), 'w')
|
|||
def out(self, msg):
|
|||
print '[{:4d}] {:s}'.format(self.chunk_size, msg)
|
|||
sys.stdout.flush()
|
|||
def cmd(self, cmd):
|
|||
return subprocess.call(cmd, shell=True, stdout=self.subproclog,
|
|||
stderr=self.subproclog)
|
|||
def run(self):
|
|||
self.out('Started')
|
|||
# Unmount mount path
|
|||
cmd = 'umount {:s}'.format(self.mount_path)
|
|||
rc = self.cmd(cmd)
|
|||
if rc == 0:
|
|||
self.out('Unmounted {:s}'.format(self.mount_path))
|
|||
elif rc == 2:
|
|||
self.out('{:s} was not mounted'.format(self.mount_path))
|
|||
else:
|
|||
self.out('Error unmounting {:s}'.format(self.mount_path))
|
|||
# Format device partition
|
|||
cmd = '{:s} -f {:s}'.format(self.mkfs_cmd, self.device)
|
|||
rc = self.cmd(cmd)
|
|||
if rc == 0:
|
|||
self.out('Formatted {:s}'.format(self.device))
|
|||
else:
|
|||
self.out('Error while formatting {:s}'.format(self.device))
|
|||
# Mount path
|
|||
cmd = 'mount {:s} {:s}'.format(self.device, self.mount_path)
|
|||
rc = self.cmd(cmd)
|
|||
if rc == 0:
|
|||
self.out('Mounted {:s} on {:s}'.format(self.device, self.mount_path))
|
|||
else:
|
|||
self.out('Error mounting {:s} on {:s}'.format(self.device, self.mount_path))
|
|||
# Run filler script
|
|||
output_file = os.path.join(self.output_path,
|
|||
'extent_test_{:d}MB.log'.format(self.chunk_size))
|
|||
min_chunks = MIN_FILE_SIZE / self.chunk_size
|
|||
max_chunks = MAX_FILE_SIZE / self.chunk_size
|
|||
cmd_args = (self.mount_path, min_chunks, max_chunks, self.chunk_size,
|
|||
DRIVE_CAPACITY, output_file)
|
|||
cmd = 'python filler.py {:s} {:d} {:d} {:d} {:d} > {:s}'.format(*cmd_args)
|
|||
self.out('Started filler.py on {:s}'.format(self.mount_path))
|
|||
start = datetime.datetime.now()
|
|||
rc = self.cmd(cmd)
|
|||
if rc == 0:
|
|||
self.out('filler.py complete on {:s}'.format(self.mount_path))
|
|||
end = datetime.datetime.now()
|
|||
# Display elapsed time for filler.py script
|
|||
elpased = end - start
|
|||
hours, remainder = divmod(elpased.seconds, 3600)
|
|||
minutes, seconds = divmod(remainder, 60)
|
|||
time = '{:02d}:{:02d}:{:02d}'.format(hours, minutes, seconds)
|
|||
self.out('Filler took: {:s}'.format(time))
|
|||
# Run analyze.py script
|
|||
output_file = os.path.join(self.output_path,
|
|||
'extent_analysis_{:d}MB.log'.format(self.chunk_size))
|
|||
cmd_args = (self.mount_path, output_file)
|
|||
cmd = 'python analyze.py {:s} > {:s}'.format(*cmd_args)
|
|||
rc = self.cmd(cmd)
|
|||
self.out('Ran analyze.py on {:s}'.format(self.output_path))
|
|||
# Run raw_data.py script
|
|||
output_file = os.path.join(self.output_path,
|
|||
'raw_extents_{:d}MB.log'.format(self.chunk_size))
|
|||
cmd_args = (self.mount_path, output_file)
|
|||
cmd = 'python raw_data.py {:s} > {:s}'.format(*cmd_args)
|
|||
rc = self.cmd(cmd)
|
|||
self.out('Ran raw_data.py on {:s}'.format(self.output_path))
|
|||
# Close the subprocess output log for good measure
|
|||
self.subproclog.close()
|
|||
def usage():
|
|||
""" TODO: write usage blurb to be printed here
|
|||
"""
|
|||
pass
|
|||
def main():
|
|||
"""
|
|||
arg1 - file system name (e.g. xfs)
|
|||
arg2 - path to location to store outputs
|
|||
"""
|
|||
if len(sys.argv) < 3:
|
|||
print 'ERROR: not enough arguments provided'
|
|||
return -1
|
|||
fs_name = sys.argv[1]
|
|||
output_path = sys.argv[2]
|
|||
# Make sure file system name exists (i.e. /sbin/mkfs.[FSNAME] exists)
|
|||
if not os.path.exists('/sbin/mkfs.{:s}'.format(fs_name)):
|
|||
print 'ERROR: "{:s}" is not a known file system on this system!'.format(fs_name)
|
|||
return -1
|
|||
# Make sure the output path exists
|
|||
if not os.path.exists(output_path):
|
|||
print 'ERROR: output path "{:s}" does not exist!'.format(output_path)
|
|||
return -1
|
|||
# Create output folder if it does not already exist
|
|||
output_path = os.path.join(output_path, fs_name)
|
|||
if os.path.exists(output_path):
|
|||
print 'ERROR: output folder "{:s}" already exists!'.format(output_path)
|
|||
return -1
|
|||
os.makedirs(output_path)
|
|||
# Create Tester instances for each of the devices
|
|||
tester_workers = []
|
|||
for device, dev_attrs in devices.iteritems():
|
|||
tester_workers.append(Tester(device, dev_attrs['mount'],
|
|||
dev_attrs['size'], fs_name, output_path))
|
|||
# Start all Tester processes
|
|||
for worker in tester_workers:
|
|||
worker.start()
|
|||
# Join each of the processes
|
|||
for worker in tester_workers:
|
|||
worker.join()
|
|||
print 'Test complete'
|
|||
if __name__ == '__main__':
|
|||
sys.exit(main())
|