]>
Commit | Line | Data |
---|---|---|
3d004a37 | 1 | #!/usr/bin/env python3 |
b3c09bde SH |
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(): | |
f03868bd EH |
80 | print('Usage: %s start [buffer_size_kb] | stop | dump | tail' % sys.argv[0]) |
81 | print('Control the KVM flight recorder tracing.') | |
b3c09bde SH |
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': | |
f03868bd | 90 | print('kvm_flightrecorder version 1.0') |
b3c09bde SH |
91 | sys.exit(0) |
92 | ||
93 | if not os.path.isdir(tracing_dir): | |
f03868bd EH |
94 | print('Unable to tracing debugfs directory, try:') |
95 | print('mount -t debugfs none /sys/kernel/debug') | |
b3c09bde SH |
96 | sys.exit(1) |
97 | if not os.access(tracing_dir, os.W_OK): | |
f03868bd | 98 | print('Unable to write to tracing debugfs directory, please run as root') |
b3c09bde SH |
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: | |
f03868bd | 108 | print('Invalid per-cpu trace buffer size in KB') |
b3c09bde SH |
109 | sys.exit(1) |
110 | write_file(trace_path('buffer_size_kb'), str(buffer_size_kb)) | |
f03868bd | 111 | print('Per-CPU ring buffer size set to %d KB' % buffer_size_kb) |
b3c09bde SH |
112 | |
113 | start_tracing() | |
f03868bd | 114 | print('KVM flight recorder enabled') |
b3c09bde SH |
115 | elif cmd == 'stop': |
116 | stop_tracing() | |
f03868bd | 117 | print('KVM flight recorder disabled') |
b3c09bde SH |
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()) |