• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/bin/sh
2
3################################################################################
4##                                                                            ##
5## Copyright (c) 2015 SUSE                                                    ##
6##                                                                            ##
7## This program is free software;  you can redistribute it and#or modify      ##
8## it under the terms of the GNU General Public License as published by       ##
9## the Free Software Foundation; either version 2 of the License, or          ##
10## (at your option) any later version.                                        ##
11##                                                                            ##
12## This program is distributed in the hope that it will be useful, but        ##
13## WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ##
14## or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License   ##
15## for more details.                                                          ##
16##                                                                            ##
17## You should have received a copy of the GNU General Public License          ##
18## along with this program;  if not, write to the Free Software               ##
19## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301   ##
20## USA                                                                        ##
21##                                                                            ##
22## Author: Cedric Hnyda <chnyda@suse.com>                                     ##
23##                                                                            ##
24################################################################################
25
26# Usage
27# ./pids.sh caseno max
28#
29TST_CLEANUP=cleanup
30TST_SETUP=setup
31TST_TESTFUNC=do_test
32TST_POS_ARGS=3
33TST_USAGE=usage
34TST_NEEDS_ROOT=1
35TST_NEEDS_CMDS="killall"
36
37. tst_test.sh
38
39caseno=$1
40max=$2
41subcgroup_num=$3
42mounted=1
43
44usage()
45{
46	cat << EOF
47usage: $0 caseno max_processes
48
49caseno        - testcase number from interval 1-9
50max_processes - maximal number of processes to attach
51                (not applicable to testcase 5)
52subcgroup_num - number of subgroups created in group
53		(only applicable to testcase 7)
54OPTIONS
55EOF
56}
57
58cleanup()
59{
60	killall -9 pids_task2 >/dev/null 2>&1
61
62	tst_res TINFO "removing created directories"
63	rmdir $testpath
64	if [ "$mounted" -ne "1" ]; then
65		tst_res TINFO "Umounting pids"
66		umount $mount_point
67		rmdir $mount_point
68	fi
69}
70
71setup()
72{
73	exist=`grep -w pids /proc/cgroups | cut -f1`;
74	if [ "$exist" = "" ]; then
75		tst_brk TCONF NULL "pids not supported"
76	fi
77
78	mount_point=`grep -w pids /proc/mounts | cut -f 2 | cut -d " " -f2`
79
80	if [ "$mount_point" = "" ]; then
81		mounted=0
82		mount_point=/dev/cgroup
83	fi
84
85	testpath=$mount_point/ltp_pids_$caseno
86
87	if [ "$mounted" -eq "0" ]; then
88		ROD mkdir -p $mount_point
89		ROD mount -t cgroup -o pids none $mount_point
90	fi
91	ROD mkdir -p $testpath
92}
93
94start_pids_tasks2()
95{
96	start_pids_tasks2_path $testpath $1
97}
98
99start_pids_tasks2_path()
100{
101	path=$1
102	nb=$2
103	for i in `seq 1 $nb`; do
104		pids_task2 &
105		echo $! > $path/tasks
106	done
107
108	if [ $(cat "$path/tasks" | wc -l) -ne $nb ]; then
109		tst_brk TBROK "failed to attach process"
110	fi
111}
112
113stop_pids_tasks()
114{
115	stop_pids_tasks_path $testpath
116}
117
118stop_pids_tasks_path()
119{
120	local i
121	path=$1
122
123	for i in `cat $path/tasks`; do
124		ROD kill -9 $i
125		wait $i
126	done
127}
128
129case1()
130{
131	start_pids_tasks2 $max
132
133	# should return 0 because there is no limit
134	pids_task1 "$testpath/tasks"
135	ret=$?
136
137	if [ "$ret" -eq "2" ]; then
138		tst_res TFAIL "fork failed unexpectedly"
139	elif [ "$ret" -eq "0" ]; then
140		tst_res TPASS "fork didn't fail"
141	else
142		tst_res TBROK "pids_task1 failed"
143	fi
144
145	stop_pids_tasks
146}
147
148case2()
149{
150	tmp=$((max - 1))
151	tst_res TINFO "limit the number of pid to $max"
152	ROD echo $max \> $testpath/pids.max
153
154	start_pids_tasks2 $tmp
155
156	# should return 2 because the limit of pids is reached
157	pids_task1 "$testpath/tasks"
158	ret=$?
159
160	if [ "$ret" -eq "2" ]; then
161		tst_res TPASS "fork failed as expected"
162	elif [ "$ret" -eq "0" ]; then
163		tst_res TFAIL "fork didn't fail despite the limit"
164	else
165		tst_res TBROK "pids_task1 failed"
166	fi
167
168	stop_pids_tasks
169}
170
171case3()
172{
173	lim=$((max + 2))
174	tst_res TINFO "limit the number of avalaible pid to $lim"
175	ROD echo $lim \> $testpath/pids.max
176
177	start_pids_tasks2 $max
178
179	pids_task1 "$testpath/tasks"
180	ret=$?
181
182	if [ "$ret" -eq "2" ]; then
183		tst_res TFAIL "fork failed unexpectedly"
184	elif [ "$ret" -eq "0" ]; then
185		tst_res TPASS "fork worked as expected"
186	else
187		tst_res TBROK "pids_task1 failed"
188	fi
189
190	stop_pids_tasks
191}
192
193case4()
194{
195	tst_res TINFO "limit the number of avalaible pid to 0"
196	ROD echo 0 \> $testpath/pids.max
197
198	start_pids_tasks2 $max
199
200	tst_res TPASS "all process were attached"
201
202	stop_pids_tasks
203}
204
205case5()
206{
207	tst_res TINFO "try to limit the number of avalaible pid to -1"
208	echo -1 > $testpath/pids.max
209
210	if [ "$?" -eq "0" ]; then
211		tst_res TFAIL "managed to set the limit to -1"
212	else
213		tst_res TPASS "didn't manage to set the limit to -1"
214	fi
215}
216
217case6()
218{
219	tst_res TINFO "set a limit that is smaller than current number of pids"
220	start_pids_tasks2 $max
221
222	lim=$((max - 1))
223	ROD echo $lim \> $testpath/pids.max
224
225	pids_task1 "$testpath/tasks"
226	ret=$?
227
228	if [ "$ret" -eq "2" ]; then
229		tst_res TPASS "fork failed as expected"
230	elif [ "$ret" -eq "0" ]; then
231		tst_res TFAIL "fork didn't fail despite the limit"
232	else
233		tst_res TBROK "pids_task1 failed"
234	fi
235
236	stop_pids_tasks
237}
238
239case7()
240{
241	tst_res TINFO "the number of all child cgroup tasks larger than its parent limit"
242
243	lim=$((max / subcgroup_num))
244	if [ "$((lim * subcgroup_num))" -ne "$max" ]; then
245		tst_res TWARN "input max value must be a multiplier of $subcgroup_num"
246		return
247	fi
248
249	ROD echo $max \> $testpath/pids.max
250
251	for i in `seq 1 $subcgroup_num`; do
252		mkdir $testpath/child$i
253		start_pids_tasks2_path $testpath/child$i $lim
254	done
255
256	pids_task1 "$testpath/tasks"
257	ret=$?
258
259	if [ "$ret" -eq "2" ]; then
260		tst_res TPASS "parent cgroup fork failed as expected"
261	elif [ "$ret" -eq "0" ]; then
262		tst_res TFAIL "parent cgroup fork didn't fail despite the limit"
263	else
264		tst_res TBROK "parent cgroup pids_task1 failed"
265	fi
266
267	for i in `seq 1 $subcgroup_num`; do
268		pids_task1 "$testpath/child$i/tasks"
269		ret=$?
270
271		if [ "$ret" -eq "2" ]; then
272			tst_res TPASS "child$i cgroup fork failed as expected"
273		elif [ "$ret" -eq "0" ]; then
274			tst_res TFAIL "child$i cgroup fork didn't fail despite the limit"
275		else
276			tst_res TBROK "child$i cgroup pids_task1 failed"
277		fi
278	done
279
280	for i in `seq 1 $subcgroup_num`; do
281		stop_pids_tasks_path $testpath/child$i
282		rmdir $testpath/child$i
283	done
284
285	stop_pids_tasks
286}
287
288case8()
289{
290	tst_res TINFO "set child cgroup limit smaller than its parent limit"
291	ROD echo $max \> $testpath/pids.max
292	mkdir $testpath/child
293
294	lim=$((max - 1))
295	ROD echo $lim \> $testpath/child/pids.max
296	tmp=$((max - 2))
297	start_pids_tasks2_path $testpath/child $tmp
298
299	pids_task1 "$testpath/child/tasks"
300	ret=$?
301
302	if [ "$ret" -eq "2" ]; then
303		tst_res TPASS "fork failed as expected"
304	elif [ "$ret" -eq "0" ]; then
305		tst_res TFAIL "fork didn't fail despite the limit"
306	else
307		tst_res TBROK "pids_task1 failed"
308	fi
309
310	stop_pids_tasks_path $testpath/child
311	rmdir $testpath/child
312}
313
314case9()
315{
316	tst_res TINFO "migrate cgroup"
317	lim=$((max - 1))
318
319	for i in 1 2; do
320		mkdir $testpath/child$i
321		ROD echo $max \> $testpath/child$i/pids.max
322		start_pids_tasks2_path $testpath/child$i $lim
323	done
324
325	pid=`head -n 1 $testpath/child1/tasks`;
326	ROD echo $pid \> $testpath/child2/tasks
327
328	if grep -q "$pid" "$testpath/child2/tasks"; then
329		tst_res TPASS "migrate pid $pid from cgroup1 to cgroup2 as expected"
330	else
331		tst_res TPASS "migrate pid $pid from cgroup1 to cgroup2 failed"
332	fi
333
334	if [ $(cat "$testpath/child1/pids.current") -eq $((lim - 1)) ]; then
335		tst_res TPASS "migrate child1 cgroup as expected"
336	else
337		tst_res TFAIL "migrate child1 cgroup failed"
338	fi
339
340	if [ $(cat "$testpath/child2/pids.current") -eq $((lim + 1)) ]; then
341		tst_res TPASS "migrate child2 cgroup as expected"
342	else
343		tst_res TFAIL "migrate child2 cgroup failed"
344	fi
345
346	pids_task1 "$testpath/child1/tasks"
347	ret=$?
348
349	if [ "$ret" -eq "2" ]; then
350		tst_res TFAIL "child1 fork failed unexpectedly"
351	elif [ "$ret" -eq "0" ]; then
352		tst_res TPASS "child1 fork worked as expected"
353	else
354		tst_res TBROK "child1 pids_task1 failed"
355	fi
356
357	pids_task1 "$testpath/child2/tasks"
358	ret=$?
359
360	if [ "$ret" -eq "2" ]; then
361		tst_res TPASS "child2 fork failed as expected"
362	elif [ "$ret" -eq "0" ]; then
363		tst_res TFAIL "child2 fork didn't fail despite the limit"
364	else
365		tst_res TBROK "child2 pids_task1 failed"
366	fi
367
368	for i in 1 2; do
369		stop_pids_tasks_path $testpath/child$i
370		rmdir $testpath/child$i
371	done
372	stop_pids_tasks
373}
374
375do_test()
376{
377	tst_res TINFO "Running testcase $caseno with $max processes"
378	case$caseno
379}
380
381tst_run
382