• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1import os, re, time, subprocess, sys, logging
2from autotest_lib.client.bin import test, utils
3from autotest_lib.client.common_lib import error
4
5
6class 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