|
|
1.1 root 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 <[email protected]>
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())
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.