cgroup_regression_test.sh revision 4548c6cf9bcdd96d8303caa4130ab638b61f8a30
1#! /bin/bash
2
3################################################################################
4##                                                                            ##
5## Copyright (c) 2009 FUJITSU LIMITED                                         ##
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 USA    ##
20##                                                                            ##
21## Author: Li Zefan <lizf@cn.fujitsu.com>                                     ##
22##                                                                            ##
23################################################################################
24
25cd $LTPROOT/testcases/bin
26
27export TCID="cgroup_regression_test"
28export TST_TOTAL=10
29export TST_COUNT=1
30
31tst_kvercmp 2 6 29
32if [ $? -eq 0 ]; then
33	tst_brkm TCONF ignored "test must be run with kernel 2.6.29 or newer"
34	exit 0
35elif [ ! -f /proc/cgroups ]; then
36	tst_brkm TCONF ignored "Kernel does not support for control groups; skipping testcases";
37	exit 0
38elif [ "x$(id -ru)" != x0 ]; then
39	tst_brkm TCONF ignored "Test must be run as root"
40	exit 0
41fi
42
43dmesg -c > /dev/null
44nr_bug=`dmesg | grep -c "kernel BUG"`
45nr_null=`dmesg | grep -c "kernel NULL pointer dereference"`
46nr_warning=`dmesg | grep -c "^WARNING"`
47nr_lockdep=`dmesg | grep -c "possible recursive locking detected"`
48
49# check_kernel_bug - check if some kind of kernel bug happened
50check_kernel_bug()
51{
52	new_bug=`dmesg | grep -c "kernel BUG"`
53	new_null=`dmesg | grep -c "kernel NULL pointer dereference"`
54	new_warning=`dmesg | grep -c "^WARNING"`
55	new_lockdep=`dmesg | grep -c "possible recursive locking detected"`
56
57	# no kernel bug is detected
58	if [ $new_bug -eq $nr_bug -a $new_warning -eq $nr_warning -a \
59	     $new_null -eq $nr_null -a $new_lockdep -eq $nr_lockdep ]; then
60		return 1
61	fi
62
63	# some kernel bug is detected
64	if [ $new_bug -gt $nr_bug ]; then
65		tst_resm TFAIL "kernel BUG was detected!"
66	fi
67	if [ $new_warning -gt $nr_warning ]; then
68		tst_resm TFAIL "kernel WARNING was detected!"
69	fi
70	if [ $new_null -gt $nr_null ]; then
71		tst_resm TFAIL "kernel NULL pointer dereference!"
72	fi
73	if [ $new_lockdep -gt $nr_lockdep ]; then
74		tst_resm TFAIL "kernel lockdep warning was detected!"
75	fi
76
77	nr_bug=$new_bug
78	nr_null=$new_null
79	nr_warning=$new_warning
80	nr_lockdep=$new_lockdep
81
82	echo "check_kernel_bug found something!"
83	dmesg
84	failed=1
85	return 0
86}
87
88#---------------------------------------------------------------------------
89# Bug:    There was a race when keeping forking processes and at the same
90#         time cat /cgroup/tasks (should be the very first time to read
91#         /cgroup/tasks, otherwise this bug won't be triggered)
92# Kernel: 2.6.24, 2.6.25-rcX
93# Links:  http://lkml.org/lkml/2007/10/17/224
94#         http://lkml.org/lkml/2008/3/5/332
95#         http://lkml.org/lkml/2008/4/16/493
96# Fix:    commit 0e04388f0189fa1f6812a8e1cb6172136eada87e
97#---------------------------------------------------------------------------
98test_1()
99{
100	./fork_processes &
101	sleep 1
102
103	mount -t cgroup -o none,name=foo cgroup cgroup/
104	if [ $? -ne 0 ]; then
105		tst_resm TFAIL "failed to mount cgroup filesystem"
106		failed=1
107		/bin/kill -SIGTERM $!
108		return
109	fi
110	cat cgroup/tasks > /dev/null
111
112	check_kernel_bug
113	if [ $? -eq 1 ]; then
114		tst_resm TPASS "no kernel bug was found"
115	fi
116
117	/bin/kill -SIGTERM $!
118	wait $!
119	umount cgroup/
120}
121
122#---------------------------------------------------------------------------
123# Bug:    a cgroup's notify_on_release flag did not inherit from its parent.
124# Kernel: 2.6.24-rcX
125# Links:  http://lkml.org/lkml/2008/2/25/12
126# Fix:    commit bc231d2a048010d5e0b49ac7fddbfa822fc41109
127#---------------------------------------------------------------------------
128test_2()
129{
130	mount -t cgroup -o none,name=foo cgroup cgroup/
131	if [ $? -ne 0 ]; then
132		tst_resm TFAIL "Failed to mount cgroup filesystem"
133		failed=1
134		return 1
135	fi
136
137	echo 0 > cgroup/notify_on_release
138	mkdir cgroup/0
139	val1=`cat cgroup/0/notify_on_release`
140
141	echo 1 > cgroup/notify_on_release
142	mkdir cgroup/1
143	val2=`cat cgroup/1/notify_on_release`
144
145	if [ $val1 -ne 0 -o $val2 -ne 1 ]; then
146		tst_resm TFAIL "wrong notify_on_release value"
147		failed=1
148	else
149		tst_resm TPASS "notify_on_release is inherited"
150	fi
151
152	rmdir cgroup/0 cgroup/1
153	umount cgroup/
154
155	return $failed
156}
157
158#---------------------------------------------------------------------------
159# Bug:    Accessing NULL cgrp->dentry when reading /proc/sched_debug
160# Kernel: 2.6.26-2.6.28
161# Links:  http://lkml.org/lkml/2008/10/30/44
162#         http://lkml.org/lkml/2008/12/12/107
163#         http://lkml.org/lkml/2008/12/16/481
164# Fix:    commit a47295e6bc42ad35f9c15ac66f598aa24debd4e2
165#---------------------------------------------------------------------------
166test_3()
167{
168	if [ ! -e /proc/sched_debug ]; then
169		tst_resm TCONF "CONFIG_SCHED_DEBUG is not enabled"
170		return
171	fi
172
173	grep -q -w "cpu" /proc/cgroups
174	if [ $? -ne 0 ]; then
175		tst_resm TCONF "CONFIG_CGROUP_SCHED is not enabled"
176		return
177	fi
178
179	# Run the test for 30 secs
180	mount -t cgroup -o cpu xxx cgroup/
181	if [ $? -ne 0 ]; then
182		tst_resm TFAIL "Failed to mount cpu subsys"
183		failed=1
184		return
185	fi
186
187	./test_3_1.sh &
188	pid1=$!
189	./test_3_2.sh &
190	pid2=$!
191
192	sleep 30
193	/bin/kill -SIGUSR1 $pid1 $pid2
194	wait $pid1
195	wait $pid2
196
197	check_kernel_bug
198	if [ $? -eq 1 ]; then
199		tst_resm TPASS "no kernel bug was found"
200	fi
201
202	rmdir cgroup/* 2> /dev/null
203	umount cgroup/
204}
205
206#---------------------------------------------------------------------------
207# Bug:    cgroup hierarchy lock's lockdep subclass may overflow
208# Kernel: 2.6.29-rcX
209# Link:   http://lkml.org/lkml/2009/2/4/67
210# Fix:
211#---------------------------------------------------------------------------
212test_4()
213{
214	if [ ! -e /proc/lockdep ]; then
215		tst_resm TCONF "CONFIG_LOCKDEP is not enabled"
216		return
217	fi
218
219	# MAX_LOCKDEP_SUBCLASSES is 8, so number of subsys should be > 8
220	lines=`cat /proc/cgroups | wc -l`
221	if [ $lines -le 9 ]; then
222		tst_resm TCONF "require more than 8 cgroup subsystems"
223		return
224	fi
225
226	mount -t cgroup -o none,name=foo cgroup cgroup/
227	mkdir cgroup/0
228	rmdir cgroup/0
229	umount cgroup/
230
231	dmesg | grep -q "MAX_LOCKDEP_SUBCLASSES too low"
232	if [ $? -eq 0 ]; then
233		tst_resm TFAIL "lockdep BUG was found"
234		failed=1
235		return
236	else
237		tst_resm TPASS "no lockdep BUG was found"
238	fi
239}
240
241#---------------------------------------------------------------------------
242# Bug:    When mount cgroup fs and the fs was busy, root_count should not be
243#         decremented in cgroup_kill_sb()
244# Kernel: 2.6.29-rcX
245# Links:  https://openvz.org/pipermail/devel/2009-January/016345.html
246#         http://lkml.org/lkml/2009/1/28/190
247# Fix:    commit 839ec5452ebfd5905b9c69b20ceb640903a8ea1a
248#---------------------------------------------------------------------------
249test_5()
250{
251	lines=`cat /proc/cgroups | wc -l`
252	if [ $lines -le 2 ]; then
253		tst_resm TCONF "require at least 2 cgroup subsystems"
254		return
255	fi
256
257	subsys1=`tail -n 1 /proc/cgroups | awk '{ print $1 }'`
258	subsys2=`tail -n 2 /proc/cgroups | head -1 | awk '{ print $1 }'`
259
260	mount -t cgroup -o $subsys1,$subsys2 xxx cgroup/
261	if [ $? -ne 0 ]; then
262		tst_resm TFAIL "mount $subsys1 and $subsys2 failed"
263		failed=1
264		return
265	fi
266
267	# This 2nd mount should fail
268	mount -t cgroup -o $subsys1 xxx cgroup/ 2> /dev/null
269	if [ $? -eq 0 ]; then
270		tst_resm TFAIL "mount $subsys1 should fail"
271		umount cgroup/
272		failed=1
273		return
274	fi
275
276	mkdir cgroup/0
277	# Otherwise we can't attach task
278	if [ "$subsys1" == cpuset -o "$subsys2" == cpuset ]; then
279		echo 0 > cgroup/0/cpuset.cpus 2> /dev/null
280		echo 0 > cgroup/0/cpuset.mems 2> /dev/null
281	fi
282
283	sleep 100 &
284	echo $! > cgroup/0/tasks
285
286	check_kernel_bug
287	if [ $? -eq 1 ]; then
288		tst_resm TPASS "no kernel bug was found"
289	fi
290
291	# clean up
292	/bin/kill -SIGTERM $! > /dev/null
293	wait $!
294	rmdir cgroup/0
295	umount cgroup/
296}
297
298#---------------------------------------------------------------------------
299# Bug:    There was a race between cgroup_clone and umount
300# Kernel: 2.6.24 - 2.6.28, 2.6.29-rcX
301# Links:  http://lkml.org/lkml/2008/12/24/124
302# Fix:    commit 7b574b7b0124ed344911f5d581e9bc2d83bbeb19
303#---------------------------------------------------------------------------
304test_6()
305{
306	grep -q -w "ns" /proc/cgroups
307	if [ $? -ne 0 ]; then
308		tst_resm TCONF "CONFIG_CGROUP_NS"
309		return
310	fi
311
312	# run the test for 30 secs
313	./test_6_1.sh &
314	pid1=$!
315	./test_6_2 &
316	pid2=$!
317
318	sleep 30
319	/bin/kill -SIGUSR1 $pid1
320	/bin/kill -SIGTERM $pid2
321	wait $pid1
322	wait $pid2
323
324	check_kernel_bug
325	if [ $? -eq 1 ]; then
326		tst_resm TPASS "no kernel bug was found"
327	fi
328
329	# clean up
330	mount -t cgroup -o ns xxx cgroup/ > /dev/null 2>&1
331	rmdir cgroup/[1-9]* > /dev/null 2>&1
332	umount cgroup/
333}
334
335#---------------------------------------------------------------------------
336# Bug:    There was a bug when remount cgroup fs with some dead subdirs in
337#         it (rmdir()ed but still has some refcnts on it). It caused memory
338#         leak, and may cause oops when cat /proc/sched_debug.
339# Kernel: 2.6.24 - 2.6.27, 2.6.28-rcX
340# Links:  http://lkml.org/lkml/2008/12/10/369
341# Fix:    commit 307257cf475aac25db30b669987f13d90c934e3a
342#---------------------------------------------------------------------------
343test_7_1()
344{
345	mount -t cgroup -o $subsys xxx cgroup/
346	if [ $? -ne 0 ]; then
347		tst_resm TFAIL "failed to mount $subsys"
348		failed=1
349		return
350	fi
351
352	mkdir cgroup/0
353	sleep 100 < cgroup/0 &	# add refcnt to this dir
354	rmdir cgroup/0
355
356	# remount with new subsystems added
357	# since 2.6.28, this remount will fail
358	mount -t cgroup -o remount xxx cgroup/ 2> /dev/null
359	/bin/kill -SIGTERM $!
360	wait $!
361	umount cgroup/
362}
363
364test_7_2()
365{
366	mount -t cgroup -o none,name=foo cgroup cgroup/
367	if [ $? -ne 0 ]; then
368		tst_resm TFAIL "failed to mount cgroup"
369		failed=1
370		return
371	fi
372
373	mkdir cgroup/0
374	sleep 100 < cgroup/0 &	# add refcnt to this dir
375	rmdir cgroup/0
376
377	# remount with some subsystems removed
378	# since 2.6.28, this remount will fail
379	mount -t cgroup -o remount,$subsys xxx cgroup/ 2> /dev/null
380	/bin/kill -SIGTERM $!
381	wait $!
382	umount cgroup/
383
384	# due to the bug, reading /proc/sched_debug may lead to oops
385	grep -q -w "cpu" /proc/cgroups
386	if [ $? -ne 0 -o ! -e /proc/sched_debug ]; then
387		return
388	fi
389
390	tmp=0
391	while [ $tmp -lt 50 ] ; do
392		echo 3 > /proc/sys/vm/drop_caches
393		cat /proc/sched_debug > /dev/null
394		: $(( tmp += 1 ))
395	done
396}
397
398test_7()
399{
400	lines=`cat /proc/cgroups | wc -l`
401	if [ $lines -le 2 ]; then
402		tst_resm TCONF "require at least 2 cgroup subsystems"
403		slt_result $SLT_Untested
404		return
405	fi
406
407	subsys=`tail -n 1 /proc/cgroups | awk '{ print $1 }'`
408
409	# remount to add new subsystems to the hierarchy
410	i=1
411	while [ $i -le 2 ] ; do
412		test_7_$i
413		if [ $? -ne 0 ]; then
414			return
415		fi
416
417		check_kernel_bug
418		if [ $? -eq 0 ]; then
419			return
420		fi
421		: $(( i += 1 ))
422	done
423
424	tst_resm TPASS "no kernel bug was found"
425}
426
427#---------------------------------------------------------------------------
428# Bug:    oops when get cgroupstat of a cgroup control file
429# Kernel: 2.6.24 - 2.6.27, 2.6.28-rcX
430# Links:  http://lkml.org/lkml/2008/11/19/53
431# Fix:    commit 33d283bef23132c48195eafc21449f8ba88fce6b
432#---------------------------------------------------------------------------
433test_8()
434{
435	mount -t cgroup -o none,name=foo cgroup cgroup/
436	if [ $? -ne 0 ]; then
437		tst_resm TFAIL "failed to mount cgroup filesystem"
438		failed=1
439		return
440	fi
441
442	./getdelays -C cgroup/tasks > /dev/null 2>&1
443	if [ $? -eq 0 ]; then
444		tst_resm TFAIL "should have failed to get cgroupstat of tasks file"
445		umount cgroup/
446		failed=1
447		return
448	fi
449
450	check_kernel_bug
451	if [ $? -eq 1 ]; then
452		tst_resm TPASS "no kernel bug was found"
453	fi
454
455	umount cgroup/
456}
457
458#---------------------------------------------------------------------------
459# Bug:    When running 2 concurrent mount/umount threads, lockdep warning
460#         may be triggered, it's a false positive, and it's VFS' issue but
461#         not cgroup.
462# Kernel: 2.6.24 - 2.6.29-rcX
463# Links:  http://lkml.org/lkml/2009/1/4/352
464# Fix:    commit ada723dcd681e2dffd7d73345cc8fda0eb0df9bd
465#---------------------------------------------------------------------------
466test_9()
467{
468	./test_9_1.sh &
469	pid1=$!
470	./test_9_2.sh &
471	pid2=$!
472
473	sleep 30
474	/bin/kill -SIGUSR1 $pid1 $pid2
475	wait $pid1
476	wait $pid2
477
478	umount cgroup/ 2> /dev/null
479
480	check_kernel_bug
481	if [ $? -eq 1 ]; then
482		tst_resm TPASS "no kernel warning was found"
483	fi
484}
485
486#---------------------------------------------------------------------------
487# Bug:    When running 2 concurrent mount/umount threads, kernel WARNING
488#         may be triggered, but it's VFS' issue but not cgroup.
489# Kernel: 2.6.24 - 2.6.29-rcX
490# Links:  http://lkml.org/lkml/2009/1/4/354
491# Fix:    commit 1a88b5364b535edaa321d70a566e358390ff0872
492#---------------------------------------------------------------------------
493test_10()
494{
495	./test_10_1.sh &
496	pid1=$!
497	./test_10_2.sh &
498	pid2=$!
499
500	sleep 30
501	/bin/kill -SIGUSR1 $pid1 $pid2
502	wait $pid1
503	wait $pid2
504
505	mount -t cgroup none cgroup 2> /dev/null
506	rmdir cgroup/0
507	umount cgroup/
508
509	check_kernel_bug
510	if [ $? -eq 1 ]; then
511		tst_resm TPASS "no kernel warning was found"
512	fi
513}
514
515# main
516
517mkdir cgroup/
518
519for ((cur = 1; cur <= $TST_TOTAL; cur++))
520{
521	export TST_COUNT=$cur
522
523	test_$cur
524}
525
526rmdir cgroup/
527
528exit $failed
529
530