233 lines · bash
1#!/bin/bash2# SPDX-License-Identifier: GPL-2.03#4# NAME5# failcmd.sh - run a command with injecting slab/page allocation failures6#7# SYNOPSIS8# failcmd.sh --help9# failcmd.sh [<options>] command [arguments]10#11# DESCRIPTION12# Run command with injecting slab/page allocation failures by fault13# injection.14#15# NOTE: you need to run this script as root.16#17 18usage()19{20 cat >&2 <<EOF21Usage: $0 [options] command [arguments]22 23OPTIONS24 -p percent25 --probability=percent26 likelihood of failure injection, in percent.27 Default value is 128 29 -t value30 --times=value31 specifies how many times failures may happen at most.32 Default value is 133 34 --oom-kill-allocating-task=value35 set /proc/sys/vm/oom_kill_allocating_task to specified value36 before running the command.37 Default value is 138 39 -h, --help40 Display a usage message and exit41 42 --interval=value, --space=value, --verbose=value, --task-filter=value,43 --stacktrace-depth=value, --require-start=value, --require-end=value,44 --reject-start=value, --reject-end=value, --ignore-gfp-wait=value45 See Documentation/fault-injection/fault-injection.rst for more46 information47 48 failslab options:49 --cache-filter=value50 51 fail_page_alloc options:52 --ignore-gfp-highmem=value, --min-order=value53 54ENVIRONMENT55 FAILCMD_TYPE56 The following values for FAILCMD_TYPE are recognized:57 58 failslab59 inject slab allocation failures60 fail_page_alloc61 inject page allocation failures62 63 If FAILCMD_TYPE is not defined, then failslab is used.64EOF65}66 67exit_if_not_hex() {68 local value="$1"69 if ! [[ $value =~ ^0x[0-9a-fA-F]+$ ]]; then70 echo "Error: The provided value '$value' is not a valid hexadecimal number." >&271 exit 172 fi73}74 75if [ $UID != 0 ]; then76 echo must be run as root >&277 exit 178fi79 80DEBUGFS=`mount -t debugfs | head -1 | awk '{ print $3}'`81 82if [ ! -d "$DEBUGFS" ]; then83 echo debugfs is not mounted >&284 exit 185fi86 87FAILCMD_TYPE=${FAILCMD_TYPE:-failslab}88FAULTATTR=$DEBUGFS/$FAILCMD_TYPE89 90if [ ! -d $FAULTATTR ]; then91 echo $FAILCMD_TYPE is not available >&292 exit 193fi94 95LONGOPTS=probability:,interval:,times:,space:,verbose:,task-filter:96LONGOPTS=$LONGOPTS,stacktrace-depth:,require-start:,require-end:97LONGOPTS=$LONGOPTS,reject-start:,reject-end:,oom-kill-allocating-task:,help98 99if [ $FAILCMD_TYPE = failslab ]; then100 LONGOPTS=$LONGOPTS,ignore-gfp-wait:,cache-filter:101elif [ $FAILCMD_TYPE = fail_page_alloc ]; then102 LONGOPTS=$LONGOPTS,ignore-gfp-wait:,ignore-gfp-highmem:,min-order:103fi104 105TEMP=`getopt -o p:i:t:s:v:h --long $LONGOPTS -n 'failcmd.sh' -- "$@"`106 107if [ $? != 0 ]; then108 usage109 exit 1110fi111 112eval set -- "$TEMP"113 114fault_attr_default()115{116 echo N > $FAULTATTR/task-filter117 echo 0 > $FAULTATTR/probability118 echo 1 > $FAULTATTR/times119}120 121fault_attr_default122 123oom_kill_allocating_task_saved=`cat /proc/sys/vm/oom_kill_allocating_task`124 125restore_values()126{127 fault_attr_default128 echo $oom_kill_allocating_task_saved \129 > /proc/sys/vm/oom_kill_allocating_task130}131 132#133# Default options134#135declare -i oom_kill_allocating_task=1136declare task_filter=Y137declare -i probability=1138declare -i times=1139 140while true; do141 case "$1" in142 -p|--probability)143 probability=$2144 shift 2145 ;;146 -i|--interval)147 echo $2 > $FAULTATTR/interval148 shift 2149 ;;150 -t|--times)151 times=$2152 shift 2153 ;;154 -s|--space)155 echo $2 > $FAULTATTR/space156 shift 2157 ;;158 -v|--verbose)159 echo $2 > $FAULTATTR/verbose160 shift 2161 ;;162 --task-filter)163 task_filter=$2164 shift 2165 ;;166 --stacktrace-depth)167 echo $2 > $FAULTATTR/stacktrace-depth168 shift 2169 ;;170 --require-start)171 exit_if_not_hex "$2"172 echo $2 > $FAULTATTR/require-start173 shift 2174 ;;175 --require-end)176 exit_if_not_hex "$2"177 echo $2 > $FAULTATTR/require-end178 shift 2179 ;;180 --reject-start)181 exit_if_not_hex "$2"182 echo $2 > $FAULTATTR/reject-start183 shift 2184 ;;185 --reject-end)186 exit_if_not_hex "$2"187 echo $2 > $FAULTATTR/reject-end188 shift 2189 ;;190 --oom-kill-allocating-task)191 oom_kill_allocating_task=$2192 shift 2193 ;;194 --ignore-gfp-wait)195 echo $2 > $FAULTATTR/ignore-gfp-wait196 shift 2197 ;;198 --cache-filter)199 echo $2 > $FAULTATTR/cache_filter200 shift 2201 ;;202 --ignore-gfp-highmem)203 echo $2 > $FAULTATTR/ignore-gfp-highmem204 shift 2205 ;;206 --min-order)207 echo $2 > $FAULTATTR/min-order208 shift 2209 ;;210 -h|--help)211 usage212 exit 0213 shift214 ;;215 --)216 shift217 break218 ;;219 esac220done221 222[ -z "$1" ] && exit 0223 224echo $oom_kill_allocating_task > /proc/sys/vm/oom_kill_allocating_task225echo $task_filter > $FAULTATTR/task-filter226echo $probability > $FAULTATTR/probability227echo $times > $FAULTATTR/times228 229trap "restore_values" SIGINT SIGTERM EXIT230 231cmd="echo 1 > /proc/self/make-it-fail && exec $@"232bash -c "$cmd"233