2006-12-08 13:39:42 +03:00
Fault injection capabilities infrastructure
===========================================
See also drivers/md/faulty.c and "every_nth" module option for scsi_debug.
Available fault injection capabilities
--------------------------------------
o failslab
injects slab allocation failures. (kmalloc(), kmem_cache_alloc(), ...)
o fail_page_alloc
injects page allocation failures. (alloc_pages(), get_free_pages(), ...)
o fail_make_request
2006-12-08 13:39:50 +03:00
injects disk IO errors on devices permitted by setting
2006-12-08 13:39:42 +03:00
/sys/block/<device>/make-it-fail or
/sys/block/<device>/<partition>/make-it-fail. (generic_make_request())
2011-08-19 16:52:38 +04:00
o fail_mmc_request
injects MMC data errors on devices permitted by setting
debugfs entries under /sys/kernel/debug/mmc0/fail_mmc_request
2006-12-08 13:39:42 +03:00
Configure fault-injection capabilities behavior
-----------------------------------------------
o debugfs entries
fault-inject-debugfs kernel module provides some debugfs entries for runtime
configuration of fault-injection capabilities.
2009-06-02 10:01:37 +04:00
- /sys/kernel/debug/fail*/probability:
2006-12-08 13:39:42 +03:00
likelihood of failure injection, in percent.
Format: <percent>
2006-12-08 13:39:50 +03:00
Note that one-failure-per-hundred is a very high error rate
for some testcases. Consider setting probability=100 and configure
2009-06-02 10:01:37 +04:00
/sys/kernel/debug/fail*/interval for such testcases.
2006-12-08 13:39:42 +03:00
2009-06-02 10:01:37 +04:00
- /sys/kernel/debug/fail*/interval:
2006-12-08 13:39:42 +03:00
specifies the interval between failures, for calls to
should_fail() that pass all the other tests.
Note that if you enable this, by setting interval>1, you will
probably want to set probability=100.
2009-06-02 10:01:37 +04:00
- /sys/kernel/debug/fail*/times:
2006-12-08 13:39:42 +03:00
specifies how many times failures may happen at most.
A value of -1 means "no limit".
2009-06-02 10:01:37 +04:00
- /sys/kernel/debug/fail*/space:
2006-12-08 13:39:42 +03:00
specifies an initial resource "budget", decremented by "size"
on each call to should_fail(,size). Failure injection is
suppressed until "space" reaches zero.
2009-06-02 10:01:37 +04:00
- /sys/kernel/debug/fail*/verbose
2006-12-08 13:39:42 +03:00
Format: { 0 | 1 | 2 }
2006-12-08 13:39:50 +03:00
specifies the verbosity of the messages when failure is
injected. '0' means no messages; '1' will print only a single
log line per failure; '2' will print a call trace too -- useful
to debug the problems revealed by fault injection.
2006-12-08 13:39:42 +03:00
2009-06-02 10:01:37 +04:00
- /sys/kernel/debug/fail*/task-filter:
2006-12-08 13:39:42 +03:00
2006-12-08 13:39:50 +03:00
Format: { 'Y' | 'N' }
A value of 'N' disables filtering by process (default).
2006-12-08 13:39:42 +03:00
Any positive value limits failures to only processes indicated by
/proc/<pid>/make-it-fail==1.
2009-06-02 10:01:37 +04:00
- /sys/kernel/debug/fail*/require-start:
- /sys/kernel/debug/fail*/require-end:
- /sys/kernel/debug/fail*/reject-start:
- /sys/kernel/debug/fail*/reject-end:
2006-12-08 13:39:42 +03:00
specifies the range of virtual addresses tested during
stacktrace walking. Failure is injected only if some caller
2006-12-08 13:39:48 +03:00
in the walked stacktrace lies within the required range, and
none lies within the rejected range.
Default required range is [0,ULONG_MAX) (whole of virtual address space).
Default rejected range is [0,0).
2006-12-08 13:39:42 +03:00
2009-06-02 10:01:37 +04:00
- /sys/kernel/debug/fail*/stacktrace-depth:
2006-12-08 13:39:42 +03:00
specifies the maximum stacktrace depth walked during search
2006-12-08 13:39:50 +03:00
for a caller within [require-start,require-end) OR
[reject-start,reject-end).
2006-12-08 13:39:42 +03:00
2009-06-02 10:01:37 +04:00
- /sys/kernel/debug/fail_page_alloc/ignore-gfp-highmem:
2006-12-08 13:39:42 +03:00
2006-12-08 13:39:50 +03:00
Format: { 'Y' | 'N' }
default is 'N', setting it to 'Y' won't inject failures into
2006-12-08 13:39:42 +03:00
highmem/user allocations.
2009-06-02 10:01:37 +04:00
- /sys/kernel/debug/failslab/ignore-gfp-wait:
- /sys/kernel/debug/fail_page_alloc/ignore-gfp-wait:
2006-12-08 13:39:42 +03:00
2006-12-08 13:39:50 +03:00
Format: { 'Y' | 'N' }
default is 'N', setting it to 'Y' will inject failures
2006-12-08 13:39:42 +03:00
only into non-sleep allocations (GFP_ATOMIC allocations).
2009-06-02 10:01:37 +04:00
- /sys/kernel/debug/fail_page_alloc/min-order:
2007-07-16 10:40:23 +04:00
specifies the minimum page allocation order to be injected
failures.
2006-12-08 13:39:42 +03:00
o Boot option
In order to inject faults while debugfs is not available (early boot time),
use the boot option:
failslab=
fail_page_alloc=
2011-08-19 16:52:38 +04:00
fail_make_request=
2011-09-14 01:03:30 +04:00
mmc_core.fail_request=<interval>,<probability>,<space>,<times>
2006-12-08 13:39:42 +03:00
How to add new fault injection capability
-----------------------------------------
o #include <linux/fault-inject.h>
o define the fault attributes
DECLARE_FAULT_INJECTION(name);
Please see the definition of struct fault_attr in fault-inject.h
for details.
2006-12-08 13:39:50 +03:00
o provide a way to configure fault attributes
2006-12-08 13:39:42 +03:00
- boot option
If you need to enable the fault injection capability from boot time, you can
2006-12-08 13:39:50 +03:00
provide boot option to configure it. There is a helper function for it:
2006-12-08 13:39:42 +03:00
2006-12-08 13:39:50 +03:00
setup_fault_attr(attr, str);
2006-12-08 13:39:42 +03:00
- debugfs entries
failslab, fail_page_alloc, and fail_make_request use this way.
2006-12-08 13:39:50 +03:00
Helper functions:
2006-12-08 13:39:42 +03:00
2011-08-04 03:21:01 +04:00
fault_create_debugfs_attr(name, parent, attr);
2006-12-08 13:39:42 +03:00
- module parameters
If the scope of the fault injection capability is limited to a
single kernel module, it is better to provide module parameters to
configure the fault attributes.
o add a hook to insert failures
2006-12-08 13:39:50 +03:00
Upon should_fail() returning true, client code should inject a failure.
2006-12-08 13:39:42 +03:00
2006-12-08 13:39:50 +03:00
should_fail(attr, size);
2006-12-08 13:39:42 +03:00
Application Examples
--------------------
2007-07-16 10:40:24 +04:00
o Inject slab allocation failures into module init/exit code
2006-12-08 13:39:42 +03:00
#!/bin/bash
2007-07-16 10:40:24 +04:00
FAILTYPE=failslab
2009-06-02 10:01:37 +04:00
echo Y > /sys/kernel/debug/$FAILTYPE/task-filter
echo 10 > /sys/kernel/debug/$FAILTYPE/probability
echo 100 > /sys/kernel/debug/$FAILTYPE/interval
echo -1 > /sys/kernel/debug/$FAILTYPE/times
echo 0 > /sys/kernel/debug/$FAILTYPE/space
echo 2 > /sys/kernel/debug/$FAILTYPE/verbose
echo 1 > /sys/kernel/debug/$FAILTYPE/ignore-gfp-wait
2006-12-08 13:39:42 +03:00
2007-07-16 10:40:24 +04:00
faulty_system()
2006-12-08 13:39:42 +03:00
{
2007-07-16 10:40:24 +04:00
bash -c "echo 1 > /proc/self/make-it-fail && exec $*"
2006-12-08 13:39:42 +03:00
}
2007-07-16 10:40:24 +04:00
if [ $# -eq 0 ]
then
echo "Usage: $0 modulename [ modulename ... ]"
exit 1
fi
for m in $*
do
echo inserting $m...
faulty_system modprobe $m
2006-12-08 13:39:42 +03:00
2007-07-16 10:40:24 +04:00
echo removing $m...
faulty_system modprobe -r $m
done
2006-12-08 13:39:42 +03:00
------------------------------------------------------------------------------
2007-07-16 10:40:24 +04:00
o Inject page allocation failures only for a specific module
2006-12-08 13:39:42 +03:00
#!/bin/bash
2007-07-16 10:40:24 +04:00
FAILTYPE=fail_page_alloc
module=$1
2006-12-08 13:39:42 +03:00
2007-07-16 10:40:24 +04:00
if [ -z $module ]
then
echo "Usage: $0 <modulename>"
exit 1
fi
2006-12-08 13:39:42 +03:00
2007-07-16 10:40:24 +04:00
modprobe $module
2006-12-08 13:39:42 +03:00
2007-07-16 10:40:24 +04:00
if [ ! -d /sys/module/$module/sections ]
then
echo Module $module is not loaded
exit 1
fi
2009-06-02 10:01:37 +04:00
cat /sys/module/$module/sections/.text > /sys/kernel/debug/$FAILTYPE/require-start
cat /sys/module/$module/sections/.data > /sys/kernel/debug/$FAILTYPE/require-end
2007-07-16 10:40:24 +04:00
2009-06-02 10:01:37 +04:00
echo N > /sys/kernel/debug/$FAILTYPE/task-filter
echo 10 > /sys/kernel/debug/$FAILTYPE/probability
echo 100 > /sys/kernel/debug/$FAILTYPE/interval
echo -1 > /sys/kernel/debug/$FAILTYPE/times
echo 0 > /sys/kernel/debug/$FAILTYPE/space
echo 2 > /sys/kernel/debug/$FAILTYPE/verbose
echo 1 > /sys/kernel/debug/$FAILTYPE/ignore-gfp-wait
echo 1 > /sys/kernel/debug/$FAILTYPE/ignore-gfp-highmem
echo 10 > /sys/kernel/debug/$FAILTYPE/stacktrace-depth
2007-07-16 10:40:24 +04:00
2009-06-02 10:01:37 +04:00
trap "echo 0 > /sys/kernel/debug/$FAILTYPE/probability" SIGINT SIGTERM EXIT
2007-07-16 10:40:24 +04:00
echo "Injecting errors into the module $module... (interrupt to stop)"
sleep 1000000
2006-12-08 13:39:42 +03:00