GNU Linux-libre 4.19.286-gnu1
[releases.git] / tools / testing / fault-injection / failcmd.sh
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"