1#!/bin/bash 2# SPDX-License-Identifier: GPL-2.0 3# 4# NAME 5# failcmd.sh - run a command with injecting slab/page allocation failures 6# 7# SYNOPSIS 8# failcmd.sh --help 9# failcmd.sh [<options>] command [arguments] 10# 11# DESCRIPTION 12# Run command with injecting slab/page allocation failures by fault 13# injection. 14# 15# NOTE: you need to run this script as root. 16# 17 18usage() 19{ 20 cat >&2 <<EOF 21Usage: $0 [options] command [arguments] 22 23OPTIONS 24 -p percent 25 --probability=percent 26 likelihood of failure injection, in percent. 27 Default value is 1 28 29 -t value 30 --times=value 31 specifies how many times failures may happen at most. 32 Default value is 1 33 34 --oom-kill-allocating-task=value 35 set /proc/sys/vm/oom_kill_allocating_task to specified value 36 before running the command. 37 Default value is 1 38 39 -h, --help 40 Display a usage message and exit 41 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=value 45 See Documentation/fault-injection/fault-injection.rst for more 46 information 47 48 failslab options: 49 --cache-filter=value 50 51 fail_page_alloc options: 52 --ignore-gfp-highmem=value, --min-order=value 53 54ENVIRONMENT 55 FAILCMD_TYPE 56 The following values for FAILCMD_TYPE are recognized: 57 58 failslab 59 inject slab allocation failures 60 fail_page_alloc 61 inject page allocation failures 62 63 If FAILCMD_TYPE is not defined, then failslab is used. 64EOF 65} 66 67exit_if_not_hex() { 68 local value="$1" 69 if ! [[ $value =~ ^0x[0-9a-fA-F]+$ ]]; then 70 echo "Error: The provided value '$value' is not a valid hexadecimal number." >&2 71 exit 1 72 fi 73} 74 75if [ $UID != 0 ]; then 76 echo must be run as root >&2 77 exit 1 78fi 79 80DEBUGFS=`mount -t debugfs | head -1 | awk '{ print $3}'` 81 82if [ ! -d "$DEBUGFS" ]; then 83 echo debugfs is not mounted >&2 84 exit 1 85fi 86 87FAILCMD_TYPE=${FAILCMD_TYPE:-failslab} 88FAULTATTR=$DEBUGFS/$FAILCMD_TYPE 89 90if [ ! -d $FAULTATTR ]; then 91 echo $FAILCMD_TYPE is not available >&2 92 exit 1 93fi 94 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:,help 98 99if [ $FAILCMD_TYPE = failslab ]; then 100 LONGOPTS=$LONGOPTS,ignore-gfp-wait:,cache-filter: 101elif [ $FAILCMD_TYPE = fail_page_alloc ]; then 102 LONGOPTS=$LONGOPTS,ignore-gfp-wait:,ignore-gfp-highmem:,min-order: 103fi 104 105TEMP=`getopt -o p:i:t:s:v:h --long $LONGOPTS -n 'failcmd.sh' -- "$@"` 106 107if [ $? != 0 ]; then 108 usage 109 exit 1 110fi 111 112eval set -- "$TEMP" 113 114fault_attr_default() 115{ 116 echo N > $FAULTATTR/task-filter 117 echo 0 > $FAULTATTR/probability 118 echo 1 > $FAULTATTR/times 119} 120 121fault_attr_default 122 123oom_kill_allocating_task_saved=`cat /proc/sys/vm/oom_kill_allocating_task` 124 125restore_values() 126{ 127 fault_attr_default 128 echo $oom_kill_allocating_task_saved \ 129 > /proc/sys/vm/oom_kill_allocating_task 130} 131 132# 133# Default options 134# 135declare -i oom_kill_allocating_task=1 136declare task_filter=Y 137declare -i probability=1 138declare -i times=1 139 140while true; do 141 case "$1" in 142 -p|--probability) 143 probability=$2 144 shift 2 145 ;; 146 -i|--interval) 147 echo $2 > $FAULTATTR/interval 148 shift 2 149 ;; 150 -t|--times) 151 times=$2 152 shift 2 153 ;; 154 -s|--space) 155 echo $2 > $FAULTATTR/space 156 shift 2 157 ;; 158 -v|--verbose) 159 echo $2 > $FAULTATTR/verbose 160 shift 2 161 ;; 162 --task-filter) 163 task_filter=$2 164 shift 2 165 ;; 166 --stacktrace-depth) 167 echo $2 > $FAULTATTR/stacktrace-depth 168 shift 2 169 ;; 170 --require-start) 171 exit_if_not_hex "$2" 172 echo $2 > $FAULTATTR/require-start 173 shift 2 174 ;; 175 --require-end) 176 exit_if_not_hex "$2" 177 echo $2 > $FAULTATTR/require-end 178 shift 2 179 ;; 180 --reject-start) 181 exit_if_not_hex "$2" 182 echo $2 > $FAULTATTR/reject-start 183 shift 2 184 ;; 185 --reject-end) 186 exit_if_not_hex "$2" 187 echo $2 > $FAULTATTR/reject-end 188 shift 2 189 ;; 190 --oom-kill-allocating-task) 191 oom_kill_allocating_task=$2 192 shift 2 193 ;; 194 --ignore-gfp-wait) 195 echo $2 > $FAULTATTR/ignore-gfp-wait 196 shift 2 197 ;; 198 --cache-filter) 199 echo $2 > $FAULTATTR/cache_filter 200 shift 2 201 ;; 202 --ignore-gfp-highmem) 203 echo $2 > $FAULTATTR/ignore-gfp-highmem 204 shift 2 205 ;; 206 --min-order) 207 echo $2 > $FAULTATTR/min-order 208 shift 2 209 ;; 210 -h|--help) 211 usage 212 exit 0 213 shift 214 ;; 215 --) 216 shift 217 break 218 ;; 219 esac 220done 221 222[ -z "$1" ] && exit 0 223 224echo $oom_kill_allocating_task > /proc/sys/vm/oom_kill_allocating_task 225echo $task_filter > $FAULTATTR/task-filter 226echo $probability > $FAULTATTR/probability 227echo $times > $FAULTATTR/times 228 229trap "restore_values" SIGINT SIGTERM EXIT 230 231cmd="echo 1 > /proc/self/make-it-fail && exec $@" 232bash -c "$cmd" 233