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