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