xref: /linux/tools/testing/selftests/kmod/kmod.sh (revision 7ae9fb1b7ecbb5d85d07857943f677fd1a559b18)
1d9c6a72dSLuis R. Rodriguez#!/bin/bash
2*6cad1ecdSLuis Chamberlain# SPDX-License-Identifier: GPL-2.0-or-later OR copyleft-next-0.3.1
3d9c6a72dSLuis R. Rodriguez# Copyright (C) 2017 Luis R. Rodriguez <mcgrof@kernel.org>
4d9c6a72dSLuis R. Rodriguez#
5d9c6a72dSLuis R. Rodriguez# This is a stress test script for kmod, the kernel module loader. It uses
6d9c6a72dSLuis R. Rodriguez# test_kmod which exposes a series of knobs for the API for us so we can
7d9c6a72dSLuis R. Rodriguez# tweak each test in userspace rather than in kernelspace.
8d9c6a72dSLuis R. Rodriguez#
9d9c6a72dSLuis R. Rodriguez# The way kmod works is it uses the kernel's usermode helper API to eventually
10d9c6a72dSLuis R. Rodriguez# call /sbin/modprobe. It has a limit of the number of concurrent calls
11d9c6a72dSLuis R. Rodriguez# possible. The kernel interface to load modules is request_module(), however
12d9c6a72dSLuis R. Rodriguez# mount uses get_fs_type(). Both behave slightly differently, but the
13d9c6a72dSLuis R. Rodriguez# differences are important enough to test each call separately. For this
14d9c6a72dSLuis R. Rodriguez# reason test_kmod starts by providing tests for both calls.
15d9c6a72dSLuis R. Rodriguez#
16d9c6a72dSLuis R. Rodriguez# The test driver test_kmod assumes a series of defaults which you can
17d9c6a72dSLuis R. Rodriguez# override by exporting to your environment prior running this script.
18d9c6a72dSLuis R. Rodriguez# For instance this script assumes you do not have xfs loaded upon boot.
19d9c6a72dSLuis R. Rodriguez# If this is false, export DEFAULT_KMOD_FS="ext4" prior to running this
2036876b30SMasanari Iida# script if the filesystem module you don't have loaded upon bootup
21d9c6a72dSLuis R. Rodriguez# is ext4 instead. Refer to allow_user_defaults() for a list of user
22d9c6a72dSLuis R. Rodriguez# override variables possible.
23d9c6a72dSLuis R. Rodriguez#
24d9c6a72dSLuis R. Rodriguez# You'll want at least 4 GiB of RAM to expect to run these tests
25d9c6a72dSLuis R. Rodriguez# without running out of memory on them. For other requirements refer
26d9c6a72dSLuis R. Rodriguez# to test_reqs()
27d9c6a72dSLuis R. Rodriguez
28d9c6a72dSLuis R. Rodriguezset -e
29d9c6a72dSLuis R. Rodriguez
30d9c6a72dSLuis R. RodriguezTEST_NAME="kmod"
31d9c6a72dSLuis R. RodriguezTEST_DRIVER="test_${TEST_NAME}"
32d9c6a72dSLuis R. RodriguezTEST_DIR=$(dirname $0)
33d9c6a72dSLuis R. Rodriguez
34d9c6a72dSLuis R. Rodriguez# This represents
35d9c6a72dSLuis R. Rodriguez#
36d9c6a72dSLuis R. Rodriguez# TEST_ID:TEST_COUNT:ENABLED
37d9c6a72dSLuis R. Rodriguez#
38d9c6a72dSLuis R. Rodriguez# TEST_ID: is the test id number
39d9c6a72dSLuis R. Rodriguez# TEST_COUNT: number of times we should run the test
40d9c6a72dSLuis R. Rodriguez# ENABLED: 1 if enabled, 0 otherwise
41d9c6a72dSLuis R. Rodriguez#
42d9c6a72dSLuis R. Rodriguez# Once these are enabled please leave them as-is. Write your own test,
43d9c6a72dSLuis R. Rodriguez# we have tons of space.
44d9c6a72dSLuis R. RodriguezALL_TESTS="0001:3:1"
45d9c6a72dSLuis R. RodriguezALL_TESTS="$ALL_TESTS 0002:3:1"
46d9c6a72dSLuis R. RodriguezALL_TESTS="$ALL_TESTS 0003:1:1"
47d9c6a72dSLuis R. RodriguezALL_TESTS="$ALL_TESTS 0004:1:1"
48d9c6a72dSLuis R. RodriguezALL_TESTS="$ALL_TESTS 0005:10:1"
49d9c6a72dSLuis R. RodriguezALL_TESTS="$ALL_TESTS 0006:10:1"
50d9c6a72dSLuis R. RodriguezALL_TESTS="$ALL_TESTS 0007:5:1"
516d7964a7SLuis R. RodriguezALL_TESTS="$ALL_TESTS 0008:150:1"
526d7964a7SLuis R. RodriguezALL_TESTS="$ALL_TESTS 0009:150:1"
5323756e55SEric BiggersALL_TESTS="$ALL_TESTS 0010:1:1"
5423756e55SEric BiggersALL_TESTS="$ALL_TESTS 0011:1:1"
55a80d6055SKees CookALL_TESTS="$ALL_TESTS 0012:1:1"
56a80d6055SKees CookALL_TESTS="$ALL_TESTS 0013:1:1"
57d9c6a72dSLuis R. Rodriguez
5882337406SShuah Khan (Samsung OSG)# Kselftest framework requirement - SKIP code is 4.
5982337406SShuah Khan (Samsung OSG)ksft_skip=4
6082337406SShuah Khan (Samsung OSG)
61d9c6a72dSLuis R. Rodrigueztest_modprobe()
62d9c6a72dSLuis R. Rodriguez{
63d9c6a72dSLuis R. Rodriguez       if [ ! -d $DIR ]; then
64d9c6a72dSLuis R. Rodriguez               echo "$0: $DIR not present" >&2
65d9c6a72dSLuis R. Rodriguez               echo "You must have the following enabled in your kernel:" >&2
66d9c6a72dSLuis R. Rodriguez               cat $TEST_DIR/config >&2
6782337406SShuah Khan (Samsung OSG)               exit $ksft_skip
68d9c6a72dSLuis R. Rodriguez       fi
69d9c6a72dSLuis R. Rodriguez}
70d9c6a72dSLuis R. Rodriguez
71d9c6a72dSLuis R. Rodriguezfunction allow_user_defaults()
72d9c6a72dSLuis R. Rodriguez{
73d9c6a72dSLuis R. Rodriguez	if [ -z $DEFAULT_KMOD_DRIVER ]; then
74d9c6a72dSLuis R. Rodriguez		DEFAULT_KMOD_DRIVER="test_module"
75d9c6a72dSLuis R. Rodriguez	fi
76d9c6a72dSLuis R. Rodriguez
77d9c6a72dSLuis R. Rodriguez	if [ -z $DEFAULT_KMOD_FS ]; then
78d9c6a72dSLuis R. Rodriguez		DEFAULT_KMOD_FS="xfs"
79d9c6a72dSLuis R. Rodriguez	fi
80d9c6a72dSLuis R. Rodriguez
81d9c6a72dSLuis R. Rodriguez	if [ -z $PROC_DIR ]; then
82d9c6a72dSLuis R. Rodriguez		PROC_DIR="/proc/sys/kernel/"
83d9c6a72dSLuis R. Rodriguez	fi
84d9c6a72dSLuis R. Rodriguez
85d9c6a72dSLuis R. Rodriguez	if [ -z $MODPROBE_LIMIT ]; then
86d9c6a72dSLuis R. Rodriguez		MODPROBE_LIMIT=50
87d9c6a72dSLuis R. Rodriguez	fi
88d9c6a72dSLuis R. Rodriguez
89d9c6a72dSLuis R. Rodriguez	if [ -z $DIR ]; then
90d9c6a72dSLuis R. Rodriguez		DIR="/sys/devices/virtual/misc/${TEST_DRIVER}0/"
91d9c6a72dSLuis R. Rodriguez	fi
92d9c6a72dSLuis R. Rodriguez
93d9c6a72dSLuis R. Rodriguez	if [ -z $DEFAULT_NUM_TESTS ]; then
94d9c6a72dSLuis R. Rodriguez		DEFAULT_NUM_TESTS=150
95d9c6a72dSLuis R. Rodriguez	fi
96d9c6a72dSLuis R. Rodriguez
97d9c6a72dSLuis R. Rodriguez	MODPROBE_LIMIT_FILE="${PROC_DIR}/kmod-limit"
98d9c6a72dSLuis R. Rodriguez}
99d9c6a72dSLuis R. Rodriguez
100d9c6a72dSLuis R. Rodrigueztest_reqs()
101d9c6a72dSLuis R. Rodriguez{
102d9c6a72dSLuis R. Rodriguez	if ! which modprobe 2> /dev/null > /dev/null; then
103d9c6a72dSLuis R. Rodriguez		echo "$0: You need modprobe installed" >&2
10482337406SShuah Khan (Samsung OSG)		exit $ksft_skip
105d9c6a72dSLuis R. Rodriguez	fi
106d9c6a72dSLuis R. Rodriguez
107d9c6a72dSLuis R. Rodriguez	if ! which kmod 2> /dev/null > /dev/null; then
108d9c6a72dSLuis R. Rodriguez		echo "$0: You need kmod installed" >&2
10982337406SShuah Khan (Samsung OSG)		exit $ksft_skip
110d9c6a72dSLuis R. Rodriguez	fi
111d9c6a72dSLuis R. Rodriguez
112d9c6a72dSLuis R. Rodriguez	# kmod 19 has a bad bug where it returns 0 when modprobe
113d9c6a72dSLuis R. Rodriguez	# gets called *even* if the module was not loaded due to
114d9c6a72dSLuis R. Rodriguez	# some bad heuristics. For details see:
115d9c6a72dSLuis R. Rodriguez	#
116d9c6a72dSLuis R. Rodriguez	# A work around is possible in-kernel but its rather
117d9c6a72dSLuis R. Rodriguez	# complex.
118d9c6a72dSLuis R. Rodriguez	KMOD_VERSION=$(kmod --version | awk '{print $3}')
119d9c6a72dSLuis R. Rodriguez	if [[ $KMOD_VERSION  -le 19 ]]; then
120d9c6a72dSLuis R. Rodriguez		echo "$0: You need at least kmod 20" >&2
121d9c6a72dSLuis R. Rodriguez		echo "kmod <= 19 is buggy, for details see:" >&2
122541f5643SAlexander A. Klimov		echo "https://git.kernel.org/cgit/utils/kernel/kmod/kmod.git/commit/libkmod/libkmod-module.c?id=fd44a98ae2eb5eb32161088954ab21e58e19dfc4" >&2
12382337406SShuah Khan (Samsung OSG)		exit $ksft_skip
124d9c6a72dSLuis R. Rodriguez	fi
125d9c6a72dSLuis R. Rodriguez
126d9c6a72dSLuis R. Rodriguez	uid=$(id -u)
127d9c6a72dSLuis R. Rodriguez	if [ $uid -ne 0 ]; then
128d9c6a72dSLuis R. Rodriguez		echo $msg must be run as root >&2
12982337406SShuah Khan (Samsung OSG)		exit $ksft_skip
130d9c6a72dSLuis R. Rodriguez	fi
131d9c6a72dSLuis R. Rodriguez}
132d9c6a72dSLuis R. Rodriguez
133d9c6a72dSLuis R. Rodriguezfunction load_req_mod()
134d9c6a72dSLuis R. Rodriguez{
135d9c6a72dSLuis R. Rodriguez	trap "test_modprobe" EXIT
136d9c6a72dSLuis R. Rodriguez
137d9c6a72dSLuis R. Rodriguez	if [ ! -d $DIR ]; then
138d9c6a72dSLuis R. Rodriguez		# Alanis: "Oh isn't it ironic?"
139d9c6a72dSLuis R. Rodriguez		modprobe $TEST_DRIVER
140d9c6a72dSLuis R. Rodriguez	fi
141d9c6a72dSLuis R. Rodriguez}
142d9c6a72dSLuis R. Rodriguez
143d9c6a72dSLuis R. Rodrigueztest_finish()
144d9c6a72dSLuis R. Rodriguez{
14523756e55SEric Biggers	echo "$MODPROBE" > /proc/sys/kernel/modprobe
146d9c6a72dSLuis R. Rodriguez	echo "Test completed"
147d9c6a72dSLuis R. Rodriguez}
148d9c6a72dSLuis R. Rodriguez
149d9c6a72dSLuis R. Rodriguezerrno_name_to_val()
150d9c6a72dSLuis R. Rodriguez{
151d9c6a72dSLuis R. Rodriguez	case "$1" in
152d9c6a72dSLuis R. Rodriguez	# kmod calls modprobe and upon of a module not found
153d9c6a72dSLuis R. Rodriguez	# modprobe returns just 1... However in the kernel we
154d9c6a72dSLuis R. Rodriguez	# *sometimes* see 256...
155d9c6a72dSLuis R. Rodriguez	MODULE_NOT_FOUND)
156d9c6a72dSLuis R. Rodriguez		echo 256;;
157d9c6a72dSLuis R. Rodriguez	SUCCESS)
158d9c6a72dSLuis R. Rodriguez		echo 0;;
159d9c6a72dSLuis R. Rodriguez	-EPERM)
160d9c6a72dSLuis R. Rodriguez		echo -1;;
161d9c6a72dSLuis R. Rodriguez	-ENOENT)
162d9c6a72dSLuis R. Rodriguez		echo -2;;
163d9c6a72dSLuis R. Rodriguez	-EINVAL)
164d9c6a72dSLuis R. Rodriguez		echo -22;;
165d9c6a72dSLuis R. Rodriguez	-ERR_ANY)
166d9c6a72dSLuis R. Rodriguez		echo -123456;;
167d9c6a72dSLuis R. Rodriguez	*)
168d9c6a72dSLuis R. Rodriguez		echo invalid;;
169d9c6a72dSLuis R. Rodriguez	esac
170d9c6a72dSLuis R. Rodriguez}
171d9c6a72dSLuis R. Rodriguez
172d9c6a72dSLuis R. Rodriguezerrno_val_to_name()
173d9c6a72dSLuis R. Rodriguez	case "$1" in
174d9c6a72dSLuis R. Rodriguez	256)
175d9c6a72dSLuis R. Rodriguez		echo MODULE_NOT_FOUND;;
176d9c6a72dSLuis R. Rodriguez	0)
177d9c6a72dSLuis R. Rodriguez		echo SUCCESS;;
178d9c6a72dSLuis R. Rodriguez	-1)
179d9c6a72dSLuis R. Rodriguez		echo -EPERM;;
180d9c6a72dSLuis R. Rodriguez	-2)
181d9c6a72dSLuis R. Rodriguez		echo -ENOENT;;
182d9c6a72dSLuis R. Rodriguez	-22)
183d9c6a72dSLuis R. Rodriguez		echo -EINVAL;;
184d9c6a72dSLuis R. Rodriguez	-123456)
185d9c6a72dSLuis R. Rodriguez		echo -ERR_ANY;;
186d9c6a72dSLuis R. Rodriguez	*)
187d9c6a72dSLuis R. Rodriguez		echo invalid;;
188d9c6a72dSLuis R. Rodriguez	esac
189d9c6a72dSLuis R. Rodriguez
190d9c6a72dSLuis R. Rodriguezconfig_set_test_case_driver()
191d9c6a72dSLuis R. Rodriguez{
192d9c6a72dSLuis R. Rodriguez	if ! echo -n 1 >$DIR/config_test_case; then
193d9c6a72dSLuis R. Rodriguez		echo "$0: Unable to set to test case to driver" >&2
194d9c6a72dSLuis R. Rodriguez		exit 1
195d9c6a72dSLuis R. Rodriguez	fi
196d9c6a72dSLuis R. Rodriguez}
197d9c6a72dSLuis R. Rodriguez
198d9c6a72dSLuis R. Rodriguezconfig_set_test_case_fs()
199d9c6a72dSLuis R. Rodriguez{
200d9c6a72dSLuis R. Rodriguez	if ! echo -n 2 >$DIR/config_test_case; then
201d9c6a72dSLuis R. Rodriguez		echo "$0: Unable to set to test case to fs" >&2
202d9c6a72dSLuis R. Rodriguez		exit 1
203d9c6a72dSLuis R. Rodriguez	fi
204d9c6a72dSLuis R. Rodriguez}
205d9c6a72dSLuis R. Rodriguez
206d9c6a72dSLuis R. Rodriguezconfig_num_threads()
207d9c6a72dSLuis R. Rodriguez{
208d9c6a72dSLuis R. Rodriguez	if ! echo -n $1 >$DIR/config_num_threads; then
209d9c6a72dSLuis R. Rodriguez		echo "$0: Unable to set to number of threads" >&2
210d9c6a72dSLuis R. Rodriguez		exit 1
211d9c6a72dSLuis R. Rodriguez	fi
212d9c6a72dSLuis R. Rodriguez}
213d9c6a72dSLuis R. Rodriguez
214d9c6a72dSLuis R. Rodriguezconfig_get_modprobe_limit()
215d9c6a72dSLuis R. Rodriguez{
216d9c6a72dSLuis R. Rodriguez	if [[ -f ${MODPROBE_LIMIT_FILE} ]] ; then
217d9c6a72dSLuis R. Rodriguez		MODPROBE_LIMIT=$(cat $MODPROBE_LIMIT_FILE)
218d9c6a72dSLuis R. Rodriguez	fi
219d9c6a72dSLuis R. Rodriguez	echo $MODPROBE_LIMIT
220d9c6a72dSLuis R. Rodriguez}
221d9c6a72dSLuis R. Rodriguez
222d9c6a72dSLuis R. Rodriguezconfig_num_thread_limit_extra()
223d9c6a72dSLuis R. Rodriguez{
224d9c6a72dSLuis R. Rodriguez	MODPROBE_LIMIT=$(config_get_modprobe_limit)
225d9c6a72dSLuis R. Rodriguez	let EXTRA_LIMIT=$MODPROBE_LIMIT+$1
226d9c6a72dSLuis R. Rodriguez	config_num_threads $EXTRA_LIMIT
227d9c6a72dSLuis R. Rodriguez}
228d9c6a72dSLuis R. Rodriguez
229d9c6a72dSLuis R. Rodriguez# For special characters use printf directly,
230d9c6a72dSLuis R. Rodriguez# refer to kmod_test_0001
231d9c6a72dSLuis R. Rodriguezconfig_set_driver()
232d9c6a72dSLuis R. Rodriguez{
233d9c6a72dSLuis R. Rodriguez	if ! echo -n $1 >$DIR/config_test_driver; then
234d9c6a72dSLuis R. Rodriguez		echo "$0: Unable to set driver" >&2
235d9c6a72dSLuis R. Rodriguez		exit 1
236d9c6a72dSLuis R. Rodriguez	fi
237d9c6a72dSLuis R. Rodriguez}
238d9c6a72dSLuis R. Rodriguez
239d9c6a72dSLuis R. Rodriguezconfig_set_fs()
240d9c6a72dSLuis R. Rodriguez{
241d9c6a72dSLuis R. Rodriguez	if ! echo -n $1 >$DIR/config_test_fs; then
242d9c6a72dSLuis R. Rodriguez		echo "$0: Unable to set driver" >&2
243d9c6a72dSLuis R. Rodriguez		exit 1
244d9c6a72dSLuis R. Rodriguez	fi
245d9c6a72dSLuis R. Rodriguez}
246d9c6a72dSLuis R. Rodriguez
247d9c6a72dSLuis R. Rodriguezconfig_get_driver()
248d9c6a72dSLuis R. Rodriguez{
249d9c6a72dSLuis R. Rodriguez	cat $DIR/config_test_driver
250d9c6a72dSLuis R. Rodriguez}
251d9c6a72dSLuis R. Rodriguez
252d9c6a72dSLuis R. Rodriguezconfig_get_test_result()
253d9c6a72dSLuis R. Rodriguez{
254d9c6a72dSLuis R. Rodriguez	cat $DIR/test_result
255d9c6a72dSLuis R. Rodriguez}
256d9c6a72dSLuis R. Rodriguez
257d9c6a72dSLuis R. Rodriguezconfig_reset()
258d9c6a72dSLuis R. Rodriguez{
259d9c6a72dSLuis R. Rodriguez	if ! echo -n "1" >"$DIR"/reset; then
26036876b30SMasanari Iida		echo "$0: reset should have worked" >&2
261d9c6a72dSLuis R. Rodriguez		exit 1
262d9c6a72dSLuis R. Rodriguez	fi
263d9c6a72dSLuis R. Rodriguez}
264d9c6a72dSLuis R. Rodriguez
265d9c6a72dSLuis R. Rodriguezconfig_show_config()
266d9c6a72dSLuis R. Rodriguez{
267d9c6a72dSLuis R. Rodriguez	echo "----------------------------------------------------"
268d9c6a72dSLuis R. Rodriguez	cat "$DIR"/config
269d9c6a72dSLuis R. Rodriguez	echo "----------------------------------------------------"
270d9c6a72dSLuis R. Rodriguez}
271d9c6a72dSLuis R. Rodriguez
272d9c6a72dSLuis R. Rodriguezconfig_trigger()
273d9c6a72dSLuis R. Rodriguez{
274d9c6a72dSLuis R. Rodriguez	if ! echo -n "1" >"$DIR"/trigger_config 2>/dev/null; then
275d9c6a72dSLuis R. Rodriguez		echo "$1: FAIL - loading should have worked"
276d9c6a72dSLuis R. Rodriguez		config_show_config
277d9c6a72dSLuis R. Rodriguez		exit 1
278d9c6a72dSLuis R. Rodriguez	fi
279d9c6a72dSLuis R. Rodriguez	echo "$1: OK! - loading kmod test"
280d9c6a72dSLuis R. Rodriguez}
281d9c6a72dSLuis R. Rodriguez
282d9c6a72dSLuis R. Rodriguezconfig_trigger_want_fail()
283d9c6a72dSLuis R. Rodriguez{
284d9c6a72dSLuis R. Rodriguez	if echo "1" > $DIR/trigger_config 2>/dev/null; then
285d9c6a72dSLuis R. Rodriguez		echo "$1: FAIL - test case was expected to fail"
286d9c6a72dSLuis R. Rodriguez		config_show_config
287d9c6a72dSLuis R. Rodriguez		exit 1
288d9c6a72dSLuis R. Rodriguez	fi
289d9c6a72dSLuis R. Rodriguez	echo "$1: OK! - kmod test case failed as expected"
290d9c6a72dSLuis R. Rodriguez}
291d9c6a72dSLuis R. Rodriguez
292d9c6a72dSLuis R. Rodriguezconfig_expect_result()
293d9c6a72dSLuis R. Rodriguez{
294d9c6a72dSLuis R. Rodriguez	RC=$(config_get_test_result)
295d9c6a72dSLuis R. Rodriguez	RC_NAME=$(errno_val_to_name $RC)
296d9c6a72dSLuis R. Rodriguez
297d9c6a72dSLuis R. Rodriguez	ERRNO_NAME=$2
298d9c6a72dSLuis R. Rodriguez	ERRNO=$(errno_name_to_val $ERRNO_NAME)
299d9c6a72dSLuis R. Rodriguez
300d9c6a72dSLuis R. Rodriguez	if [[ $ERRNO_NAME = "-ERR_ANY" ]]; then
301d9c6a72dSLuis R. Rodriguez		if [[ $RC -ge 0 ]]; then
302d9c6a72dSLuis R. Rodriguez			echo "$1: FAIL, test expects $ERRNO_NAME - got $RC_NAME ($RC)" >&2
303d9c6a72dSLuis R. Rodriguez			config_show_config
304d9c6a72dSLuis R. Rodriguez			exit 1
305d9c6a72dSLuis R. Rodriguez		fi
306d9c6a72dSLuis R. Rodriguez	elif [[ $RC != $ERRNO ]]; then
307d9c6a72dSLuis R. Rodriguez		echo "$1: FAIL, test expects $ERRNO_NAME ($ERRNO) - got $RC_NAME ($RC)" >&2
308d9c6a72dSLuis R. Rodriguez		config_show_config
309d9c6a72dSLuis R. Rodriguez		exit 1
310d9c6a72dSLuis R. Rodriguez	fi
311d9c6a72dSLuis R. Rodriguez	echo "$1: OK! - Return value: $RC ($RC_NAME), expected $ERRNO_NAME"
312d9c6a72dSLuis R. Rodriguez}
313d9c6a72dSLuis R. Rodriguez
314d9c6a72dSLuis R. Rodriguezkmod_defaults_driver()
315d9c6a72dSLuis R. Rodriguez{
316d9c6a72dSLuis R. Rodriguez	config_reset
317d9c6a72dSLuis R. Rodriguez	modprobe -r $DEFAULT_KMOD_DRIVER
318d9c6a72dSLuis R. Rodriguez	config_set_driver $DEFAULT_KMOD_DRIVER
319d9c6a72dSLuis R. Rodriguez}
320d9c6a72dSLuis R. Rodriguez
321d9c6a72dSLuis R. Rodriguezkmod_defaults_fs()
322d9c6a72dSLuis R. Rodriguez{
323d9c6a72dSLuis R. Rodriguez	config_reset
324d9c6a72dSLuis R. Rodriguez	modprobe -r $DEFAULT_KMOD_FS
325d9c6a72dSLuis R. Rodriguez	config_set_fs $DEFAULT_KMOD_FS
326d9c6a72dSLuis R. Rodriguez	config_set_test_case_fs
327d9c6a72dSLuis R. Rodriguez}
328d9c6a72dSLuis R. Rodriguez
329d9c6a72dSLuis R. Rodriguezkmod_test_0001_driver()
330d9c6a72dSLuis R. Rodriguez{
331d9c6a72dSLuis R. Rodriguez	NAME='\000'
332d9c6a72dSLuis R. Rodriguez
333d9c6a72dSLuis R. Rodriguez	kmod_defaults_driver
334d9c6a72dSLuis R. Rodriguez	config_num_threads 1
335aaa3e7fbSTiezhu Yang	printf $NAME >"$DIR"/config_test_driver
336d9c6a72dSLuis R. Rodriguez	config_trigger ${FUNCNAME[0]}
337d9c6a72dSLuis R. Rodriguez	config_expect_result ${FUNCNAME[0]} MODULE_NOT_FOUND
338d9c6a72dSLuis R. Rodriguez}
339d9c6a72dSLuis R. Rodriguez
340d9c6a72dSLuis R. Rodriguezkmod_test_0001_fs()
341d9c6a72dSLuis R. Rodriguez{
342d9c6a72dSLuis R. Rodriguez	NAME='\000'
343d9c6a72dSLuis R. Rodriguez
344d9c6a72dSLuis R. Rodriguez	kmod_defaults_fs
345d9c6a72dSLuis R. Rodriguez	config_num_threads 1
346aaa3e7fbSTiezhu Yang	printf $NAME >"$DIR"/config_test_fs
347d9c6a72dSLuis R. Rodriguez	config_trigger ${FUNCNAME[0]}
348d9c6a72dSLuis R. Rodriguez	config_expect_result ${FUNCNAME[0]} -EINVAL
349d9c6a72dSLuis R. Rodriguez}
350d9c6a72dSLuis R. Rodriguez
351d9c6a72dSLuis R. Rodriguezkmod_test_0001()
352d9c6a72dSLuis R. Rodriguez{
353d9c6a72dSLuis R. Rodriguez	kmod_test_0001_driver
354d9c6a72dSLuis R. Rodriguez	kmod_test_0001_fs
355d9c6a72dSLuis R. Rodriguez}
356d9c6a72dSLuis R. Rodriguez
357d9c6a72dSLuis R. Rodriguezkmod_test_0002_driver()
358d9c6a72dSLuis R. Rodriguez{
359d9c6a72dSLuis R. Rodriguez	NAME="nope-$DEFAULT_KMOD_DRIVER"
360d9c6a72dSLuis R. Rodriguez
361d9c6a72dSLuis R. Rodriguez	kmod_defaults_driver
362d9c6a72dSLuis R. Rodriguez	config_set_driver $NAME
363d9c6a72dSLuis R. Rodriguez	config_num_threads 1
364d9c6a72dSLuis R. Rodriguez	config_trigger ${FUNCNAME[0]}
365d9c6a72dSLuis R. Rodriguez	config_expect_result ${FUNCNAME[0]} MODULE_NOT_FOUND
366d9c6a72dSLuis R. Rodriguez}
367d9c6a72dSLuis R. Rodriguez
368d9c6a72dSLuis R. Rodriguezkmod_test_0002_fs()
369d9c6a72dSLuis R. Rodriguez{
370d9c6a72dSLuis R. Rodriguez	NAME="nope-$DEFAULT_KMOD_FS"
371d9c6a72dSLuis R. Rodriguez
372d9c6a72dSLuis R. Rodriguez	kmod_defaults_fs
373d9c6a72dSLuis R. Rodriguez	config_set_fs $NAME
374d9c6a72dSLuis R. Rodriguez	config_trigger ${FUNCNAME[0]}
375d9c6a72dSLuis R. Rodriguez	config_expect_result ${FUNCNAME[0]} -EINVAL
376d9c6a72dSLuis R. Rodriguez}
377d9c6a72dSLuis R. Rodriguez
378d9c6a72dSLuis R. Rodriguezkmod_test_0002()
379d9c6a72dSLuis R. Rodriguez{
380d9c6a72dSLuis R. Rodriguez	kmod_test_0002_driver
381d9c6a72dSLuis R. Rodriguez	kmod_test_0002_fs
382d9c6a72dSLuis R. Rodriguez}
383d9c6a72dSLuis R. Rodriguez
384d9c6a72dSLuis R. Rodriguezkmod_test_0003()
385d9c6a72dSLuis R. Rodriguez{
386d9c6a72dSLuis R. Rodriguez	kmod_defaults_fs
387d9c6a72dSLuis R. Rodriguez	config_num_threads 1
388d9c6a72dSLuis R. Rodriguez	config_trigger ${FUNCNAME[0]}
389d9c6a72dSLuis R. Rodriguez	config_expect_result ${FUNCNAME[0]} SUCCESS
390d9c6a72dSLuis R. Rodriguez}
391d9c6a72dSLuis R. Rodriguez
392d9c6a72dSLuis R. Rodriguezkmod_test_0004()
393d9c6a72dSLuis R. Rodriguez{
394d9c6a72dSLuis R. Rodriguez	kmod_defaults_fs
395d9c6a72dSLuis R. Rodriguez	config_num_threads 2
396d9c6a72dSLuis R. Rodriguez	config_trigger ${FUNCNAME[0]}
397d9c6a72dSLuis R. Rodriguez	config_expect_result ${FUNCNAME[0]} SUCCESS
398d9c6a72dSLuis R. Rodriguez}
399d9c6a72dSLuis R. Rodriguez
400d9c6a72dSLuis R. Rodriguezkmod_test_0005()
401d9c6a72dSLuis R. Rodriguez{
402d9c6a72dSLuis R. Rodriguez	kmod_defaults_driver
403d9c6a72dSLuis R. Rodriguez	config_trigger ${FUNCNAME[0]}
404d9c6a72dSLuis R. Rodriguez	config_expect_result ${FUNCNAME[0]} SUCCESS
405d9c6a72dSLuis R. Rodriguez}
406d9c6a72dSLuis R. Rodriguez
407d9c6a72dSLuis R. Rodriguezkmod_test_0006()
408d9c6a72dSLuis R. Rodriguez{
409d9c6a72dSLuis R. Rodriguez	kmod_defaults_fs
410d9c6a72dSLuis R. Rodriguez	config_trigger ${FUNCNAME[0]}
411d9c6a72dSLuis R. Rodriguez	config_expect_result ${FUNCNAME[0]} SUCCESS
412d9c6a72dSLuis R. Rodriguez}
413d9c6a72dSLuis R. Rodriguez
414d9c6a72dSLuis R. Rodriguezkmod_test_0007()
415d9c6a72dSLuis R. Rodriguez{
416d9c6a72dSLuis R. Rodriguez	kmod_test_0005
417d9c6a72dSLuis R. Rodriguez	kmod_test_0006
418d9c6a72dSLuis R. Rodriguez}
419d9c6a72dSLuis R. Rodriguez
420d9c6a72dSLuis R. Rodriguezkmod_test_0008()
421d9c6a72dSLuis R. Rodriguez{
422d9c6a72dSLuis R. Rodriguez	kmod_defaults_driver
423d9c6a72dSLuis R. Rodriguez	MODPROBE_LIMIT=$(config_get_modprobe_limit)
424d9c6a72dSLuis R. Rodriguez	let EXTRA=$MODPROBE_LIMIT/6
425d9c6a72dSLuis R. Rodriguez	config_num_thread_limit_extra $EXTRA
426d9c6a72dSLuis R. Rodriguez	config_trigger ${FUNCNAME[0]}
427d9c6a72dSLuis R. Rodriguez	config_expect_result ${FUNCNAME[0]} SUCCESS
428d9c6a72dSLuis R. Rodriguez}
429d9c6a72dSLuis R. Rodriguez
430d9c6a72dSLuis R. Rodriguezkmod_test_0009()
431d9c6a72dSLuis R. Rodriguez{
432d9c6a72dSLuis R. Rodriguez	kmod_defaults_fs
433d9c6a72dSLuis R. Rodriguez	MODPROBE_LIMIT=$(config_get_modprobe_limit)
434d9c6a72dSLuis R. Rodriguez	let EXTRA=$MODPROBE_LIMIT/4
435d9c6a72dSLuis R. Rodriguez	config_num_thread_limit_extra $EXTRA
436d9c6a72dSLuis R. Rodriguez	config_trigger ${FUNCNAME[0]}
437d9c6a72dSLuis R. Rodriguez	config_expect_result ${FUNCNAME[0]} SUCCESS
438d9c6a72dSLuis R. Rodriguez}
439d9c6a72dSLuis R. Rodriguez
44023756e55SEric Biggerskmod_test_0010()
44123756e55SEric Biggers{
44223756e55SEric Biggers	kmod_defaults_driver
44323756e55SEric Biggers	config_num_threads 1
44423756e55SEric Biggers	echo "/KMOD_TEST_NONEXISTENT" > /proc/sys/kernel/modprobe
44523756e55SEric Biggers	config_trigger ${FUNCNAME[0]}
44623756e55SEric Biggers	config_expect_result ${FUNCNAME[0]} -ENOENT
44723756e55SEric Biggers	echo "$MODPROBE" > /proc/sys/kernel/modprobe
44823756e55SEric Biggers}
44923756e55SEric Biggers
45023756e55SEric Biggerskmod_test_0011()
45123756e55SEric Biggers{
45223756e55SEric Biggers	kmod_defaults_driver
45323756e55SEric Biggers	config_num_threads 1
45423756e55SEric Biggers	# This causes the kernel to not even try executing modprobe.  The error
45523756e55SEric Biggers	# code is still -ENOENT like when modprobe doesn't exist, so we can't
45623756e55SEric Biggers	# easily test for the exact difference.  But this still is a useful test
45723756e55SEric Biggers	# since there was a bug where request_module() returned 0 in this case.
45823756e55SEric Biggers	echo > /proc/sys/kernel/modprobe
45923756e55SEric Biggers	config_trigger ${FUNCNAME[0]}
46023756e55SEric Biggers	config_expect_result ${FUNCNAME[0]} -ENOENT
46123756e55SEric Biggers	echo "$MODPROBE" > /proc/sys/kernel/modprobe
46223756e55SEric Biggers}
46323756e55SEric Biggers
464a80d6055SKees Cookkmod_check_visibility()
465a80d6055SKees Cook{
466a80d6055SKees Cook	local name="$1"
467a80d6055SKees Cook	local cmd="$2"
468a80d6055SKees Cook
469a80d6055SKees Cook	modprobe $DEFAULT_KMOD_DRIVER
470a80d6055SKees Cook
471a80d6055SKees Cook	local priv=$(eval $cmd)
472a80d6055SKees Cook	local unpriv=$(capsh --drop=CAP_SYSLOG -- -c "$cmd")
473a80d6055SKees Cook
474a80d6055SKees Cook	if [ "$priv" = "$unpriv" ] || \
475a80d6055SKees Cook	   [ "${priv:0:3}" = "0x0" ] || \
476a80d6055SKees Cook	   [ "${unpriv:0:3}" != "0x0" ] ; then
477a80d6055SKees Cook		echo "${FUNCNAME[0]}: FAIL, $name visible to unpriv: '$priv' vs '$unpriv'" >&2
478a80d6055SKees Cook		exit 1
479a80d6055SKees Cook	else
480a80d6055SKees Cook		echo "${FUNCNAME[0]}: OK!"
481a80d6055SKees Cook	fi
482a80d6055SKees Cook}
483a80d6055SKees Cook
484a80d6055SKees Cookkmod_test_0012()
485a80d6055SKees Cook{
486a80d6055SKees Cook	kmod_check_visibility /proc/modules \
487a80d6055SKees Cook		"grep '^${DEFAULT_KMOD_DRIVER}\b' /proc/modules | awk '{print \$NF}'"
488a80d6055SKees Cook}
489a80d6055SKees Cook
490a80d6055SKees Cookkmod_test_0013()
491a80d6055SKees Cook{
492a80d6055SKees Cook	kmod_check_visibility '/sys/module/*/sections/*' \
493a80d6055SKees Cook		"cat /sys/module/${DEFAULT_KMOD_DRIVER}/sections/.*text | head -n1"
494a80d6055SKees Cook}
495a80d6055SKees Cook
496d9c6a72dSLuis R. Rodriguezlist_tests()
497d9c6a72dSLuis R. Rodriguez{
498d9c6a72dSLuis R. Rodriguez	echo "Test ID list:"
499d9c6a72dSLuis R. Rodriguez	echo
500d9c6a72dSLuis R. Rodriguez	echo "TEST_ID x NUM_TEST"
501d9c6a72dSLuis R. Rodriguez	echo "TEST_ID:   Test ID"
502d9c6a72dSLuis R. Rodriguez	echo "NUM_TESTS: Number of recommended times to run the test"
503d9c6a72dSLuis R. Rodriguez	echo
504d9c6a72dSLuis R. Rodriguez	echo "0001 x $(get_test_count 0001) - Simple test - 1 thread  for empty string"
505d9c6a72dSLuis R. Rodriguez	echo "0002 x $(get_test_count 0002) - Simple test - 1 thread  for modules/filesystems that do not exist"
506d9c6a72dSLuis R. Rodriguez	echo "0003 x $(get_test_count 0003) - Simple test - 1 thread  for get_fs_type() only"
507d9c6a72dSLuis R. Rodriguez	echo "0004 x $(get_test_count 0004) - Simple test - 2 threads for get_fs_type() only"
508d9c6a72dSLuis R. Rodriguez	echo "0005 x $(get_test_count 0005) - multithreaded tests with default setup - request_module() only"
509d9c6a72dSLuis R. Rodriguez	echo "0006 x $(get_test_count 0006) - multithreaded tests with default setup - get_fs_type() only"
510d9c6a72dSLuis R. Rodriguez	echo "0007 x $(get_test_count 0007) - multithreaded tests with default setup test request_module() and get_fs_type()"
511d9c6a72dSLuis R. Rodriguez	echo "0008 x $(get_test_count 0008) - multithreaded - push kmod_concurrent over max_modprobes for request_module()"
512d9c6a72dSLuis R. Rodriguez	echo "0009 x $(get_test_count 0009) - multithreaded - push kmod_concurrent over max_modprobes for get_fs_type()"
51323756e55SEric Biggers	echo "0010 x $(get_test_count 0010) - test nonexistent modprobe path"
51423756e55SEric Biggers	echo "0011 x $(get_test_count 0011) - test completely disabling module autoloading"
515a80d6055SKees Cook	echo "0012 x $(get_test_count 0012) - test /proc/modules address visibility under CAP_SYSLOG"
516a80d6055SKees Cook	echo "0013 x $(get_test_count 0013) - test /sys/module/*/sections/* visibility under CAP_SYSLOG"
517d9c6a72dSLuis R. Rodriguez}
518d9c6a72dSLuis R. Rodriguez
519d9c6a72dSLuis R. Rodriguezusage()
520d9c6a72dSLuis R. Rodriguez{
521d9c6a72dSLuis R. Rodriguez	NUM_TESTS=$(grep -o ' ' <<<"$ALL_TESTS" | grep -c .)
522d9c6a72dSLuis R. Rodriguez	let NUM_TESTS=$NUM_TESTS+1
523d9c6a72dSLuis R. Rodriguez	MAX_TEST=$(printf "%04d\n" $NUM_TESTS)
524d9c6a72dSLuis R. Rodriguez	echo "Usage: $0 [ -t <4-number-digit> ] | [ -w <4-number-digit> ] |"
525d9c6a72dSLuis R. Rodriguez	echo "		 [ -s <4-number-digit> ] | [ -c <4-number-digit> <test- count>"
526d9c6a72dSLuis R. Rodriguez	echo "           [ all ] [ -h | --help ] [ -l ]"
527d9c6a72dSLuis R. Rodriguez	echo ""
528d9c6a72dSLuis R. Rodriguez	echo "Valid tests: 0001-$MAX_TEST"
529d9c6a72dSLuis R. Rodriguez	echo ""
530d9c6a72dSLuis R. Rodriguez	echo "    all     Runs all tests (default)"
531d9c6a72dSLuis R. Rodriguez	echo "    -t      Run test ID the number amount of times is recommended"
532d9c6a72dSLuis R. Rodriguez	echo "    -w      Watch test ID run until it runs into an error"
533768dc4e4SLuis R. Rodriguez	echo "    -s      Run test ID once"
534768dc4e4SLuis R. Rodriguez	echo "    -c      Run test ID x test-count number of times"
535d9c6a72dSLuis R. Rodriguez	echo "    -l      List all test ID list"
536d9c6a72dSLuis R. Rodriguez	echo " -h|--help  Help"
537d9c6a72dSLuis R. Rodriguez	echo
538d9c6a72dSLuis R. Rodriguez	echo "If an error every occurs execution will immediately terminate."
539d9c6a72dSLuis R. Rodriguez	echo "If you are adding a new test try using -w <test-ID> first to"
540d9c6a72dSLuis R. Rodriguez	echo "make sure the test passes a series of tests."
541d9c6a72dSLuis R. Rodriguez	echo
542d9c6a72dSLuis R. Rodriguez	echo Example uses:
543d9c6a72dSLuis R. Rodriguez	echo
544d9c6a72dSLuis R. Rodriguez	echo "${TEST_NAME}.sh		-- executes all tests"
54536876b30SMasanari Iida	echo "${TEST_NAME}.sh -t 0008	-- Executes test ID 0008 number of times is recommended"
546d9c6a72dSLuis R. Rodriguez	echo "${TEST_NAME}.sh -w 0008	-- Watch test ID 0008 run until an error occurs"
547d9c6a72dSLuis R. Rodriguez	echo "${TEST_NAME}.sh -s 0008	-- Run test ID 0008 once"
548d9c6a72dSLuis R. Rodriguez	echo "${TEST_NAME}.sh -c 0008 3	-- Run test ID 0008 three times"
549d9c6a72dSLuis R. Rodriguez	echo
550d9c6a72dSLuis R. Rodriguez	list_tests
551d9c6a72dSLuis R. Rodriguez	exit 1
552d9c6a72dSLuis R. Rodriguez}
553d9c6a72dSLuis R. Rodriguez
554d9c6a72dSLuis R. Rodriguezfunction test_num()
555d9c6a72dSLuis R. Rodriguez{
556d9c6a72dSLuis R. Rodriguez	re='^[0-9]+$'
557d9c6a72dSLuis R. Rodriguez	if ! [[ $1 =~ $re ]]; then
558d9c6a72dSLuis R. Rodriguez		usage
559d9c6a72dSLuis R. Rodriguez	fi
560d9c6a72dSLuis R. Rodriguez}
561d9c6a72dSLuis R. Rodriguez
5626d573a07SEric Biggersfunction get_test_data()
563d9c6a72dSLuis R. Rodriguez{
564d9c6a72dSLuis R. Rodriguez	test_num $1
5656d573a07SEric Biggers	local field_num=$(echo $1 | sed 's/^0*//')
5666d573a07SEric Biggers	echo $ALL_TESTS | awk '{print $'$field_num'}'
5676d573a07SEric Biggers}
5686d573a07SEric Biggers
5696d573a07SEric Biggersfunction get_test_count()
5706d573a07SEric Biggers{
5716d573a07SEric Biggers	TEST_DATA=$(get_test_data $1)
572d9c6a72dSLuis R. Rodriguez	LAST_TWO=${TEST_DATA#*:*}
573d9c6a72dSLuis R. Rodriguez	echo ${LAST_TWO%:*}
574d9c6a72dSLuis R. Rodriguez}
575d9c6a72dSLuis R. Rodriguez
576d9c6a72dSLuis R. Rodriguezfunction get_test_enabled()
577d9c6a72dSLuis R. Rodriguez{
5786d573a07SEric Biggers	TEST_DATA=$(get_test_data $1)
579d9c6a72dSLuis R. Rodriguez	echo ${TEST_DATA#*:*:}
580d9c6a72dSLuis R. Rodriguez}
581d9c6a72dSLuis R. Rodriguez
582d9c6a72dSLuis R. Rodriguezfunction run_all_tests()
583d9c6a72dSLuis R. Rodriguez{
584d9c6a72dSLuis R. Rodriguez	for i in $ALL_TESTS ; do
585d9c6a72dSLuis R. Rodriguez		TEST_ID=${i%:*:*}
586d9c6a72dSLuis R. Rodriguez		ENABLED=$(get_test_enabled $TEST_ID)
587d9c6a72dSLuis R. Rodriguez		TEST_COUNT=$(get_test_count $TEST_ID)
588d9c6a72dSLuis R. Rodriguez		if [[ $ENABLED -eq "1" ]]; then
589d9c6a72dSLuis R. Rodriguez			test_case $TEST_ID $TEST_COUNT
590d9c6a72dSLuis R. Rodriguez		fi
591d9c6a72dSLuis R. Rodriguez	done
592d9c6a72dSLuis R. Rodriguez}
593d9c6a72dSLuis R. Rodriguez
594d9c6a72dSLuis R. Rodriguezfunction watch_log()
595d9c6a72dSLuis R. Rodriguez{
596d9c6a72dSLuis R. Rodriguez	if [ $# -ne 3 ]; then
597d9c6a72dSLuis R. Rodriguez		clear
598d9c6a72dSLuis R. Rodriguez	fi
599d9c6a72dSLuis R. Rodriguez	date
600d9c6a72dSLuis R. Rodriguez	echo "Running test: $2 - run #$1"
601d9c6a72dSLuis R. Rodriguez}
602d9c6a72dSLuis R. Rodriguez
603d9c6a72dSLuis R. Rodriguezfunction watch_case()
604d9c6a72dSLuis R. Rodriguez{
605d9c6a72dSLuis R. Rodriguez	i=0
606d9c6a72dSLuis R. Rodriguez	while [ 1 ]; do
607d9c6a72dSLuis R. Rodriguez
608d9c6a72dSLuis R. Rodriguez		if [ $# -eq 1 ]; then
609d9c6a72dSLuis R. Rodriguez			test_num $1
610d9c6a72dSLuis R. Rodriguez			watch_log $i ${TEST_NAME}_test_$1
611d9c6a72dSLuis R. Rodriguez			${TEST_NAME}_test_$1
612d9c6a72dSLuis R. Rodriguez		else
613d9c6a72dSLuis R. Rodriguez			watch_log $i all
614d9c6a72dSLuis R. Rodriguez			run_all_tests
615d9c6a72dSLuis R. Rodriguez		fi
616d9c6a72dSLuis R. Rodriguez		let i=$i+1
617d9c6a72dSLuis R. Rodriguez	done
618d9c6a72dSLuis R. Rodriguez}
619d9c6a72dSLuis R. Rodriguez
620d9c6a72dSLuis R. Rodriguezfunction test_case()
621d9c6a72dSLuis R. Rodriguez{
622d9c6a72dSLuis R. Rodriguez	NUM_TESTS=$DEFAULT_NUM_TESTS
623d9c6a72dSLuis R. Rodriguez	if [ $# -eq 2 ]; then
624d9c6a72dSLuis R. Rodriguez		NUM_TESTS=$2
625d9c6a72dSLuis R. Rodriguez	fi
626d9c6a72dSLuis R. Rodriguez
627d9c6a72dSLuis R. Rodriguez	i=0
628d9c6a72dSLuis R. Rodriguez	while [ $i -lt $NUM_TESTS ]; do
629d9c6a72dSLuis R. Rodriguez		test_num $1
630d9c6a72dSLuis R. Rodriguez		watch_log $i ${TEST_NAME}_test_$1 noclear
631d9c6a72dSLuis R. Rodriguez		RUN_TEST=${TEST_NAME}_test_$1
632d9c6a72dSLuis R. Rodriguez		$RUN_TEST
633d9c6a72dSLuis R. Rodriguez		let i=$i+1
634d9c6a72dSLuis R. Rodriguez	done
635d9c6a72dSLuis R. Rodriguez}
636d9c6a72dSLuis R. Rodriguez
637d9c6a72dSLuis R. Rodriguezfunction parse_args()
638d9c6a72dSLuis R. Rodriguez{
639d9c6a72dSLuis R. Rodriguez	if [ $# -eq 0 ]; then
640d9c6a72dSLuis R. Rodriguez		run_all_tests
641d9c6a72dSLuis R. Rodriguez	else
642d9c6a72dSLuis R. Rodriguez		if [[ "$1" = "all" ]]; then
643d9c6a72dSLuis R. Rodriguez			run_all_tests
644d9c6a72dSLuis R. Rodriguez		elif [[ "$1" = "-w" ]]; then
645d9c6a72dSLuis R. Rodriguez			shift
646d9c6a72dSLuis R. Rodriguez			watch_case $@
647d9c6a72dSLuis R. Rodriguez		elif [[ "$1" = "-t" ]]; then
648d9c6a72dSLuis R. Rodriguez			shift
649d9c6a72dSLuis R. Rodriguez			test_num $1
650d9c6a72dSLuis R. Rodriguez			test_case $1 $(get_test_count $1)
651d9c6a72dSLuis R. Rodriguez		elif [[ "$1" = "-c" ]]; then
652d9c6a72dSLuis R. Rodriguez			shift
653d9c6a72dSLuis R. Rodriguez			test_num $1
654d9c6a72dSLuis R. Rodriguez			test_num $2
655d9c6a72dSLuis R. Rodriguez			test_case $1 $2
656d9c6a72dSLuis R. Rodriguez		elif [[ "$1" = "-s" ]]; then
657d9c6a72dSLuis R. Rodriguez			shift
658d9c6a72dSLuis R. Rodriguez			test_case $1 1
659d9c6a72dSLuis R. Rodriguez		elif [[ "$1" = "-l" ]]; then
660d9c6a72dSLuis R. Rodriguez			list_tests
661d9c6a72dSLuis R. Rodriguez		elif [[ "$1" = "-h" || "$1" = "--help" ]]; then
662d9c6a72dSLuis R. Rodriguez			usage
663d9c6a72dSLuis R. Rodriguez		else
664d9c6a72dSLuis R. Rodriguez			usage
665d9c6a72dSLuis R. Rodriguez		fi
666d9c6a72dSLuis R. Rodriguez	fi
667d9c6a72dSLuis R. Rodriguez}
668d9c6a72dSLuis R. Rodriguez
669d9c6a72dSLuis R. Rodrigueztest_reqs
670d9c6a72dSLuis R. Rodriguezallow_user_defaults
671d9c6a72dSLuis R. Rodriguezload_req_mod
672d9c6a72dSLuis R. Rodriguez
67323756e55SEric BiggersMODPROBE=$(</proc/sys/kernel/modprobe)
674d9c6a72dSLuis R. Rodrigueztrap "test_finish" EXIT
675d9c6a72dSLuis R. Rodriguez
676d9c6a72dSLuis R. Rodriguezparse_args $@
677d9c6a72dSLuis R. Rodriguez
678d9c6a72dSLuis R. Rodriguezexit 0
679