xref: /OK3568_Linux_fs/kernel/tools/testing/selftests/lkdtm/run.sh (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun#!/bin/sh
2*4882a593Smuzhiyun# SPDX-License-Identifier: GPL-2.0
3*4882a593Smuzhiyun#
4*4882a593Smuzhiyun# This reads tests.txt for the list of LKDTM tests to invoke. Any marked
5*4882a593Smuzhiyun# with a leading "#" are skipped. The rest of the line after the
6*4882a593Smuzhiyun# test name is either the text to look for in dmesg for a "success",
7*4882a593Smuzhiyun# or the rationale for why a test is marked to be skipped.
8*4882a593Smuzhiyun#
9*4882a593Smuzhiyunset -e
10*4882a593SmuzhiyunTRIGGER=/sys/kernel/debug/provoke-crash/DIRECT
11*4882a593SmuzhiyunCLEAR_ONCE=/sys/kernel/debug/clear_warn_once
12*4882a593SmuzhiyunKSELFTEST_SKIP_TEST=4
13*4882a593Smuzhiyun
14*4882a593Smuzhiyun# Verify we have LKDTM available in the kernel.
15*4882a593Smuzhiyunif [ ! -r $TRIGGER ] ; then
16*4882a593Smuzhiyun	/sbin/modprobe -q lkdtm || true
17*4882a593Smuzhiyun	if [ ! -r $TRIGGER ] ; then
18*4882a593Smuzhiyun		echo "Cannot find $TRIGGER (missing CONFIG_LKDTM?)"
19*4882a593Smuzhiyun	else
20*4882a593Smuzhiyun		echo "Cannot write $TRIGGER (need to run as root?)"
21*4882a593Smuzhiyun	fi
22*4882a593Smuzhiyun	# Skip this test
23*4882a593Smuzhiyun	exit $KSELFTEST_SKIP_TEST
24*4882a593Smuzhiyunfi
25*4882a593Smuzhiyun
26*4882a593Smuzhiyun# Figure out which test to run from our script name.
27*4882a593Smuzhiyuntest=$(basename $0 .sh)
28*4882a593Smuzhiyun# Look up details about the test from master list of LKDTM tests.
29*4882a593Smuzhiyunline=$(grep -E '^#?'"$test"'\b' tests.txt)
30*4882a593Smuzhiyunif [ -z "$line" ]; then
31*4882a593Smuzhiyun	echo "Skipped: missing test '$test' in tests.txt"
32*4882a593Smuzhiyun	exit $KSELFTEST_SKIP_TEST
33*4882a593Smuzhiyunfi
34*4882a593Smuzhiyun# Check that the test is known to LKDTM.
35*4882a593Smuzhiyunif ! grep -E -q '^'"$test"'$' "$TRIGGER" ; then
36*4882a593Smuzhiyun	echo "Skipped: test '$test' missing in $TRIGGER!"
37*4882a593Smuzhiyun	exit $KSELFTEST_SKIP_TEST
38*4882a593Smuzhiyunfi
39*4882a593Smuzhiyun
40*4882a593Smuzhiyun# Extract notes/expected output from test list.
41*4882a593Smuzhiyuntest=$(echo "$line" | cut -d" " -f1)
42*4882a593Smuzhiyunif echo "$line" | grep -q ' ' ; then
43*4882a593Smuzhiyun	expect=$(echo "$line" | cut -d" " -f2-)
44*4882a593Smuzhiyunelse
45*4882a593Smuzhiyun	expect=""
46*4882a593Smuzhiyunfi
47*4882a593Smuzhiyun
48*4882a593Smuzhiyun# If the test is commented out, report a skip
49*4882a593Smuzhiyunif echo "$test" | grep -q '^#' ; then
50*4882a593Smuzhiyun	test=$(echo "$test" | cut -c2-)
51*4882a593Smuzhiyun	if [ -z "$expect" ]; then
52*4882a593Smuzhiyun		expect="crashes entire system"
53*4882a593Smuzhiyun	fi
54*4882a593Smuzhiyun	echo "Skipping $test: $expect"
55*4882a593Smuzhiyun	exit $KSELFTEST_SKIP_TEST
56*4882a593Smuzhiyunfi
57*4882a593Smuzhiyun
58*4882a593Smuzhiyun# If no expected output given, assume an Oops with back trace is success.
59*4882a593Smuzhiyunif [ -z "$expect" ]; then
60*4882a593Smuzhiyun	expect="call trace:"
61*4882a593Smuzhiyunfi
62*4882a593Smuzhiyun
63*4882a593Smuzhiyun# Prepare log for report checking
64*4882a593SmuzhiyunLOG=$(mktemp --tmpdir -t lkdtm-log-XXXXXX)
65*4882a593SmuzhiyunDMESG=$(mktemp --tmpdir -t lkdtm-dmesg-XXXXXX)
66*4882a593Smuzhiyuncleanup() {
67*4882a593Smuzhiyun	rm -f "$LOG" "$DMESG"
68*4882a593Smuzhiyun}
69*4882a593Smuzhiyuntrap cleanup EXIT
70*4882a593Smuzhiyun
71*4882a593Smuzhiyun# Reset WARN_ONCE counters so we trip it each time this runs.
72*4882a593Smuzhiyunif [ -w $CLEAR_ONCE ] ; then
73*4882a593Smuzhiyun	echo 1 > $CLEAR_ONCE
74*4882a593Smuzhiyunfi
75*4882a593Smuzhiyun
76*4882a593Smuzhiyun# Save existing dmesg so we can detect new content below
77*4882a593Smuzhiyundmesg > "$DMESG"
78*4882a593Smuzhiyun
79*4882a593Smuzhiyun# Since the kernel is likely killing the process writing to the trigger
80*4882a593Smuzhiyun# file, it must not be the script's shell itself. i.e. we cannot do:
81*4882a593Smuzhiyun#     echo "$test" >"$TRIGGER"
82*4882a593Smuzhiyun# Instead, use "cat" to take the signal. Since the shell will yell about
83*4882a593Smuzhiyun# the signal that killed the subprocess, we must ignore the failure and
84*4882a593Smuzhiyun# continue. However we don't silence stderr since there might be other
85*4882a593Smuzhiyun# useful details reported there in the case of other unexpected conditions.
86*4882a593Smuzhiyunecho "$test" | cat >"$TRIGGER" || true
87*4882a593Smuzhiyun
88*4882a593Smuzhiyun# Record and dump the results
89*4882a593Smuzhiyundmesg | comm --nocheck-order -13 "$DMESG" - > "$LOG" || true
90*4882a593Smuzhiyun
91*4882a593Smuzhiyuncat "$LOG"
92*4882a593Smuzhiyun# Check for expected output
93*4882a593Smuzhiyunif grep -E -qi "$expect" "$LOG" ; then
94*4882a593Smuzhiyun	echo "$test: saw '$expect': ok"
95*4882a593Smuzhiyun	exit 0
96*4882a593Smuzhiyunelse
97*4882a593Smuzhiyun	if grep -E -qi XFAIL: "$LOG" ; then
98*4882a593Smuzhiyun		echo "$test: saw 'XFAIL': [SKIP]"
99*4882a593Smuzhiyun		exit $KSELFTEST_SKIP_TEST
100*4882a593Smuzhiyun	else
101*4882a593Smuzhiyun		echo "$test: missing '$expect': [FAIL]"
102*4882a593Smuzhiyun		exit 1
103*4882a593Smuzhiyun	fi
104*4882a593Smuzhiyunfi
105