failcmd.sh 4.5 KB

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