• 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
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