Home | History | Annotate | Download | only in btreplay
      1 import time, os
      2 from autotest_lib.client.bin import test, os_dep, utils
      3 from autotest_lib.client.common_lib import error
      4 
      5 
      6 class 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