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