hc
2024-05-10 61598093bbdd283a7edc367d900f223070ead8d2
kernel/tools/testing/selftests/sysctl/sysctl.sh
....@@ -24,29 +24,22 @@
2424
2525 # This represents
2626 #
27
-# TEST_ID:TEST_COUNT:ENABLED
27
+# TEST_ID:TEST_COUNT:ENABLED:TARGET
2828 #
2929 # TEST_ID: is the test id number
3030 # TEST_COUNT: number of times we should run the test
3131 # ENABLED: 1 if enabled, 0 otherwise
32
+# TARGET: test target file required on the test_sysctl module
3233 #
3334 # Once these are enabled please leave them as-is. Write your own test,
3435 # we have tons of space.
35
-ALL_TESTS="0001:1:1"
36
-ALL_TESTS="$ALL_TESTS 0002:1:1"
37
-ALL_TESTS="$ALL_TESTS 0003:1:1"
38
-ALL_TESTS="$ALL_TESTS 0004:1:1"
39
-ALL_TESTS="$ALL_TESTS 0005:3:1"
40
-
41
-test_modprobe()
42
-{
43
- if [ ! -d $DIR ]; then
44
- echo "$0: $DIR not present" >&2
45
- echo "You must have the following enabled in your kernel:" >&2
46
- cat $TEST_DIR/config >&2
47
- exit $ksft_skip
48
- fi
49
-}
36
+ALL_TESTS="0001:1:1:int_0001"
37
+ALL_TESTS="$ALL_TESTS 0002:1:1:string_0001"
38
+ALL_TESTS="$ALL_TESTS 0003:1:1:int_0002"
39
+ALL_TESTS="$ALL_TESTS 0004:1:1:uint_0001"
40
+ALL_TESTS="$ALL_TESTS 0005:3:1:int_0003"
41
+ALL_TESTS="$ALL_TESTS 0006:50:1:bitmap_0001"
42
+ALL_TESTS="$ALL_TESTS 0007:1:1:boot_int"
5043
5144 function allow_user_defaults()
5245 {
....@@ -120,13 +113,15 @@
120113
121114 function load_req_mod()
122115 {
123
- if [ ! -d $DIR ]; then
116
+ if [ ! -d $SYSCTL ]; then
124117 if ! modprobe -q -n $TEST_DRIVER; then
125118 echo "$0: module $TEST_DRIVER not found [SKIP]"
119
+ echo "You must set CONFIG_TEST_SYSCTL=m in your kernel" >&2
126120 exit $ksft_skip
127121 fi
128122 modprobe $TEST_DRIVER
129123 if [ $? -ne 0 ]; then
124
+ echo "$0: modprobe $TEST_DRIVER failed."
130125 exit
131126 fi
132127 fi
....@@ -149,6 +144,9 @@
149144 string_0001)
150145 VAL="(none)"
151146 ;;
147
+ bitmap_0001)
148
+ VAL=""
149
+ ;;
152150 *)
153151 ;;
154152 esac
....@@ -157,8 +155,10 @@
157155
158156 set_orig()
159157 {
160
- if [ ! -z $TARGET ]; then
161
- echo "${ORIG}" > "${TARGET}"
158
+ if [ ! -z $TARGET ] && [ ! -z $ORIG ]; then
159
+ if [ -f ${TARGET} ]; then
160
+ echo "${ORIG}" > "${TARGET}"
161
+ fi
162162 fi
163163 }
164164
....@@ -177,9 +177,25 @@
177177 return 0
178178 }
179179
180
+# proc files get read a page at a time, which can confuse diff,
181
+# and get you incorrect results on proc files with long data. To use
182
+# diff against them you must first extract the output to a file, and
183
+# then compare against that file.
184
+verify_diff_proc_file()
185
+{
186
+ TMP_DUMP_FILE=$(mktemp)
187
+ cat $1 > $TMP_DUMP_FILE
188
+
189
+ if ! diff -w -q $TMP_DUMP_FILE $2; then
190
+ return 1
191
+ else
192
+ return 0
193
+ fi
194
+}
195
+
180196 verify_diff_w()
181197 {
182
- echo "$TEST_STR" | diff -q -w -u - $1
198
+ echo "$TEST_STR" | diff -q -w -u - $1 > /dev/null
183199 return $?
184200 }
185201
....@@ -288,6 +304,58 @@
288304 echo "ok"
289305 fi
290306 test_rc
307
+}
308
+
309
+check_failure()
310
+{
311
+ echo -n "Testing that $1 fails as expected..."
312
+ reset_vals
313
+ TEST_STR="$1"
314
+ orig="$(cat $TARGET)"
315
+ echo -n "$TEST_STR" > $TARGET 2> /dev/null
316
+
317
+ # write should fail and $TARGET should retain its original value
318
+ if [ $? = 0 ] || [ "$(cat $TARGET)" != "$orig" ]; then
319
+ echo "FAIL" >&2
320
+ rc=1
321
+ else
322
+ echo "ok"
323
+ fi
324
+ test_rc
325
+}
326
+
327
+run_wideint_tests()
328
+{
329
+ # sysctl conversion functions receive a boolean sign and ulong
330
+ # magnitude; here we list the magnitudes we want to test (each of
331
+ # which will be tested in both positive and negative forms). Since
332
+ # none of these values fit in 32 bits, writing them to an int- or
333
+ # uint-typed sysctl should fail.
334
+ local magnitudes=(
335
+ # common boundary-condition values (zero, +1, -1, INT_MIN,
336
+ # and INT_MAX respectively) if truncated to lower 32 bits
337
+ # (potential for being falsely deemed in range)
338
+ 0x0000000100000000
339
+ 0x0000000100000001
340
+ 0x00000001ffffffff
341
+ 0x0000000180000000
342
+ 0x000000017fffffff
343
+
344
+ # these look like negatives, but without a leading '-' are
345
+ # actually large positives (should be rejected as above
346
+ # despite being zero/+1/-1/INT_MIN/INT_MAX in the lower 32)
347
+ 0xffffffff00000000
348
+ 0xffffffff00000001
349
+ 0xffffffffffffffff
350
+ 0xffffffff80000000
351
+ 0xffffffff7fffffff
352
+ )
353
+
354
+ for sign in '' '-'; do
355
+ for mag in "${magnitudes[@]}"; do
356
+ check_failure "${sign}${mag}"
357
+ done
358
+ done
291359 }
292360
293361 # Your test must accept digits 3 and 4 to use this
....@@ -548,20 +616,82 @@
548616 test_rc
549617 }
550618
619
+target_exists()
620
+{
621
+ TARGET="${SYSCTL}/$1"
622
+ TEST_ID="$2"
623
+
624
+ if [ ! -f ${TARGET} ] ; then
625
+ echo "Target for test $TEST_ID: $TARGET not exist, skipping test ..."
626
+ return 0
627
+ fi
628
+ return 1
629
+}
630
+
631
+run_bitmaptest() {
632
+ # Total length of bitmaps string to use, a bit under
633
+ # the maximum input size of the test node
634
+ LENGTH=$((RANDOM % 65000))
635
+
636
+ # First bit to set
637
+ BIT=$((RANDOM % 1024))
638
+
639
+ # String containing our list of bits to set
640
+ TEST_STR=$BIT
641
+
642
+ # build up the string
643
+ while [ "${#TEST_STR}" -le "$LENGTH" ]; do
644
+ # Make sure next entry is discontiguous,
645
+ # skip ahead at least 2
646
+ BIT=$((BIT + $((2 + RANDOM % 10))))
647
+
648
+ # Add new bit to the list
649
+ TEST_STR="${TEST_STR},${BIT}"
650
+
651
+ # Randomly make it a range
652
+ if [ "$((RANDOM % 2))" -eq "1" ]; then
653
+ RANGE_END=$((BIT + $((1 + RANDOM % 10))))
654
+ TEST_STR="${TEST_STR}-${RANGE_END}"
655
+ BIT=$RANGE_END
656
+ fi
657
+ done
658
+
659
+ echo -n "Checking bitmap handler... "
660
+ TEST_FILE=$(mktemp)
661
+ echo -n "$TEST_STR" > $TEST_FILE
662
+
663
+ cat $TEST_FILE > $TARGET 2> /dev/null
664
+ if [ $? -ne 0 ]; then
665
+ echo "FAIL" >&2
666
+ rc=1
667
+ test_rc
668
+ fi
669
+
670
+ if ! verify_diff_proc_file "$TARGET" "$TEST_FILE"; then
671
+ echo "FAIL" >&2
672
+ rc=1
673
+ else
674
+ echo "ok"
675
+ rc=0
676
+ fi
677
+ test_rc
678
+}
679
+
551680 sysctl_test_0001()
552681 {
553
- TARGET="${SYSCTL}/int_0001"
682
+ TARGET="${SYSCTL}/$(get_test_target 0001)"
554683 reset_vals
555684 ORIG=$(cat "${TARGET}")
556685 TEST_STR=$(( $ORIG + 1 ))
557686
558687 run_numerictests
688
+ run_wideint_tests
559689 run_limit_digit
560690 }
561691
562692 sysctl_test_0002()
563693 {
564
- TARGET="${SYSCTL}/string_0001"
694
+ TARGET="${SYSCTL}/$(get_test_target 0002)"
565695 reset_vals
566696 ORIG=$(cat "${TARGET}")
567697 TEST_STR="Testing sysctl"
....@@ -574,35 +704,85 @@
574704
575705 sysctl_test_0003()
576706 {
577
- TARGET="${SYSCTL}/int_0002"
707
+ TARGET="${SYSCTL}/$(get_test_target 0003)"
578708 reset_vals
579709 ORIG=$(cat "${TARGET}")
580710 TEST_STR=$(( $ORIG + 1 ))
581711
582712 run_numerictests
713
+ run_wideint_tests
583714 run_limit_digit
584715 run_limit_digit_int
585716 }
586717
587718 sysctl_test_0004()
588719 {
589
- TARGET="${SYSCTL}/uint_0001"
720
+ TARGET="${SYSCTL}/$(get_test_target 0004)"
590721 reset_vals
591722 ORIG=$(cat "${TARGET}")
592723 TEST_STR=$(( $ORIG + 1 ))
593724
594725 run_numerictests
726
+ run_wideint_tests
595727 run_limit_digit
596728 run_limit_digit_uint
597729 }
598730
599731 sysctl_test_0005()
600732 {
601
- TARGET="${SYSCTL}/int_0003"
733
+ TARGET="${SYSCTL}/$(get_test_target 0005)"
602734 reset_vals
603735 ORIG=$(cat "${TARGET}")
604736
605737 run_limit_digit_int_array
738
+}
739
+
740
+sysctl_test_0006()
741
+{
742
+ TARGET="${SYSCTL}/bitmap_0001"
743
+ reset_vals
744
+ ORIG=""
745
+ run_bitmaptest
746
+}
747
+
748
+sysctl_test_0007()
749
+{
750
+ TARGET="${SYSCTL}/boot_int"
751
+ if [ ! -f $TARGET ]; then
752
+ echo "Skipping test for $TARGET as it is not present ..."
753
+ return $ksft_skip
754
+ fi
755
+
756
+ if [ -d $DIR ]; then
757
+ echo "Boot param test only possible sysctl_test is built-in, not module:"
758
+ cat $TEST_DIR/config >&2
759
+ return $ksft_skip
760
+ fi
761
+
762
+ echo -n "Testing if $TARGET is set to 1 ..."
763
+ ORIG=$(cat "${TARGET}")
764
+
765
+ if [ x$ORIG = "x1" ]; then
766
+ echo "ok"
767
+ return 0
768
+ fi
769
+ echo "FAIL"
770
+ echo "Checking if /proc/cmdline contains setting of the expected parameter ..."
771
+ if [ ! -f /proc/cmdline ]; then
772
+ echo "/proc/cmdline does not exist, test inconclusive"
773
+ return 0
774
+ fi
775
+
776
+ FOUND=$(grep -c "sysctl[./]debug[./]test_sysctl[./]boot_int=1" /proc/cmdline)
777
+ if [ $FOUND = "1" ]; then
778
+ echo "Kernel param found but $TARGET is not 1, TEST FAILED"
779
+ rc=1
780
+ test_rc
781
+ fi
782
+
783
+ echo "Skipping test, expected kernel parameter missing."
784
+ echo "To perform this test, make sure kernel is booted with parameter: sysctl.debug.test_sysctl.boot_int=1"
785
+ return $ksft_skip
606786 }
607787
608788 list_tests()
....@@ -618,9 +798,9 @@
618798 echo "0003 x $(get_test_count 0003) - tests proc_dointvec()"
619799 echo "0004 x $(get_test_count 0004) - tests proc_douintvec()"
620800 echo "0005 x $(get_test_count 0005) - tests proc_douintvec() array"
801
+ echo "0006 x $(get_test_count 0006) - tests proc_do_large_bitmap()"
802
+ echo "0007 x $(get_test_count 0007) - tests setting sysctl from kernel boot param"
621803 }
622
-
623
-test_reqs
624804
625805 usage()
626806 {
....@@ -669,25 +849,35 @@
669849 {
670850 test_num $1
671851 TEST_DATA=$(echo $ALL_TESTS | awk '{print $'$1'}')
672
- LAST_TWO=${TEST_DATA#*:*}
673
- echo ${LAST_TWO%:*}
852
+ echo ${TEST_DATA} | awk -F":" '{print $2}'
674853 }
675854
676855 function get_test_enabled()
677856 {
678857 test_num $1
679858 TEST_DATA=$(echo $ALL_TESTS | awk '{print $'$1'}')
680
- echo ${TEST_DATA#*:*:}
859
+ echo ${TEST_DATA} | awk -F":" '{print $3}'
860
+}
861
+
862
+function get_test_target()
863
+{
864
+ test_num $1
865
+ TEST_DATA=$(echo $ALL_TESTS | awk '{print $'$1'}')
866
+ echo ${TEST_DATA} | awk -F":" '{print $4}'
681867 }
682868
683869 function run_all_tests()
684870 {
685871 for i in $ALL_TESTS ; do
686
- TEST_ID=${i%:*:*}
872
+ TEST_ID=${i%:*:*:*}
687873 ENABLED=$(get_test_enabled $TEST_ID)
688874 TEST_COUNT=$(get_test_count $TEST_ID)
875
+ TEST_TARGET=$(get_test_target $TEST_ID)
876
+ if target_exists $TEST_TARGET $TEST_ID; then
877
+ continue
878
+ fi
689879 if [[ $ENABLED -eq "1" ]]; then
690
- test_case $TEST_ID $TEST_COUNT
880
+ test_case $TEST_ID $TEST_COUNT $TEST_TARGET
691881 fi
692882 done
693883 }
....@@ -720,12 +910,14 @@
720910
721911 function test_case()
722912 {
723
- NUM_TESTS=$DEFAULT_NUM_TESTS
724
- if [ $# -eq 2 ]; then
725
- NUM_TESTS=$2
726
- fi
913
+ NUM_TESTS=$2
727914
728915 i=0
916
+
917
+ if target_exists $3 $1; then
918
+ continue
919
+ fi
920
+
729921 while [ $i -lt $NUM_TESTS ]; do
730922 test_num $1
731923 watch_log $i ${TEST_NAME}_test_$1 noclear
....@@ -748,15 +940,15 @@
748940 elif [[ "$1" = "-t" ]]; then
749941 shift
750942 test_num $1
751
- test_case $1 $(get_test_count $1)
943
+ test_case $1 $(get_test_count $1) $(get_test_target $1)
752944 elif [[ "$1" = "-c" ]]; then
753945 shift
754946 test_num $1
755947 test_num $2
756
- test_case $1 $2
948
+ test_case $1 $2 $(get_test_target $1)
757949 elif [[ "$1" = "-s" ]]; then
758950 shift
759
- test_case $1 1
951
+ test_case $1 1 $(get_test_target $1)
760952 elif [[ "$1" = "-l" ]]; then
761953 list_tests
762954 elif [[ "$1" = "-h" || "$1" = "--help" ]]; then
....@@ -770,7 +962,6 @@
770962 test_reqs
771963 allow_user_defaults
772964 check_production_sysctl_writes_strict
773
-test_modprobe
774965 load_req_mod
775966
776967 trap "test_finish" EXIT