failcmd.sh 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  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.txt 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. if [ $UID != 0 ]; then
  56. echo must be run as root >&2
  57. exit 1
  58. fi
  59. DEBUGFS=`mount -t debugfs | head -1 | awk '{ print $3}'`
  60. if [ ! -d "$DEBUGFS" ]; then
  61. echo debugfs is not mounted >&2
  62. exit 1
  63. fi
  64. FAILCMD_TYPE=${FAILCMD_TYPE:-failslab}
  65. FAULTATTR=$DEBUGFS/$FAILCMD_TYPE
  66. if [ ! -d $FAULTATTR ]; then
  67. echo $FAILCMD_TYPE is not available >&2
  68. exit 1
  69. fi
  70. LONGOPTS=probability:,interval:,times:,space:,verbose:,task-filter:
  71. LONGOPTS=$LONGOPTS,stacktrace-depth:,require-start:,require-end:
  72. LONGOPTS=$LONGOPTS,reject-start:,reject-end:,oom-kill-allocating-task:,help
  73. if [ $FAILCMD_TYPE = failslab ]; then
  74. LONGOPTS=$LONGOPTS,ignore-gfp-wait:,cache-filter:
  75. elif [ $FAILCMD_TYPE = fail_page_alloc ]; then
  76. LONGOPTS=$LONGOPTS,ignore-gfp-wait:,ignore-gfp-highmem:,min-order:
  77. fi
  78. TEMP=`getopt -o p:i:t:s:v:h --long $LONGOPTS -n 'failcmd.sh' -- "$@"`
  79. if [ $? != 0 ]; then
  80. usage
  81. exit 1
  82. fi
  83. eval set -- "$TEMP"
  84. fault_attr_default()
  85. {
  86. echo N > $FAULTATTR/task-filter
  87. echo 0 > $FAULTATTR/probability
  88. echo 1 > $FAULTATTR/times
  89. }
  90. fault_attr_default
  91. oom_kill_allocating_task_saved=`cat /proc/sys/vm/oom_kill_allocating_task`
  92. restore_values()
  93. {
  94. fault_attr_default
  95. echo $oom_kill_allocating_task_saved \
  96. > /proc/sys/vm/oom_kill_allocating_task
  97. }
  98. #
  99. # Default options
  100. #
  101. declare -i oom_kill_allocating_task=1
  102. declare task_filter=Y
  103. declare -i probability=1
  104. declare -i times=1
  105. while true; do
  106. case "$1" in
  107. -p|--probability)
  108. probability=$2
  109. shift 2
  110. ;;
  111. -i|--interval)
  112. echo $2 > $FAULTATTR/interval
  113. shift 2
  114. ;;
  115. -t|--times)
  116. times=$2
  117. shift 2
  118. ;;
  119. -s|--space)
  120. echo $2 > $FAULTATTR/space
  121. shift 2
  122. ;;
  123. -v|--verbose)
  124. echo $2 > $FAULTATTR/verbose
  125. shift 2
  126. ;;
  127. --task-filter)
  128. task_filter=$2
  129. shift 2
  130. ;;
  131. --stacktrace-depth)
  132. echo $2 > $FAULTATTR/stacktrace-depth
  133. shift 2
  134. ;;
  135. --require-start)
  136. echo $2 > $FAULTATTR/require-start
  137. shift 2
  138. ;;
  139. --require-end)
  140. echo $2 > $FAULTATTR/require-end
  141. shift 2
  142. ;;
  143. --reject-start)
  144. echo $2 > $FAULTATTR/reject-start
  145. shift 2
  146. ;;
  147. --reject-end)
  148. echo $2 > $FAULTATTR/reject-end
  149. shift 2
  150. ;;
  151. --oom-kill-allocating-task)
  152. oom_kill_allocating_task=$2
  153. shift 2
  154. ;;
  155. --ignore-gfp-wait)
  156. echo $2 > $FAULTATTR/ignore-gfp-wait
  157. shift 2
  158. ;;
  159. --cache-filter)
  160. echo $2 > $FAULTATTR/cache_filter
  161. shift 2
  162. ;;
  163. --ignore-gfp-highmem)
  164. echo $2 > $FAULTATTR/ignore-gfp-highmem
  165. shift 2
  166. ;;
  167. --min-order)
  168. echo $2 > $FAULTATTR/min-order
  169. shift 2
  170. ;;
  171. -h|--help)
  172. usage
  173. exit 0
  174. shift
  175. ;;
  176. --)
  177. shift
  178. break
  179. ;;
  180. esac
  181. done
  182. [ -z "$1" ] && exit 0
  183. echo $oom_kill_allocating_task > /proc/sys/vm/oom_kill_allocating_task
  184. echo $task_filter > $FAULTATTR/task-filter
  185. echo $probability > $FAULTATTR/probability
  186. echo $times > $FAULTATTR/times
  187. trap "restore_values" SIGINT SIGTERM EXIT
  188. cmd="echo 1 > /proc/self/make-it-fail && exec $@"
  189. bash -c "$cmd"