| #!/bin/sh |
| # SPDX-License-Identifier: GPL-2.0-or-later |
| # Copyright (c) 2019 Petr Vorel <pvorel@suse.cz> |
| # Copyright (c) 2009 FUJITSU LIMITED |
| # Author: Li Zefan <lizf@cn.fujitsu.com> |
| |
| TST_TESTFUNC=test |
| TST_SETUP=do_setup |
| TST_CLEANUP=do_cleanup |
| TST_CNT=10 |
| TST_NEEDS_ROOT=1 |
| TST_NEEDS_TMPDIR=1 |
| TST_NEEDS_CMDS="awk dmesg find mountpoint rmdir" |
| |
| . cgroup_lib.sh |
| |
| do_setup() |
| { |
| mkdir cgroup/ |
| |
| if tst_kvcmp -lt "2.6.29"; then |
| tst_brk TCONF ignored "test must be run with kernel 2.6.29 or newer" |
| fi |
| |
| if [ ! -f /proc/cgroups ]; then |
| tst_brk TCONF ignored "Kernel does not support for control groups; skipping testcases"; |
| fi |
| |
| dmesg -c > /dev/null |
| NR_BUG=`dmesg | grep -c "kernel BUG"` |
| NR_NULL=`dmesg | grep -c "kernel NULL pointer dereference"` |
| NR_WARNING=`dmesg | grep -c "^WARNING"` |
| NR_LOCKDEP=`dmesg | grep -c "possible recursive locking detected"` |
| } |
| |
| do_cleanup() |
| { |
| if mountpoint -q cgroup/; then |
| find cgroup/ -maxdepth 1 -depth -exec rmdir {} + |
| umount cgroup |
| rmdir cgroup |
| fi |
| } |
| |
| check_kernel_bug() |
| { |
| local id="$1" |
| local ok_msg="no kernel bug was found" |
| local new_bug=`dmesg | grep -c "kernel BUG"` |
| local new_null=`dmesg | grep -c "kernel NULL pointer dereference"` |
| local new_warning=`dmesg | grep -c "^WARNING"` |
| local new_lockdep=`dmesg | grep -c "possible recursive locking detected"` |
| |
| [ "$id" ] && ok_msg="$ok_msg for test $i" |
| |
| # no kernel bug is detected |
| if [ $new_bug -eq $NR_BUG -a $new_warning -eq $NR_WARNING -a \ |
| $new_null -eq $NR_NULL -a $new_lockdep -eq $NR_LOCKDEP ]; then |
| tst_res TPASS $ok_msg |
| return 0 |
| fi |
| |
| # some kernel bug is detected |
| if [ $new_bug -gt $NR_BUG ]; then |
| tst_res TFAIL "kernel BUG was detected!" |
| fi |
| if [ $new_warning -gt $NR_WARNING ]; then |
| tst_res TFAIL "kernel WARNING was detected!" |
| fi |
| if [ $new_null -gt $NR_NULL ]; then |
| tst_res TFAIL "kernel NULL pointer dereference!" |
| fi |
| if [ $new_lockdep -gt $NR_LOCKDEP ]; then |
| tst_res TFAIL "kernel lockdep warning was detected!" |
| fi |
| |
| NR_BUG=$new_bug |
| NR_NULL=$new_null |
| NR_WARNING=$new_warning |
| NR_LOCKDEP=$new_lockdep |
| |
| tst_res TWARN "BUG FOUND!" |
| dmesg |
| return 1 |
| } |
| |
| #--------------------------------------------------------------------------- |
| # Bug: There was a race when keeping forking processes and at the same |
| # time cat /cgroup/tasks (should be the very first time to read |
| # /cgroup/tasks, otherwise this bug won't be triggered) |
| # Kernel: 2.6.24, 2.6.25-rcX |
| # Links: http://lkml.org/lkml/2007/10/17/224 |
| # http://lkml.org/lkml/2008/3/5/332 |
| # http://lkml.org/lkml/2008/4/16/493 |
| # Fix: commit 0e04388f0189fa1f6812a8e1cb6172136eada87e |
| #--------------------------------------------------------------------------- |
| test1() |
| { |
| cgroup_regression_fork_processes & |
| sleep 1 |
| |
| mount -t cgroup -o none,name=foo cgroup cgroup/ |
| if [ $? -ne 0 ]; then |
| tst_res TFAIL "failed to mount cgroup filesystem" |
| kill -TERM $! |
| return |
| fi |
| cat cgroup/tasks > /dev/null |
| |
| kill -TERM $! |
| wait $! 2>/dev/null |
| umount cgroup |
| check_kernel_bug |
| } |
| |
| #--------------------------------------------------------------------------- |
| # Bug: a cgroup's notify_on_release flag did not inherit from its parent. |
| # Kernel: 2.6.24-rcX |
| # Links: http://lkml.org/lkml/2008/2/25/12 |
| # Fix: commit bc231d2a048010d5e0b49ac7fddbfa822fc41109 |
| #--------------------------------------------------------------------------- |
| test2() |
| { |
| local val1 |
| local val2 |
| |
| mount -t cgroup -o none,name=foo cgroup cgroup/ |
| if [ $? -ne 0 ]; then |
| tst_res TFAIL "Failed to mount cgroup filesystem" |
| return |
| fi |
| |
| echo 0 > cgroup/notify_on_release |
| mkdir cgroup/0 |
| val1=`cat cgroup/0/notify_on_release` |
| |
| echo 1 > cgroup/notify_on_release |
| mkdir cgroup/1 |
| val2=`cat cgroup/1/notify_on_release` |
| |
| if [ $val1 -ne 0 -o $val2 -ne 1 ]; then |
| tst_res TFAIL "wrong notify_on_release value" |
| else |
| tst_res TPASS "notify_on_release is inherited" |
| fi |
| |
| rmdir cgroup/0 cgroup/1 |
| umount cgroup |
| } |
| |
| #--------------------------------------------------------------------------- |
| # Bug: Accessing NULL cgrp->dentry when reading /proc/sched_debug |
| # Kernel: 2.6.26-2.6.28 |
| # Links: http://lkml.org/lkml/2008/10/30/44 |
| # http://lkml.org/lkml/2008/12/12/107 |
| # http://lkml.org/lkml/2008/12/16/481 |
| # Fix: commit a47295e6bc42ad35f9c15ac66f598aa24debd4e2 |
| #--------------------------------------------------------------------------- |
| test3() |
| { |
| local cpu_subsys_path |
| |
| if [ ! -e /proc/sched_debug ]; then |
| tst_res TCONF "CONFIG_SCHED_DEBUG is not enabled" |
| return |
| fi |
| |
| if ! grep -q -w "cpu" /proc/cgroups; then |
| tst_res TCONF "CONFIG_CGROUP_SCHED is not enabled" |
| return |
| fi |
| |
| cpu_subsys_path=$(get_cgroup_mountpoint "cpu") |
| |
| # Run the test for 30 secs |
| if [ -z "$cpu_subsys_path" ]; then |
| mount -t cgroup -o cpu xxx cgroup/ |
| if [ $? -ne 0 ]; then |
| tst_res TFAIL "Failed to mount cpu subsys" |
| return |
| fi |
| cpu_subsys_path=cgroup |
| fi |
| |
| cgroup_regression_3_1.sh $cpu_subsys_path & |
| pid1=$! |
| cgroup_regression_3_2.sh & |
| pid2=$! |
| |
| sleep 30 |
| kill -USR1 $pid1 $pid2 |
| wait $pid1 2>/dev/null |
| wait $pid2 2>/dev/null |
| |
| rmdir $cpu_subsys_path/* 2> /dev/null |
| umount cgroup 2> /dev/null |
| check_kernel_bug |
| } |
| |
| #--------------------------------------------------------------------------- |
| # Bug: cgroup hierarchy lock's lockdep subclass may overflow |
| # Kernel: 2.6.29-rcX |
| # Link: http://lkml.org/lkml/2009/2/4/67 |
| # Fix: |
| #--------------------------------------------------------------------------- |
| test4() |
| { |
| local lines |
| |
| if [ ! -e /proc/lockdep ]; then |
| tst_res TCONF "CONFIG_LOCKDEP is not enabled" |
| return |
| fi |
| |
| # MAX_LOCKDEP_SUBCLASSES is 8, so number of subsys should be > 8 |
| lines=`cat /proc/cgroups | wc -l` |
| if [ $lines -le 9 ]; then |
| tst_res TCONF "require more than 8 cgroup subsystems" |
| return |
| fi |
| |
| mount -t cgroup -o none,name=foo cgroup cgroup/ |
| mkdir cgroup/0 |
| rmdir cgroup/0 |
| umount cgroup |
| |
| if dmesg | grep -q "MAX_LOCKDEP_SUBCLASSES too low"; then |
| tst_res TFAIL "lockdep BUG was found" |
| return |
| fi |
| |
| tst_res TPASS "no lockdep BUG was found" |
| } |
| |
| #--------------------------------------------------------------------------- |
| # Bug: When mount cgroup fs and the fs was busy, root_count should not be |
| # decremented in cgroup_kill_sb() |
| # Kernel: 2.6.29-rcX |
| # Links: https://openvz.org/pipermail/devel/2009-January/016345.html |
| # http://lkml.org/lkml/2009/1/28/190 |
| # Fix: commit 839ec5452ebfd5905b9c69b20ceb640903a8ea1a |
| #--------------------------------------------------------------------------- |
| test5() |
| { |
| local mounted |
| local failing |
| local mntpoint |
| |
| local lines=`cat /proc/cgroups | wc -l` |
| if [ $lines -le 2 ]; then |
| tst_res TCONF "require at least 2 cgroup subsystems" |
| return |
| fi |
| |
| local subsys1=`tail -n 1 /proc/cgroups | awk '{ print $1 }'` |
| local subsys2=`tail -n 2 /proc/cgroups | head -1 | awk '{ print $1 }'` |
| |
| # Accounting here for the fact that the chosen subsystems could |
| # have been already previously mounted at boot time: in such a |
| # case we must skip the initial co-mount step (which would |
| # fail anyway) and properly re-organize the $mntpoint and |
| # $failing params to be used in the following expected-to-fail |
| # mount action. Note that the subsysN name itself will be listed |
| # amongst mounts options. |
| get_cgroup_mountpoint $subsys1 >/dev/null && mounted=$subsys1 |
| [ -z "$mounted" ] && get_cgroup_mountpoint $subsys2 >/dev/null && mounted=$subsys2 |
| if [ -z "$mounted" ]; then |
| mntpoint=cgroup |
| failing=$subsys1 |
| mount -t cgroup -o $subsys1,$subsys2 xxx $mntpoint/ |
| if [ $? -ne 0 ]; then |
| tst_res TFAIL "mount $subsys1 and $subsys2 failed" |
| return |
| fi |
| else |
| # Use the pre-esistent mountpoint as $mntpoint and use a |
| # co-mount with $failing: this way the 2nd mount will |
| # also fail (as expected) in this 'mirrored' configuration. |
| mntpoint=$(get_cgroup_mountpoint $mounted) |
| failing=$subsys1,$subsys2 |
| fi |
| |
| # This 2nd mount has been properly configured to fail |
| mount -t cgroup -o $failing xxx $mntpoint/ 2> /dev/null |
| if [ $? -eq 0 ]; then |
| tst_res TFAIL "mount $failing should fail" |
| # Do NOT unmount pre-existent mountpoints... |
| [ -z "$mounted" ] && umount $mntpoint |
| return |
| fi |
| |
| mkdir $mntpoint/0 |
| # Otherwise we can't attach task |
| if [ "$subsys1" = cpuset -o "$subsys2" = cpuset ]; then |
| echo 0 > $mntpoint/0/cpuset.cpus 2> /dev/null |
| echo 0 > $mntpoint/0/cpuset.mems 2> /dev/null |
| fi |
| |
| sleep 100 & |
| echo $! > $mntpoint/0/tasks |
| |
| kill -TERM $! > /dev/null |
| wait $! 2>/dev/null |
| rmdir $mntpoint/0 |
| # Do NOT unmount pre-existent mountpoints... |
| [ -z "$mounted" ] && umount $mntpoint |
| check_kernel_bug |
| } |
| |
| #--------------------------------------------------------------------------- |
| # Bug: There was a race between cgroup_clone and umount |
| # Kernel: 2.6.24 - 2.6.28, 2.6.29-rcX |
| # Links: http://lkml.org/lkml/2008/12/24/124 |
| # Fix: commit 7b574b7b0124ed344911f5d581e9bc2d83bbeb19 |
| #--------------------------------------------------------------------------- |
| test6() |
| { |
| if tst_kvcmp -ge "3.0"; then |
| tst_res TCONF "CONFIG_CGROUP_NS is NOT supported in Kernels >= 3.0" |
| return |
| fi |
| |
| if ! grep -q -w "ns" /proc/cgroups; then |
| tst_res TCONF "CONFIG_CGROUP_NS is NOT enabled" |
| return |
| fi |
| |
| cgroup_regression_6_1.sh & |
| local pid1=$! |
| cgroup_regression_6_2 & |
| local pid2=$! |
| |
| tst_res TINFO "run test for 30 sec" |
| sleep 30 |
| kill -USR1 $pid1 |
| kill -TERM $pid2 |
| wait $pid1 2>/dev/null |
| wait $pid2 2>/dev/null |
| |
| mount -t cgroup -o ns xxx cgroup/ > /dev/null 2>&1 |
| rmdir cgroup/[1-9]* > /dev/null 2>&1 |
| umount cgroup |
| check_kernel_bug |
| } |
| |
| #--------------------------------------------------------------------------- |
| # Bug: There was a bug when remount cgroup fs with some dead subdirs in |
| # it (rmdir()ed but still has some refcnts on it). It caused memory |
| # leak, and may cause oops when cat /proc/sched_debug. |
| # Kernel: 2.6.24 - 2.6.27, 2.6.28-rcX |
| # Links: http://lkml.org/lkml/2008/12/10/369 |
| # Fix: commit 307257cf475aac25db30b669987f13d90c934e3a |
| #--------------------------------------------------------------------------- |
| test_7_1() |
| { |
| local subsys=$1 |
| # we should be careful to select a $subsys_path which is related to |
| # cgroup only: if cgroup debugging is enabled a 'debug' $subsys |
| # could be passed here as params and this will lead to ambiguity and |
| # errors when grepping simply for 'debug' in /proc/mounts since we'll |
| # find also /sys/kernel/debug. Helper takes care of this. |
| local subsys_path=$(get_cgroup_mountpoint $subsys) |
| |
| if [ -z "$subsys_path" ]; then |
| mount -t cgroup -o $subsys xxx cgroup/ |
| if [ $? -ne 0 ]; then |
| tst_res TFAIL "failed to mount $subsys" |
| return |
| fi |
| subsys_path=cgroup |
| fi |
| |
| mkdir $subsys_path/0 |
| sleep 100 < $subsys_path/0 & # add refcnt to this dir |
| rmdir $subsys_path/0 |
| |
| # remount with new subsystems added |
| # since 2.6.28, this remount will fail |
| |
| if [ "$subsys_path" = "cgroup" ]; then |
| mount -t cgroup -o remount xxx cgroup/ 2> /dev/null |
| kill -TERM $! |
| wait $! 2>/dev/null |
| umount cgroup |
| fi |
| } |
| |
| test_7_2() |
| { |
| local subsys=$1 |
| |
| mount -t cgroup -o none,name=foo cgroup cgroup/ |
| if [ $? -ne 0 ]; then |
| tst_res TFAIL "failed to mount cgroup" |
| return |
| fi |
| |
| mkdir cgroup/0 |
| sleep 100 < cgroup/0 & # add refcnt to this dir |
| rmdir cgroup/0 |
| |
| # remount with some subsystems removed |
| # since 2.6.28, this remount will fail |
| mount -t cgroup -o remount,$subsys xxx cgroup/ 2> /dev/null |
| kill -TERM $! |
| wait $! 2>/dev/null |
| umount cgroup |
| |
| grep -q -w "cpu" /proc/cgroups |
| if [ $? -ne 0 -o ! -e /proc/sched_debug ]; then |
| tst_res TWARN "skip rest of testing due possible oops triggered by reading /proc/sched_debug" |
| return |
| fi |
| |
| tmp=0 |
| while [ $tmp -lt 50 ]; do |
| echo 3 > /proc/sys/vm/drop_caches |
| cat /proc/sched_debug > /dev/null |
| tmp=$((tmp+1)) |
| done |
| } |
| |
| test7() |
| { |
| local lines=`cat /proc/cgroups | wc -l` |
| local subsys |
| local i=1 |
| |
| if [ $lines -le 2 ]; then |
| tst_res TCONF "require at least 2 cgroup subsystems" |
| slt_result $SLT_Untested |
| return |
| fi |
| |
| subsys=`tail -n 1 /proc/cgroups | awk '{ print $1 }'` |
| |
| # remount to add new subsystems to the hierarchy |
| while [ $i -le 2 ]; do |
| test_7_$i $subsys || return |
| check_kernel_bug $i || return |
| i=$((i+1)) |
| done |
| } |
| |
| #--------------------------------------------------------------------------- |
| # Bug: oops when get cgroupstat of a cgroup control file |
| # Kernel: 2.6.24 - 2.6.27, 2.6.28-rcX |
| # Links: http://lkml.org/lkml/2008/11/19/53 |
| # Fix: commit 33d283bef23132c48195eafc21449f8ba88fce6b |
| #--------------------------------------------------------------------------- |
| test8() |
| { |
| mount -t cgroup -o none,name=foo cgroup cgroup/ |
| if [ $? -ne 0 ]; then |
| tst_res TFAIL "failed to mount cgroup filesystem" |
| return |
| fi |
| |
| if cgroup_regression_getdelays -C cgroup/tasks > /dev/null 2>&1; then |
| tst_res TFAIL "should have failed to get cgroupstat of tasks file" |
| fi |
| |
| umount cgroup |
| check_kernel_bug |
| } |
| |
| #--------------------------------------------------------------------------- |
| # Bug: When running 2 concurrent mount/umount threads, lockdep warning |
| # may be triggered, it's a false positive, and it's VFS' issue but |
| # not cgroup. |
| # Kernel: 2.6.24 - 2.6.29-rcX |
| # Links: http://lkml.org/lkml/2009/1/4/352 |
| # Fix: commit ada723dcd681e2dffd7d73345cc8fda0eb0df9bd |
| #--------------------------------------------------------------------------- |
| test9() |
| { |
| cgroup_regression_9_1.sh & |
| local pid1=$! |
| cgroup_regression_9_2.sh & |
| local pid2=$! |
| |
| sleep 30 |
| kill -USR1 $pid1 $pid2 |
| wait $pid1 2>/dev/null |
| wait $pid2 2>/dev/null |
| |
| umount cgroup 2> /dev/null |
| check_kernel_bug |
| } |
| |
| #--------------------------------------------------------------------------- |
| # Bug: When running 2 concurrent mount/umount threads, kernel WARNING |
| # may be triggered, but it's VFS' issue but not cgroup. |
| # Kernel: 2.6.24 - 2.6.29-rcX |
| # Links: http://lkml.org/lkml/2009/1/4/354 |
| # Fix: commit 1a88b5364b535edaa321d70a566e358390ff0872 |
| #--------------------------------------------------------------------------- |
| test10() |
| { |
| cgroup_regression_10_1.sh & |
| local pid1=$! |
| cgroup_regression_10_2.sh & |
| local pid2=$! |
| |
| sleep 30 |
| kill -USR1 $pid1 $pid2 |
| wait $pid1 2>/dev/null |
| wait $pid2 2>/dev/null |
| |
| mount -t cgroup none cgroup 2> /dev/null |
| mkdir cgroup/0 |
| rmdir cgroup/0 |
| umount cgroup 2> /dev/null |
| check_kernel_bug |
| } |
| |
| tst_run |