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