Add qemu 2.4.0
[kvmfornfv.git] / qemu / scripts / kvm / kvm_flightrecorder
1 #!/usr/bin/env python
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())