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