mem-on-off-test.sh 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. #!/bin/bash
  2. SYSFS=
  3. prerequisite()
  4. {
  5. msg="skip all tests:"
  6. if [ $UID != 0 ]; then
  7. echo $msg must be run as root >&2
  8. exit 0
  9. fi
  10. SYSFS=`mount -t sysfs | head -1 | awk '{ print $3 }'`
  11. if [ ! -d "$SYSFS" ]; then
  12. echo $msg sysfs is not mounted >&2
  13. exit 0
  14. fi
  15. if ! ls $SYSFS/devices/system/memory/memory* > /dev/null 2>&1; then
  16. echo $msg memory hotplug is not supported >&2
  17. exit 0
  18. fi
  19. }
  20. #
  21. # list all hot-pluggable memory
  22. #
  23. hotpluggable_memory()
  24. {
  25. local state=${1:-.\*}
  26. for memory in $SYSFS/devices/system/memory/memory*; do
  27. if grep -q 1 $memory/removable &&
  28. grep -q $state $memory/state; then
  29. echo ${memory##/*/memory}
  30. fi
  31. done
  32. }
  33. hotplaggable_offline_memory()
  34. {
  35. hotpluggable_memory offline
  36. }
  37. hotpluggable_online_memory()
  38. {
  39. hotpluggable_memory online
  40. }
  41. memory_is_online()
  42. {
  43. grep -q online $SYSFS/devices/system/memory/memory$1/state
  44. }
  45. memory_is_offline()
  46. {
  47. grep -q offline $SYSFS/devices/system/memory/memory$1/state
  48. }
  49. online_memory()
  50. {
  51. echo online > $SYSFS/devices/system/memory/memory$1/state
  52. }
  53. offline_memory()
  54. {
  55. echo offline > $SYSFS/devices/system/memory/memory$1/state
  56. }
  57. online_memory_expect_success()
  58. {
  59. local memory=$1
  60. if ! online_memory $memory; then
  61. echo $FUNCNAME $memory: unexpected fail >&2
  62. elif ! memory_is_online $memory; then
  63. echo $FUNCNAME $memory: unexpected offline >&2
  64. fi
  65. }
  66. online_memory_expect_fail()
  67. {
  68. local memory=$1
  69. if online_memory $memory 2> /dev/null; then
  70. echo $FUNCNAME $memory: unexpected success >&2
  71. elif ! memory_is_offline $memory; then
  72. echo $FUNCNAME $memory: unexpected online >&2
  73. fi
  74. }
  75. offline_memory_expect_success()
  76. {
  77. local memory=$1
  78. if ! offline_memory $memory; then
  79. echo $FUNCNAME $memory: unexpected fail >&2
  80. elif ! memory_is_offline $memory; then
  81. echo $FUNCNAME $memory: unexpected offline >&2
  82. fi
  83. }
  84. offline_memory_expect_fail()
  85. {
  86. local memory=$1
  87. if offline_memory $memory 2> /dev/null; then
  88. echo $FUNCNAME $memory: unexpected success >&2
  89. elif ! memory_is_online $memory; then
  90. echo $FUNCNAME $memory: unexpected offline >&2
  91. fi
  92. }
  93. error=-12
  94. priority=0
  95. ratio=10
  96. while getopts e:hp:r: opt; do
  97. case $opt in
  98. e)
  99. error=$OPTARG
  100. ;;
  101. h)
  102. echo "Usage $0 [ -e errno ] [ -p notifier-priority ] [ -r percent-of-memory-to-offline ]"
  103. exit
  104. ;;
  105. p)
  106. priority=$OPTARG
  107. ;;
  108. r)
  109. ratio=$OPTARG
  110. ;;
  111. esac
  112. done
  113. if ! [ "$error" -ge -4095 -a "$error" -lt 0 ]; then
  114. echo "error code must be -4095 <= errno < 0" >&2
  115. exit 1
  116. fi
  117. prerequisite
  118. echo "Test scope: $ratio% hotplug memory"
  119. echo -e "\t online all hotplug memory in offline state"
  120. echo -e "\t offline $ratio% hotplug memory in online state"
  121. echo -e "\t online all hotplug memory in offline state"
  122. #
  123. # Online all hot-pluggable memory
  124. #
  125. for memory in `hotplaggable_offline_memory`; do
  126. echo offline-online $memory
  127. online_memory_expect_success $memory
  128. done
  129. #
  130. # Offline $ratio percent of hot-pluggable memory
  131. #
  132. for memory in `hotpluggable_online_memory`; do
  133. if [ $((RANDOM % 100)) -lt $ratio ]; then
  134. echo online-offline $memory
  135. offline_memory_expect_success $memory
  136. fi
  137. done
  138. #
  139. # Online all hot-pluggable memory again
  140. #
  141. for memory in `hotplaggable_offline_memory`; do
  142. echo offline-online $memory
  143. online_memory_expect_success $memory
  144. done
  145. #
  146. # Test with memory notifier error injection
  147. #
  148. DEBUGFS=`mount -t debugfs | head -1 | awk '{ print $3 }'`
  149. NOTIFIER_ERR_INJECT_DIR=$DEBUGFS/notifier-error-inject/memory
  150. prerequisite_extra()
  151. {
  152. msg="skip extra tests:"
  153. /sbin/modprobe -q -r memory-notifier-error-inject
  154. /sbin/modprobe -q memory-notifier-error-inject priority=$priority
  155. if [ ! -d "$DEBUGFS" ]; then
  156. echo $msg debugfs is not mounted >&2
  157. exit 0
  158. fi
  159. if [ ! -d $NOTIFIER_ERR_INJECT_DIR ]; then
  160. echo $msg memory-notifier-error-inject module is not available >&2
  161. exit 0
  162. fi
  163. }
  164. prerequisite_extra
  165. #
  166. # Offline $ratio percent of hot-pluggable memory
  167. #
  168. echo 0 > $NOTIFIER_ERR_INJECT_DIR/actions/MEM_GOING_OFFLINE/error
  169. for memory in `hotpluggable_online_memory`; do
  170. if [ $((RANDOM % 100)) -lt $ratio ]; then
  171. offline_memory_expect_success $memory
  172. fi
  173. done
  174. #
  175. # Test memory hot-add error handling (offline => online)
  176. #
  177. echo $error > $NOTIFIER_ERR_INJECT_DIR/actions/MEM_GOING_ONLINE/error
  178. for memory in `hotplaggable_offline_memory`; do
  179. online_memory_expect_fail $memory
  180. done
  181. #
  182. # Online all hot-pluggable memory
  183. #
  184. echo 0 > $NOTIFIER_ERR_INJECT_DIR/actions/MEM_GOING_ONLINE/error
  185. for memory in `hotplaggable_offline_memory`; do
  186. online_memory_expect_success $memory
  187. done
  188. #
  189. # Test memory hot-remove error handling (online => offline)
  190. #
  191. echo $error > $NOTIFIER_ERR_INJECT_DIR/actions/MEM_GOING_OFFLINE/error
  192. for memory in `hotpluggable_online_memory`; do
  193. offline_memory_expect_fail $memory
  194. done
  195. echo 0 > $NOTIFIER_ERR_INJECT_DIR/actions/MEM_GOING_OFFLINE/error
  196. /sbin/modprobe -q -r memory-notifier-error-inject