1f08c3bdfSopenharmony_ci#!/bin/sh
2f08c3bdfSopenharmony_ci# SPDX-License-Identifier: GPL-2.0-or-later
3f08c3bdfSopenharmony_ci# Copyright (c) 2015 SUSE
4f08c3bdfSopenharmony_ci# Author: Cedric Hnyda <chnyda@suse.com>
5f08c3bdfSopenharmony_ci# Usage
6f08c3bdfSopenharmony_ci# ./pids.sh caseno max
7f08c3bdfSopenharmony_ci
8f08c3bdfSopenharmony_ciTST_CLEANUP=cleanup
9f08c3bdfSopenharmony_ciTST_SETUP=setup
10f08c3bdfSopenharmony_ciTST_TESTFUNC=do_test
11f08c3bdfSopenharmony_ciTST_POS_ARGS=3
12f08c3bdfSopenharmony_ciTST_USAGE=usage
13f08c3bdfSopenharmony_ciTST_NEEDS_ROOT=1
14f08c3bdfSopenharmony_ciTST_NEEDS_CMDS="killall"
15f08c3bdfSopenharmony_ci
16f08c3bdfSopenharmony_cicaseno=$1
17f08c3bdfSopenharmony_cimax=$2
18f08c3bdfSopenharmony_cisubcgroup_num=$3
19f08c3bdfSopenharmony_cimounted=1
20f08c3bdfSopenharmony_ci
21f08c3bdfSopenharmony_ciusage()
22f08c3bdfSopenharmony_ci{
23f08c3bdfSopenharmony_ci	cat << EOF
24f08c3bdfSopenharmony_ciusage: $0 caseno max_processes
25f08c3bdfSopenharmony_ci
26f08c3bdfSopenharmony_cicaseno        - testcase number from interval 1-9
27f08c3bdfSopenharmony_cimax_processes - maximal number of processes to attach
28f08c3bdfSopenharmony_ci                (not applicable to testcase 5)
29f08c3bdfSopenharmony_cisubcgroup_num - number of subgroups created in group
30f08c3bdfSopenharmony_ci		(only applicable to testcase 7)
31f08c3bdfSopenharmony_ciOPTIONS
32f08c3bdfSopenharmony_ciEOF
33f08c3bdfSopenharmony_ci}
34f08c3bdfSopenharmony_ci
35f08c3bdfSopenharmony_cicleanup()
36f08c3bdfSopenharmony_ci{
37f08c3bdfSopenharmony_ci	killall -9 pids_task2 >/dev/null 2>&1
38f08c3bdfSopenharmony_ci
39f08c3bdfSopenharmony_ci	cgroup_cleanup
40f08c3bdfSopenharmony_ci}
41f08c3bdfSopenharmony_ci
42f08c3bdfSopenharmony_cisetup()
43f08c3bdfSopenharmony_ci{
44f08c3bdfSopenharmony_ci	cgroup_require "pids"
45f08c3bdfSopenharmony_ci	cgroup_version=$(cgroup_get_version "pids")
46f08c3bdfSopenharmony_ci	testpath=$(cgroup_get_test_path "pids")
47f08c3bdfSopenharmony_ci	task_list=$(cgroup_get_task_list "pids")
48f08c3bdfSopenharmony_ci
49f08c3bdfSopenharmony_ci	tst_res TINFO "test starts with cgroup version $cgroup_version"
50f08c3bdfSopenharmony_ci}
51f08c3bdfSopenharmony_ci
52f08c3bdfSopenharmony_cistart_pids_tasks2()
53f08c3bdfSopenharmony_ci{
54f08c3bdfSopenharmony_ci	start_pids_tasks2_path $testpath $1
55f08c3bdfSopenharmony_ci}
56f08c3bdfSopenharmony_ci
57f08c3bdfSopenharmony_cistart_pids_tasks2_path()
58f08c3bdfSopenharmony_ci{
59f08c3bdfSopenharmony_ci	path=$1
60f08c3bdfSopenharmony_ci	nb=$2
61f08c3bdfSopenharmony_ci	for i in `seq 1 $nb`; do
62f08c3bdfSopenharmony_ci		pids_task2 &
63f08c3bdfSopenharmony_ci		echo $! > "$path/$task_list"
64f08c3bdfSopenharmony_ci	done
65f08c3bdfSopenharmony_ci
66f08c3bdfSopenharmony_ci	if [ $(wc -l < "$path/$task_list") -ne "$nb" ]; then
67f08c3bdfSopenharmony_ci		tst_brk TBROK "failed to attach process"
68f08c3bdfSopenharmony_ci	fi
69f08c3bdfSopenharmony_ci}
70f08c3bdfSopenharmony_ci
71f08c3bdfSopenharmony_cistop_pids_tasks()
72f08c3bdfSopenharmony_ci{
73f08c3bdfSopenharmony_ci	stop_pids_tasks_path $testpath
74f08c3bdfSopenharmony_ci}
75f08c3bdfSopenharmony_ci
76f08c3bdfSopenharmony_cistop_pids_tasks_path()
77f08c3bdfSopenharmony_ci{
78f08c3bdfSopenharmony_ci	local i
79f08c3bdfSopenharmony_ci	path=$1
80f08c3bdfSopenharmony_ci
81f08c3bdfSopenharmony_ci	for i in $(cat "$path/$task_list"); do
82f08c3bdfSopenharmony_ci		ROD kill -9 $i
83f08c3bdfSopenharmony_ci		wait $i
84f08c3bdfSopenharmony_ci	done
85f08c3bdfSopenharmony_ci}
86f08c3bdfSopenharmony_ci
87f08c3bdfSopenharmony_cicase1()
88f08c3bdfSopenharmony_ci{
89f08c3bdfSopenharmony_ci	start_pids_tasks2 $max
90f08c3bdfSopenharmony_ci
91f08c3bdfSopenharmony_ci	# should return 0 because there is no limit
92f08c3bdfSopenharmony_ci	pids_task1 "$testpath/$task_list"
93f08c3bdfSopenharmony_ci	ret=$?
94f08c3bdfSopenharmony_ci
95f08c3bdfSopenharmony_ci	if [ "$ret" -eq "2" ]; then
96f08c3bdfSopenharmony_ci		tst_res TFAIL "fork failed unexpectedly"
97f08c3bdfSopenharmony_ci	elif [ "$ret" -eq "0" ]; then
98f08c3bdfSopenharmony_ci		tst_res TPASS "fork didn't fail"
99f08c3bdfSopenharmony_ci	else
100f08c3bdfSopenharmony_ci		tst_res TBROK "pids_task1 failed"
101f08c3bdfSopenharmony_ci	fi
102f08c3bdfSopenharmony_ci
103f08c3bdfSopenharmony_ci	stop_pids_tasks
104f08c3bdfSopenharmony_ci}
105f08c3bdfSopenharmony_ci
106f08c3bdfSopenharmony_cicase2()
107f08c3bdfSopenharmony_ci{
108f08c3bdfSopenharmony_ci	tmp=$((max - 1))
109f08c3bdfSopenharmony_ci	tst_res TINFO "limit the number of pid to $max"
110f08c3bdfSopenharmony_ci	ROD echo $max \> $testpath/pids.max
111f08c3bdfSopenharmony_ci
112f08c3bdfSopenharmony_ci	start_pids_tasks2 $tmp
113f08c3bdfSopenharmony_ci
114f08c3bdfSopenharmony_ci	# should return 2 because the limit of pids is reached
115f08c3bdfSopenharmony_ci	pids_task1 "$testpath/$task_list"
116f08c3bdfSopenharmony_ci	ret=$?
117f08c3bdfSopenharmony_ci
118f08c3bdfSopenharmony_ci	if [ "$ret" -eq "2" ]; then
119f08c3bdfSopenharmony_ci		tst_res TPASS "fork failed as expected"
120f08c3bdfSopenharmony_ci	elif [ "$ret" -eq "0" ]; then
121f08c3bdfSopenharmony_ci		tst_res TFAIL "fork didn't fail despite the limit"
122f08c3bdfSopenharmony_ci	else
123f08c3bdfSopenharmony_ci		tst_res TBROK "pids_task1 failed"
124f08c3bdfSopenharmony_ci	fi
125f08c3bdfSopenharmony_ci
126f08c3bdfSopenharmony_ci	stop_pids_tasks
127f08c3bdfSopenharmony_ci}
128f08c3bdfSopenharmony_ci
129f08c3bdfSopenharmony_cicase3()
130f08c3bdfSopenharmony_ci{
131f08c3bdfSopenharmony_ci	lim=$((max + 2))
132f08c3bdfSopenharmony_ci	tst_res TINFO "limit the number of avalaible pid to $lim"
133f08c3bdfSopenharmony_ci	ROD echo $lim \> $testpath/pids.max
134f08c3bdfSopenharmony_ci
135f08c3bdfSopenharmony_ci	start_pids_tasks2 $max
136f08c3bdfSopenharmony_ci
137f08c3bdfSopenharmony_ci	pids_task1 "$testpath/$task_list"
138f08c3bdfSopenharmony_ci	ret=$?
139f08c3bdfSopenharmony_ci
140f08c3bdfSopenharmony_ci	if [ "$ret" -eq "2" ]; then
141f08c3bdfSopenharmony_ci		tst_res TFAIL "fork failed unexpectedly"
142f08c3bdfSopenharmony_ci	elif [ "$ret" -eq "0" ]; then
143f08c3bdfSopenharmony_ci		tst_res TPASS "fork worked as expected"
144f08c3bdfSopenharmony_ci	else
145f08c3bdfSopenharmony_ci		tst_res TBROK "pids_task1 failed"
146f08c3bdfSopenharmony_ci	fi
147f08c3bdfSopenharmony_ci
148f08c3bdfSopenharmony_ci	stop_pids_tasks
149f08c3bdfSopenharmony_ci}
150f08c3bdfSopenharmony_ci
151f08c3bdfSopenharmony_cicase4()
152f08c3bdfSopenharmony_ci{
153f08c3bdfSopenharmony_ci	tst_res TINFO "limit the number of avalaible pid to 0"
154f08c3bdfSopenharmony_ci	ROD echo 0 \> $testpath/pids.max
155f08c3bdfSopenharmony_ci
156f08c3bdfSopenharmony_ci	start_pids_tasks2 $max
157f08c3bdfSopenharmony_ci
158f08c3bdfSopenharmony_ci	tst_res TPASS "all process were attached"
159f08c3bdfSopenharmony_ci
160f08c3bdfSopenharmony_ci	stop_pids_tasks
161f08c3bdfSopenharmony_ci}
162f08c3bdfSopenharmony_ci
163f08c3bdfSopenharmony_cicase5()
164f08c3bdfSopenharmony_ci{
165f08c3bdfSopenharmony_ci	tst_res TINFO "try to limit the number of avalaible pid to -1"
166f08c3bdfSopenharmony_ci	echo -1 > $testpath/pids.max
167f08c3bdfSopenharmony_ci
168f08c3bdfSopenharmony_ci	if [ "$?" -eq "0" ]; then
169f08c3bdfSopenharmony_ci		tst_res TFAIL "managed to set the limit to -1"
170f08c3bdfSopenharmony_ci	else
171f08c3bdfSopenharmony_ci		tst_res TPASS "didn't manage to set the limit to -1"
172f08c3bdfSopenharmony_ci	fi
173f08c3bdfSopenharmony_ci}
174f08c3bdfSopenharmony_ci
175f08c3bdfSopenharmony_cicase6()
176f08c3bdfSopenharmony_ci{
177f08c3bdfSopenharmony_ci	tst_res TINFO "set a limit that is smaller than current number of pids"
178f08c3bdfSopenharmony_ci	start_pids_tasks2 $max
179f08c3bdfSopenharmony_ci
180f08c3bdfSopenharmony_ci	lim=$((max - 1))
181f08c3bdfSopenharmony_ci	ROD echo $lim \> $testpath/pids.max
182f08c3bdfSopenharmony_ci
183f08c3bdfSopenharmony_ci	pids_task1 "$testpath/$task_list"
184f08c3bdfSopenharmony_ci	ret=$?
185f08c3bdfSopenharmony_ci
186f08c3bdfSopenharmony_ci	if [ "$ret" -eq "2" ]; then
187f08c3bdfSopenharmony_ci		tst_res TPASS "fork failed as expected"
188f08c3bdfSopenharmony_ci	elif [ "$ret" -eq "0" ]; then
189f08c3bdfSopenharmony_ci		tst_res TFAIL "fork didn't fail despite the limit"
190f08c3bdfSopenharmony_ci	else
191f08c3bdfSopenharmony_ci		tst_res TBROK "pids_task1 failed"
192f08c3bdfSopenharmony_ci	fi
193f08c3bdfSopenharmony_ci
194f08c3bdfSopenharmony_ci	stop_pids_tasks
195f08c3bdfSopenharmony_ci}
196f08c3bdfSopenharmony_ci
197f08c3bdfSopenharmony_cicase7()
198f08c3bdfSopenharmony_ci{
199f08c3bdfSopenharmony_ci	tst_res TINFO "the number of all child cgroup tasks larger than its parent limit"
200f08c3bdfSopenharmony_ci
201f08c3bdfSopenharmony_ci	lim=$((max / subcgroup_num))
202f08c3bdfSopenharmony_ci	if [ "$((lim * subcgroup_num))" -ne "$max" ]; then
203f08c3bdfSopenharmony_ci		tst_res TWARN "input max value must be a multiplier of $subcgroup_num"
204f08c3bdfSopenharmony_ci		return
205f08c3bdfSopenharmony_ci	fi
206f08c3bdfSopenharmony_ci
207f08c3bdfSopenharmony_ci	ROD echo $max \> $testpath/pids.max
208f08c3bdfSopenharmony_ci
209f08c3bdfSopenharmony_ci	for i in `seq 1 $subcgroup_num`; do
210f08c3bdfSopenharmony_ci		mkdir $testpath/child$i
211f08c3bdfSopenharmony_ci		start_pids_tasks2_path $testpath/child$i $lim
212f08c3bdfSopenharmony_ci	done
213f08c3bdfSopenharmony_ci
214f08c3bdfSopenharmony_ci	pids_task1 "$testpath/$task_list"
215f08c3bdfSopenharmony_ci	ret=$?
216f08c3bdfSopenharmony_ci
217f08c3bdfSopenharmony_ci	if [ "$ret" -eq "2" ]; then
218f08c3bdfSopenharmony_ci		tst_res TPASS "parent cgroup fork failed as expected"
219f08c3bdfSopenharmony_ci	elif [ "$ret" -eq "0" ]; then
220f08c3bdfSopenharmony_ci		tst_res TFAIL "parent cgroup fork didn't fail despite the limit"
221f08c3bdfSopenharmony_ci	else
222f08c3bdfSopenharmony_ci		tst_res TBROK "parent cgroup pids_task1 failed"
223f08c3bdfSopenharmony_ci	fi
224f08c3bdfSopenharmony_ci
225f08c3bdfSopenharmony_ci	for i in `seq 1 $subcgroup_num`; do
226f08c3bdfSopenharmony_ci		pids_task1 "$testpath/child$i/$task_list"
227f08c3bdfSopenharmony_ci		ret=$?
228f08c3bdfSopenharmony_ci
229f08c3bdfSopenharmony_ci		if [ "$ret" -eq "2" ]; then
230f08c3bdfSopenharmony_ci			tst_res TPASS "child$i cgroup fork failed as expected"
231f08c3bdfSopenharmony_ci		elif [ "$ret" -eq "0" ]; then
232f08c3bdfSopenharmony_ci			tst_res TFAIL "child$i cgroup fork didn't fail despite the limit"
233f08c3bdfSopenharmony_ci		else
234f08c3bdfSopenharmony_ci			tst_res TBROK "child$i cgroup pids_task1 failed"
235f08c3bdfSopenharmony_ci		fi
236f08c3bdfSopenharmony_ci	done
237f08c3bdfSopenharmony_ci
238f08c3bdfSopenharmony_ci	for i in `seq 1 $subcgroup_num`; do
239f08c3bdfSopenharmony_ci		stop_pids_tasks_path $testpath/child$i
240f08c3bdfSopenharmony_ci		rmdir $testpath/child$i
241f08c3bdfSopenharmony_ci	done
242f08c3bdfSopenharmony_ci
243f08c3bdfSopenharmony_ci	stop_pids_tasks
244f08c3bdfSopenharmony_ci}
245f08c3bdfSopenharmony_ci
246f08c3bdfSopenharmony_cicase8()
247f08c3bdfSopenharmony_ci{
248f08c3bdfSopenharmony_ci	tst_res TINFO "set child cgroup limit smaller than its parent limit"
249f08c3bdfSopenharmony_ci	ROD echo $max \> $testpath/pids.max
250f08c3bdfSopenharmony_ci	if [ "$cgroup_version" = "2" ]; then
251f08c3bdfSopenharmony_ci		ROD echo +pids \> "$testpath"/cgroup.subtree_control
252f08c3bdfSopenharmony_ci	fi
253f08c3bdfSopenharmony_ci	mkdir $testpath/child
254f08c3bdfSopenharmony_ci
255f08c3bdfSopenharmony_ci	lim=$((max - 1))
256f08c3bdfSopenharmony_ci	ROD echo $lim \> $testpath/child/pids.max
257f08c3bdfSopenharmony_ci	tmp=$((max - 2))
258f08c3bdfSopenharmony_ci	start_pids_tasks2_path $testpath/child $tmp
259f08c3bdfSopenharmony_ci
260f08c3bdfSopenharmony_ci	pids_task1 "$testpath/child/$task_list"
261f08c3bdfSopenharmony_ci	ret=$?
262f08c3bdfSopenharmony_ci
263f08c3bdfSopenharmony_ci	if [ "$ret" -eq "2" ]; then
264f08c3bdfSopenharmony_ci		tst_res TPASS "fork failed as expected"
265f08c3bdfSopenharmony_ci	elif [ "$ret" -eq "0" ]; then
266f08c3bdfSopenharmony_ci		tst_res TFAIL "fork didn't fail despite the limit"
267f08c3bdfSopenharmony_ci	else
268f08c3bdfSopenharmony_ci		tst_res TBROK "pids_task1 failed"
269f08c3bdfSopenharmony_ci	fi
270f08c3bdfSopenharmony_ci
271f08c3bdfSopenharmony_ci	stop_pids_tasks_path $testpath/child
272f08c3bdfSopenharmony_ci	rmdir $testpath/child
273f08c3bdfSopenharmony_ci}
274f08c3bdfSopenharmony_ci
275f08c3bdfSopenharmony_cicase9()
276f08c3bdfSopenharmony_ci{
277f08c3bdfSopenharmony_ci	tst_res TINFO "migrate cgroup"
278f08c3bdfSopenharmony_ci	lim=$((max - 1))
279f08c3bdfSopenharmony_ci
280f08c3bdfSopenharmony_ci	if [ "$cgroup_version" = "2" ]; then
281f08c3bdfSopenharmony_ci		ROD echo +pids \> "$testpath"/cgroup.subtree_control
282f08c3bdfSopenharmony_ci	fi
283f08c3bdfSopenharmony_ci	for i in 1 2; do
284f08c3bdfSopenharmony_ci		mkdir $testpath/child$i
285f08c3bdfSopenharmony_ci		ROD echo $max \> $testpath/child$i/pids.max
286f08c3bdfSopenharmony_ci		start_pids_tasks2_path $testpath/child$i $lim
287f08c3bdfSopenharmony_ci	done
288f08c3bdfSopenharmony_ci
289f08c3bdfSopenharmony_ci	pid=`head -n 1 "$testpath/child1/$task_list"`;
290f08c3bdfSopenharmony_ci	ROD echo $pid \> "$testpath/child2/$task_list"
291f08c3bdfSopenharmony_ci
292f08c3bdfSopenharmony_ci	if grep -q "$pid" "$testpath/child2/$task_list"; then
293f08c3bdfSopenharmony_ci		tst_res TPASS "migrate pid $pid from cgroup1 to cgroup2 as expected"
294f08c3bdfSopenharmony_ci	else
295f08c3bdfSopenharmony_ci		tst_res TPASS "migrate pid $pid from cgroup1 to cgroup2 failed"
296f08c3bdfSopenharmony_ci	fi
297f08c3bdfSopenharmony_ci
298f08c3bdfSopenharmony_ci	if [ $(cat "$testpath/child1/pids.current") -eq $((lim - 1)) ]; then
299f08c3bdfSopenharmony_ci		tst_res TPASS "migrate child1 cgroup as expected"
300f08c3bdfSopenharmony_ci	else
301f08c3bdfSopenharmony_ci		tst_res TFAIL "migrate child1 cgroup failed"
302f08c3bdfSopenharmony_ci	fi
303f08c3bdfSopenharmony_ci
304f08c3bdfSopenharmony_ci	if [ $(cat "$testpath/child2/pids.current") -eq $((lim + 1)) ]; then
305f08c3bdfSopenharmony_ci		tst_res TPASS "migrate child2 cgroup as expected"
306f08c3bdfSopenharmony_ci	else
307f08c3bdfSopenharmony_ci		tst_res TFAIL "migrate child2 cgroup failed"
308f08c3bdfSopenharmony_ci	fi
309f08c3bdfSopenharmony_ci
310f08c3bdfSopenharmony_ci	pids_task1 "$testpath/child1/$task_list"
311f08c3bdfSopenharmony_ci	ret=$?
312f08c3bdfSopenharmony_ci
313f08c3bdfSopenharmony_ci	if [ "$ret" -eq "2" ]; then
314f08c3bdfSopenharmony_ci		tst_res TFAIL "child1 fork failed unexpectedly"
315f08c3bdfSopenharmony_ci	elif [ "$ret" -eq "0" ]; then
316f08c3bdfSopenharmony_ci		tst_res TPASS "child1 fork worked as expected"
317f08c3bdfSopenharmony_ci	else
318f08c3bdfSopenharmony_ci		tst_res TBROK "child1 pids_task1 failed"
319f08c3bdfSopenharmony_ci	fi
320f08c3bdfSopenharmony_ci
321f08c3bdfSopenharmony_ci	pids_task1 "$testpath/child2/$task_list"
322f08c3bdfSopenharmony_ci	ret=$?
323f08c3bdfSopenharmony_ci
324f08c3bdfSopenharmony_ci	if [ "$ret" -eq "2" ]; then
325f08c3bdfSopenharmony_ci		tst_res TPASS "child2 fork failed as expected"
326f08c3bdfSopenharmony_ci	elif [ "$ret" -eq "0" ]; then
327f08c3bdfSopenharmony_ci		tst_res TFAIL "child2 fork didn't fail despite the limit"
328f08c3bdfSopenharmony_ci	else
329f08c3bdfSopenharmony_ci		tst_res TBROK "child2 pids_task1 failed"
330f08c3bdfSopenharmony_ci	fi
331f08c3bdfSopenharmony_ci
332f08c3bdfSopenharmony_ci	for i in 1 2; do
333f08c3bdfSopenharmony_ci		stop_pids_tasks_path $testpath/child$i
334f08c3bdfSopenharmony_ci		rmdir $testpath/child$i
335f08c3bdfSopenharmony_ci	done
336f08c3bdfSopenharmony_ci	stop_pids_tasks
337f08c3bdfSopenharmony_ci}
338f08c3bdfSopenharmony_ci
339f08c3bdfSopenharmony_cido_test()
340f08c3bdfSopenharmony_ci{
341f08c3bdfSopenharmony_ci	tst_res TINFO "Running testcase $caseno with $max processes"
342f08c3bdfSopenharmony_ci	case$caseno
343f08c3bdfSopenharmony_ci}
344f08c3bdfSopenharmony_ci
345f08c3bdfSopenharmony_ci. cgroup_lib.sh
346f08c3bdfSopenharmony_citst_run
347