1#!/bin/sh 2# usage: . cpuset_funcs.sh 3# functions for cpuset test 4 5################################################################################ 6## ## 7## Copyright (c) 2009 FUJITSU LIMITED ## 8## ## 9## This program is free software; you can redistribute it and#or modify ## 10## it under the terms of the GNU General Public License as published by ## 11## the Free Software Foundation; either version 2 of the License, or ## 12## (at your option) any later version. ## 13## ## 14## This program is distributed in the hope that it will be useful, but ## 15## WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ## 16## or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ## 17## for more details. ## 18## ## 19## You should have received a copy of the GNU General Public License ## 20## along with this program; if not, write to the Free Software ## 21## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ## 22## ## 23## Author: Miao Xie <miaox@cn.fujitsu.com> ## 24## ## 25################################################################################ 26 27. test.sh 28 29cpu_string="`cat /sys/devices/system/cpu/online`" 30NR_CPUS=`tst_ncpus` 31 32if [ -f "/sys/devices/system/node/has_high_memory" ]; then 33 mem_string="`cat /sys/devices/system/node/has_high_memory`" 34else 35 mem_string="`cat /sys/devices/system/node/has_normal_memory`" 36fi 37N_NODES="`echo $mem_string | tr ',' ' '`" 38count=0 39final_node=0 40for item in $N_NODES; do 41 delta=1 42 if [ "${item#*-*}" != "$item" ]; then 43 delta=$((${item#*-*} - ${item%*-*} + 1)) 44 fi 45 final_node=${item#*-*} 46 count=$((count + $delta)) 47done 48final_node=$((final_node + 1)) 49N_NODES=$count 50 51final_cpu=0 52N_CPUS="`echo $cpu_string | tr ',' ' '`" 53for item in $N_CPUS; do 54 final_cpu=${item#*-*} 55done 56final_cpu=$((final_cpu + 1)) 57 58CPUSET="/dev/cpuset" 59CPUSET_TMP="/tmp/cpuset_tmp" 60CLONE_CHILDREN="/dev/cpuset/cgroup.clone_children" 61CHILDREN_VALUE="0" 62HOTPLUG_CPU="1" 63SCHED_LB="/dev/cpuset/cpuset.sched_load_balance" 64SCHED_LB_VALUE="0" 65 66cpuset_log() 67{ 68 tst_resm TINFO "$*" 69} 70 71# cpuset_log_error <error_file> 72cpuset_log_error() 73{ 74 local error_message= 75 76 while read error_message 77 do 78 cpuset_log "$error_message" 79 done < "$1" 80} 81 82version_check() 83{ 84 if tst_kvcmp -lt "2.6.28"; then 85 tst_brkm TCONF "kernel is below 2.6.28" 86 fi 87} 88 89ncpus_check() 90{ 91 if [ $NR_CPUS -lt $1 ]; then 92 tst_brkm TCONF "The total of CPUs is less than $1" 93 fi 94 # check online cpus whether match 0-num 95 if [ $final_cpu -eq $NR_CPUS ]; then 96 tst_resm TINFO "CPUs are numbered continuously starting at 0 ($cpu_string)" 97 else 98 tst_brkm TCONF "CPUs are not numbered continuously starting at 0 ($cpu_string)" 99 fi 100} 101 102nnodes_check() 103{ 104 if [ $N_NODES -lt $1 ]; then 105 tst_brkm TCONF "The total of nodes is less than $1" 106 fi 107 # check online nodes whether match 0-num 108 if [ $final_node -eq $N_NODES ]; then 109 tst_resm TINFO "Nodes are numbered continuously starting at 0 ($mem_string)" 110 else 111 tst_brkm TCONF "Nodes are not numbered continuously starting at 0 ($mem_string)" 112 fi 113} 114 115user_check() 116{ 117 if [ $(id -u) != 0 ]; then 118 tst_brkm TCONF "Test must be run as root" 119 fi 120} 121 122cpuset_check() 123{ 124 if [ -f /proc/cgroups ]; then 125 CPUSET_CONTROLLER=`grep -w cpuset /proc/cgroups | cut -f1` 126 CPUSET_CONTROLLER_VALUE=`grep -w cpuset /proc/cgroups | cut -f4` 127 128 if [ "$CPUSET_CONTROLLER" = "cpuset" ] && [ "$CPUSET_CONTROLLER_VALUE" = "1" ] 129 then 130 return 0 131 fi 132 fi 133 134 tst_brkm TCONF "Cpuset is not supported" 135} 136 137machine_check() 138{ 139 if tst_virt_hyperv; then 140 tst_brkm TCONF "Microsoft Hyper-V detected, no support for CPU hotplug" 141 fi 142} 143 144# optional parameters (pass both or none of them): 145# $1 - required number of cpus (default 2) 146# $2 - required number of memory nodes (default 2) 147check() 148{ 149 user_check 150 151 cpuset_check 152 153 version_check 154 155 ncpus_check ${1:-2} 156 157 nnodes_check ${2:-2} 158 159 machine_check 160} 161 162# Create /dev/cpuset & mount the cgroup file system with cpuset 163# clean any group created eralier (if any) 164setup() 165{ 166 if [ -e "$CPUSET" ] 167 then 168 tst_resm TWARN "$CPUSET already exist.. overwriting" 169 cleanup || tst_brkm TFAIL "Can't cleanup... Exiting" 170 fi 171 172 mkdir -p "$CPUSET_TMP" 173 mkdir "$CPUSET" 174 mount -t cgroup -o cpuset cpuset "$CPUSET" 2> /dev/null 175 if [ $? -ne 0 ]; then 176 cleanup 177 tst_brkm TFAIL "Could not mount cgroup filesystem with"\ 178 " cpuset on $CPUSET..Exiting test" 179 fi 180 181 CHILDREN_VALUE="`cat $CLONE_CHILDREN`" 182 SCHED_LB_VALUE="`cat $SCHED_LB`" 183} 184 185# Write the cleanup function 186cleanup() 187{ 188 grep "$CPUSET" /proc/mounts >/dev/null 2>&1 || { 189 rm -rf "$CPUSET" >/dev/null 2>&1 190 return 0 191 } 192 193 echo $CHILDREN_VALUE > $CLONE_CHILDREN 194 echo $SCHED_LB_VALUE > $SCHED_LB 195 196 find "$CPUSET" -type d | sort | sed -n '2,$p' | tac | while read subdir 197 do 198 while read pid 199 do 200 /bin/kill -9 $pid > /dev/null 2>&1 201 if [ $? -ne 0 ]; then 202 tst_brkm TFAIL "Couldn't kill task - "\ 203 "$pid in the cpuset" 204 fi 205 done < "$subdir/tasks" 206 rmdir "$subdir" 207 if [ $? -ne 0 ]; then 208 tst_brkm TFAIL "Couldn't remove subdir - " 209 "$subdir in the cpuset" 210 fi 211 done 212 213 umount "$CPUSET" 214 if [ $? -ne 0 ]; then 215 tst_brkm TFAIL "Couldn't umount cgroup filesystem with"\ 216 " cpuset on $CPUSET..Exiting test" 217 fi 218 rmdir "$CPUSET" > /dev/null 2>&1 219 rm -rf "$CPUSET_TMP" > /dev/null 2>&1 220} 221 222# set the cpuset's parameter 223# cpuset_set <cpusetpath> <cpus> <mems> <load_balance> 224cpuset_set() 225{ 226 local path="$1" 227 mkdir -p "$path" 228 if [ $? -ne 0 ]; then 229 return 1 230 fi 231 232 local cpus="$2" 233 local mems="$3" 234 local load_balance="$4" 235 236 if [ "$path" != "$CPUSET" ]; then 237 if [ "$cpus" != "-" ]; then 238 /bin/echo $cpus > $path/cpuset.cpus 239 if [ $? -ne 0 ]; then 240 return 1 241 fi 242 fi 243 244 /bin/echo $mems > $path/cpuset.mems 245 if [ $? -ne 0 ]; then 246 return 1 247 fi 248 fi 249 250 /bin/echo $load_balance > $path/cpuset.sched_load_balance 251 if [ $? -ne 0 ]; then 252 return 1 253 fi 254} 255 256# cpu_hotplug cpu_id offline/online 257cpu_hotplug() 258{ 259 if [ "$2" = "online" ]; then 260 /bin/echo 1 > "/sys/devices/system/cpu/cpu$1/online" 261 if [ $? -ne 0 ]; then 262 return 1 263 fi 264 elif [ "$2" = "offline" ]; then 265 /bin/echo 0 > "/sys/devices/system/cpu/cpu$1/online" 266 if [ $? -ne 0 ]; then 267 return 1 268 fi 269 fi 270} 271 272# setup_test_environment <online | offline> 273# online - online a CPU in testing, so we must offline a CPU first 274# offline - offline a CPU in testing, we needn't do anything 275setup_test_environment() 276{ 277 if [ "$1" = "online" ]; then 278 cpu_hotplug $HOTPLUG_CPU offline 279 if [ $? -ne 0 ]; then 280 return 1 281 fi 282 fi 283} 284 285cpu_hotplug_cleanup() 286{ 287 local cpus_array="$(seq -s' ' 1 $((NR_CPUS-1)))" 288 local cpuid= 289 for cpuid in $cpus_array 290 do 291 local file="/sys/devices/system/cpu/cpu$cpuid/online" 292 local offline="$(cat $file)" 293 if [ $offline -eq 0 ]; then 294 cpu_hotplug $cpuid "online" 295 fi 296 done 297} 298 299