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