root/software/fiemap_testing/extent_test.py @ 92782e4a
| 0a32526d | David Sorber | from multiprocessing import Process
|
||
import datetime
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
| f147b728 | David Sorber | import time
|
||
| 0a32526d | David Sorber | |||
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)
|
||||
| 76bbab9d | David Sorber | time_str = '{:02d}:{:02d}:{:02d}'.format(hours, minutes, seconds)
|
||
self.out('Filler took: {:s}'.format(time_str))
|
||||
| 0a32526d | David Sorber | |||
| f147b728 | David Sorber | # Wait for 30 seconds for any delayed actions to resolve
|
||
time.sleep(30)
|
||||
| 0a32526d | David Sorber | # 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,
|
||||
| f147b728 | David Sorber | 'raw_extents_{:d}MB.txt'.format(self.chunk_size))
|
||
| 0a32526d | David Sorber | 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
|
||||
"""
|
||||
| f147b728 | David Sorber | print 'USAGE: python extent_test.py <FS name> <path to output location>'
|
||
| 0a32526d | David Sorber | |||
def main():
|
||||
"""
|
||||
arg1 - file system name (e.g. xfs)
|
||||
arg2 - path to location to store outputs
|
||||
"""
|
||||
if len(sys.argv) < 3:
|
||||
| f147b728 | David Sorber | print 'ERROR: not enough arguments provided\n'
|
||
usage()
|
||||
| 0a32526d | David Sorber | 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
|
||||
| 76bbab9d | David Sorber | date_str = datetime.datetime.now().strftime('%Y%m%d-%H%M')
|
||
output_path = os.path.join(output_path, fs_name, date_str)
|
||||
| 0a32526d | David Sorber | 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())
|