mem-on-off-test.sh 5.9 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
#!/bin/bash

SYSFS=

prerequisite()
{
	msg="skip all tests:"

	if [ $UID != 0 ]; then
		echo $msg must be run as root >&2
		exit 0
	fi

	SYSFS=`mount -t sysfs | head -1 | awk '{ print $3 }'`

	if [ ! -d "$SYSFS" ]; then
		echo $msg sysfs is not mounted >&2
		exit 0
	fi

	if ! ls $SYSFS/devices/system/memory/memory* > /dev/null 2>&1; then
		echo $msg memory hotplug is not supported >&2
		exit 0
	fi
25 26 27 28 29

	if ! grep -q 1 $SYSFS/devices/system/memory/memory*/removable; then
		echo $msg no hot-pluggable memory >&2
		exit 0
	fi
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
}

#
# list all hot-pluggable memory
#
hotpluggable_memory()
{
	local state=${1:-.\*}

	for memory in $SYSFS/devices/system/memory/memory*; do
		if grep -q 1 $memory/removable &&
		   grep -q $state $memory/state; then
			echo ${memory##/*/memory}
		fi
	done
}

47
hotpluggable_offline_memory()
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
{
	hotpluggable_memory offline
}

hotpluggable_online_memory()
{
	hotpluggable_memory online
}

memory_is_online()
{
	grep -q online $SYSFS/devices/system/memory/memory$1/state
}

memory_is_offline()
{
	grep -q offline $SYSFS/devices/system/memory/memory$1/state
}

online_memory()
{
	echo online > $SYSFS/devices/system/memory/memory$1/state
}

offline_memory()
{
	echo offline > $SYSFS/devices/system/memory/memory$1/state
}

online_memory_expect_success()
{
	local memory=$1

	if ! online_memory $memory; then
		echo $FUNCNAME $memory: unexpected fail >&2
P
Po-Hsu Lin 已提交
83
		return 1
84 85
	elif ! memory_is_online $memory; then
		echo $FUNCNAME $memory: unexpected offline >&2
P
Po-Hsu Lin 已提交
86
		return 1
87
	fi
P
Po-Hsu Lin 已提交
88
	return 0
89 90 91 92 93 94 95 96
}

online_memory_expect_fail()
{
	local memory=$1

	if online_memory $memory 2> /dev/null; then
		echo $FUNCNAME $memory: unexpected success >&2
P
Po-Hsu Lin 已提交
97
		return 1
98 99
	elif ! memory_is_offline $memory; then
		echo $FUNCNAME $memory: unexpected online >&2
P
Po-Hsu Lin 已提交
100
		return 1
101
	fi
P
Po-Hsu Lin 已提交
102
	return 0
103 104 105 106 107 108 109 110
}

offline_memory_expect_success()
{
	local memory=$1

	if ! offline_memory $memory; then
		echo $FUNCNAME $memory: unexpected fail >&2
P
Po-Hsu Lin 已提交
111
		return 1
112 113
	elif ! memory_is_offline $memory; then
		echo $FUNCNAME $memory: unexpected offline >&2
P
Po-Hsu Lin 已提交
114
		return 1
115
	fi
P
Po-Hsu Lin 已提交
116
	return 0
117 118 119 120 121 122 123 124
}

offline_memory_expect_fail()
{
	local memory=$1

	if offline_memory $memory 2> /dev/null; then
		echo $FUNCNAME $memory: unexpected success >&2
P
Po-Hsu Lin 已提交
125
		return 1
126 127
	elif ! memory_is_online $memory; then
		echo $FUNCNAME $memory: unexpected offline >&2
P
Po-Hsu Lin 已提交
128
		return 1
129
	fi
P
Po-Hsu Lin 已提交
130
	return 0
131 132 133 134 135
}

error=-12
priority=0
ratio=10
P
Po-Hsu Lin 已提交
136
retval=0
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151

while getopts e:hp:r: opt; do
	case $opt in
	e)
		error=$OPTARG
		;;
	h)
		echo "Usage $0 [ -e errno ] [ -p notifier-priority ] [ -r percent-of-memory-to-offline ]"
		exit
		;;
	p)
		priority=$OPTARG
		;;
	r)
		ratio=$OPTARG
152 153 154 155
		if [ "$ratio" -gt 100 ] || [ "$ratio" -lt 0 ]; then
			echo "The percentage should be an integer within 0~100 range"
			exit 1
		fi
156 157 158 159 160 161 162 163 164 165 166
		;;
	esac
done

if ! [ "$error" -ge -4095 -a "$error" -lt 0 ]; then
	echo "error code must be -4095 <= errno < 0" >&2
	exit 1
fi

prerequisite

167 168
echo "Test scope: $ratio% hotplug memory"

169 170 171
#
# Online all hot-pluggable memory
#
P
Po-Hsu Lin 已提交
172 173 174 175 176 177 178 179 180 181 182 183
hotpluggable_num=`hotpluggable_offline_memory | wc -l`
echo -e "\t online all hot-pluggable memory in offline state:"
if [ "$hotpluggable_num" -gt 0 ]; then
	for memory in `hotpluggable_offline_memory`; do
		echo "offline->online memory$memory"
		if ! online_memory_expect_success $memory; then
			retval=1
		fi
	done
else
	echo -e "\t\t SKIPPED - no hot-pluggable memory in offline state"
fi
184 185 186 187

#
# Offline $ratio percent of hot-pluggable memory
#
P
Po-Hsu Lin 已提交
188 189 190 191
hotpluggable_num=`hotpluggable_online_memory | wc -l`
target=`echo "a=$hotpluggable_num*$ratio; if ( a%100 ) a/100+1 else a/100" | bc`
echo -e "\t offline $ratio% hot-pluggable memory in online state"
echo -e "\t trying to offline $target out of $hotpluggable_num memory block(s):"
192
for memory in `hotpluggable_online_memory`; do
P
Po-Hsu Lin 已提交
193 194 195 196 197
	if [ "$target" -gt 0 ]; then
		echo "online->offline memory$memory"
		if offline_memory_expect_success $memory; then
			target=$(($target - 1))
		fi
198 199
	fi
done
P
Po-Hsu Lin 已提交
200 201 202 203
if [ "$target" -gt 0 ]; then
	retval=1
	echo -e "\t\t FAILED - unable to offline some memory blocks, device busy?"
fi
204 205 206 207

#
# Online all hot-pluggable memory again
#
P
Po-Hsu Lin 已提交
208 209 210 211 212 213 214 215 216 217 218 219
hotpluggable_num=`hotpluggable_offline_memory | wc -l`
echo -e "\t online all hot-pluggable memory in offline state:"
if [ "$hotpluggable_num" -gt 0 ]; then
	for memory in `hotpluggable_offline_memory`; do
		echo "offline->online memory$memory"
		if ! online_memory_expect_success $memory; then
			retval=1
		fi
	done
else
	echo -e "\t\t SKIPPED - no hot-pluggable memory in offline state"
fi
220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236

#
# Test with memory notifier error injection
#

DEBUGFS=`mount -t debugfs | head -1 | awk '{ print $3 }'`
NOTIFIER_ERR_INJECT_DIR=$DEBUGFS/notifier-error-inject/memory

prerequisite_extra()
{
	msg="skip extra tests:"

	/sbin/modprobe -q -r memory-notifier-error-inject
	/sbin/modprobe -q memory-notifier-error-inject priority=$priority

	if [ ! -d "$DEBUGFS" ]; then
		echo $msg debugfs is not mounted >&2
P
Po-Hsu Lin 已提交
237
		exit $retval
238 239 240 241
	fi

	if [ ! -d $NOTIFIER_ERR_INJECT_DIR ]; then
		echo $msg memory-notifier-error-inject module is not available >&2
P
Po-Hsu Lin 已提交
242
		exit $retval
243 244 245
	fi
}

246
echo -e "\t Test with memory notifier error injection"
247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262
prerequisite_extra

#
# Offline $ratio percent of hot-pluggable memory
#
echo 0 > $NOTIFIER_ERR_INJECT_DIR/actions/MEM_GOING_OFFLINE/error
for memory in `hotpluggable_online_memory`; do
	if [ $((RANDOM % 100)) -lt $ratio ]; then
		offline_memory_expect_success $memory
	fi
done

#
# Test memory hot-add error handling (offline => online)
#
echo $error > $NOTIFIER_ERR_INJECT_DIR/actions/MEM_GOING_ONLINE/error
263
for memory in `hotpluggable_offline_memory`; do
264 265 266 267 268 269 270
	online_memory_expect_fail $memory
done

#
# Online all hot-pluggable memory
#
echo 0 > $NOTIFIER_ERR_INJECT_DIR/actions/MEM_GOING_ONLINE/error
271
for memory in `hotpluggable_offline_memory`; do
272 273 274 275 276 277 278 279 280 281 282 283 284
	online_memory_expect_success $memory
done

#
# Test memory hot-remove error handling (online => offline)
#
echo $error > $NOTIFIER_ERR_INJECT_DIR/actions/MEM_GOING_OFFLINE/error
for memory in `hotpluggable_online_memory`; do
	offline_memory_expect_fail $memory
done

echo 0 > $NOTIFIER_ERR_INJECT_DIR/actions/MEM_GOING_OFFLINE/error
/sbin/modprobe -q -r memory-notifier-error-inject
P
Po-Hsu Lin 已提交
285 286

exit $retval