1*4882a593Smuzhiyun=========================================== 2*4882a593SmuzhiyunFault injection capabilities infrastructure 3*4882a593Smuzhiyun=========================================== 4*4882a593Smuzhiyun 5*4882a593SmuzhiyunSee also drivers/md/md-faulty.c and "every_nth" module option for scsi_debug. 6*4882a593Smuzhiyun 7*4882a593Smuzhiyun 8*4882a593SmuzhiyunAvailable fault injection capabilities 9*4882a593Smuzhiyun-------------------------------------- 10*4882a593Smuzhiyun 11*4882a593Smuzhiyun- failslab 12*4882a593Smuzhiyun 13*4882a593Smuzhiyun injects slab allocation failures. (kmalloc(), kmem_cache_alloc(), ...) 14*4882a593Smuzhiyun 15*4882a593Smuzhiyun- fail_page_alloc 16*4882a593Smuzhiyun 17*4882a593Smuzhiyun injects page allocation failures. (alloc_pages(), get_free_pages(), ...) 18*4882a593Smuzhiyun 19*4882a593Smuzhiyun- fail_usercopy 20*4882a593Smuzhiyun 21*4882a593Smuzhiyun injects failures in user memory access functions. (copy_from_user(), get_user(), ...) 22*4882a593Smuzhiyun 23*4882a593Smuzhiyun- fail_futex 24*4882a593Smuzhiyun 25*4882a593Smuzhiyun injects futex deadlock and uaddr fault errors. 26*4882a593Smuzhiyun 27*4882a593Smuzhiyun- fail_make_request 28*4882a593Smuzhiyun 29*4882a593Smuzhiyun injects disk IO errors on devices permitted by setting 30*4882a593Smuzhiyun /sys/block/<device>/make-it-fail or 31*4882a593Smuzhiyun /sys/block/<device>/<partition>/make-it-fail. (submit_bio_noacct()) 32*4882a593Smuzhiyun 33*4882a593Smuzhiyun- fail_mmc_request 34*4882a593Smuzhiyun 35*4882a593Smuzhiyun injects MMC data errors on devices permitted by setting 36*4882a593Smuzhiyun debugfs entries under /sys/kernel/debug/mmc0/fail_mmc_request 37*4882a593Smuzhiyun 38*4882a593Smuzhiyun- fail_function 39*4882a593Smuzhiyun 40*4882a593Smuzhiyun injects error return on specific functions, which are marked by 41*4882a593Smuzhiyun ALLOW_ERROR_INJECTION() macro, by setting debugfs entries 42*4882a593Smuzhiyun under /sys/kernel/debug/fail_function. No boot option supported. 43*4882a593Smuzhiyun 44*4882a593Smuzhiyun- NVMe fault injection 45*4882a593Smuzhiyun 46*4882a593Smuzhiyun inject NVMe status code and retry flag on devices permitted by setting 47*4882a593Smuzhiyun debugfs entries under /sys/kernel/debug/nvme*/fault_inject. The default 48*4882a593Smuzhiyun status code is NVME_SC_INVALID_OPCODE with no retry. The status code and 49*4882a593Smuzhiyun retry flag can be set via the debugfs. 50*4882a593Smuzhiyun 51*4882a593Smuzhiyun 52*4882a593SmuzhiyunConfigure fault-injection capabilities behavior 53*4882a593Smuzhiyun----------------------------------------------- 54*4882a593Smuzhiyun 55*4882a593Smuzhiyundebugfs entries 56*4882a593Smuzhiyun^^^^^^^^^^^^^^^ 57*4882a593Smuzhiyun 58*4882a593Smuzhiyunfault-inject-debugfs kernel module provides some debugfs entries for runtime 59*4882a593Smuzhiyunconfiguration of fault-injection capabilities. 60*4882a593Smuzhiyun 61*4882a593Smuzhiyun- /sys/kernel/debug/fail*/probability: 62*4882a593Smuzhiyun 63*4882a593Smuzhiyun likelihood of failure injection, in percent. 64*4882a593Smuzhiyun 65*4882a593Smuzhiyun Format: <percent> 66*4882a593Smuzhiyun 67*4882a593Smuzhiyun Note that one-failure-per-hundred is a very high error rate 68*4882a593Smuzhiyun for some testcases. Consider setting probability=100 and configure 69*4882a593Smuzhiyun /sys/kernel/debug/fail*/interval for such testcases. 70*4882a593Smuzhiyun 71*4882a593Smuzhiyun- /sys/kernel/debug/fail*/interval: 72*4882a593Smuzhiyun 73*4882a593Smuzhiyun specifies the interval between failures, for calls to 74*4882a593Smuzhiyun should_fail() that pass all the other tests. 75*4882a593Smuzhiyun 76*4882a593Smuzhiyun Note that if you enable this, by setting interval>1, you will 77*4882a593Smuzhiyun probably want to set probability=100. 78*4882a593Smuzhiyun 79*4882a593Smuzhiyun- /sys/kernel/debug/fail*/times: 80*4882a593Smuzhiyun 81*4882a593Smuzhiyun specifies how many times failures may happen at most. 82*4882a593Smuzhiyun A value of -1 means "no limit". 83*4882a593Smuzhiyun 84*4882a593Smuzhiyun- /sys/kernel/debug/fail*/space: 85*4882a593Smuzhiyun 86*4882a593Smuzhiyun specifies an initial resource "budget", decremented by "size" 87*4882a593Smuzhiyun on each call to should_fail(,size). Failure injection is 88*4882a593Smuzhiyun suppressed until "space" reaches zero. 89*4882a593Smuzhiyun 90*4882a593Smuzhiyun- /sys/kernel/debug/fail*/verbose 91*4882a593Smuzhiyun 92*4882a593Smuzhiyun Format: { 0 | 1 | 2 } 93*4882a593Smuzhiyun 94*4882a593Smuzhiyun specifies the verbosity of the messages when failure is 95*4882a593Smuzhiyun injected. '0' means no messages; '1' will print only a single 96*4882a593Smuzhiyun log line per failure; '2' will print a call trace too -- useful 97*4882a593Smuzhiyun to debug the problems revealed by fault injection. 98*4882a593Smuzhiyun 99*4882a593Smuzhiyun- /sys/kernel/debug/fail*/task-filter: 100*4882a593Smuzhiyun 101*4882a593Smuzhiyun Format: { 'Y' | 'N' } 102*4882a593Smuzhiyun 103*4882a593Smuzhiyun A value of 'N' disables filtering by process (default). 104*4882a593Smuzhiyun Any positive value limits failures to only processes indicated by 105*4882a593Smuzhiyun /proc/<pid>/make-it-fail==1. 106*4882a593Smuzhiyun 107*4882a593Smuzhiyun- /sys/kernel/debug/fail*/require-start, 108*4882a593Smuzhiyun /sys/kernel/debug/fail*/require-end, 109*4882a593Smuzhiyun /sys/kernel/debug/fail*/reject-start, 110*4882a593Smuzhiyun /sys/kernel/debug/fail*/reject-end: 111*4882a593Smuzhiyun 112*4882a593Smuzhiyun specifies the range of virtual addresses tested during 113*4882a593Smuzhiyun stacktrace walking. Failure is injected only if some caller 114*4882a593Smuzhiyun in the walked stacktrace lies within the required range, and 115*4882a593Smuzhiyun none lies within the rejected range. 116*4882a593Smuzhiyun Default required range is [0,ULONG_MAX) (whole of virtual address space). 117*4882a593Smuzhiyun Default rejected range is [0,0). 118*4882a593Smuzhiyun 119*4882a593Smuzhiyun- /sys/kernel/debug/fail*/stacktrace-depth: 120*4882a593Smuzhiyun 121*4882a593Smuzhiyun specifies the maximum stacktrace depth walked during search 122*4882a593Smuzhiyun for a caller within [require-start,require-end) OR 123*4882a593Smuzhiyun [reject-start,reject-end). 124*4882a593Smuzhiyun 125*4882a593Smuzhiyun- /sys/kernel/debug/fail_page_alloc/ignore-gfp-highmem: 126*4882a593Smuzhiyun 127*4882a593Smuzhiyun Format: { 'Y' | 'N' } 128*4882a593Smuzhiyun 129*4882a593Smuzhiyun default is 'N', setting it to 'Y' won't inject failures into 130*4882a593Smuzhiyun highmem/user allocations. 131*4882a593Smuzhiyun 132*4882a593Smuzhiyun- /sys/kernel/debug/failslab/ignore-gfp-wait: 133*4882a593Smuzhiyun- /sys/kernel/debug/fail_page_alloc/ignore-gfp-wait: 134*4882a593Smuzhiyun 135*4882a593Smuzhiyun Format: { 'Y' | 'N' } 136*4882a593Smuzhiyun 137*4882a593Smuzhiyun default is 'N', setting it to 'Y' will inject failures 138*4882a593Smuzhiyun only into non-sleep allocations (GFP_ATOMIC allocations). 139*4882a593Smuzhiyun 140*4882a593Smuzhiyun- /sys/kernel/debug/fail_page_alloc/min-order: 141*4882a593Smuzhiyun 142*4882a593Smuzhiyun specifies the minimum page allocation order to be injected 143*4882a593Smuzhiyun failures. 144*4882a593Smuzhiyun 145*4882a593Smuzhiyun- /sys/kernel/debug/fail_futex/ignore-private: 146*4882a593Smuzhiyun 147*4882a593Smuzhiyun Format: { 'Y' | 'N' } 148*4882a593Smuzhiyun 149*4882a593Smuzhiyun default is 'N', setting it to 'Y' will disable failure injections 150*4882a593Smuzhiyun when dealing with private (address space) futexes. 151*4882a593Smuzhiyun 152*4882a593Smuzhiyun- /sys/kernel/debug/fail_function/inject: 153*4882a593Smuzhiyun 154*4882a593Smuzhiyun Format: { 'function-name' | '!function-name' | '' } 155*4882a593Smuzhiyun 156*4882a593Smuzhiyun specifies the target function of error injection by name. 157*4882a593Smuzhiyun If the function name leads '!' prefix, given function is 158*4882a593Smuzhiyun removed from injection list. If nothing specified ('') 159*4882a593Smuzhiyun injection list is cleared. 160*4882a593Smuzhiyun 161*4882a593Smuzhiyun- /sys/kernel/debug/fail_function/injectable: 162*4882a593Smuzhiyun 163*4882a593Smuzhiyun (read only) shows error injectable functions and what type of 164*4882a593Smuzhiyun error values can be specified. The error type will be one of 165*4882a593Smuzhiyun below; 166*4882a593Smuzhiyun - NULL: retval must be 0. 167*4882a593Smuzhiyun - ERRNO: retval must be -1 to -MAX_ERRNO (-4096). 168*4882a593Smuzhiyun - ERR_NULL: retval must be 0 or -1 to -MAX_ERRNO (-4096). 169*4882a593Smuzhiyun 170*4882a593Smuzhiyun- /sys/kernel/debug/fail_function/<functiuon-name>/retval: 171*4882a593Smuzhiyun 172*4882a593Smuzhiyun specifies the "error" return value to inject to the given 173*4882a593Smuzhiyun function for given function. This will be created when 174*4882a593Smuzhiyun user specifies new injection entry. 175*4882a593Smuzhiyun 176*4882a593SmuzhiyunBoot option 177*4882a593Smuzhiyun^^^^^^^^^^^ 178*4882a593Smuzhiyun 179*4882a593SmuzhiyunIn order to inject faults while debugfs is not available (early boot time), 180*4882a593Smuzhiyunuse the boot option:: 181*4882a593Smuzhiyun 182*4882a593Smuzhiyun failslab= 183*4882a593Smuzhiyun fail_page_alloc= 184*4882a593Smuzhiyun fail_usercopy= 185*4882a593Smuzhiyun fail_make_request= 186*4882a593Smuzhiyun fail_futex= 187*4882a593Smuzhiyun mmc_core.fail_request=<interval>,<probability>,<space>,<times> 188*4882a593Smuzhiyun 189*4882a593Smuzhiyunproc entries 190*4882a593Smuzhiyun^^^^^^^^^^^^ 191*4882a593Smuzhiyun 192*4882a593Smuzhiyun- /proc/<pid>/fail-nth, 193*4882a593Smuzhiyun /proc/self/task/<tid>/fail-nth: 194*4882a593Smuzhiyun 195*4882a593Smuzhiyun Write to this file of integer N makes N-th call in the task fail. 196*4882a593Smuzhiyun Read from this file returns a integer value. A value of '0' indicates 197*4882a593Smuzhiyun that the fault setup with a previous write to this file was injected. 198*4882a593Smuzhiyun A positive integer N indicates that the fault wasn't yet injected. 199*4882a593Smuzhiyun Note that this file enables all types of faults (slab, futex, etc). 200*4882a593Smuzhiyun This setting takes precedence over all other generic debugfs settings 201*4882a593Smuzhiyun like probability, interval, times, etc. But per-capability settings 202*4882a593Smuzhiyun (e.g. fail_futex/ignore-private) take precedence over it. 203*4882a593Smuzhiyun 204*4882a593Smuzhiyun This feature is intended for systematic testing of faults in a single 205*4882a593Smuzhiyun system call. See an example below. 206*4882a593Smuzhiyun 207*4882a593SmuzhiyunHow to add new fault injection capability 208*4882a593Smuzhiyun----------------------------------------- 209*4882a593Smuzhiyun 210*4882a593Smuzhiyun- #include <linux/fault-inject.h> 211*4882a593Smuzhiyun 212*4882a593Smuzhiyun- define the fault attributes 213*4882a593Smuzhiyun 214*4882a593Smuzhiyun DECLARE_FAULT_ATTR(name); 215*4882a593Smuzhiyun 216*4882a593Smuzhiyun Please see the definition of struct fault_attr in fault-inject.h 217*4882a593Smuzhiyun for details. 218*4882a593Smuzhiyun 219*4882a593Smuzhiyun- provide a way to configure fault attributes 220*4882a593Smuzhiyun 221*4882a593Smuzhiyun- boot option 222*4882a593Smuzhiyun 223*4882a593Smuzhiyun If you need to enable the fault injection capability from boot time, you can 224*4882a593Smuzhiyun provide boot option to configure it. There is a helper function for it: 225*4882a593Smuzhiyun 226*4882a593Smuzhiyun setup_fault_attr(attr, str); 227*4882a593Smuzhiyun 228*4882a593Smuzhiyun- debugfs entries 229*4882a593Smuzhiyun 230*4882a593Smuzhiyun failslab, fail_page_alloc, fail_usercopy, and fail_make_request use this way. 231*4882a593Smuzhiyun Helper functions: 232*4882a593Smuzhiyun 233*4882a593Smuzhiyun fault_create_debugfs_attr(name, parent, attr); 234*4882a593Smuzhiyun 235*4882a593Smuzhiyun- module parameters 236*4882a593Smuzhiyun 237*4882a593Smuzhiyun If the scope of the fault injection capability is limited to a 238*4882a593Smuzhiyun single kernel module, it is better to provide module parameters to 239*4882a593Smuzhiyun configure the fault attributes. 240*4882a593Smuzhiyun 241*4882a593Smuzhiyun- add a hook to insert failures 242*4882a593Smuzhiyun 243*4882a593Smuzhiyun Upon should_fail() returning true, client code should inject a failure: 244*4882a593Smuzhiyun 245*4882a593Smuzhiyun should_fail(attr, size); 246*4882a593Smuzhiyun 247*4882a593SmuzhiyunApplication Examples 248*4882a593Smuzhiyun-------------------- 249*4882a593Smuzhiyun 250*4882a593Smuzhiyun- Inject slab allocation failures into module init/exit code:: 251*4882a593Smuzhiyun 252*4882a593Smuzhiyun #!/bin/bash 253*4882a593Smuzhiyun 254*4882a593Smuzhiyun FAILTYPE=failslab 255*4882a593Smuzhiyun echo Y > /sys/kernel/debug/$FAILTYPE/task-filter 256*4882a593Smuzhiyun echo 10 > /sys/kernel/debug/$FAILTYPE/probability 257*4882a593Smuzhiyun echo 100 > /sys/kernel/debug/$FAILTYPE/interval 258*4882a593Smuzhiyun echo -1 > /sys/kernel/debug/$FAILTYPE/times 259*4882a593Smuzhiyun echo 0 > /sys/kernel/debug/$FAILTYPE/space 260*4882a593Smuzhiyun echo 2 > /sys/kernel/debug/$FAILTYPE/verbose 261*4882a593Smuzhiyun echo 1 > /sys/kernel/debug/$FAILTYPE/ignore-gfp-wait 262*4882a593Smuzhiyun 263*4882a593Smuzhiyun faulty_system() 264*4882a593Smuzhiyun { 265*4882a593Smuzhiyun bash -c "echo 1 > /proc/self/make-it-fail && exec $*" 266*4882a593Smuzhiyun } 267*4882a593Smuzhiyun 268*4882a593Smuzhiyun if [ $# -eq 0 ] 269*4882a593Smuzhiyun then 270*4882a593Smuzhiyun echo "Usage: $0 modulename [ modulename ... ]" 271*4882a593Smuzhiyun exit 1 272*4882a593Smuzhiyun fi 273*4882a593Smuzhiyun 274*4882a593Smuzhiyun for m in $* 275*4882a593Smuzhiyun do 276*4882a593Smuzhiyun echo inserting $m... 277*4882a593Smuzhiyun faulty_system modprobe $m 278*4882a593Smuzhiyun 279*4882a593Smuzhiyun echo removing $m... 280*4882a593Smuzhiyun faulty_system modprobe -r $m 281*4882a593Smuzhiyun done 282*4882a593Smuzhiyun 283*4882a593Smuzhiyun------------------------------------------------------------------------------ 284*4882a593Smuzhiyun 285*4882a593Smuzhiyun- Inject page allocation failures only for a specific module:: 286*4882a593Smuzhiyun 287*4882a593Smuzhiyun #!/bin/bash 288*4882a593Smuzhiyun 289*4882a593Smuzhiyun FAILTYPE=fail_page_alloc 290*4882a593Smuzhiyun module=$1 291*4882a593Smuzhiyun 292*4882a593Smuzhiyun if [ -z $module ] 293*4882a593Smuzhiyun then 294*4882a593Smuzhiyun echo "Usage: $0 <modulename>" 295*4882a593Smuzhiyun exit 1 296*4882a593Smuzhiyun fi 297*4882a593Smuzhiyun 298*4882a593Smuzhiyun modprobe $module 299*4882a593Smuzhiyun 300*4882a593Smuzhiyun if [ ! -d /sys/module/$module/sections ] 301*4882a593Smuzhiyun then 302*4882a593Smuzhiyun echo Module $module is not loaded 303*4882a593Smuzhiyun exit 1 304*4882a593Smuzhiyun fi 305*4882a593Smuzhiyun 306*4882a593Smuzhiyun cat /sys/module/$module/sections/.text > /sys/kernel/debug/$FAILTYPE/require-start 307*4882a593Smuzhiyun cat /sys/module/$module/sections/.data > /sys/kernel/debug/$FAILTYPE/require-end 308*4882a593Smuzhiyun 309*4882a593Smuzhiyun echo N > /sys/kernel/debug/$FAILTYPE/task-filter 310*4882a593Smuzhiyun echo 10 > /sys/kernel/debug/$FAILTYPE/probability 311*4882a593Smuzhiyun echo 100 > /sys/kernel/debug/$FAILTYPE/interval 312*4882a593Smuzhiyun echo -1 > /sys/kernel/debug/$FAILTYPE/times 313*4882a593Smuzhiyun echo 0 > /sys/kernel/debug/$FAILTYPE/space 314*4882a593Smuzhiyun echo 2 > /sys/kernel/debug/$FAILTYPE/verbose 315*4882a593Smuzhiyun echo 1 > /sys/kernel/debug/$FAILTYPE/ignore-gfp-wait 316*4882a593Smuzhiyun echo 1 > /sys/kernel/debug/$FAILTYPE/ignore-gfp-highmem 317*4882a593Smuzhiyun echo 10 > /sys/kernel/debug/$FAILTYPE/stacktrace-depth 318*4882a593Smuzhiyun 319*4882a593Smuzhiyun trap "echo 0 > /sys/kernel/debug/$FAILTYPE/probability" SIGINT SIGTERM EXIT 320*4882a593Smuzhiyun 321*4882a593Smuzhiyun echo "Injecting errors into the module $module... (interrupt to stop)" 322*4882a593Smuzhiyun sleep 1000000 323*4882a593Smuzhiyun 324*4882a593Smuzhiyun------------------------------------------------------------------------------ 325*4882a593Smuzhiyun 326*4882a593Smuzhiyun- Inject open_ctree error while btrfs mount:: 327*4882a593Smuzhiyun 328*4882a593Smuzhiyun #!/bin/bash 329*4882a593Smuzhiyun 330*4882a593Smuzhiyun rm -f testfile.img 331*4882a593Smuzhiyun dd if=/dev/zero of=testfile.img bs=1M seek=1000 count=1 332*4882a593Smuzhiyun DEVICE=$(losetup --show -f testfile.img) 333*4882a593Smuzhiyun mkfs.btrfs -f $DEVICE 334*4882a593Smuzhiyun mkdir -p tmpmnt 335*4882a593Smuzhiyun 336*4882a593Smuzhiyun FAILTYPE=fail_function 337*4882a593Smuzhiyun FAILFUNC=open_ctree 338*4882a593Smuzhiyun echo $FAILFUNC > /sys/kernel/debug/$FAILTYPE/inject 339*4882a593Smuzhiyun echo -12 > /sys/kernel/debug/$FAILTYPE/$FAILFUNC/retval 340*4882a593Smuzhiyun echo N > /sys/kernel/debug/$FAILTYPE/task-filter 341*4882a593Smuzhiyun echo 100 > /sys/kernel/debug/$FAILTYPE/probability 342*4882a593Smuzhiyun echo 0 > /sys/kernel/debug/$FAILTYPE/interval 343*4882a593Smuzhiyun echo -1 > /sys/kernel/debug/$FAILTYPE/times 344*4882a593Smuzhiyun echo 0 > /sys/kernel/debug/$FAILTYPE/space 345*4882a593Smuzhiyun echo 1 > /sys/kernel/debug/$FAILTYPE/verbose 346*4882a593Smuzhiyun 347*4882a593Smuzhiyun mount -t btrfs $DEVICE tmpmnt 348*4882a593Smuzhiyun if [ $? -ne 0 ] 349*4882a593Smuzhiyun then 350*4882a593Smuzhiyun echo "SUCCESS!" 351*4882a593Smuzhiyun else 352*4882a593Smuzhiyun echo "FAILED!" 353*4882a593Smuzhiyun umount tmpmnt 354*4882a593Smuzhiyun fi 355*4882a593Smuzhiyun 356*4882a593Smuzhiyun echo > /sys/kernel/debug/$FAILTYPE/inject 357*4882a593Smuzhiyun 358*4882a593Smuzhiyun rmdir tmpmnt 359*4882a593Smuzhiyun losetup -d $DEVICE 360*4882a593Smuzhiyun rm testfile.img 361*4882a593Smuzhiyun 362*4882a593Smuzhiyun 363*4882a593SmuzhiyunTool to run command with failslab or fail_page_alloc 364*4882a593Smuzhiyun---------------------------------------------------- 365*4882a593SmuzhiyunIn order to make it easier to accomplish the tasks mentioned above, we can use 366*4882a593Smuzhiyuntools/testing/fault-injection/failcmd.sh. Please run a command 367*4882a593Smuzhiyun"./tools/testing/fault-injection/failcmd.sh --help" for more information and 368*4882a593Smuzhiyunsee the following examples. 369*4882a593Smuzhiyun 370*4882a593SmuzhiyunExamples: 371*4882a593Smuzhiyun 372*4882a593SmuzhiyunRun a command "make -C tools/testing/selftests/ run_tests" with injecting slab 373*4882a593Smuzhiyunallocation failure:: 374*4882a593Smuzhiyun 375*4882a593Smuzhiyun # ./tools/testing/fault-injection/failcmd.sh \ 376*4882a593Smuzhiyun -- make -C tools/testing/selftests/ run_tests 377*4882a593Smuzhiyun 378*4882a593SmuzhiyunSame as above except to specify 100 times failures at most instead of one time 379*4882a593Smuzhiyunat most by default:: 380*4882a593Smuzhiyun 381*4882a593Smuzhiyun # ./tools/testing/fault-injection/failcmd.sh --times=100 \ 382*4882a593Smuzhiyun -- make -C tools/testing/selftests/ run_tests 383*4882a593Smuzhiyun 384*4882a593SmuzhiyunSame as above except to inject page allocation failure instead of slab 385*4882a593Smuzhiyunallocation failure:: 386*4882a593Smuzhiyun 387*4882a593Smuzhiyun # env FAILCMD_TYPE=fail_page_alloc \ 388*4882a593Smuzhiyun ./tools/testing/fault-injection/failcmd.sh --times=100 \ 389*4882a593Smuzhiyun -- make -C tools/testing/selftests/ run_tests 390*4882a593Smuzhiyun 391*4882a593SmuzhiyunSystematic faults using fail-nth 392*4882a593Smuzhiyun--------------------------------- 393*4882a593Smuzhiyun 394*4882a593SmuzhiyunThe following code systematically faults 0-th, 1-st, 2-nd and so on 395*4882a593Smuzhiyuncapabilities in the socketpair() system call:: 396*4882a593Smuzhiyun 397*4882a593Smuzhiyun #include <sys/types.h> 398*4882a593Smuzhiyun #include <sys/stat.h> 399*4882a593Smuzhiyun #include <sys/socket.h> 400*4882a593Smuzhiyun #include <sys/syscall.h> 401*4882a593Smuzhiyun #include <fcntl.h> 402*4882a593Smuzhiyun #include <unistd.h> 403*4882a593Smuzhiyun #include <string.h> 404*4882a593Smuzhiyun #include <stdlib.h> 405*4882a593Smuzhiyun #include <stdio.h> 406*4882a593Smuzhiyun #include <errno.h> 407*4882a593Smuzhiyun 408*4882a593Smuzhiyun int main() 409*4882a593Smuzhiyun { 410*4882a593Smuzhiyun int i, err, res, fail_nth, fds[2]; 411*4882a593Smuzhiyun char buf[128]; 412*4882a593Smuzhiyun 413*4882a593Smuzhiyun system("echo N > /sys/kernel/debug/failslab/ignore-gfp-wait"); 414*4882a593Smuzhiyun sprintf(buf, "/proc/self/task/%ld/fail-nth", syscall(SYS_gettid)); 415*4882a593Smuzhiyun fail_nth = open(buf, O_RDWR); 416*4882a593Smuzhiyun for (i = 1;; i++) { 417*4882a593Smuzhiyun sprintf(buf, "%d", i); 418*4882a593Smuzhiyun write(fail_nth, buf, strlen(buf)); 419*4882a593Smuzhiyun res = socketpair(AF_LOCAL, SOCK_STREAM, 0, fds); 420*4882a593Smuzhiyun err = errno; 421*4882a593Smuzhiyun pread(fail_nth, buf, sizeof(buf), 0); 422*4882a593Smuzhiyun if (res == 0) { 423*4882a593Smuzhiyun close(fds[0]); 424*4882a593Smuzhiyun close(fds[1]); 425*4882a593Smuzhiyun } 426*4882a593Smuzhiyun printf("%d-th fault %c: res=%d/%d\n", i, atoi(buf) ? 'N' : 'Y', 427*4882a593Smuzhiyun res, err); 428*4882a593Smuzhiyun if (atoi(buf)) 429*4882a593Smuzhiyun break; 430*4882a593Smuzhiyun } 431*4882a593Smuzhiyun return 0; 432*4882a593Smuzhiyun } 433*4882a593Smuzhiyun 434*4882a593SmuzhiyunAn example output:: 435*4882a593Smuzhiyun 436*4882a593Smuzhiyun 1-th fault Y: res=-1/23 437*4882a593Smuzhiyun 2-th fault Y: res=-1/23 438*4882a593Smuzhiyun 3-th fault Y: res=-1/12 439*4882a593Smuzhiyun 4-th fault Y: res=-1/12 440*4882a593Smuzhiyun 5-th fault Y: res=-1/23 441*4882a593Smuzhiyun 6-th fault Y: res=-1/23 442*4882a593Smuzhiyun 7-th fault Y: res=-1/23 443*4882a593Smuzhiyun 8-th fault Y: res=-1/12 444*4882a593Smuzhiyun 9-th fault Y: res=-1/12 445*4882a593Smuzhiyun 10-th fault Y: res=-1/12 446*4882a593Smuzhiyun 11-th fault Y: res=-1/12 447*4882a593Smuzhiyun 12-th fault Y: res=-1/12 448*4882a593Smuzhiyun 13-th fault Y: res=-1/12 449*4882a593Smuzhiyun 14-th fault Y: res=-1/12 450*4882a593Smuzhiyun 15-th fault Y: res=-1/12 451*4882a593Smuzhiyun 16-th fault N: res=0/12 452