123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221 |
- #!/bin/bash
- # SPDX-License-Identifier: GPL-2.0
- #
- # NAME
- # failcmd.sh - run a command with injecting slab/page allocation failures
- #
- # SYNOPSIS
- # failcmd.sh --help
- # failcmd.sh [<options>] command [arguments]
- #
- # DESCRIPTION
- # Run command with injecting slab/page allocation failures by fault
- # injection.
- #
- # NOTE: you need to run this script as root.
- #
- usage()
- {
- cat >&2 <<EOF
- Usage: $0 [options] command [arguments]
- OPTIONS
- -p percent
- --probability=percent
- likelihood of failure injection, in percent.
- Default value is 1
- -t value
- --times=value
- specifies how many times failures may happen at most.
- Default value is 1
- --oom-kill-allocating-task=value
- set /proc/sys/vm/oom_kill_allocating_task to specified value
- before running the command.
- Default value is 1
- -h, --help
- Display a usage message and exit
- --interval=value, --space=value, --verbose=value, --task-filter=value,
- --stacktrace-depth=value, --require-start=value, --require-end=value,
- --reject-start=value, --reject-end=value, --ignore-gfp-wait=value
- See Documentation/fault-injection/fault-injection.txt for more
- information
- failslab options:
- --cache-filter=value
- fail_page_alloc options:
- --ignore-gfp-highmem=value, --min-order=value
- ENVIRONMENT
- FAILCMD_TYPE
- The following values for FAILCMD_TYPE are recognized:
- failslab
- inject slab allocation failures
- fail_page_alloc
- inject page allocation failures
- If FAILCMD_TYPE is not defined, then failslab is used.
- EOF
- }
- if [ $UID != 0 ]; then
- echo must be run as root >&2
- exit 1
- fi
- DEBUGFS=`mount -t debugfs | head -1 | awk '{ print $3}'`
- if [ ! -d "$DEBUGFS" ]; then
- echo debugfs is not mounted >&2
- exit 1
- fi
- FAILCMD_TYPE=${FAILCMD_TYPE:-failslab}
- FAULTATTR=$DEBUGFS/$FAILCMD_TYPE
- if [ ! -d $FAULTATTR ]; then
- echo $FAILCMD_TYPE is not available >&2
- exit 1
- fi
- LONGOPTS=probability:,interval:,times:,space:,verbose:,task-filter:
- LONGOPTS=$LONGOPTS,stacktrace-depth:,require-start:,require-end:
- LONGOPTS=$LONGOPTS,reject-start:,reject-end:,oom-kill-allocating-task:,help
- if [ $FAILCMD_TYPE = failslab ]; then
- LONGOPTS=$LONGOPTS,ignore-gfp-wait:,cache-filter:
- elif [ $FAILCMD_TYPE = fail_page_alloc ]; then
- LONGOPTS=$LONGOPTS,ignore-gfp-wait:,ignore-gfp-highmem:,min-order:
- fi
- TEMP=`getopt -o p:i:t:s:v:h --long $LONGOPTS -n 'failcmd.sh' -- "$@"`
- if [ $? != 0 ]; then
- usage
- exit 1
- fi
- eval set -- "$TEMP"
- fault_attr_default()
- {
- echo N > $FAULTATTR/task-filter
- echo 0 > $FAULTATTR/probability
- echo 1 > $FAULTATTR/times
- }
- fault_attr_default
- oom_kill_allocating_task_saved=`cat /proc/sys/vm/oom_kill_allocating_task`
- restore_values()
- {
- fault_attr_default
- echo $oom_kill_allocating_task_saved \
- > /proc/sys/vm/oom_kill_allocating_task
- }
- #
- # Default options
- #
- declare -i oom_kill_allocating_task=1
- declare task_filter=Y
- declare -i probability=1
- declare -i times=1
- while true; do
- case "$1" in
- -p|--probability)
- probability=$2
- shift 2
- ;;
- -i|--interval)
- echo $2 > $FAULTATTR/interval
- shift 2
- ;;
- -t|--times)
- times=$2
- shift 2
- ;;
- -s|--space)
- echo $2 > $FAULTATTR/space
- shift 2
- ;;
- -v|--verbose)
- echo $2 > $FAULTATTR/verbose
- shift 2
- ;;
- --task-filter)
- task_filter=$2
- shift 2
- ;;
- --stacktrace-depth)
- echo $2 > $FAULTATTR/stacktrace-depth
- shift 2
- ;;
- --require-start)
- echo $2 > $FAULTATTR/require-start
- shift 2
- ;;
- --require-end)
- echo $2 > $FAULTATTR/require-end
- shift 2
- ;;
- --reject-start)
- echo $2 > $FAULTATTR/reject-start
- shift 2
- ;;
- --reject-end)
- echo $2 > $FAULTATTR/reject-end
- shift 2
- ;;
- --oom-kill-allocating-task)
- oom_kill_allocating_task=$2
- shift 2
- ;;
- --ignore-gfp-wait)
- echo $2 > $FAULTATTR/ignore-gfp-wait
- shift 2
- ;;
- --cache-filter)
- echo $2 > $FAULTATTR/cache_filter
- shift 2
- ;;
- --ignore-gfp-highmem)
- echo $2 > $FAULTATTR/ignore-gfp-highmem
- shift 2
- ;;
- --min-order)
- echo $2 > $FAULTATTR/min-order
- shift 2
- ;;
- -h|--help)
- usage
- exit 0
- shift
- ;;
- --)
- shift
- break
- ;;
- esac
- done
- [ -z "$1" ] && exit 0
- echo $oom_kill_allocating_task > /proc/sys/vm/oom_kill_allocating_task
- echo $task_filter > $FAULTATTR/task-filter
- echo $probability > $FAULTATTR/probability
- echo $times > $FAULTATTR/times
- trap "restore_values" SIGINT SIGTERM EXIT
- cmd="echo 1 > /proc/self/make-it-fail && exec $@"
- bash -c "$cmd"
|