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