| xj | b04a402 | 2021-11-25 15:01:52 +0800 | [diff] [blame] | 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 |  | 
|  | 18 | usage() | 
|  | 19 | { | 
|  | 20 | cat >&2 <<EOF | 
|  | 21 | Usage: $0 [options] command [arguments] | 
|  | 22 |  | 
|  | 23 | OPTIONS | 
|  | 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.txt 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 |  | 
|  | 54 | ENVIRONMENT | 
|  | 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. | 
|  | 64 | EOF | 
|  | 65 | } | 
|  | 66 |  | 
|  | 67 | if [ $UID != 0 ]; then | 
|  | 68 | echo must be run as root >&2 | 
|  | 69 | exit 1 | 
|  | 70 | fi | 
|  | 71 |  | 
|  | 72 | DEBUGFS=`mount -t debugfs | head -1 | awk '{ print $3}'` | 
|  | 73 |  | 
|  | 74 | if [ ! -d "$DEBUGFS" ]; then | 
|  | 75 | echo debugfs is not mounted >&2 | 
|  | 76 | exit 1 | 
|  | 77 | fi | 
|  | 78 |  | 
|  | 79 | FAILCMD_TYPE=${FAILCMD_TYPE:-failslab} | 
|  | 80 | FAULTATTR=$DEBUGFS/$FAILCMD_TYPE | 
|  | 81 |  | 
|  | 82 | if [ ! -d $FAULTATTR ]; then | 
|  | 83 | echo $FAILCMD_TYPE is not available >&2 | 
|  | 84 | exit 1 | 
|  | 85 | fi | 
|  | 86 |  | 
|  | 87 | LONGOPTS=probability:,interval:,times:,space:,verbose:,task-filter: | 
|  | 88 | LONGOPTS=$LONGOPTS,stacktrace-depth:,require-start:,require-end: | 
|  | 89 | LONGOPTS=$LONGOPTS,reject-start:,reject-end:,oom-kill-allocating-task:,help | 
|  | 90 |  | 
|  | 91 | if [ $FAILCMD_TYPE = failslab ]; then | 
|  | 92 | LONGOPTS=$LONGOPTS,ignore-gfp-wait:,cache-filter: | 
|  | 93 | elif [ $FAILCMD_TYPE = fail_page_alloc ]; then | 
|  | 94 | LONGOPTS=$LONGOPTS,ignore-gfp-wait:,ignore-gfp-highmem:,min-order: | 
|  | 95 | fi | 
|  | 96 |  | 
|  | 97 | TEMP=`getopt -o p:i:t:s:v:h --long $LONGOPTS -n 'failcmd.sh' -- "$@"` | 
|  | 98 |  | 
|  | 99 | if [ $? != 0 ]; then | 
|  | 100 | usage | 
|  | 101 | exit 1 | 
|  | 102 | fi | 
|  | 103 |  | 
|  | 104 | eval set -- "$TEMP" | 
|  | 105 |  | 
|  | 106 | fault_attr_default() | 
|  | 107 | { | 
|  | 108 | echo N > $FAULTATTR/task-filter | 
|  | 109 | echo 0 > $FAULTATTR/probability | 
|  | 110 | echo 1 > $FAULTATTR/times | 
|  | 111 | } | 
|  | 112 |  | 
|  | 113 | fault_attr_default | 
|  | 114 |  | 
|  | 115 | oom_kill_allocating_task_saved=`cat /proc/sys/vm/oom_kill_allocating_task` | 
|  | 116 |  | 
|  | 117 | restore_values() | 
|  | 118 | { | 
|  | 119 | fault_attr_default | 
|  | 120 | echo $oom_kill_allocating_task_saved \ | 
|  | 121 | > /proc/sys/vm/oom_kill_allocating_task | 
|  | 122 | } | 
|  | 123 |  | 
|  | 124 | # | 
|  | 125 | # Default options | 
|  | 126 | # | 
|  | 127 | declare -i oom_kill_allocating_task=1 | 
|  | 128 | declare task_filter=Y | 
|  | 129 | declare -i probability=1 | 
|  | 130 | declare -i times=1 | 
|  | 131 |  | 
|  | 132 | while true; do | 
|  | 133 | case "$1" in | 
|  | 134 | -p|--probability) | 
|  | 135 | probability=$2 | 
|  | 136 | shift 2 | 
|  | 137 | ;; | 
|  | 138 | -i|--interval) | 
|  | 139 | echo $2 > $FAULTATTR/interval | 
|  | 140 | shift 2 | 
|  | 141 | ;; | 
|  | 142 | -t|--times) | 
|  | 143 | times=$2 | 
|  | 144 | shift 2 | 
|  | 145 | ;; | 
|  | 146 | -s|--space) | 
|  | 147 | echo $2 > $FAULTATTR/space | 
|  | 148 | shift 2 | 
|  | 149 | ;; | 
|  | 150 | -v|--verbose) | 
|  | 151 | echo $2 > $FAULTATTR/verbose | 
|  | 152 | shift 2 | 
|  | 153 | ;; | 
|  | 154 | --task-filter) | 
|  | 155 | task_filter=$2 | 
|  | 156 | shift 2 | 
|  | 157 | ;; | 
|  | 158 | --stacktrace-depth) | 
|  | 159 | echo $2 > $FAULTATTR/stacktrace-depth | 
|  | 160 | shift 2 | 
|  | 161 | ;; | 
|  | 162 | --require-start) | 
|  | 163 | echo $2 > $FAULTATTR/require-start | 
|  | 164 | shift 2 | 
|  | 165 | ;; | 
|  | 166 | --require-end) | 
|  | 167 | echo $2 > $FAULTATTR/require-end | 
|  | 168 | shift 2 | 
|  | 169 | ;; | 
|  | 170 | --reject-start) | 
|  | 171 | echo $2 > $FAULTATTR/reject-start | 
|  | 172 | shift 2 | 
|  | 173 | ;; | 
|  | 174 | --reject-end) | 
|  | 175 | echo $2 > $FAULTATTR/reject-end | 
|  | 176 | shift 2 | 
|  | 177 | ;; | 
|  | 178 | --oom-kill-allocating-task) | 
|  | 179 | oom_kill_allocating_task=$2 | 
|  | 180 | shift 2 | 
|  | 181 | ;; | 
|  | 182 | --ignore-gfp-wait) | 
|  | 183 | echo $2 > $FAULTATTR/ignore-gfp-wait | 
|  | 184 | shift 2 | 
|  | 185 | ;; | 
|  | 186 | --cache-filter) | 
|  | 187 | echo $2 > $FAULTATTR/cache_filter | 
|  | 188 | shift 2 | 
|  | 189 | ;; | 
|  | 190 | --ignore-gfp-highmem) | 
|  | 191 | echo $2 > $FAULTATTR/ignore-gfp-highmem | 
|  | 192 | shift 2 | 
|  | 193 | ;; | 
|  | 194 | --min-order) | 
|  | 195 | echo $2 > $FAULTATTR/min-order | 
|  | 196 | shift 2 | 
|  | 197 | ;; | 
|  | 198 | -h|--help) | 
|  | 199 | usage | 
|  | 200 | exit 0 | 
|  | 201 | shift | 
|  | 202 | ;; | 
|  | 203 | --) | 
|  | 204 | shift | 
|  | 205 | break | 
|  | 206 | ;; | 
|  | 207 | esac | 
|  | 208 | done | 
|  | 209 |  | 
|  | 210 | [ -z "$1" ] && exit 0 | 
|  | 211 |  | 
|  | 212 | echo $oom_kill_allocating_task > /proc/sys/vm/oom_kill_allocating_task | 
|  | 213 | echo $task_filter > $FAULTATTR/task-filter | 
|  | 214 | echo $probability > $FAULTATTR/probability | 
|  | 215 | echo $times > $FAULTATTR/times | 
|  | 216 |  | 
|  | 217 | trap "restore_values" SIGINT SIGTERM EXIT | 
|  | 218 |  | 
|  | 219 | cmd="echo 1 > /proc/self/make-it-fail && exec $@" | 
|  | 220 | bash -c "$cmd" |