2
0

kvm_flightrecorder 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  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. import sys
  35. import os
  36. tracing_dir = '/sys/kernel/debug/tracing'
  37. def trace_path(*args):
  38. return os.path.join(tracing_dir, *args)
  39. def write_file(path, data):
  40. open(path, 'wb').write(data)
  41. def enable_event(subsystem, event, enable):
  42. write_file(trace_path('events', subsystem, event, 'enable'), '1' if enable else '0')
  43. def enable_subsystem(subsystem, enable):
  44. write_file(trace_path('events', subsystem, 'enable'), '1' if enable else '0')
  45. def start_tracing():
  46. enable_subsystem('kvm', True)
  47. write_file(trace_path('tracing_on'), '1')
  48. def stop_tracing():
  49. write_file(trace_path('tracing_on'), '0')
  50. enable_subsystem('kvm', False)
  51. write_file(trace_path('events', 'enable'), '0')
  52. write_file(trace_path('current_tracer'), 'nop')
  53. def dump_trace():
  54. tracefile = open(trace_path('trace'), 'r')
  55. try:
  56. lines = True
  57. while lines:
  58. lines = tracefile.readlines(64 * 1024)
  59. sys.stdout.writelines(lines)
  60. except KeyboardInterrupt:
  61. pass
  62. def tail_trace():
  63. try:
  64. for line in open(trace_path('trace_pipe'), 'r'):
  65. sys.stdout.write(line)
  66. except KeyboardInterrupt:
  67. pass
  68. def usage():
  69. print('Usage: %s start [buffer_size_kb] | stop | dump | tail' % sys.argv[0])
  70. print('Control the KVM flight recorder tracing.')
  71. sys.exit(0)
  72. def main():
  73. if len(sys.argv) < 2:
  74. usage()
  75. cmd = sys.argv[1]
  76. if cmd == '--version':
  77. print('kvm_flightrecorder version 1.0')
  78. sys.exit(0)
  79. if not os.path.isdir(tracing_dir):
  80. print('Unable to tracing debugfs directory, try:')
  81. print('mount -t debugfs none /sys/kernel/debug')
  82. sys.exit(1)
  83. if not os.access(tracing_dir, os.W_OK):
  84. print('Unable to write to tracing debugfs directory, please run as root')
  85. sys.exit(1)
  86. if cmd == 'start':
  87. stop_tracing() # clean up first
  88. if len(sys.argv) == 3:
  89. try:
  90. buffer_size_kb = int(sys.argv[2])
  91. except ValueError:
  92. print('Invalid per-cpu trace buffer size in KB')
  93. sys.exit(1)
  94. write_file(trace_path('buffer_size_kb'), str(buffer_size_kb))
  95. print('Per-CPU ring buffer size set to %d KB' % buffer_size_kb)
  96. start_tracing()
  97. print('KVM flight recorder enabled')
  98. elif cmd == 'stop':
  99. stop_tracing()
  100. print('KVM flight recorder disabled')
  101. elif cmd == 'dump':
  102. dump_trace()
  103. elif cmd == 'tail':
  104. tail_trace()
  105. else:
  106. usage()
  107. if __name__ == '__main__':
  108. sys.exit(main())