1 import os, re, time, subprocess, sys, logging 2 from autotest_lib.client.bin import test, utils 3 from autotest_lib.client.common_lib import error 4 5 6 class parallel_dd(test.test): 7 version = 2 8 9 def initialize(self, fs, fstype = 'ext2', megabytes = 1000, streams = 2, 10 seq_read = True): 11 self.megabytes = megabytes 12 self.blocks = megabytes * 256 13 self.blocks_per_file = self.blocks / streams 14 self.fs = fs 15 self.fstype = fstype 16 self.streams = streams 17 self.seq_read = seq_read 18 19 self.old_fstype = self._device_to_fstype('/etc/mtab') 20 if not self.old_fstype: 21 self.old_fstpye = self._device_to_fstype('/etc/fstab') 22 if not self.old_fstype: 23 self.old_fstype = self.fstype 24 25 logging.info('Dumping %d megabytes across %d streams', megabytes, 26 streams) 27 28 29 def raw_write(self): 30 logging.info("Timing raw write of %d megabytes" % self.megabytes) 31 sys.stdout.flush() 32 dd = 'dd if=/dev/zero of=%s bs=4k count=%d' % (self.fs.device, 33 self.blocks) 34 utils.system(dd + ' > /dev/null') 35 36 37 def raw_read(self): 38 logging.info("Timing raw read of %d megabytes", self.megabytes) 39 sys.stdout.flush() 40 dd = 'dd if=%s of=/dev/null bs=4k count=%d' % (self.fs.device, 41 self.blocks) 42 utils.system(dd + ' > /dev/null') 43 44 45 def fs_write(self): 46 p = [] 47 # Write out 'streams' files in parallel background tasks 48 for i in range(self.streams): 49 file = os.path.join(self.job.tmpdir, 'poo%d' % (i+1)) 50 dd = 'dd if=/dev/zero of=%s bs=4k count=%d' % \ 51 (file, self.blocks_per_file) 52 p.append(subprocess.Popen(dd + ' > /dev/null', shell=True)) 53 logging.info("Waiting for %d streams", self.streams) 54 # Wait for everyone to complete 55 for i in range(self.streams): 56 logging.info("Waiting for %d", p[i].pid) 57 sys.stdout.flush() 58 os.waitpid(p[i].pid, 0) 59 sys.stdout.flush() 60 sys.stderr.flush() 61 62 63 def fs_read(self): 64 p = [] 65 # Read in 'streams' files in parallel background tasks 66 for i in range(self.streams): 67 file = os.path.join(self.job.tmpdir, 'poo%d' % (i+1)) 68 dd = 'dd if=%s of=/dev/null bs=4k count=%d' % \ 69 (file, self.blocks_per_file) 70 if self.seq_read: 71 utils.system(dd + ' > /dev/null') 72 else: 73 p.append(subprocess.Popen(dd + ' > /dev/null', shell=True)) 74 if self.seq_read: 75 return 76 logging.info("Waiting for %d streams", self.streams) 77 # Wait for everyone to complete 78 for i in range(self.streams): 79 logging.info("Waiting for %d", p[i].pid) 80 sys.stdout.flush() 81 os.waitpid(p[i].pid, 0) 82 83 84 def _device_to_fstype(self, file): 85 device = self.fs.device 86 try: 87 line = utils.system_output('egrep ^%s %s' % (device, file)) 88 logging.debug(line) 89 fstype = line.split()[2] 90 logging.debug('Found %s is type %s from %s', device, fstype, file) 91 return fstype 92 except error.CmdError, e: 93 logging.error('No %s found in %s', device, file) 94 return None 95 96 97 def run_once(self): 98 try: 99 self.fs.unmount() 100 except error.CmdError, e: 101 pass 102 103 logging.info('------------- Timing raw operations ------------------') 104 start = time.time() 105 self.raw_write() 106 self.raw_write_rate = self.megabytes / (time.time() - start) 107 108 start = time.time() 109 self.raw_read() 110 self.raw_read_rate = self.megabytes / (time.time() - start) 111 112 # Set up the filesystem 113 self.fs.mkfs(self.fstype) 114 self.fs.mount(None) 115 116 logging.info('------------- Timing fs operations ------------------') 117 start = time.time() 118 self.fs_write() 119 self.fs_write_rate = self.megabytes / (time.time() - start) 120 self.fs.unmount() 121 122 self.fs.mount(None) 123 start = time.time() 124 self.fs_read() 125 self.fs_read_rate = self.megabytes / (time.time() - start) 126 127 self.write_perf_keyval({ 128 'raw_write' : self.raw_write_rate, 129 'raw_read' : self.raw_read_rate, 130 'fs_write' : self.fs_write_rate, 131 'fs_read' : self.fs_read_rate }) 132 133 134 def cleanup(self): 135 try: 136 self.fs.unmount() 137 except error.CmdError, e: 138 pass 139 logging.debug('\nFormatting %s back to type %s\n', self.fs, 140 self.old_fstype) 141 self.fs.mkfs(self.old_fstype) 142 self.fs.mount(None) 143