Home | History | Annotate | Download | only in lttng
      1 """
      2 Trace kernel events with Linux Tracing Toolkit (lttng).
      3 You need to install the lttng patched kernel in order to use the profiler.
      4 
      5 Examples:
      6     job.profilers.add('lttng', tracepoints = None): enable all trace points.
      7     job.profilers.add('lttng', tracepoints = []): disable all trace points.
      8     job.profilers.add('lttng', tracepoints = ['kernel_arch_syscall_entry',
      9                                               'kernel_arch_syscall_exit'])
     10                                will only trace syscall events.
     11 Take a look at /proc/ltt for the list of the tracing events currently
     12 supported by lttng and their output formats.
     13 
     14 To view the collected traces, copy results/your-test/profiler/lttng
     15 to a machine that has Linux Tracing Toolkit Viewer (lttv) installed:
     16     test$ scp -r results/your-test/profiler/lttng user@localmachine:/home/tmp/
     17 Then you can examine the traces either in text mode or in GUI:
     18     localmachine$ lttv -m textDump -t /home/tmp/lttng
     19 or
     20     localmachine$ lttv-gui -t /home/tmp/lttng &
     21 """
     22 
     23 import os, shutil, time
     24 from autotest_lib.client.bin import utils, profiler
     25 from autotest_lib.client.common_lib import error
     26 
     27 class lttng(profiler.profiler):
     28     version = 1
     29 
     30     # http://ltt.polymtl.ca/lttng/ltt-control-0.51-12082008.tar.gz
     31     def setup(self, tarball='ltt-control-0.51-12082008.tar.gz', **dargs):
     32         self.tarball = utils.unmap_url(self.bindir, tarball, self.tmpdir)
     33         utils.extract_tarball_to_dir(self.tarball, self.srcdir)
     34         os.chdir(self.srcdir)
     35 
     36         utils.configure()
     37         utils.make()
     38 
     39 
     40     # tracepoints: list of trace points to enable
     41     # outputsize: size limit for lttng output file. -1: no limit.
     42     def initialize(self, outputsize=1048576, tracepoints=None, **dargs):
     43         self.job.require_gcc()
     44 
     45         self.tracepoints = tracepoints
     46         self.ltt_bindir = os.path.join(self.srcdir, 'lttctl')
     47         self.lttctl = os.path.join(self.ltt_bindir, 'lttctl')
     48         self.lttd = os.path.join(self.srcdir, 'lttd', 'lttd')
     49         self.armall = os.path.join(self.ltt_bindir, 'ltt-armall')
     50         self.disarmall = os.path.join(self.ltt_bindir, 'ltt-disarmall')
     51         self.mountpoint = '/mnt/debugfs'
     52         self.outputsize = outputsize
     53 
     54         os.putenv('LTT_DAEMON', self.lttd)
     55 
     56         if not os.path.exists(self.mountpoint):
     57             os.mkdir(self.mountpoint)
     58 
     59         utils.system('mount -t debugfs debugfs ' + self.mountpoint,
     60                                                             ignore_status=True)
     61         utils.system('modprobe ltt-control')
     62         utils.system('modprobe ltt-statedump')
     63         # clean up from any tracing we left running
     64         utils.system(self.lttctl + ' -n test -R', ignore_status=True)
     65         utils.system(self.disarmall, ignore_status=True)
     66 
     67         if tracepoints is None:
     68             utils.system(self.armall, ignore_status=True)
     69         else:
     70             for tracepoint in self.tracepoints:
     71                 if tracepoint in ('list_process_state',
     72                                   'user_generic_thread_brand', 'fs_exec',
     73                                   'kernel_process_fork', 'kernel_process_free',
     74                                   'kernel_process_exit',
     75                                   'kernel_arch_kthread_create',
     76                                   'list_statedump_end', 'list_vm_map'):
     77                     channel = 'processes'
     78                 elif tracepoint in ('list_interrupt',
     79                                     'statedump_idt_table',
     80                                     'statedump_sys_call_table'):
     81                     channel = 'interrupts'
     82                 elif tracepoint in ('list_network_ipv4_interface',
     83                                     'list_network_ip_interface'):
     84                     channel = 'network'
     85                 elif tracepoint in ('kernel_module_load', 'kernel_module_free'):
     86                     channel = 'modules'
     87                 else:
     88                     channel = ''
     89                 print 'Connecting ' + tracepoint
     90                 utils.write_one_line('/proc/ltt', 'connect ' + tracepoint
     91                                      + ' default dynamic ' + channel)
     92 
     93     def start(self, test):
     94         self.output = os.path.join(test.profdir, 'lttng')
     95         utils.system('%s -n test -d -l %s/ltt -t %s' %
     96                                   (self.lttctl, self.mountpoint, self.output))
     97 
     98 
     99     def stop(self, test):
    100         utils.system(self.lttctl + ' -n test -R')
    101         time.sleep(10)
    102         if self.outputsize != -1:
    103             # truncate lttng output file to the specified limit
    104             for filename in os.listdir(self.output):
    105                 file_path = os.path.join(self.output, filename)
    106                 if os.path.isdir(file_path):
    107                     continue
    108                 size = os.stat(file_path)[6] # grab file size
    109                 if size > self.outputsize:
    110                     f = open(file_path, 'r+')
    111                     f.truncate(self.outputsize)
    112                     f.close()
    113         tarball = os.path.join(test.profdir, 'lttng.tar.bz2')
    114         utils.system("tar -cvjf %s -C %s %s" % (tarball, test.profdir, 'lttng'))
    115         utils.system('rm -rf ' + self.output)
    116