sysctl.sh 21 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069
  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. # This performs a series tests against the proc sysctl interface.
  5. # Kselftest framework requirement - SKIP code is 4.
  6. ksft_skip=4
  7. TEST_NAME="sysctl"
  8. TEST_DRIVER="test_${TEST_NAME}"
  9. TEST_DIR=$(dirname $0)
  10. TEST_FILE=$(mktemp)
  11. # This represents
  12. #
  13. # TEST_ID:TEST_COUNT:ENABLED:TARGET:SKIP_NO_TARGET
  14. #
  15. # TEST_ID: is the test id number
  16. # TEST_COUNT: number of times we should run the test
  17. # ENABLED: 1 if enabled, 0 otherwise
  18. # TARGET: test target file required on the test_sysctl module
  19. # SKIP_NO_TARGET: 1 skip if TARGET not there
  20. # 0 run eventhough TARGET not there
  21. #
  22. # Once these are enabled please leave them as-is. Write your own test,
  23. # we have tons of space.
  24. ALL_TESTS="0001:1:1:int_0001:1"
  25. ALL_TESTS="$ALL_TESTS 0002:1:1:string_0001:1"
  26. ALL_TESTS="$ALL_TESTS 0003:1:1:int_0002:1"
  27. ALL_TESTS="$ALL_TESTS 0004:1:1:uint_0001:1"
  28. ALL_TESTS="$ALL_TESTS 0005:3:1:int_0003:1"
  29. ALL_TESTS="$ALL_TESTS 0006:50:1:bitmap_0001:1"
  30. ALL_TESTS="$ALL_TESTS 0007:1:1:boot_int:1"
  31. ALL_TESTS="$ALL_TESTS 0008:1:1:match_int:1"
  32. ALL_TESTS="$ALL_TESTS 0009:1:1:unregister_error:0"
  33. ALL_TESTS="$ALL_TESTS 0010:1:1:mnt/mnt_error:0"
  34. ALL_TESTS="$ALL_TESTS 0011:1:1:empty_add:0"
  35. function allow_user_defaults()
  36. {
  37. if [ -z $DIR ]; then
  38. DIR="/sys/module/test_sysctl/"
  39. fi
  40. if [ -z $DEFAULT_NUM_TESTS ]; then
  41. DEFAULT_NUM_TESTS=50
  42. fi
  43. if [ -z $SYSCTL ]; then
  44. SYSCTL="/proc/sys/debug/test_sysctl"
  45. fi
  46. if [ -z $PROD_SYSCTL ]; then
  47. PROD_SYSCTL="/proc/sys"
  48. fi
  49. if [ -z $WRITES_STRICT ]; then
  50. WRITES_STRICT="${PROD_SYSCTL}/kernel/sysctl_writes_strict"
  51. fi
  52. }
  53. function check_production_sysctl_writes_strict()
  54. {
  55. echo -n "Checking production write strict setting ... "
  56. if [ ! -e ${WRITES_STRICT} ]; then
  57. echo "FAIL, but skip in case of old kernel" >&2
  58. else
  59. old_strict=$(cat ${WRITES_STRICT})
  60. if [ "$old_strict" = "1" ]; then
  61. echo "OK"
  62. else
  63. echo "FAIL, strict value is 0 but force to 1 to continue" >&2
  64. echo "1" > ${WRITES_STRICT}
  65. fi
  66. fi
  67. if [ -z $PAGE_SIZE ]; then
  68. PAGE_SIZE=$(getconf PAGESIZE)
  69. fi
  70. if [ -z $MAX_DIGITS ]; then
  71. MAX_DIGITS=$(($PAGE_SIZE/8))
  72. fi
  73. if [ -z $INT_MAX ]; then
  74. INT_MAX=$(getconf INT_MAX)
  75. fi
  76. if [ -z $UINT_MAX ]; then
  77. UINT_MAX=$(getconf UINT_MAX)
  78. fi
  79. }
  80. test_reqs()
  81. {
  82. uid=$(id -u)
  83. if [ $uid -ne 0 ]; then
  84. echo $msg must be run as root >&2
  85. exit $ksft_skip
  86. fi
  87. if ! which perl 2> /dev/null > /dev/null; then
  88. echo "$0: You need perl installed"
  89. exit $ksft_skip
  90. fi
  91. if ! which getconf 2> /dev/null > /dev/null; then
  92. echo "$0: You need getconf installed"
  93. exit $ksft_skip
  94. fi
  95. if ! which diff 2> /dev/null > /dev/null; then
  96. echo "$0: You need diff installed"
  97. exit $ksft_skip
  98. fi
  99. }
  100. function load_req_mod()
  101. {
  102. if [ ! -d $SYSCTL ]; then
  103. if ! modprobe -q -n $TEST_DRIVER; then
  104. echo "$0: module $TEST_DRIVER not found [SKIP]"
  105. echo "You must set CONFIG_TEST_SYSCTL=m in your kernel" >&2
  106. exit $ksft_skip
  107. fi
  108. modprobe $TEST_DRIVER
  109. if [ $? -ne 0 ]; then
  110. echo "$0: modprobe $TEST_DRIVER failed."
  111. exit
  112. fi
  113. fi
  114. }
  115. reset_vals()
  116. {
  117. VAL=""
  118. TRIGGER=$(basename ${TARGET})
  119. case "$TRIGGER" in
  120. int_0001)
  121. VAL="60"
  122. ;;
  123. int_0002)
  124. VAL="1"
  125. ;;
  126. uint_0001)
  127. VAL="314"
  128. ;;
  129. string_0001)
  130. VAL="(none)"
  131. ;;
  132. bitmap_0001)
  133. VAL=""
  134. ;;
  135. *)
  136. ;;
  137. esac
  138. echo -n $VAL > $TARGET
  139. }
  140. set_orig()
  141. {
  142. if [ ! -z $TARGET ] && [ ! -z $ORIG ]; then
  143. if [ -f ${TARGET} ]; then
  144. echo "${ORIG}" > "${TARGET}"
  145. fi
  146. fi
  147. }
  148. set_test()
  149. {
  150. echo "${TEST_STR}" > "${TARGET}"
  151. }
  152. verify()
  153. {
  154. local seen
  155. seen=$(cat "$1")
  156. if [ "${seen}" != "${TEST_STR}" ]; then
  157. return 1
  158. fi
  159. return 0
  160. }
  161. # proc files get read a page at a time, which can confuse diff,
  162. # and get you incorrect results on proc files with long data. To use
  163. # diff against them you must first extract the output to a file, and
  164. # then compare against that file.
  165. verify_diff_proc_file()
  166. {
  167. TMP_DUMP_FILE=$(mktemp)
  168. cat $1 > $TMP_DUMP_FILE
  169. if ! diff -w -q $TMP_DUMP_FILE $2; then
  170. return 1
  171. else
  172. return 0
  173. fi
  174. }
  175. verify_diff_w()
  176. {
  177. echo "$TEST_STR" | diff -q -w -u - $1 > /dev/null
  178. return $?
  179. }
  180. test_rc()
  181. {
  182. if [[ $rc != 0 ]]; then
  183. echo "Failed test, return value: $rc" >&2
  184. exit $rc
  185. fi
  186. }
  187. test_finish()
  188. {
  189. set_orig
  190. rm -f "${TEST_FILE}"
  191. if [ ! -z ${old_strict} ]; then
  192. echo ${old_strict} > ${WRITES_STRICT}
  193. fi
  194. exit $rc
  195. }
  196. run_numerictests()
  197. {
  198. echo "== Testing sysctl behavior against ${TARGET} =="
  199. rc=0
  200. echo -n "Writing test file ... "
  201. echo "${TEST_STR}" > "${TEST_FILE}"
  202. if ! verify "${TEST_FILE}"; then
  203. echo "FAIL" >&2
  204. exit 1
  205. else
  206. echo "OK"
  207. fi
  208. echo -n "Checking sysctl is not set to test value ... "
  209. if verify "${TARGET}"; then
  210. echo "FAIL" >&2
  211. exit 1
  212. else
  213. echo "OK"
  214. fi
  215. echo -n "Writing sysctl from shell ... "
  216. set_test
  217. if ! verify "${TARGET}"; then
  218. echo "FAIL" >&2
  219. exit 1
  220. else
  221. echo "OK"
  222. fi
  223. echo -n "Resetting sysctl to original value ... "
  224. set_orig
  225. if verify "${TARGET}"; then
  226. echo "FAIL" >&2
  227. exit 1
  228. else
  229. echo "OK"
  230. fi
  231. # Now that we've validated the sanity of "set_test" and "set_orig",
  232. # we can use those functions to set starting states before running
  233. # specific behavioral tests.
  234. echo -n "Writing entire sysctl in single write ... "
  235. set_orig
  236. dd if="${TEST_FILE}" of="${TARGET}" bs=4096 2>/dev/null
  237. if ! verify "${TARGET}"; then
  238. echo "FAIL" >&2
  239. rc=1
  240. else
  241. echo "OK"
  242. fi
  243. echo -n "Writing middle of sysctl after synchronized seek ... "
  244. set_test
  245. dd if="${TEST_FILE}" of="${TARGET}" bs=1 seek=1 skip=1 2>/dev/null
  246. if ! verify "${TARGET}"; then
  247. echo "FAIL" >&2
  248. rc=1
  249. else
  250. echo "OK"
  251. fi
  252. echo -n "Writing beyond end of sysctl ... "
  253. set_orig
  254. dd if="${TEST_FILE}" of="${TARGET}" bs=20 seek=2 2>/dev/null
  255. if verify "${TARGET}"; then
  256. echo "FAIL" >&2
  257. rc=1
  258. else
  259. echo "OK"
  260. fi
  261. echo -n "Writing sysctl with multiple long writes ... "
  262. set_orig
  263. (perl -e 'print "A" x 50;'; echo "${TEST_STR}") | \
  264. dd of="${TARGET}" bs=50 2>/dev/null
  265. if verify "${TARGET}"; then
  266. echo "FAIL" >&2
  267. rc=1
  268. else
  269. echo "OK"
  270. fi
  271. test_rc
  272. }
  273. check_failure()
  274. {
  275. echo -n "Testing that $1 fails as expected ... "
  276. reset_vals
  277. TEST_STR="$1"
  278. orig="$(cat $TARGET)"
  279. echo -n "$TEST_STR" > $TARGET 2> /dev/null
  280. # write should fail and $TARGET should retain its original value
  281. if [ $? = 0 ] || [ "$(cat $TARGET)" != "$orig" ]; then
  282. echo "FAIL" >&2
  283. rc=1
  284. else
  285. echo "OK"
  286. fi
  287. test_rc
  288. }
  289. run_wideint_tests()
  290. {
  291. # sysctl conversion functions receive a boolean sign and ulong
  292. # magnitude; here we list the magnitudes we want to test (each of
  293. # which will be tested in both positive and negative forms). Since
  294. # none of these values fit in 32 bits, writing them to an int- or
  295. # uint-typed sysctl should fail.
  296. local magnitudes=(
  297. # common boundary-condition values (zero, +1, -1, INT_MIN,
  298. # and INT_MAX respectively) if truncated to lower 32 bits
  299. # (potential for being falsely deemed in range)
  300. 0x0000000100000000
  301. 0x0000000100000001
  302. 0x00000001ffffffff
  303. 0x0000000180000000
  304. 0x000000017fffffff
  305. # these look like negatives, but without a leading '-' are
  306. # actually large positives (should be rejected as above
  307. # despite being zero/+1/-1/INT_MIN/INT_MAX in the lower 32)
  308. 0xffffffff00000000
  309. 0xffffffff00000001
  310. 0xffffffffffffffff
  311. 0xffffffff80000000
  312. 0xffffffff7fffffff
  313. )
  314. for sign in '' '-'; do
  315. for mag in "${magnitudes[@]}"; do
  316. check_failure "${sign}${mag}"
  317. done
  318. done
  319. }
  320. # Your test must accept digits 3 and 4 to use this
  321. run_limit_digit()
  322. {
  323. echo -n "Checking ignoring spaces up to PAGE_SIZE works on write ... "
  324. reset_vals
  325. LIMIT=$((MAX_DIGITS -1))
  326. TEST_STR="3"
  327. (perl -e 'print " " x '$LIMIT';'; echo "${TEST_STR}") | \
  328. dd of="${TARGET}" 2>/dev/null
  329. if ! verify "${TARGET}"; then
  330. echo "FAIL" >&2
  331. rc=1
  332. else
  333. echo "OK"
  334. fi
  335. test_rc
  336. echo -n "Checking passing PAGE_SIZE of spaces fails on write ... "
  337. reset_vals
  338. LIMIT=$((MAX_DIGITS))
  339. TEST_STR="4"
  340. (perl -e 'print " " x '$LIMIT';'; echo "${TEST_STR}") | \
  341. dd of="${TARGET}" 2>/dev/null
  342. if verify "${TARGET}"; then
  343. echo "FAIL" >&2
  344. rc=1
  345. else
  346. echo "OK"
  347. fi
  348. test_rc
  349. }
  350. # You are using an int
  351. run_limit_digit_int()
  352. {
  353. echo -n "Testing INT_MAX works ... "
  354. reset_vals
  355. TEST_STR="$INT_MAX"
  356. echo -n $TEST_STR > $TARGET
  357. if ! verify "${TARGET}"; then
  358. echo "FAIL" >&2
  359. rc=1
  360. else
  361. echo "OK"
  362. fi
  363. test_rc
  364. echo -n "Testing INT_MAX + 1 will fail as expected ... "
  365. reset_vals
  366. let TEST_STR=$INT_MAX+1
  367. echo -n $TEST_STR > $TARGET 2> /dev/null
  368. if verify "${TARGET}"; then
  369. echo "FAIL" >&2
  370. rc=1
  371. else
  372. echo "OK"
  373. fi
  374. test_rc
  375. echo -n "Testing negative values will work as expected ... "
  376. reset_vals
  377. TEST_STR="-3"
  378. echo -n $TEST_STR > $TARGET 2> /dev/null
  379. if ! verify "${TARGET}"; then
  380. echo "FAIL" >&2
  381. rc=1
  382. else
  383. echo "OK"
  384. fi
  385. test_rc
  386. }
  387. # You used an int array
  388. run_limit_digit_int_array()
  389. {
  390. echo -n "Testing array works as expected ... "
  391. TEST_STR="4 3 2 1"
  392. echo -n $TEST_STR > $TARGET
  393. if ! verify_diff_w "${TARGET}"; then
  394. echo "FAIL" >&2
  395. rc=1
  396. else
  397. echo "OK"
  398. fi
  399. test_rc
  400. echo -n "Testing skipping trailing array elements works ... "
  401. # Do not reset_vals, carry on the values from the last test.
  402. # If we only echo in two digits the last two are left intact
  403. TEST_STR="100 101"
  404. echo -n $TEST_STR > $TARGET
  405. # After we echo in, to help diff we need to set on TEST_STR what
  406. # we expect the result to be.
  407. TEST_STR="100 101 2 1"
  408. if ! verify_diff_w "${TARGET}"; then
  409. echo "FAIL" >&2
  410. rc=1
  411. else
  412. echo "OK"
  413. fi
  414. test_rc
  415. echo -n "Testing PAGE_SIZE limit on array works ... "
  416. # Do not reset_vals, carry on the values from the last test.
  417. # Even if you use an int array, you are still restricted to
  418. # MAX_DIGITS, this is a known limitation. Test limit works.
  419. LIMIT=$((MAX_DIGITS -1))
  420. TEST_STR="9"
  421. (perl -e 'print " " x '$LIMIT';'; echo "${TEST_STR}") | \
  422. dd of="${TARGET}" 2>/dev/null
  423. TEST_STR="9 101 2 1"
  424. if ! verify_diff_w "${TARGET}"; then
  425. echo "FAIL" >&2
  426. rc=1
  427. else
  428. echo "OK"
  429. fi
  430. test_rc
  431. echo -n "Testing exceeding PAGE_SIZE limit fails as expected ... "
  432. # Do not reset_vals, carry on the values from the last test.
  433. # Now go over limit.
  434. LIMIT=$((MAX_DIGITS))
  435. TEST_STR="7"
  436. (perl -e 'print " " x '$LIMIT';'; echo "${TEST_STR}") | \
  437. dd of="${TARGET}" 2>/dev/null
  438. TEST_STR="7 101 2 1"
  439. if verify_diff_w "${TARGET}"; then
  440. echo "FAIL" >&2
  441. rc=1
  442. else
  443. echo "OK"
  444. fi
  445. test_rc
  446. }
  447. # You are using an unsigned int
  448. run_limit_digit_uint()
  449. {
  450. echo -n "Testing UINT_MAX works ... "
  451. reset_vals
  452. TEST_STR="$UINT_MAX"
  453. echo -n $TEST_STR > $TARGET
  454. if ! verify "${TARGET}"; then
  455. echo "FAIL" >&2
  456. rc=1
  457. else
  458. echo "OK"
  459. fi
  460. test_rc
  461. echo -n "Testing UINT_MAX + 1 will fail as expected ... "
  462. reset_vals
  463. TEST_STR=$(($UINT_MAX+1))
  464. echo -n $TEST_STR > $TARGET 2> /dev/null
  465. if verify "${TARGET}"; then
  466. echo "FAIL" >&2
  467. rc=1
  468. else
  469. echo "OK"
  470. fi
  471. test_rc
  472. echo -n "Testing negative values will not work as expected ... "
  473. reset_vals
  474. TEST_STR="-3"
  475. echo -n $TEST_STR > $TARGET 2> /dev/null
  476. if verify "${TARGET}"; then
  477. echo "FAIL" >&2
  478. rc=1
  479. else
  480. echo "OK"
  481. fi
  482. test_rc
  483. }
  484. run_stringtests()
  485. {
  486. echo -n "Writing entire sysctl in short writes ... "
  487. set_orig
  488. dd if="${TEST_FILE}" of="${TARGET}" bs=1 2>/dev/null
  489. if ! verify "${TARGET}"; then
  490. echo "FAIL" >&2
  491. rc=1
  492. else
  493. echo "OK"
  494. fi
  495. echo -n "Writing middle of sysctl after unsynchronized seek ... "
  496. set_test
  497. dd if="${TEST_FILE}" of="${TARGET}" bs=1 seek=1 2>/dev/null
  498. if verify "${TARGET}"; then
  499. echo "FAIL" >&2
  500. rc=1
  501. else
  502. echo "OK"
  503. fi
  504. echo -n "Checking sysctl maxlen is at least $MAXLEN ... "
  505. set_orig
  506. perl -e 'print "A" x ('"${MAXLEN}"'-2), "B";' | \
  507. dd of="${TARGET}" bs="${MAXLEN}" 2>/dev/null
  508. if ! grep -q B "${TARGET}"; then
  509. echo "FAIL" >&2
  510. rc=1
  511. else
  512. echo "OK"
  513. fi
  514. echo -n "Checking sysctl keeps original string on overflow append ... "
  515. set_orig
  516. perl -e 'print "A" x ('"${MAXLEN}"'-1), "B";' | \
  517. dd of="${TARGET}" bs=$(( MAXLEN - 1 )) 2>/dev/null
  518. if grep -q B "${TARGET}"; then
  519. echo "FAIL" >&2
  520. rc=1
  521. else
  522. echo "OK"
  523. fi
  524. echo -n "Checking sysctl stays NULL terminated on write ... "
  525. set_orig
  526. perl -e 'print "A" x ('"${MAXLEN}"'-1), "B";' | \
  527. dd of="${TARGET}" bs="${MAXLEN}" 2>/dev/null
  528. if grep -q B "${TARGET}"; then
  529. echo "FAIL" >&2
  530. rc=1
  531. else
  532. echo "OK"
  533. fi
  534. echo -n "Checking sysctl stays NULL terminated on overwrite ... "
  535. set_orig
  536. perl -e 'print "A" x ('"${MAXLEN}"'-1), "BB";' | \
  537. dd of="${TARGET}" bs=$(( $MAXLEN + 1 )) 2>/dev/null
  538. if grep -q B "${TARGET}"; then
  539. echo "FAIL" >&2
  540. rc=1
  541. else
  542. echo "OK"
  543. fi
  544. test_rc
  545. }
  546. target_exists()
  547. {
  548. TARGET="${SYSCTL}/$1"
  549. TEST_ID="$2"
  550. if [ ! -f ${TARGET} ] ; then
  551. return 0
  552. fi
  553. return 1
  554. }
  555. run_bitmaptest() {
  556. # Total length of bitmaps string to use, a bit under
  557. # the maximum input size of the test node
  558. LENGTH=$((RANDOM % 65000))
  559. # First bit to set
  560. BIT=$((RANDOM % 1024))
  561. # String containing our list of bits to set
  562. TEST_STR=$BIT
  563. # build up the string
  564. while [ "${#TEST_STR}" -le "$LENGTH" ]; do
  565. # Make sure next entry is discontiguous,
  566. # skip ahead at least 2
  567. BIT=$((BIT + $((2 + RANDOM % 10))))
  568. # Add new bit to the list
  569. TEST_STR="${TEST_STR},${BIT}"
  570. # Randomly make it a range
  571. if [ "$((RANDOM % 2))" -eq "1" ]; then
  572. RANGE_END=$((BIT + $((1 + RANDOM % 10))))
  573. TEST_STR="${TEST_STR}-${RANGE_END}"
  574. BIT=$RANGE_END
  575. fi
  576. done
  577. echo -n "Checking bitmap handler ... "
  578. TEST_FILE=$(mktemp)
  579. echo -n "$TEST_STR" > $TEST_FILE
  580. cat $TEST_FILE > $TARGET 2> /dev/null
  581. if [ $? -ne 0 ]; then
  582. echo "FAIL" >&2
  583. rc=1
  584. test_rc
  585. fi
  586. if ! verify_diff_proc_file "$TARGET" "$TEST_FILE"; then
  587. echo "FAIL" >&2
  588. rc=1
  589. else
  590. echo "OK"
  591. rc=0
  592. fi
  593. test_rc
  594. }
  595. sysctl_test_0001()
  596. {
  597. TARGET="${SYSCTL}/$(get_test_target 0001)"
  598. reset_vals
  599. ORIG=$(cat "${TARGET}")
  600. TEST_STR=$(( $ORIG + 1 ))
  601. run_numerictests
  602. run_wideint_tests
  603. run_limit_digit
  604. }
  605. sysctl_test_0002()
  606. {
  607. TARGET="${SYSCTL}/$(get_test_target 0002)"
  608. reset_vals
  609. ORIG=$(cat "${TARGET}")
  610. TEST_STR="Testing sysctl"
  611. # Only string sysctls support seeking/appending.
  612. MAXLEN=65
  613. run_numerictests
  614. run_stringtests
  615. }
  616. sysctl_test_0003()
  617. {
  618. TARGET="${SYSCTL}/$(get_test_target 0003)"
  619. reset_vals
  620. ORIG=$(cat "${TARGET}")
  621. TEST_STR=$(( $ORIG + 1 ))
  622. run_numerictests
  623. run_wideint_tests
  624. run_limit_digit
  625. run_limit_digit_int
  626. }
  627. sysctl_test_0004()
  628. {
  629. TARGET="${SYSCTL}/$(get_test_target 0004)"
  630. reset_vals
  631. ORIG=$(cat "${TARGET}")
  632. TEST_STR=$(( $ORIG + 1 ))
  633. run_numerictests
  634. run_wideint_tests
  635. run_limit_digit
  636. run_limit_digit_uint
  637. }
  638. sysctl_test_0005()
  639. {
  640. TARGET="${SYSCTL}/$(get_test_target 0005)"
  641. reset_vals
  642. ORIG=$(cat "${TARGET}")
  643. run_limit_digit_int_array
  644. }
  645. sysctl_test_0006()
  646. {
  647. TARGET="${SYSCTL}/$(get_test_target 0006)"
  648. reset_vals
  649. ORIG=""
  650. run_bitmaptest
  651. }
  652. sysctl_test_0007()
  653. {
  654. TARGET="${SYSCTL}/$(get_test_target 0007)"
  655. echo -n "Testing if $TARGET is set to 1 ... "
  656. if [ ! -f $TARGET ]; then
  657. echo -e "SKIPPING\n$TARGET is not present"
  658. return $ksft_skip
  659. fi
  660. if [ -d $DIR ]; then
  661. echo -e "SKIPPING\nTest only possible if sysctl_test is built-in, not module:"
  662. cat $TEST_DIR/config >&2
  663. return $ksft_skip
  664. fi
  665. ORIG=$(cat "${TARGET}")
  666. if [ x$ORIG = "x1" ]; then
  667. echo "OK"
  668. return 0
  669. fi
  670. if [ ! -f /proc/cmdline ]; then
  671. echo -e "SKIPPING\nThere is no /proc/cmdline to check for paramter"
  672. return $ksft_skip
  673. fi
  674. FOUND=$(grep -c "sysctl[./]debug[./]test_sysctl[./]boot_int=1" /proc/cmdline)
  675. if [ $FOUND = "1" ]; then
  676. echo -e "FAIL\nKernel param found but $TARGET is not 1." >&2
  677. rc=1
  678. test_rc
  679. fi
  680. echo -e "SKIPPING\nExpected kernel parameter missing."
  681. echo "Kernel must be booted with parameter: sysctl.debug.test_sysctl.boot_int=1"
  682. return $ksft_skip
  683. }
  684. sysctl_test_0008()
  685. {
  686. TARGET="${SYSCTL}/$(get_test_target 0008)"
  687. echo -n "Testing if $TARGET is matched in kernel ... "
  688. if [ ! -f $TARGET ]; then
  689. echo -e "SKIPPING\n$TARGET is not present"
  690. return $ksft_skip
  691. fi
  692. ORIG_VALUE=$(cat "${TARGET}")
  693. if [ $ORIG_VALUE -ne 1 ]; then
  694. echo "FAIL" >&2
  695. rc=1
  696. test_rc
  697. fi
  698. echo "OK"
  699. return 0
  700. }
  701. sysctl_test_0009()
  702. {
  703. TARGET="${SYSCTL}/$(get_test_target 0009)"
  704. echo -n "Testing if $TARGET unregistered correctly ... "
  705. if [ -d $TARGET ]; then
  706. echo "FAIL" >&2
  707. rc=1
  708. test_rc
  709. fi
  710. echo "OK"
  711. return 0
  712. }
  713. sysctl_test_0010()
  714. {
  715. TARGET="${SYSCTL}/$(get_test_target 0010)"
  716. echo -n "Testing that $TARGET was not created ... "
  717. if [ -d $TARGET ]; then
  718. echo "FAIL" >&2
  719. rc=1
  720. test_rc
  721. fi
  722. echo "OK"
  723. return 0
  724. }
  725. sysctl_test_0011()
  726. {
  727. TARGET="${SYSCTL}/$(get_test_target 0011)"
  728. echo -n "Testing empty dir handling in ${TARGET} ... "
  729. if [ ! -d ${TARGET} ]; then
  730. echo -e "FAIL\nCould not create ${TARGET}" >&2
  731. rc=1
  732. test_rc
  733. fi
  734. TARGET2="${TARGET}/empty"
  735. if [ ! -d ${TARGET2} ]; then
  736. echo -e "FAIL\nCould not create ${TARGET2}" >&2
  737. rc=1
  738. test_rc
  739. fi
  740. echo "OK"
  741. return 0
  742. }
  743. list_tests()
  744. {
  745. echo "Test ID list:"
  746. echo
  747. echo "TEST_ID x NUM_TEST"
  748. echo "TEST_ID: Test ID"
  749. echo "NUM_TESTS: Number of recommended times to run the test"
  750. echo
  751. echo "0001 x $(get_test_count 0001) - tests proc_dointvec_minmax()"
  752. echo "0002 x $(get_test_count 0002) - tests proc_dostring()"
  753. echo "0003 x $(get_test_count 0003) - tests proc_dointvec()"
  754. echo "0004 x $(get_test_count 0004) - tests proc_douintvec()"
  755. echo "0005 x $(get_test_count 0005) - tests proc_douintvec() array"
  756. echo "0006 x $(get_test_count 0006) - tests proc_do_large_bitmap()"
  757. echo "0007 x $(get_test_count 0007) - tests setting sysctl from kernel boot param"
  758. echo "0008 x $(get_test_count 0008) - tests sysctl macro values match"
  759. echo "0009 x $(get_test_count 0009) - tests sysct unregister"
  760. echo "0010 x $(get_test_count 0010) - tests sysct mount point"
  761. echo "0011 x $(get_test_count 0011) - tests empty directories"
  762. }
  763. usage()
  764. {
  765. NUM_TESTS=$(grep -o ' ' <<<"$ALL_TESTS" | grep -c .)
  766. let NUM_TESTS=$NUM_TESTS+1
  767. MAX_TEST=$(printf "%04d\n" $NUM_TESTS)
  768. echo "Usage: $0 [ -t <4-number-digit> ] | [ -w <4-number-digit> ] |"
  769. echo " [ -s <4-number-digit> ] | [ -c <4-number-digit> <test- count>"
  770. echo " [ all ] [ -h | --help ] [ -l ]"
  771. echo ""
  772. echo "Valid tests: 0001-$MAX_TEST"
  773. echo ""
  774. echo " all Runs all tests (default)"
  775. echo " -t Run test ID the number amount of times is recommended"
  776. echo " -w Watch test ID run until it runs into an error"
  777. echo " -c Run test ID once"
  778. echo " -s Run test ID x test-count number of times"
  779. echo " -l List all test ID list"
  780. echo " -h|--help Help"
  781. echo
  782. echo "If an error every occurs execution will immediately terminate."
  783. echo "If you are adding a new test try using -w <test-ID> first to"
  784. echo "make sure the test passes a series of tests."
  785. echo
  786. echo Example uses:
  787. echo
  788. echo "$TEST_NAME.sh -- executes all tests"
  789. echo "$TEST_NAME.sh -t 0002 -- Executes test ID 0002 number of times is recomended"
  790. echo "$TEST_NAME.sh -w 0002 -- Watch test ID 0002 run until an error occurs"
  791. echo "$TEST_NAME.sh -s 0002 -- Run test ID 0002 once"
  792. echo "$TEST_NAME.sh -c 0002 3 -- Run test ID 0002 three times"
  793. echo
  794. list_tests
  795. exit 1
  796. }
  797. function test_num()
  798. {
  799. re='^[0-9]+$'
  800. if ! [[ $1 =~ $re ]]; then
  801. usage
  802. fi
  803. }
  804. function remove_leading_zeros()
  805. {
  806. echo $1 | sed 's/^0*//'
  807. }
  808. function get_test_count()
  809. {
  810. test_num $1
  811. awk_field=$(remove_leading_zeros $1)
  812. TEST_DATA=$(echo $ALL_TESTS | awk '{print $'$awk_field'}')
  813. echo ${TEST_DATA} | awk -F":" '{print $2}'
  814. }
  815. function get_test_enabled()
  816. {
  817. test_num $1
  818. awk_field=$(remove_leading_zeros $1)
  819. TEST_DATA=$(echo $ALL_TESTS | awk '{print $'$awk_field'}')
  820. echo ${TEST_DATA} | awk -F":" '{print $3}'
  821. }
  822. function get_test_target()
  823. {
  824. test_num $1
  825. awk_field=$(remove_leading_zeros $1)
  826. TEST_DATA=$(echo $ALL_TESTS | awk '{print $'$awk_field'}')
  827. echo ${TEST_DATA} | awk -F":" '{print $4}'
  828. }
  829. function get_test_skip_no_target()
  830. {
  831. test_num $1
  832. awk_field=$(remove_leading_zeros $1)
  833. TEST_DATA=$(echo $ALL_TESTS | awk '{print $'$awk_field'}')
  834. echo ${TEST_DATA} | awk -F":" '{print $5}'
  835. }
  836. function skip_test()
  837. {
  838. TEST_ID=$1
  839. TEST_TARGET=$2
  840. if target_exists $TEST_TARGET $TEST_ID; then
  841. TEST_SKIP=$(get_test_skip_no_target $TEST_ID)
  842. if [[ $TEST_SKIP -eq "1" ]]; then
  843. echo "Target $TEST_TARGET for test $TEST_ID does not exist ... SKIPPING"
  844. return 0
  845. fi
  846. fi
  847. return 1
  848. }
  849. function run_all_tests()
  850. {
  851. for i in $ALL_TESTS ; do
  852. TEST_ID=${i%:*:*:*:*}
  853. ENABLED=$(get_test_enabled $TEST_ID)
  854. TEST_COUNT=$(get_test_count $TEST_ID)
  855. TEST_TARGET=$(get_test_target $TEST_ID)
  856. if [[ $ENABLED -eq "1" ]]; then
  857. test_case $TEST_ID $TEST_COUNT $TEST_TARGET
  858. fi
  859. done
  860. }
  861. function watch_log()
  862. {
  863. if [ $# -ne 3 ]; then
  864. clear
  865. fi
  866. date
  867. echo "Running test: $2 - run #$1"
  868. }
  869. function watch_case()
  870. {
  871. i=0
  872. while [ 1 ]; do
  873. if [ $# -eq 1 ]; then
  874. test_num $1
  875. watch_log $i ${TEST_NAME}_test_$1
  876. ${TEST_NAME}_test_$1
  877. else
  878. watch_log $i all
  879. run_all_tests
  880. fi
  881. let i=$i+1
  882. done
  883. }
  884. function test_case()
  885. {
  886. TEST_ID=$1
  887. NUM_TESTS=$2
  888. TARGET=$3
  889. if skip_test $TEST_ID $TARGET; then
  890. return
  891. fi
  892. i=0
  893. while [ $i -lt $NUM_TESTS ]; do
  894. test_num $TEST_ID
  895. watch_log $i ${TEST_NAME}_test_${TEST_ID} noclear
  896. RUN_TEST=${TEST_NAME}_test_${TEST_ID}
  897. $RUN_TEST
  898. let i=$i+1
  899. done
  900. }
  901. function parse_args()
  902. {
  903. if [ $# -eq 0 ]; then
  904. run_all_tests
  905. else
  906. if [[ "$1" = "all" ]]; then
  907. run_all_tests
  908. elif [[ "$1" = "-w" ]]; then
  909. shift
  910. watch_case $@
  911. elif [[ "$1" = "-t" ]]; then
  912. shift
  913. test_num $1
  914. test_case $1 $(get_test_count $1) $(get_test_target $1)
  915. elif [[ "$1" = "-c" ]]; then
  916. shift
  917. test_num $1
  918. test_num $2
  919. test_case $1 $2 $(get_test_target $1)
  920. elif [[ "$1" = "-s" ]]; then
  921. shift
  922. test_case $1 1 $(get_test_target $1)
  923. elif [[ "$1" = "-l" ]]; then
  924. list_tests
  925. elif [[ "$1" = "-h" || "$1" = "--help" ]]; then
  926. usage
  927. else
  928. usage
  929. fi
  930. fi
  931. }
  932. test_reqs
  933. allow_user_defaults
  934. check_production_sysctl_writes_strict
  935. load_req_mod
  936. trap "test_finish" EXIT
  937. parse_args $@
  938. exit 0