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