Merge pull request #39 from frdeso/lava_improve_fuzzing
[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
25 def load_instr_points(instr_points_archive):
26 print('Reading instrumentation points from \'{}\'.'.format(instr_points_archive), end='')
27 sys.stdout.flush()
28
29 with gzip.open(instr_points_archive, 'r') as f:
30 data = f.read()
31 print(' Done.')
32
33 return [x.decode('utf-8') for x in data.split()]
34
35 def enable_kprobe_events(instr_points):
36 print('Enabling events...', end='')
37 sys.stdout.flush()
38
39 # Use os module directly, because this is a sysfs file and seeking inside
40 # the file is not supported. The python open() function with the append
41 # ('a') flag uses lseek(, SEEK_END) to move the write pointer to the end.
42 fd = os.open('/sys/kernel/debug/tracing/kprobe_events', os.O_WRONLY|os.O_CREAT|os.O_APPEND)
43 for i, point in enumerate(instr_points):
44
45 kprobe_cmd = 'r:event_{} {}\n'.format(i, point).encode('utf-8')
46 try:
47 os.write(fd, kprobe_cmd)
48 except OSError:
49 continue
50 os.close(fd)
51 print(' Done.')
52
53 def set_kprobe_tracing_state(state):
54 if state not in (0 ,1):
55 raise ValueError
56
57 if state == 0:
58 # Clear the content of the trace.
59 open('/sys/kernel/debug/tracing/trace', 'w').close()
60
61 try:
62 with open('/sys/kernel/debug/tracing/events/kprobes/enable', 'w') as enable_kprobe_file:
63 enable_kprobe_file.write('{}\n'.format(state))
64 except IOError:
65 print('kprobes/enable file does not exist')
66
67 def run_workload():
68 print('Running workload...', end='')
69 sys.stdout.flush()
70 workload = ['stress', '--cpu', '2', '--io', '4', '--vm', '2',
71 '--vm-bytes', '128M', '--hdd', '3', '--timeout', '3s']
72 try:
73 with open(os.devnull) as devnull:
74 subprocess.call(workload, stdout=devnull, stderr=devnull)
75 except OSError as e:
76 print("Workload execution failed:", e, file=sys.stderr)
77 pprint.pprint(workload)
78
79 print(' Done.')
80
81 def mount_tracingfs():
82 with open(os.devnull) as devnull:
83 subprocess.call(['mount', '-t', 'debugfs', 'nodev', '/sys/kernel/debug/'],
84 stdout=devnull, stderr=devnull)
85
86 def print_dashed_line():
87 print('-'*100)
88
89 def main():
90 assert(len(sys.argv) == 2)
91
92 instr_point_archive = sys.argv[1]
93 # Load instrumentation points to disk and attach it to lava test run.
94 instrumentation_points = load_instr_points(instr_point_archive)
95
96 mount_tracingfs()
97
98 # Loop over the list by enabling ranges of NB_KPROBES_PER_ITER kprobes.
99 for i in range(int(len(instrumentation_points)/NB_KPROBES_PER_ITER)):
100 print_dashed_line()
101 print('Time now: {}, {} to {}'.format(datetime.datetime.now(), i*NB_KPROBES_PER_ITER, (i+1)*NB_KPROBES_PER_ITER))
102 set_kprobe_tracing_state(0)
103 enable_kprobe_events(instrumentation_points[i*NB_KPROBES_PER_ITER:(i+1)*NB_KPROBES_PER_ITER])
104 set_kprobe_tracing_state(1)
105 run_workload()
106 print('\n')
107
108 if __name__ == "__main__":
109 main()
This page took 0.034711 seconds and 5 git commands to generate.