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 (at] cn.fujitsu.com> ## 24 ## ## 25 ################################################################################ 26 27 . test.sh 28 29 NR_CPUS=`tst_ncpus` 30 if [ -f "/sys/devices/system/node/has_high_memory" ]; then 31 N_NODES="`cat /sys/devices/system/node/has_high_memory`" 32 else 33 N_NODES="`cat /sys/devices/system/node/has_normal_memory`" 34 fi 35 N_NODES=${N_NODES#*-*} 36 N_NODES=$(($N_NODES + 1)) 37 38 CPUSET="/dev/cpuset" 39 CPUSET_TMP="/tmp/cpuset_tmp" 40 41 HOTPLUG_CPU="1" 42 43 cpuset_log() 44 { 45 tst_resm TINFO "$*" 46 } 47 48 # cpuset_log_error <error_file> 49 cpuset_log_error() 50 { 51 local error_message= 52 53 while read error_message 54 do 55 cpuset_log "$error_message" 56 done < "$1" 57 } 58 59 version_check() 60 { 61 if tst_kvcmp -lt "2.6.28"; then 62 tst_brkm TCONF "kernel is below 2.6.28" 63 fi 64 } 65 66 ncpus_check() 67 { 68 if [ $NR_CPUS -lt $1 ]; then 69 tst_brkm TCONF "The total of CPUs is less than $1" 70 fi 71 } 72 73 nnodes_check() 74 { 75 if [ $N_NODES -lt $1 ]; then 76 tst_brkm TCONF "The total of nodes is less than $1" 77 fi 78 } 79 80 user_check() 81 { 82 if [ $(id -u) != 0 ]; then 83 tst_brkm TCONF "Test must be run as root" 84 fi 85 } 86 87 cpuset_check() 88 { 89 if [ -f /proc/cgroups ]; then 90 CPUSET_CONTROLLER=`grep -w cpuset /proc/cgroups | cut -f1` 91 CPUSET_CONTROLLER_VALUE=`grep -w cpuset /proc/cgroups | cut -f4` 92 93 if [ "$CPUSET_CONTROLLER" = "cpuset" ] && [ "$CPUSET_CONTROLLER_VALUE" = "1" ] 94 then 95 return 0 96 fi 97 fi 98 99 tst_brkm TCONF "Cpuset is not supported" 100 } 101 102 # optional parameters (pass both or none of them): 103 # $1 - required number of cpus (default 2) 104 # $2 - required number of memory nodes (default 2) 105 check() 106 { 107 user_check 108 109 cpuset_check 110 111 version_check 112 113 ncpus_check ${1:-2} 114 115 nnodes_check ${2:-2} 116 117 } 118 119 # Create /dev/cpuset & mount the cgroup file system with cpuset 120 # clean any group created eralier (if any) 121 setup() 122 { 123 if [ -e "$CPUSET" ] 124 then 125 tst_resm TWARN "$CPUSET already exist.. overwriting" 126 cleanup || tst_brkm TFAIL "Can't cleanup... Exiting" 127 fi 128 129 mkdir -p "$CPUSET_TMP" 130 mkdir "$CPUSET" 131 mount -t cpuset cpuset "$CPUSET" 2> /dev/null 132 if [ $? -ne 0 ]; then 133 cleanup 134 tst_brkm TFAIL "Could not mount cgroup filesystem with"\ 135 " cpuset on $CPUSET..Exiting test" 136 fi 137 } 138 139 # Write the cleanup function 140 cleanup() 141 { 142 grep "$CPUSET" /proc/mounts >/dev/null 2>&1 || { 143 rm -rf "$CPUSET" >/dev/null 2>&1 144 return 0 145 } 146 147 find "$CPUSET" -type d | sort | sed -n '2,$p' | tac | while read subdir 148 do 149 while read pid 150 do 151 /bin/kill -9 $pid > /dev/null 2>&1 152 if [ $? -ne 0 ]; then 153 tst_brkm TFAIL "Couldn't kill task - "\ 154 "$pid in the cpuset" 155 fi 156 done < "$subdir/tasks" 157 rmdir "$subdir" 158 if [ $? -ne 0 ]; then 159 tst_brkm TFAIL "Couldn't remove subdir - " 160 "$subdir in the cpuset" 161 fi 162 done 163 164 umount "$CPUSET" 165 if [ $? -ne 0 ]; then 166 tst_brkm TFAIL "Couldn't umount cgroup filesystem with"\ 167 " cpuset on $CPUSET..Exiting test" 168 fi 169 rmdir "$CPUSET" > /dev/null 2>&1 170 rm -rf "$CPUSET_TMP" > /dev/null 2>&1 171 } 172 173 # set the cpuset's parameter 174 # cpuset_set <cpusetpath> <cpus> <mems> <load_balance> 175 cpuset_set() 176 { 177 local path="$1" 178 mkdir -p "$path" 179 if [ $? -ne 0 ]; then 180 return 1 181 fi 182 183 local cpus="$2" 184 local mems="$3" 185 local load_balance="$4" 186 187 if [ "$path" != "$CPUSET" ]; then 188 if [ "$cpus" != "-" ]; then 189 /bin/echo $cpus > $path/cpuset.cpus 190 if [ $? -ne 0 ]; then 191 return 1 192 fi 193 fi 194 195 /bin/echo $mems > $path/cpuset.mems 196 if [ $? -ne 0 ]; then 197 return 1 198 fi 199 fi 200 201 /bin/echo $load_balance > $path/cpuset.sched_load_balance 202 if [ $? -ne 0 ]; then 203 return 1 204 fi 205 } 206 207 # cpu_hotplug cpu_id offline/online 208 cpu_hotplug() 209 { 210 if [ "$2" = "online" ]; then 211 /bin/echo 1 > "/sys/devices/system/cpu/cpu$1/online" 212 if [ $? -ne 0 ]; then 213 return 1 214 fi 215 elif [ "$2" = "offline" ]; then 216 /bin/echo 0 > "/sys/devices/system/cpu/cpu$1/online" 217 if [ $? -ne 0 ]; then 218 return 1 219 fi 220 fi 221 } 222 223 # setup_test_environment <online | offline> 224 # online - online a CPU in testing, so we must offline a CPU first 225 # offline - offline a CPU in testing, we needn't do anything 226 setup_test_environment() 227 { 228 if [ "$1" = "online" ]; then 229 cpu_hotplug $HOTPLUG_CPU offline 230 if [ $? -ne 0 ]; then 231 return 1 232 fi 233 fi 234 } 235 236 cpu_hotplug_cleanup() 237 { 238 local cpus_array="$(seq -s' ' 1 $((NR_CPUS-1)))" 239 local cpuid= 240 for cpuid in $cpus_array 241 do 242 local file="/sys/devices/system/cpu/cpu$cpuid/online" 243 local offline="$(cat $file)" 244 if [ $offline -eq 0 ]; then 245 cpu_hotplug $cpuid "online" 246 fi 247 done 248 } 249 250