You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
122 lines
5.2 KiB
122 lines
5.2 KiB
# Lint as: python2, python3
|
|
"""
|
|
Trace kernel events with Linux Tracing Toolkit (lttng).
|
|
You need to install the lttng patched kernel in order to use the profiler.
|
|
|
|
Examples:
|
|
job.profilers.add('lttng', tracepoints = None): enable all trace points.
|
|
job.profilers.add('lttng', tracepoints = []): disable all trace points.
|
|
job.profilers.add('lttng', tracepoints = ['kernel_arch_syscall_entry',
|
|
'kernel_arch_syscall_exit'])
|
|
will only trace syscall events.
|
|
Take a look at /proc/ltt for the list of the tracing events currently
|
|
supported by lttng and their output formats.
|
|
|
|
To view the collected traces, copy results/your-test/profiler/lttng
|
|
to a machine that has Linux Tracing Toolkit Viewer (lttv) installed:
|
|
test$ scp -r results/your-test/profiler/lttng user@localmachine:/home/tmp/
|
|
Then you can examine the traces either in text mode or in GUI:
|
|
localmachine$ lttv -m textDump -t /home/tmp/lttng
|
|
or
|
|
localmachine$ lttv-gui -t /home/tmp/lttng &
|
|
"""
|
|
|
|
from __future__ import absolute_import
|
|
from __future__ import division
|
|
from __future__ import print_function
|
|
|
|
import os, shutil, time
|
|
|
|
from autotest_lib.client.bin import utils, profiler
|
|
from autotest_lib.client.common_lib import error
|
|
|
|
class lttng(profiler.profiler):
|
|
version = 1
|
|
|
|
# http://ltt.polymtl.ca/lttng/ltt-control-0.51-12082008.tar.gz
|
|
def setup(self, tarball='ltt-control-0.51-12082008.tar.gz', **dargs):
|
|
self.tarball = utils.unmap_url(self.bindir, tarball, self.tmpdir)
|
|
utils.extract_tarball_to_dir(self.tarball, self.srcdir)
|
|
os.chdir(self.srcdir)
|
|
|
|
utils.configure()
|
|
utils.make()
|
|
|
|
|
|
# tracepoints: list of trace points to enable
|
|
# outputsize: size limit for lttng output file. -1: no limit.
|
|
def initialize(self, outputsize=1048576, tracepoints=None, **dargs):
|
|
self.job.require_gcc()
|
|
|
|
self.tracepoints = tracepoints
|
|
self.ltt_bindir = os.path.join(self.srcdir, 'lttctl')
|
|
self.lttctl = os.path.join(self.ltt_bindir, 'lttctl')
|
|
self.lttd = os.path.join(self.srcdir, 'lttd', 'lttd')
|
|
self.armall = os.path.join(self.ltt_bindir, 'ltt-armall')
|
|
self.disarmall = os.path.join(self.ltt_bindir, 'ltt-disarmall')
|
|
self.mountpoint = '/mnt/debugfs'
|
|
self.outputsize = outputsize
|
|
|
|
os.putenv('LTT_DAEMON', self.lttd)
|
|
|
|
if not os.path.exists(self.mountpoint):
|
|
os.mkdir(self.mountpoint)
|
|
|
|
utils.system('mount -t debugfs debugfs ' + self.mountpoint,
|
|
ignore_status=True)
|
|
utils.system('modprobe ltt-control')
|
|
utils.system('modprobe ltt-statedump')
|
|
# clean up from any tracing we left running
|
|
utils.system(self.lttctl + ' -n test -R', ignore_status=True)
|
|
utils.system(self.disarmall, ignore_status=True)
|
|
|
|
if tracepoints is None:
|
|
utils.system(self.armall, ignore_status=True)
|
|
else:
|
|
for tracepoint in self.tracepoints:
|
|
if tracepoint in ('list_process_state',
|
|
'user_generic_thread_brand', 'fs_exec',
|
|
'kernel_process_fork', 'kernel_process_free',
|
|
'kernel_process_exit',
|
|
'kernel_arch_kthread_create',
|
|
'list_statedump_end', 'list_vm_map'):
|
|
channel = 'processes'
|
|
elif tracepoint in ('list_interrupt',
|
|
'statedump_idt_table',
|
|
'statedump_sys_call_table'):
|
|
channel = 'interrupts'
|
|
elif tracepoint in ('list_network_ipv4_interface',
|
|
'list_network_ip_interface'):
|
|
channel = 'network'
|
|
elif tracepoint in ('kernel_module_load', 'kernel_module_free'):
|
|
channel = 'modules'
|
|
else:
|
|
channel = ''
|
|
print('Connecting ' + tracepoint)
|
|
utils.write_one_line('/proc/ltt', 'connect ' + tracepoint
|
|
+ ' default dynamic ' + channel)
|
|
|
|
def start(self, test):
|
|
self.output = os.path.join(test.profdir, 'lttng')
|
|
utils.system('%s -n test -d -l %s/ltt -t %s' %
|
|
(self.lttctl, self.mountpoint, self.output))
|
|
|
|
|
|
def stop(self, test):
|
|
utils.system(self.lttctl + ' -n test -R')
|
|
time.sleep(10)
|
|
if self.outputsize != -1:
|
|
# truncate lttng output file to the specified limit
|
|
for filename in os.listdir(self.output):
|
|
file_path = os.path.join(self.output, filename)
|
|
if os.path.isdir(file_path):
|
|
continue
|
|
size = os.stat(file_path)[6] # grab file size
|
|
if size > self.outputsize:
|
|
f = open(file_path, 'r+')
|
|
f.truncate(self.outputsize)
|
|
f.close()
|
|
tarball = os.path.join(test.profdir, 'lttng.tar.bz2')
|
|
utils.system("tar -cvjf %s -C %s %s" % (tarball, test.profdir, 'lttng'))
|
|
utils.system('rm -rf ' + self.output)
|