1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3
4#
5#	test_adding_kernel of perf_probe test
6#	Author: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
7#	Author: Michael Petlan <mpetlan@redhat.com>
8#
9#	Description:
10#
11#		This test tests adding of probes, their correct listing
12#		and removing.
13#
14
15# include working environment
16. ../common/init.sh
17. ./settings.sh
18
19# shellcheck disable=SC2034 # the variable is later used after the working environment is included
20THIS_TEST_NAME=`basename $0 .sh`
21TEST_RESULT=0
22
23TEST_PROBE=${TEST_PROBE:-"inode_permission"}
24
25check_kprobes_available
26if [ $? -ne 0 ]; then
27	print_overall_skipped
28	exit 0
29fi
30
31
32### basic probe adding
33
34for opt in "" "-a" "--add"; do
35	clear_all_probes
36	$CMD_PERF probe $opt $TEST_PROBE 2> $LOGS_DIR/adding_kernel_add$opt.err
37	PERF_EXIT_CODE=$?
38
39	../common/check_all_patterns_found.pl "Added new events?:" "probe:$TEST_PROBE" "on $TEST_PROBE" < $LOGS_DIR/adding_kernel_add$opt.err
40	CHECK_EXIT_CODE=$?
41
42	print_results $PERF_EXIT_CODE $CHECK_EXIT_CODE "adding probe $TEST_PROBE :: $opt"
43	(( TEST_RESULT += $? ))
44done
45
46
47### listing added probe :: perf list
48
49# any added probes should appear in perf-list output
50$CMD_PERF list probe:\* > $LOGS_DIR/adding_kernel_list.log
51PERF_EXIT_CODE=$?
52
53../common/check_all_lines_matched.pl "$RE_LINE_EMPTY" "List of pre-defined events" "probe:${TEST_PROBE}(?:_\d+)?\s+\[Tracepoint event\]" "Metric Groups:" < $LOGS_DIR/adding_kernel_list.log
54CHECK_EXIT_CODE=$?
55
56print_results $PERF_EXIT_CODE $CHECK_EXIT_CODE "listing added probe :: perf list"
57(( TEST_RESULT += $? ))
58
59
60### listing added probe :: perf probe -l
61
62# '-l' should list all the added probes as well
63$CMD_PERF probe -l > $LOGS_DIR/adding_kernel_list-l.log
64PERF_EXIT_CODE=$?
65
66../common/check_all_patterns_found.pl "\s*probe:${TEST_PROBE}(?:_\d+)?\s+\(on ${TEST_PROBE}(?:[:\+]$RE_NUMBER_HEX)?@.+\)" < $LOGS_DIR/adding_kernel_list-l.log
67CHECK_EXIT_CODE=$?
68
69print_results $PERF_EXIT_CODE $CHECK_EXIT_CODE "listing added probe :: perf probe -l"
70(( TEST_RESULT += $? ))
71
72
73### using added probe
74
75$CMD_PERF stat -e probe:$TEST_PROBE\* -o $LOGS_DIR/adding_kernel_using_probe.log -- cat /proc/uptime > /dev/null
76PERF_EXIT_CODE=$?
77
78REGEX_STAT_HEADER="\s*Performance counter stats for \'cat /proc/uptime\':"
79REGEX_STAT_VALUES="\s*\d+\s+probe:$TEST_PROBE"
80# the value should be greater than 1
81REGEX_STAT_VALUE_NONZERO="\s*[1-9][0-9]*\s+probe:$TEST_PROBE"
82REGEX_STAT_TIME="\s*$RE_NUMBER\s+seconds (?:time elapsed|user|sys)"
83../common/check_all_lines_matched.pl "$REGEX_STAT_HEADER" "$REGEX_STAT_VALUES" "$REGEX_STAT_TIME" "$RE_LINE_COMMENT" "$RE_LINE_EMPTY" < $LOGS_DIR/adding_kernel_using_probe.log
84CHECK_EXIT_CODE=$?
85../common/check_all_patterns_found.pl "$REGEX_STAT_HEADER" "$REGEX_STAT_VALUE_NONZERO" "$REGEX_STAT_TIME" < $LOGS_DIR/adding_kernel_using_probe.log
86(( CHECK_EXIT_CODE += $? ))
87
88print_results $PERF_EXIT_CODE $CHECK_EXIT_CODE "using added probe"
89(( TEST_RESULT += $? ))
90
91
92### removing added probe
93
94# '-d' should remove the probe
95$CMD_PERF probe -d $TEST_PROBE\* 2> $LOGS_DIR/adding_kernel_removing.err
96PERF_EXIT_CODE=$?
97
98../common/check_all_lines_matched.pl "Removed event: probe:$TEST_PROBE" < $LOGS_DIR/adding_kernel_removing.err
99CHECK_EXIT_CODE=$?
100
101print_results $PERF_EXIT_CODE $CHECK_EXIT_CODE "deleting added probe"
102(( TEST_RESULT += $? ))
103
104
105### listing removed probe
106
107# removed probes should NOT appear in perf-list output
108$CMD_PERF list probe:\* > $LOGS_DIR/adding_kernel_list_removed.log
109PERF_EXIT_CODE=$?
110
111../common/check_all_lines_matched.pl "$RE_LINE_EMPTY" "List of pre-defined events" "Metric Groups:" < $LOGS_DIR/adding_kernel_list_removed.log
112CHECK_EXIT_CODE=$?
113
114print_results $PERF_EXIT_CODE $CHECK_EXIT_CODE "listing removed probe (should NOT be listed)"
115(( TEST_RESULT += $? ))
116
117
118### dry run
119
120# the '-n' switch should run it in dry mode
121$CMD_PERF probe -n --add $TEST_PROBE 2> $LOGS_DIR/adding_kernel_dryrun.err
122PERF_EXIT_CODE=$?
123
124# check for the output (should be the same as usual)
125../common/check_all_patterns_found.pl "Added new events?:" "probe:$TEST_PROBE" "on $TEST_PROBE" < $LOGS_DIR/adding_kernel_dryrun.err
126CHECK_EXIT_CODE=$?
127
128# check that no probe was added in real
129! ( $CMD_PERF probe -l | grep "probe:$TEST_PROBE" )
130(( CHECK_EXIT_CODE += $? ))
131
132print_results $PERF_EXIT_CODE $CHECK_EXIT_CODE "dry run :: adding probe"
133(( TEST_RESULT += $? ))
134
135
136### force-adding probes
137
138# when using '--force' a probe should be added even if it is already there
139$CMD_PERF probe --add $TEST_PROBE 2> $LOGS_DIR/adding_kernel_forceadd_01.err
140PERF_EXIT_CODE=$?
141
142../common/check_all_patterns_found.pl "Added new events?:" "probe:$TEST_PROBE" "on $TEST_PROBE" < $LOGS_DIR/adding_kernel_forceadd_01.err
143CHECK_EXIT_CODE=$?
144
145print_results $PERF_EXIT_CODE $CHECK_EXIT_CODE "force-adding probes :: first probe adding"
146(( TEST_RESULT += $? ))
147
148# adding existing probe without '--force' should fail
149! $CMD_PERF probe --add $TEST_PROBE 2> $LOGS_DIR/adding_kernel_forceadd_02.err
150PERF_EXIT_CODE=$?
151
152../common/check_all_patterns_found.pl "Error: event \"$TEST_PROBE\" already exists." "Error: Failed to add events." < $LOGS_DIR/adding_kernel_forceadd_02.err
153CHECK_EXIT_CODE=$?
154
155print_results $PERF_EXIT_CODE $CHECK_EXIT_CODE "force-adding probes :: second probe adding (without force)"
156(( TEST_RESULT += $? ))
157
158# adding existing probe with '--force' should pass
159NO_OF_PROBES=`$CMD_PERF probe -l | wc -l`
160$CMD_PERF probe --force --add $TEST_PROBE 2> $LOGS_DIR/adding_kernel_forceadd_03.err
161PERF_EXIT_CODE=$?
162
163../common/check_all_patterns_found.pl "Added new events?:" "probe:${TEST_PROBE}_${NO_OF_PROBES}" "on $TEST_PROBE" < $LOGS_DIR/adding_kernel_forceadd_03.err
164CHECK_EXIT_CODE=$?
165
166print_results $PERF_EXIT_CODE $CHECK_EXIT_CODE "force-adding probes :: second probe adding (with force)"
167(( TEST_RESULT += $? ))
168
169
170### using doubled probe
171
172# since they are the same, they should produce the same results
173$CMD_PERF stat -e probe:$TEST_PROBE -e probe:${TEST_PROBE}_${NO_OF_PROBES} -x';' -o $LOGS_DIR/adding_kernel_using_two.log -- bash -c 'cat /proc/cpuinfo > /dev/null'
174PERF_EXIT_CODE=$?
175
176REGEX_LINE="$RE_NUMBER;+probe:${TEST_PROBE}_?(?:$NO_OF_PROBES)?;$RE_NUMBER;$RE_NUMBER"
177../common/check_all_lines_matched.pl "$REGEX_LINE" "$RE_LINE_EMPTY" "$RE_LINE_COMMENT" < $LOGS_DIR/adding_kernel_using_two.log
178CHECK_EXIT_CODE=$?
179
180VALUE_1=`grep "$TEST_PROBE;" $LOGS_DIR/adding_kernel_using_two.log | awk -F';' '{print $1}'`
181VALUE_2=`grep "${TEST_PROBE}_${NO_OF_PROBES};" $LOGS_DIR/adding_kernel_using_two.log | awk -F';' '{print $1}'`
182
183test $VALUE_1 -eq $VALUE_2
184(( CHECK_EXIT_CODE += $? ))
185
186print_results $PERF_EXIT_CODE $CHECK_EXIT_CODE "using doubled probe"
187
188
189### removing multiple probes
190
191# using wildcards should remove all matching probes
192$CMD_PERF probe --del \* 2> $LOGS_DIR/adding_kernel_removing_wildcard.err
193PERF_EXIT_CODE=$?
194
195../common/check_all_lines_matched.pl "Removed event: probe:$TEST_PROBE" "Removed event: probe:${TEST_PROBE}_1" < $LOGS_DIR/adding_kernel_removing_wildcard.err
196CHECK_EXIT_CODE=$?
197
198print_results $PERF_EXIT_CODE $CHECK_EXIT_CODE "removing multiple probes"
199(( TEST_RESULT += $? ))
200
201
202### wildcard adding support
203
204$CMD_PERF probe -nf --max-probes=512 -a 'vfs_* $params' 2> $LOGS_DIR/adding_kernel_adding_wildcard.err
205PERF_EXIT_CODE=$?
206
207../common/check_all_patterns_found.pl "probe:vfs_mknod" "probe:vfs_create" "probe:vfs_rmdir" "probe:vfs_link" "probe:vfs_write" < $LOGS_DIR/adding_kernel_adding_wildcard.err
208CHECK_EXIT_CODE=$?
209
210print_results $PERF_EXIT_CODE $CHECK_EXIT_CODE "wildcard adding support"
211(( TEST_RESULT += $? ))
212
213
214### non-existing variable
215
216# perf probe should survive a non-existing variable probing attempt
217{ $CMD_PERF probe 'vfs_read somenonexistingrandomstuffwhichisalsoprettylongorevenlongertoexceed64' ; } 2> $LOGS_DIR/adding_kernel_nonexisting.err
218PERF_EXIT_CODE=$?
219
220# the exitcode should not be 0 or segfault
221test $PERF_EXIT_CODE -ne 139 -a $PERF_EXIT_CODE -ne 0
222PERF_EXIT_CODE=$?
223
224# check that the error message is reasonable
225../common/check_all_patterns_found.pl "Failed to find" "somenonexistingrandomstuffwhichisalsoprettylongorevenlongertoexceed64" < $LOGS_DIR/adding_kernel_nonexisting.err
226CHECK_EXIT_CODE=$?
227../common/check_all_patterns_found.pl "in this function|at this address" "Error" "Failed to add events" < $LOGS_DIR/adding_kernel_nonexisting.err
228(( CHECK_EXIT_CODE += $? ))
229../common/check_all_lines_matched.pl "Failed to find" "Error" "Probe point .+ not found" "optimized out" "Use.+\-\-range option to show.+location range" < $LOGS_DIR/adding_kernel_nonexisting.err
230(( CHECK_EXIT_CODE += $? ))
231../common/check_no_patterns_found.pl "$RE_SEGFAULT" < $LOGS_DIR/adding_kernel_nonexisting.err
232(( CHECK_EXIT_CODE += $? ))
233
234print_results $PERF_EXIT_CODE $CHECK_EXIT_CODE "non-existing variable"
235(( TEST_RESULT += $? ))
236
237
238### function with return value
239
240# adding probe with return value
241$CMD_PERF probe --add "$TEST_PROBE%return \$retval" 2> $LOGS_DIR/adding_kernel_func_retval_add.err
242PERF_EXIT_CODE=$?
243
244../common/check_all_patterns_found.pl "Added new events?:" "probe:$TEST_PROBE" "on $TEST_PROBE%return with \\\$retval" < $LOGS_DIR/adding_kernel_func_retval_add.err
245CHECK_EXIT_CODE=$?
246
247print_results $PERF_EXIT_CODE $CHECK_EXIT_CODE "function with retval :: add"
248(( TEST_RESULT += $? ))
249
250# recording some data
251$CMD_PERF record -e probe:$TEST_PROBE\* -o $CURRENT_TEST_DIR/perf.data -- cat /proc/cpuinfo > /dev/null 2> $LOGS_DIR/adding_kernel_func_retval_record.err
252PERF_EXIT_CODE=$?
253
254../common/check_all_patterns_found.pl "$RE_LINE_RECORD1" "$RE_LINE_RECORD2" < $LOGS_DIR/adding_kernel_func_retval_record.err
255CHECK_EXIT_CODE=$?
256
257print_results $PERF_EXIT_CODE $CHECK_EXIT_CODE "function with retval :: record"
258(( TEST_RESULT += $? ))
259
260# perf script should report the function calls with the correct arg values
261$CMD_PERF script -i $CURRENT_TEST_DIR/perf.data > $LOGS_DIR/adding_kernel_func_retval_script.log
262PERF_EXIT_CODE=$?
263
264REGEX_SCRIPT_LINE="\s*cat\s+$RE_NUMBER\s+\[$RE_NUMBER\]\s+$RE_NUMBER:\s+probe:$TEST_PROBE\w*:\s+\($RE_NUMBER_HEX\s+<\-\s+$RE_NUMBER_HEX\)\s+arg1=$RE_NUMBER_HEX"
265../common/check_all_lines_matched.pl "$REGEX_SCRIPT_LINE" < $LOGS_DIR/adding_kernel_func_retval_script.log
266CHECK_EXIT_CODE=$?
267../common/check_all_patterns_found.pl "$REGEX_SCRIPT_LINE" < $LOGS_DIR/adding_kernel_func_retval_script.log
268(( CHECK_EXIT_CODE += $? ))
269
270print_results $PERF_EXIT_CODE $CHECK_EXIT_CODE "function argument probing :: script"
271(( TEST_RESULT += $? ))
272
273
274clear_all_probes
275
276# print overall results
277print_overall_results "$TEST_RESULT"
278exit $?
279