xref: /OK3568_Linux_fs/kernel/tools/testing/fault-injection/failcmd.sh (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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