Home | History | Annotate | Download | only in memory-hotplug
      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