sysctl.sh 20 KB

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