qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

kvm_flightrecorder (3642B)


      1 #!/usr/bin/env python3
      2 #
      3 # KVM Flight Recorder - ring buffer tracing script
      4 #
      5 # Copyright (C) 2012 IBM Corp
      6 #
      7 # Author: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
      8 #
      9 # This script provides a command-line interface to kvm ftrace and is designed
     10 # to be used as a flight recorder that is always running.  To start in-memory
     11 # recording:
     12 #
     13 # sudo kvm_flightrecorder start 8192  # 8 MB per-cpu ring buffers
     14 #
     15 # The per-cpu ring buffer size can be given in KB as an optional argument to
     16 # the 'start' subcommand.
     17 #
     18 # To stop the flight recorder:
     19 #
     20 # sudo kvm_flightrecorder stop
     21 #
     22 # To dump the contents of the flight recorder (this can be done when the
     23 # recorder is stopped or while it is running):
     24 #
     25 # sudo kvm_flightrecorder dump >/path/to/dump.txt
     26 #
     27 # To observe the trace while it is running, use the 'tail' subcommand:
     28 #
     29 # sudo kvm_flightrecorder tail
     30 #
     31 # Note that the flight recorder may impact overall system performance by
     32 # consuming CPU cycles.  No disk I/O is performed since the ring buffer holds a
     33 # fixed-size in-memory trace.
     34 
     35 import sys
     36 import os
     37 
     38 tracing_dir = '/sys/kernel/debug/tracing'
     39 
     40 def trace_path(*args):
     41     return os.path.join(tracing_dir, *args)
     42 
     43 def write_file(path, data):
     44     open(path, 'wb').write(data)
     45 
     46 def enable_event(subsystem, event, enable):
     47     write_file(trace_path('events', subsystem, event, 'enable'), '1' if enable else '0')
     48 
     49 def enable_subsystem(subsystem, enable):
     50     write_file(trace_path('events', subsystem, 'enable'), '1' if enable else '0')
     51 
     52 def start_tracing():
     53     enable_subsystem('kvm', True)
     54     write_file(trace_path('tracing_on'), '1')
     55 
     56 def stop_tracing():
     57     write_file(trace_path('tracing_on'), '0')
     58     enable_subsystem('kvm', False)
     59     write_file(trace_path('events', 'enable'), '0')
     60     write_file(trace_path('current_tracer'), 'nop')
     61 
     62 def dump_trace():
     63     tracefile = open(trace_path('trace'), 'r')
     64     try:
     65         lines = True
     66         while lines:
     67             lines = tracefile.readlines(64 * 1024)
     68             sys.stdout.writelines(lines)
     69     except KeyboardInterrupt:
     70         pass
     71 
     72 def tail_trace():
     73     try:
     74         for line in open(trace_path('trace_pipe'), 'r'):
     75             sys.stdout.write(line)
     76     except KeyboardInterrupt:
     77         pass
     78 
     79 def usage():
     80     print('Usage: %s start [buffer_size_kb] | stop | dump | tail' % sys.argv[0])
     81     print('Control the KVM flight recorder tracing.')
     82     sys.exit(0)
     83 
     84 def main():
     85     if len(sys.argv) < 2:
     86         usage()
     87 
     88     cmd = sys.argv[1]
     89     if cmd == '--version':
     90         print('kvm_flightrecorder version 1.0')
     91         sys.exit(0)
     92 
     93     if not os.path.isdir(tracing_dir):
     94         print('Unable to tracing debugfs directory, try:')
     95         print('mount -t debugfs none /sys/kernel/debug')
     96         sys.exit(1)
     97     if not os.access(tracing_dir, os.W_OK):
     98         print('Unable to write to tracing debugfs directory, please run as root')
     99         sys.exit(1)
    100 
    101     if cmd == 'start':
    102         stop_tracing() # clean up first
    103 
    104         if len(sys.argv) == 3:
    105             try:
    106                 buffer_size_kb = int(sys.argv[2])
    107             except ValueError:
    108                 print('Invalid per-cpu trace buffer size in KB')
    109                 sys.exit(1)
    110             write_file(trace_path('buffer_size_kb'), str(buffer_size_kb))
    111             print('Per-CPU ring buffer size set to %d KB' % buffer_size_kb)
    112 
    113         start_tracing()
    114         print('KVM flight recorder enabled')
    115     elif cmd == 'stop':
    116         stop_tracing()
    117         print('KVM flight recorder disabled')
    118     elif cmd == 'dump':
    119         dump_trace()
    120     elif cmd == 'tail':
    121         tail_trace()
    122     else:
    123         usage()
    124 
    125 if __name__ == '__main__':
    126     sys.exit(main())