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