kmod.sh 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678
  1. #!/bin/bash
  2. # SPDX-License-Identifier: GPL-2.0-or-later OR copyleft-next-0.3.1
  3. # Copyright (C) 2017 Luis R. Rodriguez <mcgrof@kernel.org>
  4. #
  5. # This is a stress test script for kmod, the kernel module loader. It uses
  6. # test_kmod which exposes a series of knobs for the API for us so we can
  7. # tweak each test in userspace rather than in kernelspace.
  8. #
  9. # The way kmod works is it uses the kernel's usermode helper API to eventually
  10. # call /sbin/modprobe. It has a limit of the number of concurrent calls
  11. # possible. The kernel interface to load modules is request_module(), however
  12. # mount uses get_fs_type(). Both behave slightly differently, but the
  13. # differences are important enough to test each call separately. For this
  14. # reason test_kmod starts by providing tests for both calls.
  15. #
  16. # The test driver test_kmod assumes a series of defaults which you can
  17. # override by exporting to your environment prior running this script.
  18. # For instance this script assumes you do not have xfs loaded upon boot.
  19. # If this is false, export DEFAULT_KMOD_FS="ext4" prior to running this
  20. # script if the filesystem module you don't have loaded upon bootup
  21. # is ext4 instead. Refer to allow_user_defaults() for a list of user
  22. # override variables possible.
  23. #
  24. # You'll want at least 4 GiB of RAM to expect to run these tests
  25. # without running out of memory on them. For other requirements refer
  26. # to test_reqs()
  27. set -e
  28. TEST_NAME="kmod"
  29. TEST_DRIVER="test_${TEST_NAME}"
  30. TEST_DIR=$(dirname $0)
  31. # This represents
  32. #
  33. # TEST_ID:TEST_COUNT:ENABLED
  34. #
  35. # TEST_ID: is the test id number
  36. # TEST_COUNT: number of times we should run the test
  37. # ENABLED: 1 if enabled, 0 otherwise
  38. #
  39. # Once these are enabled please leave them as-is. Write your own test,
  40. # we have tons of space.
  41. ALL_TESTS="0001:3:1"
  42. ALL_TESTS="$ALL_TESTS 0002:3:1"
  43. ALL_TESTS="$ALL_TESTS 0003:1:1"
  44. ALL_TESTS="$ALL_TESTS 0004:1:1"
  45. ALL_TESTS="$ALL_TESTS 0005:10:1"
  46. ALL_TESTS="$ALL_TESTS 0006:10:1"
  47. ALL_TESTS="$ALL_TESTS 0007:5:1"
  48. ALL_TESTS="$ALL_TESTS 0008:150:1"
  49. ALL_TESTS="$ALL_TESTS 0009:150:1"
  50. ALL_TESTS="$ALL_TESTS 0010:1:1"
  51. ALL_TESTS="$ALL_TESTS 0011:1:1"
  52. ALL_TESTS="$ALL_TESTS 0012:1:1"
  53. ALL_TESTS="$ALL_TESTS 0013:1:1"
  54. # Kselftest framework requirement - SKIP code is 4.
  55. ksft_skip=4
  56. test_modprobe()
  57. {
  58. if [ ! -d $DIR ]; then
  59. echo "$0: $DIR not present" >&2
  60. echo "You must have the following enabled in your kernel:" >&2
  61. cat $TEST_DIR/config >&2
  62. exit $ksft_skip
  63. fi
  64. }
  65. function allow_user_defaults()
  66. {
  67. if [ -z $DEFAULT_KMOD_DRIVER ]; then
  68. DEFAULT_KMOD_DRIVER="test_module"
  69. fi
  70. if [ -z $DEFAULT_KMOD_FS ]; then
  71. DEFAULT_KMOD_FS="xfs"
  72. fi
  73. if [ -z $PROC_DIR ]; then
  74. PROC_DIR="/proc/sys/kernel/"
  75. fi
  76. if [ -z $MODPROBE_LIMIT ]; then
  77. MODPROBE_LIMIT=50
  78. fi
  79. if [ -z $DIR ]; then
  80. DIR="/sys/devices/virtual/misc/${TEST_DRIVER}0/"
  81. fi
  82. if [ -z $DEFAULT_NUM_TESTS ]; then
  83. DEFAULT_NUM_TESTS=150
  84. fi
  85. MODPROBE_LIMIT_FILE="${PROC_DIR}/kmod-limit"
  86. }
  87. test_reqs()
  88. {
  89. if ! which modprobe 2> /dev/null > /dev/null; then
  90. echo "$0: You need modprobe installed" >&2
  91. exit $ksft_skip
  92. fi
  93. if ! which kmod 2> /dev/null > /dev/null; then
  94. echo "$0: You need kmod installed" >&2
  95. exit $ksft_skip
  96. fi
  97. # kmod 19 has a bad bug where it returns 0 when modprobe
  98. # gets called *even* if the module was not loaded due to
  99. # some bad heuristics. For details see:
  100. #
  101. # A work around is possible in-kernel but its rather
  102. # complex.
  103. KMOD_VERSION=$(kmod --version | awk '{print $3}')
  104. if [[ $KMOD_VERSION -le 19 ]]; then
  105. echo "$0: You need at least kmod 20" >&2
  106. echo "kmod <= 19 is buggy, for details see:" >&2
  107. echo "https://git.kernel.org/cgit/utils/kernel/kmod/kmod.git/commit/libkmod/libkmod-module.c?id=fd44a98ae2eb5eb32161088954ab21e58e19dfc4" >&2
  108. exit $ksft_skip
  109. fi
  110. uid=$(id -u)
  111. if [ $uid -ne 0 ]; then
  112. echo $msg must be run as root >&2
  113. exit $ksft_skip
  114. fi
  115. }
  116. function load_req_mod()
  117. {
  118. trap "test_modprobe" EXIT
  119. if [ ! -d $DIR ]; then
  120. # Alanis: "Oh isn't it ironic?"
  121. modprobe $TEST_DRIVER
  122. fi
  123. }
  124. test_finish()
  125. {
  126. echo "$MODPROBE" > /proc/sys/kernel/modprobe
  127. echo "Test completed"
  128. }
  129. errno_name_to_val()
  130. {
  131. case "$1" in
  132. # kmod calls modprobe and upon of a module not found
  133. # modprobe returns just 1... However in the kernel we
  134. # *sometimes* see 256...
  135. MODULE_NOT_FOUND)
  136. echo 256;;
  137. SUCCESS)
  138. echo 0;;
  139. -EPERM)
  140. echo -1;;
  141. -ENOENT)
  142. echo -2;;
  143. -EINVAL)
  144. echo -22;;
  145. -ERR_ANY)
  146. echo -123456;;
  147. *)
  148. echo invalid;;
  149. esac
  150. }
  151. errno_val_to_name()
  152. case "$1" in
  153. 256)
  154. echo MODULE_NOT_FOUND;;
  155. 0)
  156. echo SUCCESS;;
  157. -1)
  158. echo -EPERM;;
  159. -2)
  160. echo -ENOENT;;
  161. -22)
  162. echo -EINVAL;;
  163. -123456)
  164. echo -ERR_ANY;;
  165. *)
  166. echo invalid;;
  167. esac
  168. config_set_test_case_driver()
  169. {
  170. if ! echo -n 1 >$DIR/config_test_case; then
  171. echo "$0: Unable to set to test case to driver" >&2
  172. exit 1
  173. fi
  174. }
  175. config_set_test_case_fs()
  176. {
  177. if ! echo -n 2 >$DIR/config_test_case; then
  178. echo "$0: Unable to set to test case to fs" >&2
  179. exit 1
  180. fi
  181. }
  182. config_num_threads()
  183. {
  184. if ! echo -n $1 >$DIR/config_num_threads; then
  185. echo "$0: Unable to set to number of threads" >&2
  186. exit 1
  187. fi
  188. }
  189. config_get_modprobe_limit()
  190. {
  191. if [[ -f ${MODPROBE_LIMIT_FILE} ]] ; then
  192. MODPROBE_LIMIT=$(cat $MODPROBE_LIMIT_FILE)
  193. fi
  194. echo $MODPROBE_LIMIT
  195. }
  196. config_num_thread_limit_extra()
  197. {
  198. MODPROBE_LIMIT=$(config_get_modprobe_limit)
  199. let EXTRA_LIMIT=$MODPROBE_LIMIT+$1
  200. config_num_threads $EXTRA_LIMIT
  201. }
  202. # For special characters use printf directly,
  203. # refer to kmod_test_0001
  204. config_set_driver()
  205. {
  206. if ! echo -n $1 >$DIR/config_test_driver; then
  207. echo "$0: Unable to set driver" >&2
  208. exit 1
  209. fi
  210. }
  211. config_set_fs()
  212. {
  213. if ! echo -n $1 >$DIR/config_test_fs; then
  214. echo "$0: Unable to set driver" >&2
  215. exit 1
  216. fi
  217. }
  218. config_get_driver()
  219. {
  220. cat $DIR/config_test_driver
  221. }
  222. config_get_test_result()
  223. {
  224. cat $DIR/test_result
  225. }
  226. config_reset()
  227. {
  228. if ! echo -n "1" >"$DIR"/reset; then
  229. echo "$0: reset should have worked" >&2
  230. exit 1
  231. fi
  232. }
  233. config_show_config()
  234. {
  235. echo "----------------------------------------------------"
  236. cat "$DIR"/config
  237. echo "----------------------------------------------------"
  238. }
  239. config_trigger()
  240. {
  241. if ! echo -n "1" >"$DIR"/trigger_config 2>/dev/null; then
  242. echo "$1: FAIL - loading should have worked"
  243. config_show_config
  244. exit 1
  245. fi
  246. echo "$1: OK! - loading kmod test"
  247. }
  248. config_trigger_want_fail()
  249. {
  250. if echo "1" > $DIR/trigger_config 2>/dev/null; then
  251. echo "$1: FAIL - test case was expected to fail"
  252. config_show_config
  253. exit 1
  254. fi
  255. echo "$1: OK! - kmod test case failed as expected"
  256. }
  257. config_expect_result()
  258. {
  259. RC=$(config_get_test_result)
  260. RC_NAME=$(errno_val_to_name $RC)
  261. ERRNO_NAME=$2
  262. ERRNO=$(errno_name_to_val $ERRNO_NAME)
  263. if [[ $ERRNO_NAME = "-ERR_ANY" ]]; then
  264. if [[ $RC -ge 0 ]]; then
  265. echo "$1: FAIL, test expects $ERRNO_NAME - got $RC_NAME ($RC)" >&2
  266. config_show_config
  267. exit 1
  268. fi
  269. elif [[ $RC != $ERRNO ]]; then
  270. echo "$1: FAIL, test expects $ERRNO_NAME ($ERRNO) - got $RC_NAME ($RC)" >&2
  271. config_show_config
  272. exit 1
  273. fi
  274. echo "$1: OK! - Return value: $RC ($RC_NAME), expected $ERRNO_NAME"
  275. }
  276. kmod_defaults_driver()
  277. {
  278. config_reset
  279. modprobe -r $DEFAULT_KMOD_DRIVER
  280. config_set_driver $DEFAULT_KMOD_DRIVER
  281. }
  282. kmod_defaults_fs()
  283. {
  284. config_reset
  285. modprobe -r $DEFAULT_KMOD_FS
  286. config_set_fs $DEFAULT_KMOD_FS
  287. config_set_test_case_fs
  288. }
  289. kmod_test_0001_driver()
  290. {
  291. NAME='\000'
  292. kmod_defaults_driver
  293. config_num_threads 1
  294. printf $NAME >"$DIR"/config_test_driver
  295. config_trigger ${FUNCNAME[0]}
  296. config_expect_result ${FUNCNAME[0]} MODULE_NOT_FOUND
  297. }
  298. kmod_test_0001_fs()
  299. {
  300. NAME='\000'
  301. kmod_defaults_fs
  302. config_num_threads 1
  303. printf $NAME >"$DIR"/config_test_fs
  304. config_trigger ${FUNCNAME[0]}
  305. config_expect_result ${FUNCNAME[0]} -EINVAL
  306. }
  307. kmod_test_0001()
  308. {
  309. kmod_test_0001_driver
  310. kmod_test_0001_fs
  311. }
  312. kmod_test_0002_driver()
  313. {
  314. NAME="nope-$DEFAULT_KMOD_DRIVER"
  315. kmod_defaults_driver
  316. config_set_driver $NAME
  317. config_num_threads 1
  318. config_trigger ${FUNCNAME[0]}
  319. config_expect_result ${FUNCNAME[0]} MODULE_NOT_FOUND
  320. }
  321. kmod_test_0002_fs()
  322. {
  323. NAME="nope-$DEFAULT_KMOD_FS"
  324. kmod_defaults_fs
  325. config_set_fs $NAME
  326. config_trigger ${FUNCNAME[0]}
  327. config_expect_result ${FUNCNAME[0]} -EINVAL
  328. }
  329. kmod_test_0002()
  330. {
  331. kmod_test_0002_driver
  332. kmod_test_0002_fs
  333. }
  334. kmod_test_0003()
  335. {
  336. kmod_defaults_fs
  337. config_num_threads 1
  338. config_trigger ${FUNCNAME[0]}
  339. config_expect_result ${FUNCNAME[0]} SUCCESS
  340. }
  341. kmod_test_0004()
  342. {
  343. kmod_defaults_fs
  344. config_num_threads 2
  345. config_trigger ${FUNCNAME[0]}
  346. config_expect_result ${FUNCNAME[0]} SUCCESS
  347. }
  348. kmod_test_0005()
  349. {
  350. kmod_defaults_driver
  351. config_trigger ${FUNCNAME[0]}
  352. config_expect_result ${FUNCNAME[0]} SUCCESS
  353. }
  354. kmod_test_0006()
  355. {
  356. kmod_defaults_fs
  357. config_trigger ${FUNCNAME[0]}
  358. config_expect_result ${FUNCNAME[0]} SUCCESS
  359. }
  360. kmod_test_0007()
  361. {
  362. kmod_test_0005
  363. kmod_test_0006
  364. }
  365. kmod_test_0008()
  366. {
  367. kmod_defaults_driver
  368. MODPROBE_LIMIT=$(config_get_modprobe_limit)
  369. let EXTRA=$MODPROBE_LIMIT/6
  370. config_num_thread_limit_extra $EXTRA
  371. config_trigger ${FUNCNAME[0]}
  372. config_expect_result ${FUNCNAME[0]} SUCCESS
  373. }
  374. kmod_test_0009()
  375. {
  376. kmod_defaults_fs
  377. MODPROBE_LIMIT=$(config_get_modprobe_limit)
  378. let EXTRA=$MODPROBE_LIMIT/4
  379. config_num_thread_limit_extra $EXTRA
  380. config_trigger ${FUNCNAME[0]}
  381. config_expect_result ${FUNCNAME[0]} SUCCESS
  382. }
  383. kmod_test_0010()
  384. {
  385. kmod_defaults_driver
  386. config_num_threads 1
  387. echo "/KMOD_TEST_NONEXISTENT" > /proc/sys/kernel/modprobe
  388. config_trigger ${FUNCNAME[0]}
  389. config_expect_result ${FUNCNAME[0]} -ENOENT
  390. echo "$MODPROBE" > /proc/sys/kernel/modprobe
  391. }
  392. kmod_test_0011()
  393. {
  394. kmod_defaults_driver
  395. config_num_threads 1
  396. # This causes the kernel to not even try executing modprobe. The error
  397. # code is still -ENOENT like when modprobe doesn't exist, so we can't
  398. # easily test for the exact difference. But this still is a useful test
  399. # since there was a bug where request_module() returned 0 in this case.
  400. echo > /proc/sys/kernel/modprobe
  401. config_trigger ${FUNCNAME[0]}
  402. config_expect_result ${FUNCNAME[0]} -ENOENT
  403. echo "$MODPROBE" > /proc/sys/kernel/modprobe
  404. }
  405. kmod_check_visibility()
  406. {
  407. local name="$1"
  408. local cmd="$2"
  409. modprobe $DEFAULT_KMOD_DRIVER
  410. local priv=$(eval $cmd)
  411. local unpriv=$(capsh --drop=CAP_SYSLOG -- -c "$cmd")
  412. if [ "$priv" = "$unpriv" ] || \
  413. [ "${priv:0:3}" = "0x0" ] || \
  414. [ "${unpriv:0:3}" != "0x0" ] ; then
  415. echo "${FUNCNAME[0]}: FAIL, $name visible to unpriv: '$priv' vs '$unpriv'" >&2
  416. exit 1
  417. else
  418. echo "${FUNCNAME[0]}: OK!"
  419. fi
  420. }
  421. kmod_test_0012()
  422. {
  423. kmod_check_visibility /proc/modules \
  424. "grep '^${DEFAULT_KMOD_DRIVER}\b' /proc/modules | awk '{print \$NF}'"
  425. }
  426. kmod_test_0013()
  427. {
  428. kmod_check_visibility '/sys/module/*/sections/*' \
  429. "cat /sys/module/${DEFAULT_KMOD_DRIVER}/sections/.*text | head -n1"
  430. }
  431. list_tests()
  432. {
  433. echo "Test ID list:"
  434. echo
  435. echo "TEST_ID x NUM_TEST"
  436. echo "TEST_ID: Test ID"
  437. echo "NUM_TESTS: Number of recommended times to run the test"
  438. echo
  439. echo "0001 x $(get_test_count 0001) - Simple test - 1 thread for empty string"
  440. echo "0002 x $(get_test_count 0002) - Simple test - 1 thread for modules/filesystems that do not exist"
  441. echo "0003 x $(get_test_count 0003) - Simple test - 1 thread for get_fs_type() only"
  442. echo "0004 x $(get_test_count 0004) - Simple test - 2 threads for get_fs_type() only"
  443. echo "0005 x $(get_test_count 0005) - multithreaded tests with default setup - request_module() only"
  444. echo "0006 x $(get_test_count 0006) - multithreaded tests with default setup - get_fs_type() only"
  445. echo "0007 x $(get_test_count 0007) - multithreaded tests with default setup test request_module() and get_fs_type()"
  446. echo "0008 x $(get_test_count 0008) - multithreaded - push kmod_concurrent over max_modprobes for request_module()"
  447. echo "0009 x $(get_test_count 0009) - multithreaded - push kmod_concurrent over max_modprobes for get_fs_type()"
  448. echo "0010 x $(get_test_count 0010) - test nonexistent modprobe path"
  449. echo "0011 x $(get_test_count 0011) - test completely disabling module autoloading"
  450. echo "0012 x $(get_test_count 0012) - test /proc/modules address visibility under CAP_SYSLOG"
  451. echo "0013 x $(get_test_count 0013) - test /sys/module/*/sections/* visibility under CAP_SYSLOG"
  452. }
  453. usage()
  454. {
  455. NUM_TESTS=$(grep -o ' ' <<<"$ALL_TESTS" | grep -c .)
  456. let NUM_TESTS=$NUM_TESTS+1
  457. MAX_TEST=$(printf "%04d\n" $NUM_TESTS)
  458. echo "Usage: $0 [ -t <4-number-digit> ] | [ -w <4-number-digit> ] |"
  459. echo " [ -s <4-number-digit> ] | [ -c <4-number-digit> <test- count>"
  460. echo " [ all ] [ -h | --help ] [ -l ]"
  461. echo ""
  462. echo "Valid tests: 0001-$MAX_TEST"
  463. echo ""
  464. echo " all Runs all tests (default)"
  465. echo " -t Run test ID the number amount of times is recommended"
  466. echo " -w Watch test ID run until it runs into an error"
  467. echo " -s Run test ID once"
  468. echo " -c Run test ID x test-count number of times"
  469. echo " -l List all test ID list"
  470. echo " -h|--help Help"
  471. echo
  472. echo "If an error every occurs execution will immediately terminate."
  473. echo "If you are adding a new test try using -w <test-ID> first to"
  474. echo "make sure the test passes a series of tests."
  475. echo
  476. echo Example uses:
  477. echo
  478. echo "${TEST_NAME}.sh -- executes all tests"
  479. echo "${TEST_NAME}.sh -t 0008 -- Executes test ID 0008 number of times is recommended"
  480. echo "${TEST_NAME}.sh -w 0008 -- Watch test ID 0008 run until an error occurs"
  481. echo "${TEST_NAME}.sh -s 0008 -- Run test ID 0008 once"
  482. echo "${TEST_NAME}.sh -c 0008 3 -- Run test ID 0008 three times"
  483. echo
  484. list_tests
  485. exit 1
  486. }
  487. function test_num()
  488. {
  489. re='^[0-9]+$'
  490. if ! [[ $1 =~ $re ]]; then
  491. usage
  492. fi
  493. }
  494. function get_test_data()
  495. {
  496. test_num $1
  497. local field_num=$(echo $1 | sed 's/^0*//')
  498. echo $ALL_TESTS | awk '{print $'$field_num'}'
  499. }
  500. function get_test_count()
  501. {
  502. TEST_DATA=$(get_test_data $1)
  503. LAST_TWO=${TEST_DATA#*:*}
  504. echo ${LAST_TWO%:*}
  505. }
  506. function get_test_enabled()
  507. {
  508. TEST_DATA=$(get_test_data $1)
  509. echo ${TEST_DATA#*:*:}
  510. }
  511. function run_all_tests()
  512. {
  513. for i in $ALL_TESTS ; do
  514. TEST_ID=${i%:*:*}
  515. ENABLED=$(get_test_enabled $TEST_ID)
  516. TEST_COUNT=$(get_test_count $TEST_ID)
  517. if [[ $ENABLED -eq "1" ]]; then
  518. test_case $TEST_ID $TEST_COUNT
  519. fi
  520. done
  521. }
  522. function watch_log()
  523. {
  524. if [ $# -ne 3 ]; then
  525. clear
  526. fi
  527. date
  528. echo "Running test: $2 - run #$1"
  529. }
  530. function watch_case()
  531. {
  532. i=0
  533. while [ 1 ]; do
  534. if [ $# -eq 1 ]; then
  535. test_num $1
  536. watch_log $i ${TEST_NAME}_test_$1
  537. ${TEST_NAME}_test_$1
  538. else
  539. watch_log $i all
  540. run_all_tests
  541. fi
  542. let i=$i+1
  543. done
  544. }
  545. function test_case()
  546. {
  547. NUM_TESTS=$DEFAULT_NUM_TESTS
  548. if [ $# -eq 2 ]; then
  549. NUM_TESTS=$2
  550. fi
  551. i=0
  552. while [ $i -lt $NUM_TESTS ]; do
  553. test_num $1
  554. watch_log $i ${TEST_NAME}_test_$1 noclear
  555. RUN_TEST=${TEST_NAME}_test_$1
  556. $RUN_TEST
  557. let i=$i+1
  558. done
  559. }
  560. function parse_args()
  561. {
  562. if [ $# -eq 0 ]; then
  563. run_all_tests
  564. else
  565. if [[ "$1" = "all" ]]; then
  566. run_all_tests
  567. elif [[ "$1" = "-w" ]]; then
  568. shift
  569. watch_case $@
  570. elif [[ "$1" = "-t" ]]; then
  571. shift
  572. test_num $1
  573. test_case $1 $(get_test_count $1)
  574. elif [[ "$1" = "-c" ]]; then
  575. shift
  576. test_num $1
  577. test_num $2
  578. test_case $1 $2
  579. elif [[ "$1" = "-s" ]]; then
  580. shift
  581. test_case $1 1
  582. elif [[ "$1" = "-l" ]]; then
  583. list_tests
  584. elif [[ "$1" = "-h" || "$1" = "--help" ]]; then
  585. usage
  586. else
  587. usage
  588. fi
  589. fi
  590. }
  591. test_reqs
  592. allow_user_defaults
  593. load_req_mod
  594. MODPROBE=$(</proc/sys/kernel/modprobe)
  595. trap "test_finish" EXIT
  596. parse_args $@
  597. exit 0