Home | History | Annotate | Download | only in cpu-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 	taskset -p 01 $$
     15 
     16 	SYSFS=`mount -t sysfs | head -1 | awk '{ print $3 }'`
     17 
     18 	if [ ! -d "$SYSFS" ]; then
     19 		echo $msg sysfs is not mounted >&2
     20 		exit 0
     21 	fi
     22 
     23 	if ! ls $SYSFS/devices/system/cpu/cpu* > /dev/null 2>&1; then
     24 		echo $msg cpu hotplug is not supported >&2
     25 		exit 0
     26 	fi
     27 
     28 	echo "CPU online/offline summary:"
     29 	online_cpus=`cat $SYSFS/devices/system/cpu/online`
     30 	online_max=${online_cpus##*-}
     31 	echo -e "\t Cpus in online state: $online_cpus"
     32 
     33 	offline_cpus=`cat $SYSFS/devices/system/cpu/offline`
     34 	if [[ "a$offline_cpus" = "a" ]]; then
     35 		offline_cpus=0
     36 	else
     37 		offline_max=${offline_cpus##*-}
     38 	fi
     39 	echo -e "\t Cpus in offline state: $offline_cpus"
     40 }
     41 
     42 #
     43 # list all hot-pluggable CPUs
     44 #
     45 hotpluggable_cpus()
     46 {
     47 	local state=${1:-.\*}
     48 
     49 	for cpu in $SYSFS/devices/system/cpu/cpu*; do
     50 		if [ -f $cpu/online ] && grep -q $state $cpu/online; then
     51 			echo ${cpu##/*/cpu}
     52 		fi
     53 	done
     54 }
     55 
     56 hotplaggable_offline_cpus()
     57 {
     58 	hotpluggable_cpus 0
     59 }
     60 
     61 hotpluggable_online_cpus()
     62 {
     63 	hotpluggable_cpus 1
     64 }
     65 
     66 cpu_is_online()
     67 {
     68 	grep -q 1 $SYSFS/devices/system/cpu/cpu$1/online
     69 }
     70 
     71 cpu_is_offline()
     72 {
     73 	grep -q 0 $SYSFS/devices/system/cpu/cpu$1/online
     74 }
     75 
     76 online_cpu()
     77 {
     78 	echo 1 > $SYSFS/devices/system/cpu/cpu$1/online
     79 }
     80 
     81 offline_cpu()
     82 {
     83 	echo 0 > $SYSFS/devices/system/cpu/cpu$1/online
     84 }
     85 
     86 online_cpu_expect_success()
     87 {
     88 	local cpu=$1
     89 
     90 	if ! online_cpu $cpu; then
     91 		echo $FUNCNAME $cpu: unexpected fail >&2
     92 	elif ! cpu_is_online $cpu; then
     93 		echo $FUNCNAME $cpu: unexpected offline >&2
     94 	fi
     95 }
     96 
     97 online_cpu_expect_fail()
     98 {
     99 	local cpu=$1
    100 
    101 	if online_cpu $cpu 2> /dev/null; then
    102 		echo $FUNCNAME $cpu: unexpected success >&2
    103 	elif ! cpu_is_offline $cpu; then
    104 		echo $FUNCNAME $cpu: unexpected online >&2
    105 	fi
    106 }
    107 
    108 offline_cpu_expect_success()
    109 {
    110 	local cpu=$1
    111 
    112 	if ! offline_cpu $cpu; then
    113 		echo $FUNCNAME $cpu: unexpected fail >&2
    114 	elif ! cpu_is_offline $cpu; then
    115 		echo $FUNCNAME $cpu: unexpected offline >&2
    116 	fi
    117 }
    118 
    119 offline_cpu_expect_fail()
    120 {
    121 	local cpu=$1
    122 
    123 	if offline_cpu $cpu 2> /dev/null; then
    124 		echo $FUNCNAME $cpu: unexpected success >&2
    125 	elif ! cpu_is_online $cpu; then
    126 		echo $FUNCNAME $cpu: unexpected offline >&2
    127 	fi
    128 }
    129 
    130 error=-12
    131 allcpus=0
    132 priority=0
    133 online_cpus=0
    134 online_max=0
    135 offline_cpus=0
    136 offline_max=0
    137 
    138 while getopts e:ahp: opt; do
    139 	case $opt in
    140 	e)
    141 		error=$OPTARG
    142 		;;
    143 	a)
    144 		allcpus=1
    145 		;;
    146 	h)
    147 		echo "Usage $0 [ -a ] [ -e errno ] [ -p notifier-priority ]"
    148 		echo -e "\t default offline one cpu"
    149 		echo -e "\t run with -a option to offline all cpus"
    150 		exit
    151 		;;
    152 	p)
    153 		priority=$OPTARG
    154 		;;
    155 	esac
    156 done
    157 
    158 if ! [ "$error" -ge -4095 -a "$error" -lt 0 ]; then
    159 	echo "error code must be -4095 <= errno < 0" >&2
    160 	exit 1
    161 fi
    162 
    163 prerequisite
    164 
    165 #
    166 # Safe test (default) - offline and online one cpu
    167 #
    168 if [ $allcpus -eq 0 ]; then
    169 	echo "Limited scope test: one hotplug cpu"
    170 	echo -e "\t (leaves cpu in the original state):"
    171 	echo -e "\t online to offline to online: cpu $online_max"
    172 	offline_cpu_expect_success $online_max
    173 	online_cpu_expect_success $online_max
    174 
    175 	if [[ $offline_cpus -gt 0 ]]; then
    176 		echo -e "\t offline to online to offline: cpu $offline_max"
    177 		online_cpu_expect_success $offline_max
    178 		offline_cpu_expect_success $offline_max
    179 	fi
    180 	exit 0
    181 else
    182 	echo "Full scope test: all hotplug cpus"
    183 	echo -e "\t online all offline cpus"
    184 	echo -e "\t offline all online cpus"
    185 	echo -e "\t online all offline cpus"
    186 fi
    187 
    188 #
    189 # Online all hot-pluggable CPUs
    190 #
    191 for cpu in `hotplaggable_offline_cpus`; do
    192 	online_cpu_expect_success $cpu
    193 done
    194 
    195 #
    196 # Offline all hot-pluggable CPUs
    197 #
    198 for cpu in `hotpluggable_online_cpus`; do
    199 	offline_cpu_expect_success $cpu
    200 done
    201 
    202 #
    203 # Online all hot-pluggable CPUs again
    204 #
    205 for cpu in `hotplaggable_offline_cpus`; do
    206 	online_cpu_expect_success $cpu
    207 done
    208 
    209 #
    210 # Test with cpu notifier error injection
    211 #
    212 
    213 DEBUGFS=`mount -t debugfs | head -1 | awk '{ print $3 }'`
    214 NOTIFIER_ERR_INJECT_DIR=$DEBUGFS/notifier-error-inject/cpu
    215 
    216 prerequisite_extra()
    217 {
    218 	msg="skip extra tests:"
    219 
    220 	/sbin/modprobe -q -r cpu-notifier-error-inject
    221 	/sbin/modprobe -q cpu-notifier-error-inject priority=$priority
    222 
    223 	if [ ! -d "$DEBUGFS" ]; then
    224 		echo $msg debugfs is not mounted >&2
    225 		exit 0
    226 	fi
    227 
    228 	if [ ! -d $NOTIFIER_ERR_INJECT_DIR ]; then
    229 		echo $msg cpu-notifier-error-inject module is not available >&2
    230 		exit 0
    231 	fi
    232 }
    233 
    234 prerequisite_extra
    235 
    236 #
    237 # Offline all hot-pluggable CPUs
    238 #
    239 echo 0 > $NOTIFIER_ERR_INJECT_DIR/actions/CPU_DOWN_PREPARE/error
    240 for cpu in `hotpluggable_online_cpus`; do
    241 	offline_cpu_expect_success $cpu
    242 done
    243 
    244 #
    245 # Test CPU hot-add error handling (offline => online)
    246 #
    247 echo $error > $NOTIFIER_ERR_INJECT_DIR/actions/CPU_UP_PREPARE/error
    248 for cpu in `hotplaggable_offline_cpus`; do
    249 	online_cpu_expect_fail $cpu
    250 done
    251 
    252 #
    253 # Online all hot-pluggable CPUs
    254 #
    255 echo 0 > $NOTIFIER_ERR_INJECT_DIR/actions/CPU_UP_PREPARE/error
    256 for cpu in `hotplaggable_offline_cpus`; do
    257 	online_cpu_expect_success $cpu
    258 done
    259 
    260 #
    261 # Test CPU hot-remove error handling (online => offline)
    262 #
    263 echo $error > $NOTIFIER_ERR_INJECT_DIR/actions/CPU_DOWN_PREPARE/error
    264 for cpu in `hotpluggable_online_cpus`; do
    265 	offline_cpu_expect_fail $cpu
    266 done
    267 
    268 echo 0 > $NOTIFIER_ERR_INJECT_DIR/actions/CPU_DOWN_PREPARE/error
    269 /sbin/modprobe -q -r cpu-notifier-error-inject
    270