diff options
author | Akinobu Mita <akinobu.mita@gmail.com> | 2012-07-30 17:43:20 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-07-30 20:25:22 -0400 |
commit | c24aa64d169b7224f1a5bc6a4b1365da37ce861b (patch) | |
tree | e9974ad7a6edd7303c0b75d20fedcb7a7d5dd389 | |
parent | d89dffa976bcd13fd87eb76e02e3b71c3a7868e3 (diff) |
fault-injection: add tool to run command with failslab or fail_page_alloc
This adds tools/testing/fault-injection/failcmd.sh to run a command while
injecting slab/page allocation failures via fault injection.
Example:
Run a command "make -C tools/testing/selftests/ run_tests" with
injecting slab allocation failure.
# ./tools/testing/fault-injection/failcmd.sh \
-- make -C tools/testing/selftests/ run_tests
Same as above except to specify 100 times failures at most instead of
one time at most by default.
# ./tools/testing/fault-injection/failcmd.sh --times=100 \
-- make -C tools/testing/selftests/ run_tests
Same as above except to inject page allocation failure instead of slab
allocation failure.
# env FAILCMD_TYPE=fail_page_alloc \
./tools/testing/fault-injection/failcmd.sh --times=100 \
-- make -C tools/testing/selftests/ run_tests
Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | Documentation/fault-injection/fault-injection.txt | 27 | ||||
-rw-r--r-- | tools/testing/fault-injection/failcmd.sh | 219 |
2 files changed, 246 insertions, 0 deletions
diff --git a/Documentation/fault-injection/fault-injection.txt b/Documentation/fault-injection/fault-injection.txt index ba4be8b77093..4cf1a2a6bd72 100644 --- a/Documentation/fault-injection/fault-injection.txt +++ b/Documentation/fault-injection/fault-injection.txt | |||
@@ -240,3 +240,30 @@ trap "echo 0 > /sys/kernel/debug/$FAILTYPE/probability" SIGINT SIGTERM EXIT | |||
240 | echo "Injecting errors into the module $module... (interrupt to stop)" | 240 | echo "Injecting errors into the module $module... (interrupt to stop)" |
241 | sleep 1000000 | 241 | sleep 1000000 |
242 | 242 | ||
243 | Tool to run command with failslab or fail_page_alloc | ||
244 | ---------------------------------------------------- | ||
245 | In order to make it easier to accomplish the tasks mentioned above, we can use | ||
246 | tools/testing/fault-injection/failcmd.sh. Please run a command | ||
247 | "./tools/testing/fault-injection/failcmd.sh --help" for more information and | ||
248 | see the following examples. | ||
249 | |||
250 | Examples: | ||
251 | |||
252 | Run a command "make -C tools/testing/selftests/ run_tests" with injecting slab | ||
253 | allocation failure. | ||
254 | |||
255 | # ./tools/testing/fault-injection/failcmd.sh \ | ||
256 | -- make -C tools/testing/selftests/ run_tests | ||
257 | |||
258 | Same as above except to specify 100 times failures at most instead of one time | ||
259 | at most by default. | ||
260 | |||
261 | # ./tools/testing/fault-injection/failcmd.sh --times=100 \ | ||
262 | -- make -C tools/testing/selftests/ run_tests | ||
263 | |||
264 | Same as above except to inject page allocation failure instead of slab | ||
265 | allocation failure. | ||
266 | |||
267 | # env FAILCMD_TYPE=fail_page_alloc \ | ||
268 | ./tools/testing/fault-injection/failcmd.sh --times=100 \ | ||
269 | -- make -C tools/testing/selftests/ run_tests | ||
diff --git a/tools/testing/fault-injection/failcmd.sh b/tools/testing/fault-injection/failcmd.sh new file mode 100644 index 000000000000..1776e924b202 --- /dev/null +++ b/tools/testing/fault-injection/failcmd.sh | |||
@@ -0,0 +1,219 @@ | |||
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" | ||