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 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 TFAIL "Could not mount cgroup filesystem with"\ 169 " cpuset on $CPUSET..Exiting test" 170 fi 171 172 CHILDREN_VALUE="`cat $CLONE_CHILDREN`" 173 SCHED_LB_VALUE="`cat $SCHED_LB`" 174} 175 176# Write the cleanup function 177cleanup() 178{ 179 grep "$CPUSET" /proc/mounts >/dev/null 2>&1 || { 180 rm -rf "$CPUSET" >/dev/null 2>&1 181 return 0 182 } 183 184 echo $CHILDREN_VALUE > $CLONE_CHILDREN 185 echo $SCHED_LB_VALUE > $SCHED_LB 186 187 find "$CPUSET" -type d | sort | sed -n '2,$p' | tac | while read -r subdir 188 do 189 while read pid 190 do 191 /bin/kill -9 $pid > /dev/null 2>&1 192 if [ $? -ne 0 ]; then 193 tst_brkm TFAIL "Couldn't kill task - "\ 194 "$pid in the cpuset" 195 fi 196 done < "$subdir/tasks" 197 rmdir "$subdir" 198 if [ $? -ne 0 ]; then 199 tst_brkm TFAIL "Couldn't remove subdir - " 200 "$subdir in the cpuset" 201 fi 202 done 203 204 umount "$CPUSET" 205 if [ $? -ne 0 ]; then 206 tst_brkm TFAIL "Couldn't umount cgroup filesystem with"\ 207 " cpuset on $CPUSET..Exiting test" 208 fi 209 rmdir "$CPUSET" > /dev/null 2>&1 210 rm -rf "$CPUSET_TMP" > /dev/null 2>&1 211} 212 213# set the cpuset's parameter 214# cpuset_set <cpusetpath> <cpus> <mems> <load_balance> 215cpuset_set() 216{ 217 local path="$1" 218 mkdir -p "$path" 219 if [ $? -ne 0 ]; then 220 return 1 221 fi 222 223 local cpus="$2" 224 local mems="$3" 225 local load_balance="$4" 226 227 if [ "$path" != "$CPUSET" ]; then 228 if [ "$cpus" != "-" ]; then 229 /bin/echo $cpus > $path/cpuset.cpus 230 if [ $? -ne 0 ]; then 231 return 1 232 fi 233 fi 234 235 /bin/echo $mems > $path/cpuset.mems 236 if [ $? -ne 0 ]; then 237 return 1 238 fi 239 fi 240 241 /bin/echo $load_balance > $path/cpuset.sched_load_balance 242 if [ $? -ne 0 ]; then 243 return 1 244 fi 245} 246 247# cpu_hotplug cpu_id offline/online 248cpu_hotplug() 249{ 250 if [ "$2" = "online" ]; then 251 /bin/echo 1 > "/sys/devices/system/cpu/cpu$1/online" 252 if [ $? -ne 0 ]; then 253 return 1 254 fi 255 elif [ "$2" = "offline" ]; then 256 /bin/echo 0 > "/sys/devices/system/cpu/cpu$1/online" 257 if [ $? -ne 0 ]; then 258 return 1 259 fi 260 fi 261} 262 263# setup_test_environment <online | offline> 264# online - online a CPU in testing, so we must offline a CPU first 265# offline - offline a CPU in testing, we needn't do anything 266setup_test_environment() 267{ 268 if [ "$1" = "online" ]; then 269 cpu_hotplug $HOTPLUG_CPU offline 270 if [ $? -ne 0 ]; then 271 return 1 272 fi 273 fi 274} 275 276cpu_hotplug_cleanup() 277{ 278 local cpus_array="$(seq -s' ' 1 $((NR_CPUS-1)))" 279 local cpuid= 280 for cpuid in $cpus_array 281 do 282 local file="/sys/devices/system/cpu/cpu$cpuid/online" 283 local offline="$(cat $file)" 284 if [ $offline -eq 0 ]; then 285 cpu_hotplug $cpuid "online" 286 fi 287 done 288} 289 290