117 lines
4.4 KiB
Python
117 lines
4.4 KiB
Python
import time, os
|
|
from autotest_lib.client.bin import test, os_dep, utils
|
|
from autotest_lib.client.common_lib import error
|
|
|
|
|
|
class btreplay(test.test):
|
|
version = 1
|
|
|
|
# http://brick.kernel.dk/snaps/blktrace-git-latest.tar.gz
|
|
def setup(self, tarball = 'blktrace-git-latest.tar.gz'):
|
|
tarball = utils.unmap_url(self.bindir, tarball, self.tmpdir)
|
|
utils.extract_tarball_to_dir(tarball, self.srcdir)
|
|
|
|
self.job.setup_dep(['libaio'])
|
|
libs = '-L' + self.autodir + '/deps/libaio/lib -laio'
|
|
cflags = '-I ' + self.autodir + '/deps/libaio/include'
|
|
var_libs = 'LIBS="' + libs + '"'
|
|
var_cflags = 'CFLAGS="' + cflags + '"'
|
|
self.make_flags = var_libs + ' ' + var_cflags
|
|
|
|
os.chdir(self.srcdir)
|
|
|
|
utils.system('patch -p1 < ../Makefile.patch')
|
|
utils.system(self.make_flags + ' make')
|
|
|
|
|
|
def initialize(self):
|
|
self.job.require_gcc()
|
|
self.ldlib = 'LD_LIBRARY_PATH=%s/deps/libaio/lib'%(self.autodir)
|
|
self.results = []
|
|
|
|
|
|
def run_once(self, dev="", devices="", extra_args='', tmpdir=None):
|
|
# @dev: The device against which the trace will be replayed.
|
|
# e.g. "sdb" or "md_d1"
|
|
# @devices: A space-separated list of the underlying devices
|
|
# which make up dev, e.g. "sdb sdc". You only need to set
|
|
# devices if dev is an MD, LVM, or similar device;
|
|
# otherwise leave it as an empty string.
|
|
|
|
if not tmpdir:
|
|
tmpdir = self.tmpdir
|
|
|
|
os.chdir(self.srcdir)
|
|
|
|
alldevs = "-d /dev/" + dev
|
|
alldnames = dev
|
|
for d in devices.split():
|
|
alldevs += " -d /dev/" + d
|
|
alldnames += " " + d
|
|
|
|
# convert the trace (assumed to be in this test's base
|
|
# directory) into btreplay's required format
|
|
#
|
|
# TODO: The test currently halts here as there is no trace in the
|
|
# test's base directory.
|
|
cmd = "./btreplay/btrecord -d .. -D %s %s" % (tmpdir, dev)
|
|
self.results.append(utils.system_output(cmd, retain_output=True))
|
|
|
|
# time a replay that omits "thinktime" between requests
|
|
# (by use of the -N flag)
|
|
cmd = self.ldlib + " /usr/bin/time ./btreplay/btreplay -d "+\
|
|
tmpdir+" -N -W "+dev+" "+extra_args+" 2>&1"
|
|
self.results.append(utils.system_output(cmd, retain_output=True))
|
|
|
|
# trace a replay that reproduces inter-request delays, and
|
|
# analyse the trace with btt to determine the average request
|
|
# completion latency
|
|
utils.system("./blktrace -D %s %s >/dev/null &" % (tmpdir, alldevs))
|
|
cmd = self.ldlib + " ./btreplay/btreplay -d %s -W %s %s" %\
|
|
(tmpdir, dev, extra_args)
|
|
self.results.append(utils.system_output(cmd, retain_output=True))
|
|
utils.system("killall -INT blktrace")
|
|
|
|
# wait until blktrace is really done
|
|
slept = 0.0
|
|
while utils.system("ps -C blktrace > /dev/null",
|
|
ignore_status=True) == 0:
|
|
time.sleep(0.1)
|
|
slept += 0.1
|
|
if slept > 30.0:
|
|
utils.system("killall -9 blktrace")
|
|
raise error.TestError("blktrace failed to exit in 30 seconds")
|
|
utils.system("./blkparse -q -D %s -d %s/trace.bin -O %s >/dev/null" %
|
|
(tmpdir, tmpdir, alldnames))
|
|
cmd = "./btt/btt -i %s/trace.bin" % tmpdir
|
|
self.results.append(utils.system_output(cmd, retain_output=True))
|
|
|
|
|
|
def postprocess(self):
|
|
for n in range(len(self.results)):
|
|
if self.results[n].strip() == "==================== All Devices ====================":
|
|
words = self.results[n-2].split()
|
|
s = words[1].strip('sytem').split(':')
|
|
e = words[2].strip('elapsd').split(':')
|
|
break
|
|
|
|
systime = 0.0
|
|
for n in range(len(s)):
|
|
i = (len(s)-1) - n
|
|
systime += float(s[i]) * (60**n)
|
|
elapsed = 0.0
|
|
for n in range(len(e)):
|
|
i = (len(e)-1) - n
|
|
elapsed += float(e[i]) * (60**n)
|
|
|
|
q2c = 0.0
|
|
for line in self.results:
|
|
words = line.split()
|
|
if len(words) < 3:
|
|
continue
|
|
if words[0] == 'Q2C':
|
|
q2c = float(words[2])
|
|
break
|
|
|
|
self.write_perf_keyval({'time':elapsed, 'systime':systime,
|
|
'avg_q2c_latency':q2c})
|