• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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