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