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