| import os, re, time, subprocess, sys, logging |
| from autotest_lib.client.bin import test, utils |
| from autotest_lib.client.common_lib import error |
| |
| |
| class parallel_dd(test.test): |
| version = 2 |
| |
| def initialize(self, fs, fstype = 'ext2', megabytes = 1000, streams = 2, |
| seq_read = True): |
| self.megabytes = megabytes |
| self.blocks = megabytes * 256 |
| self.blocks_per_file = self.blocks / streams |
| self.fs = fs |
| self.fstype = fstype |
| self.streams = streams |
| self.seq_read = seq_read |
| |
| self.old_fstype = self._device_to_fstype('/etc/mtab') |
| if not self.old_fstype: |
| self.old_fstpye = self._device_to_fstype('/etc/fstab') |
| if not self.old_fstype: |
| self.old_fstype = self.fstype |
| |
| logging.info('Dumping %d megabytes across %d streams', megabytes, |
| streams) |
| |
| |
| def raw_write(self): |
| logging.info("Timing raw write of %d megabytes" % self.megabytes) |
| sys.stdout.flush() |
| dd = 'dd if=/dev/zero of=%s bs=4k count=%d' % (self.fs.device, |
| self.blocks) |
| utils.system(dd + ' > /dev/null') |
| |
| |
| def raw_read(self): |
| logging.info("Timing raw read of %d megabytes", self.megabytes) |
| sys.stdout.flush() |
| dd = 'dd if=%s of=/dev/null bs=4k count=%d' % (self.fs.device, |
| self.blocks) |
| utils.system(dd + ' > /dev/null') |
| |
| |
| def fs_write(self): |
| p = [] |
| # Write out 'streams' files in parallel background tasks |
| for i in range(self.streams): |
| file = os.path.join(self.job.tmpdir, 'poo%d' % (i+1)) |
| dd = 'dd if=/dev/zero of=%s bs=4k count=%d' % \ |
| (file, self.blocks_per_file) |
| p.append(subprocess.Popen(dd + ' > /dev/null', shell=True)) |
| logging.info("Waiting for %d streams", self.streams) |
| # Wait for everyone to complete |
| for i in range(self.streams): |
| logging.info("Waiting for %d", p[i].pid) |
| sys.stdout.flush() |
| os.waitpid(p[i].pid, 0) |
| sys.stdout.flush() |
| sys.stderr.flush() |
| |
| |
| def fs_read(self): |
| p = [] |
| # Read in 'streams' files in parallel background tasks |
| for i in range(self.streams): |
| file = os.path.join(self.job.tmpdir, 'poo%d' % (i+1)) |
| dd = 'dd if=%s of=/dev/null bs=4k count=%d' % \ |
| (file, self.blocks_per_file) |
| if self.seq_read: |
| utils.system(dd + ' > /dev/null') |
| else: |
| p.append(subprocess.Popen(dd + ' > /dev/null', shell=True)) |
| if self.seq_read: |
| return |
| logging.info("Waiting for %d streams", self.streams) |
| # Wait for everyone to complete |
| for i in range(self.streams): |
| logging.info("Waiting for %d", p[i].pid) |
| sys.stdout.flush() |
| os.waitpid(p[i].pid, 0) |
| |
| |
| def _device_to_fstype(self, file): |
| device = self.fs.device |
| try: |
| line = utils.system_output('egrep ^%s %s' % (device, file)) |
| logging.debug(line) |
| fstype = line.split()[2] |
| logging.debug('Found %s is type %s from %s', device, fstype, file) |
| return fstype |
| except error.CmdError, e: |
| logging.error('No %s found in %s', device, file) |
| return None |
| |
| |
| def run_once(self): |
| try: |
| self.fs.unmount() |
| except error.CmdError, e: |
| pass |
| |
| logging.info('------------- Timing raw operations ------------------') |
| start = time.time() |
| self.raw_write() |
| self.raw_write_rate = self.megabytes / (time.time() - start) |
| |
| start = time.time() |
| self.raw_read() |
| self.raw_read_rate = self.megabytes / (time.time() - start) |
| |
| # Set up the filesystem |
| self.fs.mkfs(self.fstype) |
| self.fs.mount(None) |
| |
| logging.info('------------- Timing fs operations ------------------') |
| start = time.time() |
| self.fs_write() |
| self.fs_write_rate = self.megabytes / (time.time() - start) |
| self.fs.unmount() |
| |
| self.fs.mount(None) |
| start = time.time() |
| self.fs_read() |
| self.fs_read_rate = self.megabytes / (time.time() - start) |
| |
| self.write_perf_keyval({ |
| 'raw_write' : self.raw_write_rate, |
| 'raw_read' : self.raw_read_rate, |
| 'fs_write' : self.fs_write_rate, |
| 'fs_read' : self.fs_read_rate }) |
| |
| |
| def cleanup(self): |
| try: |
| self.fs.unmount() |
| except error.CmdError, e: |
| pass |
| logging.debug('\nFormatting %s back to type %s\n', self.fs, |
| self.old_fstype) |
| self.fs.mkfs(self.old_fstype) |
| self.fs.mount(None) |