• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1import time, os
2from autotest_lib.client.bin import test, os_dep, utils
3from autotest_lib.client.common_lib import error
4
5
6class btreplay(test.test):
7    version = 1
8
9    # http://brick.kernel.dk/snaps/blktrace-git-latest.tar.gz
10    def setup(self, tarball = 'blktrace-git-latest.tar.gz'):
11        tarball = utils.unmap_url(self.bindir, tarball, self.tmpdir)
12        utils.extract_tarball_to_dir(tarball, self.srcdir)
13
14        self.job.setup_dep(['libaio'])
15        libs = '-L' + self.autodir + '/deps/libaio/lib -laio'
16        cflags = '-I ' + self.autodir + '/deps/libaio/include'
17        var_libs = 'LIBS="' + libs + '"'
18        var_cflags  = 'CFLAGS="' + cflags + '"'
19        self.make_flags = var_libs + ' ' + var_cflags
20
21        os.chdir(self.srcdir)
22
23        utils.system('patch -p1 < ../Makefile.patch')
24        utils.system(self.make_flags + ' make')
25
26
27    def initialize(self):
28        self.job.require_gcc()
29        self.ldlib = 'LD_LIBRARY_PATH=%s/deps/libaio/lib'%(self.autodir)
30        self.results = []
31
32
33    def run_once(self, dev="", devices="", extra_args='', tmpdir=None):
34        # @dev: The device against which the trace will be replayed.
35        #       e.g. "sdb" or "md_d1"
36        # @devices: A space-separated list of the underlying devices
37        #    which make up dev, e.g. "sdb sdc". You only need to set
38        #    devices if dev is an MD, LVM, or similar device;
39        #    otherwise leave it as an empty string.
40
41        if not tmpdir:
42            tmpdir = self.tmpdir
43
44        os.chdir(self.srcdir)
45
46        alldevs = "-d /dev/" + dev
47        alldnames = dev
48        for d in devices.split():
49            alldevs += " -d /dev/" + d
50            alldnames += " " + d
51
52        # convert the trace (assumed to be in this test's base
53        # directory) into btreplay's required format
54        #
55        # TODO: The test currently halts here as there is no trace in the
56        # test's base directory.
57        cmd = "./btreplay/btrecord -d .. -D %s %s" % (tmpdir, dev)
58        self.results.append(utils.system_output(cmd, retain_output=True))
59
60        # time a replay that omits "thinktime" between requests
61        # (by use of the -N flag)
62        cmd = self.ldlib + " /usr/bin/time ./btreplay/btreplay -d "+\
63              tmpdir+" -N -W "+dev+" "+extra_args+" 2>&1"
64        self.results.append(utils.system_output(cmd, retain_output=True))
65
66        # trace a replay that reproduces inter-request delays, and
67        # analyse the trace with btt to determine the average request
68        # completion latency
69        utils.system("./blktrace -D %s %s >/dev/null &" % (tmpdir, alldevs))
70        cmd = self.ldlib + " ./btreplay/btreplay -d %s -W %s %s" %\
71              (tmpdir, dev, extra_args)
72        self.results.append(utils.system_output(cmd, retain_output=True))
73        utils.system("killall -INT blktrace")
74
75        # wait until blktrace is really done
76        slept = 0.0
77        while utils.system("ps -C blktrace > /dev/null",
78                           ignore_status=True) == 0:
79            time.sleep(0.1)
80            slept += 0.1
81            if slept > 30.0:
82                utils.system("killall -9 blktrace")
83                raise error.TestError("blktrace failed to exit in 30 seconds")
84        utils.system("./blkparse -q -D %s -d %s/trace.bin -O %s >/dev/null" %
85                     (tmpdir, tmpdir, alldnames))
86        cmd = "./btt/btt -i %s/trace.bin" % tmpdir
87        self.results.append(utils.system_output(cmd, retain_output=True))
88
89
90    def postprocess(self):
91        for n in range(len(self.results)):
92            if self.results[n].strip() == "==================== All Devices ====================":
93                words = self.results[n-2].split()
94                s = words[1].strip('sytem').split(':')
95                e = words[2].strip('elapsd').split(':')
96                break
97
98        systime = 0.0
99        for n in range(len(s)):
100            i = (len(s)-1) - n
101            systime += float(s[i]) * (60**n)
102        elapsed = 0.0
103        for n in range(len(e)):
104            i = (len(e)-1) - n
105            elapsed += float(e[i]) * (60**n)
106
107        q2c = 0.0
108        for line in self.results:
109            words = line.split()
110            if len(words) < 3:
111                continue
112            if words[0] == 'Q2C':
113                q2c = float(words[2])
114                break
115
116        self.write_perf_keyval({'time':elapsed, 'systime':systime,
117                                'avg_q2c_latency':q2c})
118