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