1#!/bin/sh
2# SPDX-License-Identifier: GPL-2.0
3# description: ftrace - test reading of set_ftrace_filter
4#
5# The triggers are set within the set_ftrace_filter file
6# requires: set_ftrace_filter
7#
8# The set_ftrace_filter file of ftrace is used to list functions as well as
9# triggers (probes) attached to functions. The code to read this file is not
10# straight forward and has had various bugs in the past. This test is designed
11# to add functions and triggers to that file in various ways and read that
12# file in various ways (cat vs dd).
13#
14
15fail() { # mesg
16    echo $1
17    exit_fail
18}
19
20FILTER=set_ftrace_filter
21FUNC1="schedule"
22FUNC2="scheduler_tick"
23
24ALL_FUNCS="#### all functions enabled ####"
25
26test_func() {
27    if ! echo "$1" | grep -q "^$2\$"; then
28	return 0
29    fi
30    echo "$1" | grep -v "^$2\$"
31    return 1
32}
33
34check_set_ftrace_filter() {
35    cat=`cat $FILTER`
36    dd1=`dd if=$FILTER bs=1 | grep -v -e 'records in' -e 'records out' -e 'bytes copied'`
37    dd100=`dd if=$FILTER bs=100 | grep -v -e 'records in' -e 'records out' -e 'bytes copied'`
38
39    echo "Testing '$@'"
40
41    while [ $# -gt 0 ]; do
42	echo "test $1"
43	if cat=`test_func "$cat" "$1"`; then
44	    return 0
45	fi
46	if dd1=`test_func "$dd1" "$1"`; then
47	    return 0
48	fi
49	if dd100=`test_func "$dd100" "$1"`; then
50	    return 0
51	fi
52	shift
53    done
54
55    if [ -n "$cat" ]; then
56	return 0
57    fi
58    if [ -n "$dd1" ]; then
59	return 0
60    fi
61    if [ -n "$dd100" ]; then
62	return 0
63    fi
64    return 1;
65}
66
67if check_set_ftrace_filter "$ALL_FUNCS"; then
68    fail "Expected only $ALL_FUNCS"
69fi
70
71echo "$FUNC1:traceoff" > set_ftrace_filter
72if check_set_ftrace_filter "$ALL_FUNCS" "$FUNC1:traceoff:unlimited"; then
73    fail "Expected $ALL_FUNCS and $FUNC1:traceoff:unlimited"
74fi
75
76echo "$FUNC1" > set_ftrace_filter
77if check_set_ftrace_filter "$FUNC1" "$FUNC1:traceoff:unlimited"; then
78    fail "Expected $FUNC1 and $FUNC1:traceoff:unlimited"
79fi
80
81echo "$FUNC2" >> set_ftrace_filter
82if check_set_ftrace_filter "$FUNC1" "$FUNC2" "$FUNC1:traceoff:unlimited"; then
83    fail "Expected $FUNC1 $FUNC2 and $FUNC1:traceoff:unlimited"
84fi
85
86echo "$FUNC2:traceoff" >> set_ftrace_filter
87if check_set_ftrace_filter "$FUNC1" "$FUNC2" "$FUNC1:traceoff:unlimited" "$FUNC2:traceoff:unlimited"; then
88    fail "Expected $FUNC1 $FUNC2 $FUNC1:traceoff:unlimited and $FUNC2:traceoff:unlimited"
89fi
90
91echo "$FUNC1" > set_ftrace_filter
92if check_set_ftrace_filter "$FUNC1" "$FUNC1:traceoff:unlimited" "$FUNC2:traceoff:unlimited"; then
93    fail "Expected $FUNC1 $FUNC1:traceoff:unlimited and $FUNC2:traceoff:unlimited"
94fi
95
96echo > set_ftrace_filter
97if check_set_ftrace_filter "$ALL_FUNCS" "$FUNC1:traceoff:unlimited" "$FUNC2:traceoff:unlimited"; then
98    fail "Expected $ALL_FUNCS $FUNC1:traceoff:unlimited and $FUNC2:traceoff:unlimited"
99fi
100
101reset_ftrace_filter
102
103if check_set_ftrace_filter "$ALL_FUNCS"; then
104    fail "Expected $ALL_FUNCS"
105fi
106
107echo "$FUNC1" > set_ftrace_filter
108if check_set_ftrace_filter "$FUNC1" ; then
109    fail "Expected $FUNC1"
110fi
111
112echo "$FUNC2" >> set_ftrace_filter
113if check_set_ftrace_filter "$FUNC1" "$FUNC2" ; then
114    fail "Expected $FUNC1 and $FUNC2"
115fi
116
117test_actual() { # Compares $TMPDIR/expected with set_ftrace_filter
118    cat set_ftrace_filter | grep -v '#' | cut -d' ' -f1 | cut -d':' -f1 | sort -u > $TMPDIR/actual
119    DIFF=`diff $TMPDIR/actual $TMPDIR/expected`
120    test -z "$DIFF"
121}
122
123# Set traceoff trigger for all fuctions with "lock" in their name
124cat available_filter_functions | cut -d' ' -f1 |  grep 'lock' | sort -u > $TMPDIR/expected
125echo '*lock*:traceoff' > set_ftrace_filter
126test_actual
127
128# now remove all with 'try' in it, and end with lock
129grep -v 'try.*lock$' $TMPDIR/expected > $TMPDIR/expected2
130mv $TMPDIR/expected2 $TMPDIR/expected
131echo '!*try*lock:traceoff' >> set_ftrace_filter
132test_actual
133
134# remove all that start with "m" and end with "lock"
135grep -v '^m.*lock$' $TMPDIR/expected > $TMPDIR/expected2
136mv $TMPDIR/expected2 $TMPDIR/expected
137echo '!m*lock:traceoff' >> set_ftrace_filter
138test_actual
139
140# remove all that start with "c" and have "unlock"
141grep -v '^c.*unlock' $TMPDIR/expected > $TMPDIR/expected2
142mv $TMPDIR/expected2 $TMPDIR/expected
143echo '!c*unlock*:traceoff' >> set_ftrace_filter
144test_actual
145
146# clear all the rest
147> $TMPDIR/expected
148echo '!*:traceoff' >> set_ftrace_filter
149test_actual
150
151rm $TMPDIR/expected
152rm $TMPDIR/actual
153
154exit 0
155