aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/tools/testing/selftests/ftrace/test.d/ftrace/func_set_ftrace_file.tc
blob: 51f6e6146bd93a8c422d9c79cc30d02fdc010cc1 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0
# description: ftrace - test reading of set_ftrace_filter
#
# The set_ftrace_filter file of ftrace is used to list functions as well as
# triggers (probes) attached to functions. The code to read this file is not
# straight forward and has had various bugs in the past. This test is designed
# to add functions and triggers to that file in various ways and read that
# file in various ways (cat vs dd).
#

# The triggers are set within the set_ftrace_filter file
if [ ! -f set_ftrace_filter ]; then
    echo "set_ftrace_filter not found? Is dynamic ftrace not set?"
    exit_unsupported
fi

fail() { # mesg
    echo $1
    exit_fail
}

FILTER=set_ftrace_filter
FUNC1="schedule"
FUNC2="do_softirq"

ALL_FUNCS="#### all functions enabled ####"

test_func() {
    if ! echo "$1" | grep -q "^$2\$"; then
	return 0
    fi
    echo "$1" | grep -v "^$2\$"
    return 1
}

check_set_ftrace_filter() {
    cat=`cat $FILTER`
    dd1=`dd if=$FILTER bs=1 | grep -v -e 'records in' -e 'records out' -e 'bytes copied'`
    dd100=`dd if=$FILTER bs=100 | grep -v -e 'records in' -e 'records out' -e 'bytes copied'`

    echo "Testing '$@'"

    while [ $# -gt 0 ]; do
	echo "test $1"
	if cat=`test_func "$cat" "$1"`; then
	    return 0
	fi
	if dd1=`test_func "$dd1" "$1"`; then
	    return 0
	fi
	if dd100=`test_func "$dd100" "$1"`; then
	    return 0
	fi
	shift
    done

    if [ -n "$cat" ]; then
	return 0
    fi
    if [ -n "$dd1" ]; then
	return 0
    fi
    if [ -n "$dd100" ]; then
	return 0
    fi
    return 1;
}

if check_set_ftrace_filter "$ALL_FUNCS"; then
    fail "Expected only $ALL_FUNCS"
fi

echo "$FUNC1:traceoff" > set_ftrace_filter
if check_set_ftrace_filter "$ALL_FUNCS" "$FUNC1:traceoff:unlimited"; then
    fail "Expected $ALL_FUNCS and $FUNC1:traceoff:unlimited"
fi

echo "$FUNC1" > set_ftrace_filter
if check_set_ftrace_filter "$FUNC1" "$FUNC1:traceoff:unlimited"; then
    fail "Expected $FUNC1 and $FUNC1:traceoff:unlimited"
fi

echo "$FUNC2" >> set_ftrace_filter
if check_set_ftrace_filter "$FUNC1" "$FUNC2" "$FUNC1:traceoff:unlimited"; then
    fail "Expected $FUNC1 $FUNC2 and $FUNC1:traceoff:unlimited"
fi

echo "$FUNC2:traceoff" >> set_ftrace_filter
if check_set_ftrace_filter "$FUNC1" "$FUNC2" "$FUNC1:traceoff:unlimited" "$FUNC2:traceoff:unlimited"; then
    fail "Expected $FUNC1 $FUNC2 $FUNC1:traceoff:unlimited and $FUNC2:traceoff:unlimited"
fi

echo "$FUNC1" > set_ftrace_filter
if check_set_ftrace_filter "$FUNC1" "$FUNC1:traceoff:unlimited" "$FUNC2:traceoff:unlimited"; then
    fail "Expected $FUNC1 $FUNC1:traceoff:unlimited and $FUNC2:traceoff:unlimited"
fi

echo > set_ftrace_filter
if check_set_ftrace_filter "$ALL_FUNCS" "$FUNC1:traceoff:unlimited" "$FUNC2:traceoff:unlimited"; then
    fail "Expected $ALL_FUNCS $FUNC1:traceoff:unlimited and $FUNC2:traceoff:unlimited"
fi

reset_ftrace_filter

if check_set_ftrace_filter "$ALL_FUNCS"; then
    fail "Expected $ALL_FUNCS"
fi

echo "$FUNC1" > set_ftrace_filter
if check_set_ftrace_filter "$FUNC1" ; then
    fail "Expected $FUNC1"
fi

echo "$FUNC2" >> set_ftrace_filter
if check_set_ftrace_filter "$FUNC1" "$FUNC2" ; then
    fail "Expected $FUNC1 and $FUNC2"
fi

test_actual() { # Compares $TMPDIR/expected with set_ftrace_filter
    cat set_ftrace_filter | grep -v '#' | cut -d' ' -f1 | cut -d':' -f1 | sort -u > $TMPDIR/actual
    DIFF=`diff $TMPDIR/actual $TMPDIR/expected`
    test -z "$DIFF"
}

# Set traceoff trigger for all fuctions with "lock" in their name
cat available_filter_functions | cut -d' ' -f1 |  grep 'lock' | sort -u > $TMPDIR/expected
echo '*lock*:traceoff' > set_ftrace_filter
test_actual

# now remove all with 'try' in it, and end with lock
grep -v 'try.*lock$' $TMPDIR/expected > $TMPDIR/expected2
mv $TMPDIR/expected2 $TMPDIR/expected
echo '!*try*lock:traceoff' >> set_ftrace_filter
test_actual

# remove all that start with "m" and end with "lock"
grep -v '^m.*lock$' $TMPDIR/expected > $TMPDIR/expected2
mv $TMPDIR/expected2 $TMPDIR/expected
echo '!m*lock:traceoff' >> set_ftrace_filter
test_actual

# remove all that start with "c" and have "unlock"
grep -v '^c.*unlock' $TMPDIR/expected > $TMPDIR/expected2
mv $TMPDIR/expected2 $TMPDIR/expected
echo '!c*unlock*:traceoff' >> set_ftrace_filter
test_actual

# clear all the rest
> $TMPDIR/expected
echo '!*:traceoff' >> set_ftrace_filter
test_actual

rm $TMPDIR/expected
rm $TMPDIR/actual

exit 0