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 elif ! cpu_is_online $cpu; then 93 echo $FUNCNAME $cpu: unexpected offline >&2 94 fi 95} 96 97online_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 108offline_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 119offline_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 130error=-12 131allcpus=0 132priority=0 133online_cpus=0 134online_max=0 135offline_cpus=0 136offline_max=0 137 138while 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 156done 157 158if ! [ "$error" -ge -4095 -a "$error" -lt 0 ]; then 159 echo "error code must be -4095 <= errno < 0" >&2 160 exit 1 161fi 162 163prerequisite 164 165# 166# Safe test (default) - offline and online one cpu 167# 168if [ $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 181else 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" 186fi 187 188# 189# Online all hot-pluggable CPUs 190# 191for cpu in `hotplaggable_offline_cpus`; do 192 online_cpu_expect_success $cpu 193done 194 195# 196# Offline all hot-pluggable CPUs 197# 198for cpu in `hotpluggable_online_cpus`; do 199 offline_cpu_expect_success $cpu 200done 201 202# 203# Online all hot-pluggable CPUs again 204# 205for cpu in `hotplaggable_offline_cpus`; do 206 online_cpu_expect_success $cpu 207done 208 209# 210# Test with cpu notifier error injection 211# 212 213DEBUGFS=`mount -t debugfs | head -1 | awk '{ print $3 }'` 214NOTIFIER_ERR_INJECT_DIR=$DEBUGFS/notifier-error-inject/cpu 215 216prerequisite_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 234prerequisite_extra 235 236# 237# Offline all hot-pluggable CPUs 238# 239echo 0 > $NOTIFIER_ERR_INJECT_DIR/actions/CPU_DOWN_PREPARE/error 240for cpu in `hotpluggable_online_cpus`; do 241 offline_cpu_expect_success $cpu 242done 243 244# 245# Test CPU hot-add error handling (offline => online) 246# 247echo $error > $NOTIFIER_ERR_INJECT_DIR/actions/CPU_UP_PREPARE/error 248for cpu in `hotplaggable_offline_cpus`; do 249 online_cpu_expect_fail $cpu 250done 251 252# 253# Online all hot-pluggable CPUs 254# 255echo 0 > $NOTIFIER_ERR_INJECT_DIR/actions/CPU_UP_PREPARE/error 256for cpu in `hotplaggable_offline_cpus`; do 257 online_cpu_expect_success $cpu 258done 259 260# 261# Test CPU hot-remove error handling (online => offline) 262# 263echo $error > $NOTIFIER_ERR_INJECT_DIR/actions/CPU_DOWN_PREPARE/error 264for cpu in `hotpluggable_online_cpus`; do 265 offline_cpu_expect_fail $cpu 266done 267 268echo 0 > $NOTIFIER_ERR_INJECT_DIR/actions/CPU_DOWN_PREPARE/error 269/sbin/modprobe -q -r cpu-notifier-error-inject 270