Home | History | Annotate | Download | only in cpuset
      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