162306a36Sopenharmony_ci=========================================== 262306a36Sopenharmony_ciFault injection capabilities infrastructure 362306a36Sopenharmony_ci=========================================== 462306a36Sopenharmony_ci 562306a36Sopenharmony_ciSee also drivers/md/md-faulty.c and "every_nth" module option for scsi_debug. 662306a36Sopenharmony_ci 762306a36Sopenharmony_ci 862306a36Sopenharmony_ciAvailable fault injection capabilities 962306a36Sopenharmony_ci-------------------------------------- 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ci- failslab 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ci injects slab allocation failures. (kmalloc(), kmem_cache_alloc(), ...) 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ci- fail_page_alloc 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_ci injects page allocation failures. (alloc_pages(), get_free_pages(), ...) 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ci- fail_usercopy 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci injects failures in user memory access functions. (copy_from_user(), get_user(), ...) 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_ci- fail_futex 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_ci injects futex deadlock and uaddr fault errors. 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_ci- fail_sunrpc 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_ci injects kernel RPC client and server failures. 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_ci- fail_make_request 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_ci injects disk IO errors on devices permitted by setting 3462306a36Sopenharmony_ci /sys/block/<device>/make-it-fail or 3562306a36Sopenharmony_ci /sys/block/<device>/<partition>/make-it-fail. (submit_bio_noacct()) 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_ci- fail_mmc_request 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_ci injects MMC data errors on devices permitted by setting 4062306a36Sopenharmony_ci debugfs entries under /sys/kernel/debug/mmc0/fail_mmc_request 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_ci- fail_function 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_ci injects error return on specific functions, which are marked by 4562306a36Sopenharmony_ci ALLOW_ERROR_INJECTION() macro, by setting debugfs entries 4662306a36Sopenharmony_ci under /sys/kernel/debug/fail_function. No boot option supported. 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_ci- NVMe fault injection 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_ci inject NVMe status code and retry flag on devices permitted by setting 5162306a36Sopenharmony_ci debugfs entries under /sys/kernel/debug/nvme*/fault_inject. The default 5262306a36Sopenharmony_ci status code is NVME_SC_INVALID_OPCODE with no retry. The status code and 5362306a36Sopenharmony_ci retry flag can be set via the debugfs. 5462306a36Sopenharmony_ci 5562306a36Sopenharmony_ci- Null test block driver fault injection 5662306a36Sopenharmony_ci 5762306a36Sopenharmony_ci inject IO timeouts by setting config items under 5862306a36Sopenharmony_ci /sys/kernel/config/nullb/<disk>/timeout_inject, 5962306a36Sopenharmony_ci inject requeue requests by setting config items under 6062306a36Sopenharmony_ci /sys/kernel/config/nullb/<disk>/requeue_inject, and 6162306a36Sopenharmony_ci inject init_hctx() errors by setting config items under 6262306a36Sopenharmony_ci /sys/kernel/config/nullb/<disk>/init_hctx_fault_inject. 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_ciConfigure fault-injection capabilities behavior 6562306a36Sopenharmony_ci----------------------------------------------- 6662306a36Sopenharmony_ci 6762306a36Sopenharmony_cidebugfs entries 6862306a36Sopenharmony_ci^^^^^^^^^^^^^^^ 6962306a36Sopenharmony_ci 7062306a36Sopenharmony_cifault-inject-debugfs kernel module provides some debugfs entries for runtime 7162306a36Sopenharmony_ciconfiguration of fault-injection capabilities. 7262306a36Sopenharmony_ci 7362306a36Sopenharmony_ci- /sys/kernel/debug/fail*/probability: 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_ci likelihood of failure injection, in percent. 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_ci Format: <percent> 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_ci Note that one-failure-per-hundred is a very high error rate 8062306a36Sopenharmony_ci for some testcases. Consider setting probability=100 and configure 8162306a36Sopenharmony_ci /sys/kernel/debug/fail*/interval for such testcases. 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_ci- /sys/kernel/debug/fail*/interval: 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_ci specifies the interval between failures, for calls to 8662306a36Sopenharmony_ci should_fail() that pass all the other tests. 8762306a36Sopenharmony_ci 8862306a36Sopenharmony_ci Note that if you enable this, by setting interval>1, you will 8962306a36Sopenharmony_ci probably want to set probability=100. 9062306a36Sopenharmony_ci 9162306a36Sopenharmony_ci- /sys/kernel/debug/fail*/times: 9262306a36Sopenharmony_ci 9362306a36Sopenharmony_ci specifies how many times failures may happen at most. A value of -1 9462306a36Sopenharmony_ci means "no limit". 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_ci- /sys/kernel/debug/fail*/space: 9762306a36Sopenharmony_ci 9862306a36Sopenharmony_ci specifies an initial resource "budget", decremented by "size" 9962306a36Sopenharmony_ci on each call to should_fail(,size). Failure injection is 10062306a36Sopenharmony_ci suppressed until "space" reaches zero. 10162306a36Sopenharmony_ci 10262306a36Sopenharmony_ci- /sys/kernel/debug/fail*/verbose 10362306a36Sopenharmony_ci 10462306a36Sopenharmony_ci Format: { 0 | 1 | 2 } 10562306a36Sopenharmony_ci 10662306a36Sopenharmony_ci specifies the verbosity of the messages when failure is 10762306a36Sopenharmony_ci injected. '0' means no messages; '1' will print only a single 10862306a36Sopenharmony_ci log line per failure; '2' will print a call trace too -- useful 10962306a36Sopenharmony_ci to debug the problems revealed by fault injection. 11062306a36Sopenharmony_ci 11162306a36Sopenharmony_ci- /sys/kernel/debug/fail*/task-filter: 11262306a36Sopenharmony_ci 11362306a36Sopenharmony_ci Format: { 'Y' | 'N' } 11462306a36Sopenharmony_ci 11562306a36Sopenharmony_ci A value of 'N' disables filtering by process (default). 11662306a36Sopenharmony_ci Any positive value limits failures to only processes indicated by 11762306a36Sopenharmony_ci /proc/<pid>/make-it-fail==1. 11862306a36Sopenharmony_ci 11962306a36Sopenharmony_ci- /sys/kernel/debug/fail*/require-start, 12062306a36Sopenharmony_ci /sys/kernel/debug/fail*/require-end, 12162306a36Sopenharmony_ci /sys/kernel/debug/fail*/reject-start, 12262306a36Sopenharmony_ci /sys/kernel/debug/fail*/reject-end: 12362306a36Sopenharmony_ci 12462306a36Sopenharmony_ci specifies the range of virtual addresses tested during 12562306a36Sopenharmony_ci stacktrace walking. Failure is injected only if some caller 12662306a36Sopenharmony_ci in the walked stacktrace lies within the required range, and 12762306a36Sopenharmony_ci none lies within the rejected range. 12862306a36Sopenharmony_ci Default required range is [0,ULONG_MAX) (whole of virtual address space). 12962306a36Sopenharmony_ci Default rejected range is [0,0). 13062306a36Sopenharmony_ci 13162306a36Sopenharmony_ci- /sys/kernel/debug/fail*/stacktrace-depth: 13262306a36Sopenharmony_ci 13362306a36Sopenharmony_ci specifies the maximum stacktrace depth walked during search 13462306a36Sopenharmony_ci for a caller within [require-start,require-end) OR 13562306a36Sopenharmony_ci [reject-start,reject-end). 13662306a36Sopenharmony_ci 13762306a36Sopenharmony_ci- /sys/kernel/debug/fail_page_alloc/ignore-gfp-highmem: 13862306a36Sopenharmony_ci 13962306a36Sopenharmony_ci Format: { 'Y' | 'N' } 14062306a36Sopenharmony_ci 14162306a36Sopenharmony_ci default is 'Y', setting it to 'N' will also inject failures into 14262306a36Sopenharmony_ci highmem/user allocations (__GFP_HIGHMEM allocations). 14362306a36Sopenharmony_ci 14462306a36Sopenharmony_ci- /sys/kernel/debug/failslab/ignore-gfp-wait: 14562306a36Sopenharmony_ci- /sys/kernel/debug/fail_page_alloc/ignore-gfp-wait: 14662306a36Sopenharmony_ci 14762306a36Sopenharmony_ci Format: { 'Y' | 'N' } 14862306a36Sopenharmony_ci 14962306a36Sopenharmony_ci default is 'Y', setting it to 'N' will also inject failures 15062306a36Sopenharmony_ci into allocations that can sleep (__GFP_DIRECT_RECLAIM allocations). 15162306a36Sopenharmony_ci 15262306a36Sopenharmony_ci- /sys/kernel/debug/fail_page_alloc/min-order: 15362306a36Sopenharmony_ci 15462306a36Sopenharmony_ci specifies the minimum page allocation order to be injected 15562306a36Sopenharmony_ci failures. 15662306a36Sopenharmony_ci 15762306a36Sopenharmony_ci- /sys/kernel/debug/fail_futex/ignore-private: 15862306a36Sopenharmony_ci 15962306a36Sopenharmony_ci Format: { 'Y' | 'N' } 16062306a36Sopenharmony_ci 16162306a36Sopenharmony_ci default is 'N', setting it to 'Y' will disable failure injections 16262306a36Sopenharmony_ci when dealing with private (address space) futexes. 16362306a36Sopenharmony_ci 16462306a36Sopenharmony_ci- /sys/kernel/debug/fail_sunrpc/ignore-client-disconnect: 16562306a36Sopenharmony_ci 16662306a36Sopenharmony_ci Format: { 'Y' | 'N' } 16762306a36Sopenharmony_ci 16862306a36Sopenharmony_ci default is 'N', setting it to 'Y' will disable disconnect 16962306a36Sopenharmony_ci injection on the RPC client. 17062306a36Sopenharmony_ci 17162306a36Sopenharmony_ci- /sys/kernel/debug/fail_sunrpc/ignore-server-disconnect: 17262306a36Sopenharmony_ci 17362306a36Sopenharmony_ci Format: { 'Y' | 'N' } 17462306a36Sopenharmony_ci 17562306a36Sopenharmony_ci default is 'N', setting it to 'Y' will disable disconnect 17662306a36Sopenharmony_ci injection on the RPC server. 17762306a36Sopenharmony_ci 17862306a36Sopenharmony_ci- /sys/kernel/debug/fail_sunrpc/ignore-cache-wait: 17962306a36Sopenharmony_ci 18062306a36Sopenharmony_ci Format: { 'Y' | 'N' } 18162306a36Sopenharmony_ci 18262306a36Sopenharmony_ci default is 'N', setting it to 'Y' will disable cache wait 18362306a36Sopenharmony_ci injection on the RPC server. 18462306a36Sopenharmony_ci 18562306a36Sopenharmony_ci- /sys/kernel/debug/fail_function/inject: 18662306a36Sopenharmony_ci 18762306a36Sopenharmony_ci Format: { 'function-name' | '!function-name' | '' } 18862306a36Sopenharmony_ci 18962306a36Sopenharmony_ci specifies the target function of error injection by name. 19062306a36Sopenharmony_ci If the function name leads '!' prefix, given function is 19162306a36Sopenharmony_ci removed from injection list. If nothing specified ('') 19262306a36Sopenharmony_ci injection list is cleared. 19362306a36Sopenharmony_ci 19462306a36Sopenharmony_ci- /sys/kernel/debug/fail_function/injectable: 19562306a36Sopenharmony_ci 19662306a36Sopenharmony_ci (read only) shows error injectable functions and what type of 19762306a36Sopenharmony_ci error values can be specified. The error type will be one of 19862306a36Sopenharmony_ci below; 19962306a36Sopenharmony_ci - NULL: retval must be 0. 20062306a36Sopenharmony_ci - ERRNO: retval must be -1 to -MAX_ERRNO (-4096). 20162306a36Sopenharmony_ci - ERR_NULL: retval must be 0 or -1 to -MAX_ERRNO (-4096). 20262306a36Sopenharmony_ci 20362306a36Sopenharmony_ci- /sys/kernel/debug/fail_function/<function-name>/retval: 20462306a36Sopenharmony_ci 20562306a36Sopenharmony_ci specifies the "error" return value to inject to the given function. 20662306a36Sopenharmony_ci This will be created when the user specifies a new injection entry. 20762306a36Sopenharmony_ci Note that this file only accepts unsigned values. So, if you want to 20862306a36Sopenharmony_ci use a negative errno, you better use 'printf' instead of 'echo', e.g.: 20962306a36Sopenharmony_ci $ printf %#x -12 > retval 21062306a36Sopenharmony_ci 21162306a36Sopenharmony_ciBoot option 21262306a36Sopenharmony_ci^^^^^^^^^^^ 21362306a36Sopenharmony_ci 21462306a36Sopenharmony_ciIn order to inject faults while debugfs is not available (early boot time), 21562306a36Sopenharmony_ciuse the boot option:: 21662306a36Sopenharmony_ci 21762306a36Sopenharmony_ci failslab= 21862306a36Sopenharmony_ci fail_page_alloc= 21962306a36Sopenharmony_ci fail_usercopy= 22062306a36Sopenharmony_ci fail_make_request= 22162306a36Sopenharmony_ci fail_futex= 22262306a36Sopenharmony_ci mmc_core.fail_request=<interval>,<probability>,<space>,<times> 22362306a36Sopenharmony_ci 22462306a36Sopenharmony_ciproc entries 22562306a36Sopenharmony_ci^^^^^^^^^^^^ 22662306a36Sopenharmony_ci 22762306a36Sopenharmony_ci- /proc/<pid>/fail-nth, 22862306a36Sopenharmony_ci /proc/self/task/<tid>/fail-nth: 22962306a36Sopenharmony_ci 23062306a36Sopenharmony_ci Write to this file of integer N makes N-th call in the task fail. 23162306a36Sopenharmony_ci Read from this file returns a integer value. A value of '0' indicates 23262306a36Sopenharmony_ci that the fault setup with a previous write to this file was injected. 23362306a36Sopenharmony_ci A positive integer N indicates that the fault wasn't yet injected. 23462306a36Sopenharmony_ci Note that this file enables all types of faults (slab, futex, etc). 23562306a36Sopenharmony_ci This setting takes precedence over all other generic debugfs settings 23662306a36Sopenharmony_ci like probability, interval, times, etc. But per-capability settings 23762306a36Sopenharmony_ci (e.g. fail_futex/ignore-private) take precedence over it. 23862306a36Sopenharmony_ci 23962306a36Sopenharmony_ci This feature is intended for systematic testing of faults in a single 24062306a36Sopenharmony_ci system call. See an example below. 24162306a36Sopenharmony_ci 24262306a36Sopenharmony_ci 24362306a36Sopenharmony_ciError Injectable Functions 24462306a36Sopenharmony_ci-------------------------- 24562306a36Sopenharmony_ci 24662306a36Sopenharmony_ciThis part is for the kernel developers considering to add a function to 24762306a36Sopenharmony_ciALLOW_ERROR_INJECTION() macro. 24862306a36Sopenharmony_ci 24962306a36Sopenharmony_ciRequirements for the Error Injectable Functions 25062306a36Sopenharmony_ci^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 25162306a36Sopenharmony_ci 25262306a36Sopenharmony_ciSince the function-level error injection forcibly changes the code path 25362306a36Sopenharmony_ciand returns an error even if the input and conditions are proper, this can 25462306a36Sopenharmony_cicause unexpected kernel crash if you allow error injection on the function 25562306a36Sopenharmony_ciwhich is NOT error injectable. Thus, you (and reviewers) must ensure; 25662306a36Sopenharmony_ci 25762306a36Sopenharmony_ci- The function returns an error code if it fails, and the callers must check 25862306a36Sopenharmony_ci it correctly (need to recover from it). 25962306a36Sopenharmony_ci 26062306a36Sopenharmony_ci- The function does not execute any code which can change any state before 26162306a36Sopenharmony_ci the first error return. The state includes global or local, or input 26262306a36Sopenharmony_ci variable. For example, clear output address storage (e.g. `*ret = NULL`), 26362306a36Sopenharmony_ci increments/decrements counter, set a flag, preempt/irq disable or get 26462306a36Sopenharmony_ci a lock (if those are recovered before returning error, that will be OK.) 26562306a36Sopenharmony_ci 26662306a36Sopenharmony_ciThe first requirement is important, and it will result in that the release 26762306a36Sopenharmony_ci(free objects) functions are usually harder to inject errors than allocate 26862306a36Sopenharmony_cifunctions. If errors of such release functions are not correctly handled 26962306a36Sopenharmony_ciit will cause a memory leak easily (the caller will confuse that the object 27062306a36Sopenharmony_cihas been released or corrupted.) 27162306a36Sopenharmony_ci 27262306a36Sopenharmony_ciThe second one is for the caller which expects the function should always 27362306a36Sopenharmony_cidoes something. Thus if the function error injection skips whole of the 27462306a36Sopenharmony_cifunction, the expectation is betrayed and causes an unexpected error. 27562306a36Sopenharmony_ci 27662306a36Sopenharmony_ciType of the Error Injectable Functions 27762306a36Sopenharmony_ci^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 27862306a36Sopenharmony_ci 27962306a36Sopenharmony_ciEach error injectable functions will have the error type specified by the 28062306a36Sopenharmony_ciALLOW_ERROR_INJECTION() macro. You have to choose it carefully if you add 28162306a36Sopenharmony_cia new error injectable function. If the wrong error type is chosen, the 28262306a36Sopenharmony_cikernel may crash because it may not be able to handle the error. 28362306a36Sopenharmony_ciThere are 4 types of errors defined in include/asm-generic/error-injection.h 28462306a36Sopenharmony_ci 28562306a36Sopenharmony_ciEI_ETYPE_NULL 28662306a36Sopenharmony_ci This function will return `NULL` if it fails. e.g. return an allocateed 28762306a36Sopenharmony_ci object address. 28862306a36Sopenharmony_ci 28962306a36Sopenharmony_ciEI_ETYPE_ERRNO 29062306a36Sopenharmony_ci This function will return an `-errno` error code if it fails. e.g. return 29162306a36Sopenharmony_ci -EINVAL if the input is wrong. This will include the functions which will 29262306a36Sopenharmony_ci return an address which encodes `-errno` by ERR_PTR() macro. 29362306a36Sopenharmony_ci 29462306a36Sopenharmony_ciEI_ETYPE_ERRNO_NULL 29562306a36Sopenharmony_ci This function will return an `-errno` or `NULL` if it fails. If the caller 29662306a36Sopenharmony_ci of this function checks the return value with IS_ERR_OR_NULL() macro, this 29762306a36Sopenharmony_ci type will be appropriate. 29862306a36Sopenharmony_ci 29962306a36Sopenharmony_ciEI_ETYPE_TRUE 30062306a36Sopenharmony_ci This function will return `true` (non-zero positive value) if it fails. 30162306a36Sopenharmony_ci 30262306a36Sopenharmony_ciIf you specifies a wrong type, for example, EI_TYPE_ERRNO for the function 30362306a36Sopenharmony_ciwhich returns an allocated object, it may cause a problem because the returned 30462306a36Sopenharmony_civalue is not an object address and the caller can not access to the address. 30562306a36Sopenharmony_ci 30662306a36Sopenharmony_ci 30762306a36Sopenharmony_ciHow to add new fault injection capability 30862306a36Sopenharmony_ci----------------------------------------- 30962306a36Sopenharmony_ci 31062306a36Sopenharmony_ci- #include <linux/fault-inject.h> 31162306a36Sopenharmony_ci 31262306a36Sopenharmony_ci- define the fault attributes 31362306a36Sopenharmony_ci 31462306a36Sopenharmony_ci DECLARE_FAULT_ATTR(name); 31562306a36Sopenharmony_ci 31662306a36Sopenharmony_ci Please see the definition of struct fault_attr in fault-inject.h 31762306a36Sopenharmony_ci for details. 31862306a36Sopenharmony_ci 31962306a36Sopenharmony_ci- provide a way to configure fault attributes 32062306a36Sopenharmony_ci 32162306a36Sopenharmony_ci- boot option 32262306a36Sopenharmony_ci 32362306a36Sopenharmony_ci If you need to enable the fault injection capability from boot time, you can 32462306a36Sopenharmony_ci provide boot option to configure it. There is a helper function for it: 32562306a36Sopenharmony_ci 32662306a36Sopenharmony_ci setup_fault_attr(attr, str); 32762306a36Sopenharmony_ci 32862306a36Sopenharmony_ci- debugfs entries 32962306a36Sopenharmony_ci 33062306a36Sopenharmony_ci failslab, fail_page_alloc, fail_usercopy, and fail_make_request use this way. 33162306a36Sopenharmony_ci Helper functions: 33262306a36Sopenharmony_ci 33362306a36Sopenharmony_ci fault_create_debugfs_attr(name, parent, attr); 33462306a36Sopenharmony_ci 33562306a36Sopenharmony_ci- module parameters 33662306a36Sopenharmony_ci 33762306a36Sopenharmony_ci If the scope of the fault injection capability is limited to a 33862306a36Sopenharmony_ci single kernel module, it is better to provide module parameters to 33962306a36Sopenharmony_ci configure the fault attributes. 34062306a36Sopenharmony_ci 34162306a36Sopenharmony_ci- add a hook to insert failures 34262306a36Sopenharmony_ci 34362306a36Sopenharmony_ci Upon should_fail() returning true, client code should inject a failure: 34462306a36Sopenharmony_ci 34562306a36Sopenharmony_ci should_fail(attr, size); 34662306a36Sopenharmony_ci 34762306a36Sopenharmony_ciApplication Examples 34862306a36Sopenharmony_ci-------------------- 34962306a36Sopenharmony_ci 35062306a36Sopenharmony_ci- Inject slab allocation failures into module init/exit code:: 35162306a36Sopenharmony_ci 35262306a36Sopenharmony_ci #!/bin/bash 35362306a36Sopenharmony_ci 35462306a36Sopenharmony_ci FAILTYPE=failslab 35562306a36Sopenharmony_ci echo Y > /sys/kernel/debug/$FAILTYPE/task-filter 35662306a36Sopenharmony_ci echo 10 > /sys/kernel/debug/$FAILTYPE/probability 35762306a36Sopenharmony_ci echo 100 > /sys/kernel/debug/$FAILTYPE/interval 35862306a36Sopenharmony_ci echo -1 > /sys/kernel/debug/$FAILTYPE/times 35962306a36Sopenharmony_ci echo 0 > /sys/kernel/debug/$FAILTYPE/space 36062306a36Sopenharmony_ci echo 2 > /sys/kernel/debug/$FAILTYPE/verbose 36162306a36Sopenharmony_ci echo Y > /sys/kernel/debug/$FAILTYPE/ignore-gfp-wait 36262306a36Sopenharmony_ci 36362306a36Sopenharmony_ci faulty_system() 36462306a36Sopenharmony_ci { 36562306a36Sopenharmony_ci bash -c "echo 1 > /proc/self/make-it-fail && exec $*" 36662306a36Sopenharmony_ci } 36762306a36Sopenharmony_ci 36862306a36Sopenharmony_ci if [ $# -eq 0 ] 36962306a36Sopenharmony_ci then 37062306a36Sopenharmony_ci echo "Usage: $0 modulename [ modulename ... ]" 37162306a36Sopenharmony_ci exit 1 37262306a36Sopenharmony_ci fi 37362306a36Sopenharmony_ci 37462306a36Sopenharmony_ci for m in $* 37562306a36Sopenharmony_ci do 37662306a36Sopenharmony_ci echo inserting $m... 37762306a36Sopenharmony_ci faulty_system modprobe $m 37862306a36Sopenharmony_ci 37962306a36Sopenharmony_ci echo removing $m... 38062306a36Sopenharmony_ci faulty_system modprobe -r $m 38162306a36Sopenharmony_ci done 38262306a36Sopenharmony_ci 38362306a36Sopenharmony_ci------------------------------------------------------------------------------ 38462306a36Sopenharmony_ci 38562306a36Sopenharmony_ci- Inject page allocation failures only for a specific module:: 38662306a36Sopenharmony_ci 38762306a36Sopenharmony_ci #!/bin/bash 38862306a36Sopenharmony_ci 38962306a36Sopenharmony_ci FAILTYPE=fail_page_alloc 39062306a36Sopenharmony_ci module=$1 39162306a36Sopenharmony_ci 39262306a36Sopenharmony_ci if [ -z $module ] 39362306a36Sopenharmony_ci then 39462306a36Sopenharmony_ci echo "Usage: $0 <modulename>" 39562306a36Sopenharmony_ci exit 1 39662306a36Sopenharmony_ci fi 39762306a36Sopenharmony_ci 39862306a36Sopenharmony_ci modprobe $module 39962306a36Sopenharmony_ci 40062306a36Sopenharmony_ci if [ ! -d /sys/module/$module/sections ] 40162306a36Sopenharmony_ci then 40262306a36Sopenharmony_ci echo Module $module is not loaded 40362306a36Sopenharmony_ci exit 1 40462306a36Sopenharmony_ci fi 40562306a36Sopenharmony_ci 40662306a36Sopenharmony_ci cat /sys/module/$module/sections/.text > /sys/kernel/debug/$FAILTYPE/require-start 40762306a36Sopenharmony_ci cat /sys/module/$module/sections/.data > /sys/kernel/debug/$FAILTYPE/require-end 40862306a36Sopenharmony_ci 40962306a36Sopenharmony_ci echo N > /sys/kernel/debug/$FAILTYPE/task-filter 41062306a36Sopenharmony_ci echo 10 > /sys/kernel/debug/$FAILTYPE/probability 41162306a36Sopenharmony_ci echo 100 > /sys/kernel/debug/$FAILTYPE/interval 41262306a36Sopenharmony_ci echo -1 > /sys/kernel/debug/$FAILTYPE/times 41362306a36Sopenharmony_ci echo 0 > /sys/kernel/debug/$FAILTYPE/space 41462306a36Sopenharmony_ci echo 2 > /sys/kernel/debug/$FAILTYPE/verbose 41562306a36Sopenharmony_ci echo Y > /sys/kernel/debug/$FAILTYPE/ignore-gfp-wait 41662306a36Sopenharmony_ci echo Y > /sys/kernel/debug/$FAILTYPE/ignore-gfp-highmem 41762306a36Sopenharmony_ci echo 10 > /sys/kernel/debug/$FAILTYPE/stacktrace-depth 41862306a36Sopenharmony_ci 41962306a36Sopenharmony_ci trap "echo 0 > /sys/kernel/debug/$FAILTYPE/probability" SIGINT SIGTERM EXIT 42062306a36Sopenharmony_ci 42162306a36Sopenharmony_ci echo "Injecting errors into the module $module... (interrupt to stop)" 42262306a36Sopenharmony_ci sleep 1000000 42362306a36Sopenharmony_ci 42462306a36Sopenharmony_ci------------------------------------------------------------------------------ 42562306a36Sopenharmony_ci 42662306a36Sopenharmony_ci- Inject open_ctree error while btrfs mount:: 42762306a36Sopenharmony_ci 42862306a36Sopenharmony_ci #!/bin/bash 42962306a36Sopenharmony_ci 43062306a36Sopenharmony_ci rm -f testfile.img 43162306a36Sopenharmony_ci dd if=/dev/zero of=testfile.img bs=1M seek=1000 count=1 43262306a36Sopenharmony_ci DEVICE=$(losetup --show -f testfile.img) 43362306a36Sopenharmony_ci mkfs.btrfs -f $DEVICE 43462306a36Sopenharmony_ci mkdir -p tmpmnt 43562306a36Sopenharmony_ci 43662306a36Sopenharmony_ci FAILTYPE=fail_function 43762306a36Sopenharmony_ci FAILFUNC=open_ctree 43862306a36Sopenharmony_ci echo $FAILFUNC > /sys/kernel/debug/$FAILTYPE/inject 43962306a36Sopenharmony_ci printf %#x -12 > /sys/kernel/debug/$FAILTYPE/$FAILFUNC/retval 44062306a36Sopenharmony_ci echo N > /sys/kernel/debug/$FAILTYPE/task-filter 44162306a36Sopenharmony_ci echo 100 > /sys/kernel/debug/$FAILTYPE/probability 44262306a36Sopenharmony_ci echo 0 > /sys/kernel/debug/$FAILTYPE/interval 44362306a36Sopenharmony_ci echo -1 > /sys/kernel/debug/$FAILTYPE/times 44462306a36Sopenharmony_ci echo 0 > /sys/kernel/debug/$FAILTYPE/space 44562306a36Sopenharmony_ci echo 1 > /sys/kernel/debug/$FAILTYPE/verbose 44662306a36Sopenharmony_ci 44762306a36Sopenharmony_ci mount -t btrfs $DEVICE tmpmnt 44862306a36Sopenharmony_ci if [ $? -ne 0 ] 44962306a36Sopenharmony_ci then 45062306a36Sopenharmony_ci echo "SUCCESS!" 45162306a36Sopenharmony_ci else 45262306a36Sopenharmony_ci echo "FAILED!" 45362306a36Sopenharmony_ci umount tmpmnt 45462306a36Sopenharmony_ci fi 45562306a36Sopenharmony_ci 45662306a36Sopenharmony_ci echo > /sys/kernel/debug/$FAILTYPE/inject 45762306a36Sopenharmony_ci 45862306a36Sopenharmony_ci rmdir tmpmnt 45962306a36Sopenharmony_ci losetup -d $DEVICE 46062306a36Sopenharmony_ci rm testfile.img 46162306a36Sopenharmony_ci 46262306a36Sopenharmony_ci 46362306a36Sopenharmony_ciTool to run command with failslab or fail_page_alloc 46462306a36Sopenharmony_ci---------------------------------------------------- 46562306a36Sopenharmony_ciIn order to make it easier to accomplish the tasks mentioned above, we can use 46662306a36Sopenharmony_citools/testing/fault-injection/failcmd.sh. Please run a command 46762306a36Sopenharmony_ci"./tools/testing/fault-injection/failcmd.sh --help" for more information and 46862306a36Sopenharmony_cisee the following examples. 46962306a36Sopenharmony_ci 47062306a36Sopenharmony_ciExamples: 47162306a36Sopenharmony_ci 47262306a36Sopenharmony_ciRun a command "make -C tools/testing/selftests/ run_tests" with injecting slab 47362306a36Sopenharmony_ciallocation failure:: 47462306a36Sopenharmony_ci 47562306a36Sopenharmony_ci # ./tools/testing/fault-injection/failcmd.sh \ 47662306a36Sopenharmony_ci -- make -C tools/testing/selftests/ run_tests 47762306a36Sopenharmony_ci 47862306a36Sopenharmony_ciSame as above except to specify 100 times failures at most instead of one time 47962306a36Sopenharmony_ciat most by default:: 48062306a36Sopenharmony_ci 48162306a36Sopenharmony_ci # ./tools/testing/fault-injection/failcmd.sh --times=100 \ 48262306a36Sopenharmony_ci -- make -C tools/testing/selftests/ run_tests 48362306a36Sopenharmony_ci 48462306a36Sopenharmony_ciSame as above except to inject page allocation failure instead of slab 48562306a36Sopenharmony_ciallocation failure:: 48662306a36Sopenharmony_ci 48762306a36Sopenharmony_ci # env FAILCMD_TYPE=fail_page_alloc \ 48862306a36Sopenharmony_ci ./tools/testing/fault-injection/failcmd.sh --times=100 \ 48962306a36Sopenharmony_ci -- make -C tools/testing/selftests/ run_tests 49062306a36Sopenharmony_ci 49162306a36Sopenharmony_ciSystematic faults using fail-nth 49262306a36Sopenharmony_ci--------------------------------- 49362306a36Sopenharmony_ci 49462306a36Sopenharmony_ciThe following code systematically faults 0-th, 1-st, 2-nd and so on 49562306a36Sopenharmony_cicapabilities in the socketpair() system call:: 49662306a36Sopenharmony_ci 49762306a36Sopenharmony_ci #include <sys/types.h> 49862306a36Sopenharmony_ci #include <sys/stat.h> 49962306a36Sopenharmony_ci #include <sys/socket.h> 50062306a36Sopenharmony_ci #include <sys/syscall.h> 50162306a36Sopenharmony_ci #include <fcntl.h> 50262306a36Sopenharmony_ci #include <unistd.h> 50362306a36Sopenharmony_ci #include <string.h> 50462306a36Sopenharmony_ci #include <stdlib.h> 50562306a36Sopenharmony_ci #include <stdio.h> 50662306a36Sopenharmony_ci #include <errno.h> 50762306a36Sopenharmony_ci 50862306a36Sopenharmony_ci int main() 50962306a36Sopenharmony_ci { 51062306a36Sopenharmony_ci int i, err, res, fail_nth, fds[2]; 51162306a36Sopenharmony_ci char buf[128]; 51262306a36Sopenharmony_ci 51362306a36Sopenharmony_ci system("echo N > /sys/kernel/debug/failslab/ignore-gfp-wait"); 51462306a36Sopenharmony_ci sprintf(buf, "/proc/self/task/%ld/fail-nth", syscall(SYS_gettid)); 51562306a36Sopenharmony_ci fail_nth = open(buf, O_RDWR); 51662306a36Sopenharmony_ci for (i = 1;; i++) { 51762306a36Sopenharmony_ci sprintf(buf, "%d", i); 51862306a36Sopenharmony_ci write(fail_nth, buf, strlen(buf)); 51962306a36Sopenharmony_ci res = socketpair(AF_LOCAL, SOCK_STREAM, 0, fds); 52062306a36Sopenharmony_ci err = errno; 52162306a36Sopenharmony_ci pread(fail_nth, buf, sizeof(buf), 0); 52262306a36Sopenharmony_ci if (res == 0) { 52362306a36Sopenharmony_ci close(fds[0]); 52462306a36Sopenharmony_ci close(fds[1]); 52562306a36Sopenharmony_ci } 52662306a36Sopenharmony_ci printf("%d-th fault %c: res=%d/%d\n", i, atoi(buf) ? 'N' : 'Y', 52762306a36Sopenharmony_ci res, err); 52862306a36Sopenharmony_ci if (atoi(buf)) 52962306a36Sopenharmony_ci break; 53062306a36Sopenharmony_ci } 53162306a36Sopenharmony_ci return 0; 53262306a36Sopenharmony_ci } 53362306a36Sopenharmony_ci 53462306a36Sopenharmony_ciAn example output:: 53562306a36Sopenharmony_ci 53662306a36Sopenharmony_ci 1-th fault Y: res=-1/23 53762306a36Sopenharmony_ci 2-th fault Y: res=-1/23 53862306a36Sopenharmony_ci 3-th fault Y: res=-1/12 53962306a36Sopenharmony_ci 4-th fault Y: res=-1/12 54062306a36Sopenharmony_ci 5-th fault Y: res=-1/23 54162306a36Sopenharmony_ci 6-th fault Y: res=-1/23 54262306a36Sopenharmony_ci 7-th fault Y: res=-1/23 54362306a36Sopenharmony_ci 8-th fault Y: res=-1/12 54462306a36Sopenharmony_ci 9-th fault Y: res=-1/12 54562306a36Sopenharmony_ci 10-th fault Y: res=-1/12 54662306a36Sopenharmony_ci 11-th fault Y: res=-1/12 54762306a36Sopenharmony_ci 12-th fault Y: res=-1/12 54862306a36Sopenharmony_ci 13-th fault Y: res=-1/12 54962306a36Sopenharmony_ci 14-th fault Y: res=-1/12 55062306a36Sopenharmony_ci 15-th fault Y: res=-1/12 55162306a36Sopenharmony_ci 16-th fault N: res=0/12 552