LAVA: install `systemtap-sdt-dev` package to run sdt-uprobe tests
[lttng-ci.git] / scripts / system-tests / run-kprobe-fuzzing.py
1 # Copyright (C) 2018 - Francis Deslauriers <francis.deslauriers@efficios.com>
2 #
3 # This program is free software: you can redistribute it and/or modify
4 # it under the terms of the GNU General Public License as published by
5 # the Free Software Foundation, either version 3 of the License, or
6 # (at your option) any later version.
7 #
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
12 #
13 # You should have received a copy of the GNU General Public License
14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15
16 import datetime
17 import gzip
18 import os
19 import pprint
20 import subprocess
21 import sys
22
23 NB_KPROBES_PER_ITER=500
24 NB_KPROBES_PER_ROUND=20000
25
26 def load_instr_points(instr_points_archive):
27 print('Reading instrumentation points from \'{}\'.'.format(instr_points_archive), end='')
28 sys.stdout.flush()
29
30 with gzip.open(instr_points_archive, 'r') as f:
31 data = f.read()
32 print(' Done.')
33
34 return [x.decode('utf-8') for x in data.split()]
35
36 def enable_kprobe_events(instr_points):
37 print('Enabling events from {} to {}...'.format(instr_points[0], instr_points[-1]), end='')
38 sys.stdout.flush()
39
40 # Use os module directly, because this is a sysfs file and seeking inside
41 # the file is not supported. The python open() function with the append
42 # ('a') flag uses lseek(, SEEK_END) to move the write pointer to the end.
43 fd = os.open('/sys/kernel/debug/tracing/kprobe_events', os.O_WRONLY|os.O_CREAT|os.O_APPEND)
44 for i, point in enumerate(instr_points):
45
46 kprobe_cmd = 'r:event_{} {}\n'.format(i, point).encode('utf-8')
47 try:
48 os.write(fd, kprobe_cmd)
49 except OSError:
50 continue
51 os.close(fd)
52 print(' Done.')
53
54 def set_kprobe_tracing_state(state):
55 if state not in (0 ,1):
56 raise ValueError
57
58 try:
59 with open('/sys/kernel/debug/tracing/events/kprobes/enable', 'w') as enable_kprobe_file:
60 enable_kprobe_file.write('{}\n'.format(state))
61 except IOError:
62 print('kprobes/enable file does not exist')
63
64 if state == 0:
65 # Clear the content of the trace.
66 open('/sys/kernel/debug/tracing/trace', 'w').close()
67 # Clear all the events.
68 open('/sys/kernel/debug/tracing/kprobe_events', 'w').close()
69
70 def run_workload():
71 print('Running workload...', end='')
72 sys.stdout.flush()
73 workload = ['stress', '--cpu', '2', '--io', '4', '--vm', '2',
74 '--vm-bytes', '128M', '--hdd', '3', '--timeout', '3s']
75 try:
76 with open(os.devnull) as devnull:
77 subprocess.call(workload, stdout=devnull, stderr=devnull)
78 except OSError as e:
79 print("Workload execution failed:", e, file=sys.stderr)
80 pprint.pprint(workload)
81
82 print(' Done.')
83
84 def mount_tracingfs():
85 with open(os.devnull) as devnull:
86 subprocess.call(['mount', '-t', 'debugfs', 'nodev', '/sys/kernel/debug/'],
87 stdout=devnull, stderr=devnull)
88
89 def print_dashed_line():
90 print('-'*100)
91
92 def main():
93 assert(len(sys.argv) == 3)
94
95 instr_point_archive = sys.argv[1]
96 round_nb = int(sys.argv[2])
97 # Load instrumentation points to disk and attach it to lava test run.
98 instrumentation_points = load_instr_points(instr_point_archive)
99
100 # We are past the end of the instrumentation point list.
101 if len(instrumentation_points)/NB_KPROBES_PER_ROUND <= round_nb:
102 print('No instrumentation point for round {}.'.format(round_nb))
103 return
104
105 mount_tracingfs()
106
107 # Loop over the list by enabling ranges of NB_KPROBES_PER_ITER kprobes.
108 for i in range(int(NB_KPROBES_PER_ROUND/NB_KPROBES_PER_ITER)):
109 print_dashed_line()
110 lower_bound = (round_nb * NB_KPROBES_PER_ROUND) + (i * NB_KPROBES_PER_ITER)
111 upper_bound = lower_bound + NB_KPROBES_PER_ITER
112 print('Time now: {}, {} to {}'.format(datetime.datetime.now(), lower_bound , upper_bound))
113 enable_kprobe_events(instrumentation_points[lower_bound:upper_bound])
114 set_kprobe_tracing_state(1)
115 run_workload()
116 print('\n')
117 set_kprobe_tracing_state(0)
118
119 if __name__ == "__main__":
120 main()
This page took 0.031781 seconds and 4 git commands to generate.