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