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 <[email protected]> ## 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 82ncpus_check() 83{ 84 if [ $NR_CPUS -lt $1 ]; then 85 tst_brkm TCONF "The total of CPUs is less than $1" 86 fi 87 # check online cpus whether match 0-num 88 if [ $final_cpu -eq $NR_CPUS ]; then 89 tst_resm TINFO "CPUs are numbered continuously starting at 0 ($cpu_string)" 90 else 91 tst_brkm TCONF "CPUs are not numbered continuously starting at 0 ($cpu_string)" 92 fi 93} 94 95nnodes_check() 96{ 97 if [ $N_NODES -lt $1 ]; then 98 tst_brkm TCONF "The total of nodes is less than $1" 99 fi 100 # check online nodes whether match 0-num 101 if [ $final_node -eq $N_NODES ]; then 102 tst_resm TINFO "Nodes are numbered continuously starting at 0 ($mem_string)" 103 else 104 tst_brkm TCONF "Nodes are not numbered continuously starting at 0 ($mem_string)" 105 fi 106} 107 108user_check() 109{ 110 if [ $(id -u) != 0 ]; then 111 tst_brkm TCONF "Test must be run as root" 112 fi 113} 114 115cpuset_check() 116{ 117 if [ -f /proc/cgroups ]; then 118 CPUSET_CONTROLLER=`grep -w cpuset /proc/cgroups | cut -f1` 119 CPUSET_CONTROLLER_VALUE=`grep -w cpuset /proc/cgroups | cut -f4` 120 121 if [ "$CPUSET_CONTROLLER" = "cpuset" ] && [ "$CPUSET_CONTROLLER_VALUE" = "1" ] 122 then 123 return 0 124 fi 125 fi 126 127 tst_brkm TCONF "Cpuset is not supported" 128} 129 130machine_check() 131{ 132 if tst_virt_hyperv; then 133 tst_brkm TCONF "Microsoft Hyper-V detected, no support for CPU hotplug" 134 fi 135} 136 137# optional parameters (pass both or none of them): 138# $1 - required number of cpus (default 2) 139# $2 - required number of memory nodes (default 2) 140check() 141{ 142 user_check 143 144 cpuset_check 145 146 ncpus_check ${1:-2} 147 148 nnodes_check ${2:-2} 149 150 machine_check 151} 152 153# Create /dev/cpuset & mount the cgroup file system with cpuset 154# clean any group created eralier (if any) 155setup() 156{ 157 if [ -e "$CPUSET" ] 158 then 159 tst_resm TWARN "$CPUSET already exist.. overwriting" 160 cleanup || tst_brkm TFAIL "Can't cleanup... Exiting" 161 fi 162 163 mkdir -p "$CPUSET_TMP" 164 mkdir "$CPUSET" 165 mount -t cgroup -o cpuset cpuset "$CPUSET" 2> /dev/null 166 if [ $? -ne 0 ]; then 167 cleanup 168 tst_brkm TCONF "Could not mount cgroup filesystem with cpuset on $CPUSET" 169 fi 170 171 CHILDREN_VALUE="`cat $CLONE_CHILDREN`" 172 SCHED_LB_VALUE="`cat $SCHED_LB`" 173} 174 175# Write the cleanup function 176cleanup() 177{ 178 grep "$CPUSET" /proc/mounts >/dev/null 2>&1 || { 179 rm -rf "$CPUSET" >/dev/null 2>&1 180 return 0 181 } 182 183 echo $CHILDREN_VALUE > $CLONE_CHILDREN 184 echo $SCHED_LB_VALUE > $SCHED_LB 185 186 find "$CPUSET" -type d | sort | sed -n '2,$p' | tac | while read -r subdir 187 do 188 while read pid 189 do 190 /bin/kill -9 $pid > /dev/null 2>&1 191 if [ $? -ne 0 ]; then 192 tst_brkm TFAIL "Couldn't kill task - "\ 193 "$pid in the cpuset" 194 fi 195 done < "$subdir/tasks" 196 rmdir "$subdir" 197 if [ $? -ne 0 ]; then 198 tst_brkm TFAIL "Couldn't remove subdir - " 199 "$subdir in the cpuset" 200 fi 201 done 202 203 umount "$CPUSET" 204 if [ $? -ne 0 ]; then 205 tst_brkm TFAIL "Couldn't umount cgroup filesystem with"\ 206 " cpuset on $CPUSET..Exiting test" 207 fi 208 rmdir "$CPUSET" > /dev/null 2>&1 209 rm -rf "$CPUSET_TMP" > /dev/null 2>&1 210} 211 212# set the cpuset's parameter 213# cpuset_set <cpusetpath> <cpus> <mems> <load_balance> 214cpuset_set() 215{ 216 local path="$1" 217 mkdir -p "$path" 218 if [ $? -ne 0 ]; then 219 return 1 220 fi 221 222 local cpus="$2" 223 local mems="$3" 224 local load_balance="$4" 225 226 if [ "$path" != "$CPUSET" ]; then 227 if [ "$cpus" != "-" ]; then 228 /bin/echo $cpus > $path/cpuset.cpus 229 if [ $? -ne 0 ]; then 230 return 1 231 fi 232 fi 233 234 /bin/echo $mems > $path/cpuset.mems 235 if [ $? -ne 0 ]; then 236 return 1 237 fi 238 fi 239 240 /bin/echo $load_balance > $path/cpuset.sched_load_balance 241 if [ $? -ne 0 ]; then 242 return 1 243 fi 244} 245 246# cpu_hotplug cpu_id offline/online 247cpu_hotplug() 248{ 249 if [ "$2" = "online" ]; then 250 /bin/echo 1 > "/sys/devices/system/cpu/cpu$1/online" 251 if [ $? -ne 0 ]; then 252 return 1 253 fi 254 elif [ "$2" = "offline" ]; then 255 /bin/echo 0 > "/sys/devices/system/cpu/cpu$1/online" 256 if [ $? -ne 0 ]; then 257 return 1 258 fi 259 fi 260} 261 262# setup_test_environment <online | offline> 263# online - online a CPU in testing, so we must offline a CPU first 264# offline - offline a CPU in testing, we needn't do anything 265setup_test_environment() 266{ 267 if [ "$1" = "online" ]; then 268 cpu_hotplug $HOTPLUG_CPU offline 269 if [ $? -ne 0 ]; then 270 return 1 271 fi 272 fi 273} 274 275cpu_hotplug_cleanup() 276{ 277 local cpus_array="$(seq -s' ' 1 $((NR_CPUS-1)))" 278 local cpuid= 279 for cpuid in $cpus_array 280 do 281 local file="/sys/devices/system/cpu/cpu$cpuid/online" 282 local offline="$(cat $file)" 283 if [ $offline -eq 0 ]; then 284 cpu_hotplug $cpuid "online" 285 fi 286 done 287} 288 289