1#!/bin/sh 2# SPDX-License-Identifier: GPL-2.0-or-later 3# Copyright (c) 2019 Petr Vorel <pvorel@suse.cz> 4# Copyright (c) 2009 FUJITSU LIMITED 5# Author: Li Zefan <lizf@cn.fujitsu.com> 6 7TST_TESTFUNC=test 8TST_SETUP=do_setup 9TST_CLEANUP=do_cleanup 10TST_CNT=9 11TST_NEEDS_ROOT=1 12TST_NEEDS_TMPDIR=1 13TST_NEEDS_CMDS="awk dmesg find mountpoint rmdir" 14 15. cgroup_lib.sh 16 17do_setup() 18{ 19 mkdir cgroup/ 20 21 if tst_kvcmp -lt "2.6.29"; then 22 tst_brk TCONF ignored "test must be run with kernel 2.6.29 or newer" 23 fi 24 25 if [ ! -f /proc/cgroups ]; then 26 tst_brk TCONF ignored "Kernel does not support for control groups; skipping testcases"; 27 fi 28 29 dmesg -c > /dev/null 30 NR_BUG=`dmesg | grep -c "kernel BUG"` 31 NR_NULL=`dmesg | grep -c "kernel NULL pointer dereference"` 32 NR_WARNING=`dmesg | grep -c "^WARNING"` 33 NR_LOCKDEP=`dmesg | grep -c "possible recursive locking detected"` 34} 35 36do_cleanup() 37{ 38 if mountpoint -q cgroup/; then 39 find cgroup/ -maxdepth 1 -depth -exec rmdir {} + 40 umount cgroup/ 41 rmdir cgroup 42 fi 43} 44 45check_kernel_bug() 46{ 47 local id="$1" 48 local ok_msg="no kernel bug was found" 49 local new_bug=`dmesg | grep -c "kernel BUG"` 50 local new_null=`dmesg | grep -c "kernel NULL pointer dereference"` 51 local new_warning=`dmesg | grep -c "^WARNING"` 52 local new_lockdep=`dmesg | grep -c "possible recursive locking detected"` 53 54 [ "$id" ] && ok_msg="$ok_msg for test $i" 55 56 # no kernel bug is detected 57 if [ $new_bug -eq $NR_BUG -a $new_warning -eq $NR_WARNING -a \ 58 $new_null -eq $NR_NULL -a $new_lockdep -eq $NR_LOCKDEP ]; then 59 tst_res TPASS $ok_msg 60 return 0 61 fi 62 63 # some kernel bug is detected 64 if [ $new_bug -gt $NR_BUG ]; then 65 tst_res TFAIL "kernel BUG was detected!" 66 fi 67 if [ $new_warning -gt $NR_WARNING ]; then 68 tst_res TFAIL "kernel WARNING was detected!" 69 fi 70 if [ $new_null -gt $NR_NULL ]; then 71 tst_res TFAIL "kernel NULL pointer dereference!" 72 fi 73 if [ $new_lockdep -gt $NR_LOCKDEP ]; then 74 tst_res 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 tst_res TWARN "BUG FOUND!" 83 dmesg 84 return 1 85} 86 87#--------------------------------------------------------------------------- 88# Bug: There was a race when keeping forking processes and at the same 89# time cat /cgroup/tasks (should be the very first time to read 90# /cgroup/tasks, otherwise this bug won't be triggered) 91# Kernel: 2.6.24, 2.6.25-rcX 92# Links: http://lkml.org/lkml/2007/10/17/224 93# http://lkml.org/lkml/2008/3/5/332 94# http://lkml.org/lkml/2008/4/16/493 95# Fix: commit 0e04388f0189fa1f6812a8e1cb6172136eada87e 96#--------------------------------------------------------------------------- 97test1() 98{ 99 cgroup_regression_fork_processes & 100 sleep 1 101 102 mount -t cgroup -o none,name=foo cgroup cgroup/ 103 if [ $? -ne 0 ]; then 104 tst_res TFAIL "failed to mount cgroup filesystem" 105 kill -TERM $! 106 return 107 fi 108 cat cgroup/tasks > /dev/null 109 110 kill -TERM $! 111 wait $! 2>/dev/null 112 umount cgroup/ 113 check_kernel_bug 114} 115 116#--------------------------------------------------------------------------- 117# Bug: a cgroup's notify_on_release flag did not inherit from its parent. 118# Kernel: 2.6.24-rcX 119# Links: http://lkml.org/lkml/2008/2/25/12 120# Fix: commit bc231d2a048010d5e0b49ac7fddbfa822fc41109 121#--------------------------------------------------------------------------- 122test2() 123{ 124 local val1 125 local val2 126 127 mount -t cgroup -o none,name=foo cgroup cgroup/ 128 if [ $? -ne 0 ]; then 129 tst_res TFAIL "Failed to mount cgroup filesystem" 130 return 131 fi 132 133 echo 0 > cgroup/notify_on_release 134 mkdir cgroup/0 135 val1=`cat cgroup/0/notify_on_release` 136 137 echo 1 > cgroup/notify_on_release 138 mkdir cgroup/1 139 val2=`cat cgroup/1/notify_on_release` 140 141 if [ $val1 -ne 0 -o $val2 -ne 1 ]; then 142 tst_res TFAIL "wrong notify_on_release value" 143 else 144 tst_res TPASS "notify_on_release is inherited" 145 fi 146 147 rmdir cgroup/0 cgroup/1 148 umount cgroup/ 149} 150 151#--------------------------------------------------------------------------- 152# Bug: Accessing NULL cgrp->dentry when reading /proc/sched_debug 153# Kernel: 2.6.26-2.6.28 154# Links: http://lkml.org/lkml/2008/10/30/44 155# http://lkml.org/lkml/2008/12/12/107 156# http://lkml.org/lkml/2008/12/16/481 157# Fix: commit a47295e6bc42ad35f9c15ac66f598aa24debd4e2 158#--------------------------------------------------------------------------- 159test3() 160{ 161 local cpu_subsys_path 162 163 if [ ! -e /proc/sched_debug ]; then 164 tst_res TCONF "CONFIG_SCHED_DEBUG is not enabled" 165 return 166 fi 167 168 if ! grep -q -w "cpu" /proc/cgroups; then 169 tst_res TCONF "CONFIG_CGROUP_SCHED is not enabled" 170 return 171 fi 172 173 cpu_subsys_path=$(get_cgroup_mountpoint "cpu") 174 175 # Run the test for 30 secs 176 if [ -z "$cpu_subsys_path" ]; then 177 mount -t cgroup -o cpu xxx cgroup/ 178 if [ $? -ne 0 ]; then 179 tst_res TFAIL "Failed to mount cpu subsys" 180 return 181 fi 182 cpu_subsys_path=cgroup 183 fi 184 185 cgroup_regression_3_1.sh $cpu_subsys_path & 186 pid1=$! 187 cgroup_regression_3_2.sh & 188 pid2=$! 189 190 sleep 30 191 kill -USR1 $pid1 $pid2 192 wait $pid1 2>/dev/null 193 wait $pid2 2>/dev/null 194 195 rmdir $cpu_subsys_path/0 2> /dev/null 196 umount cgroup/ 2> /dev/null 197 check_kernel_bug 198} 199 200#--------------------------------------------------------------------------- 201# Bug: cgroup hierarchy lock's lockdep subclass may overflow 202# Kernel: 2.6.29-rcX 203# Link: http://lkml.org/lkml/2009/2/4/67 204# Fix: 205#--------------------------------------------------------------------------- 206test4() 207{ 208 local lines 209 210 if [ ! -e /proc/lockdep ]; then 211 tst_res TCONF "CONFIG_LOCKDEP is not enabled" 212 return 213 fi 214 215 # MAX_LOCKDEP_SUBCLASSES is 8, so number of subsys should be > 8 216 lines=`cat /proc/cgroups | wc -l` 217 if [ $lines -le 9 ]; then 218 tst_res TCONF "require more than 8 cgroup subsystems" 219 return 220 fi 221 222 mount -t cgroup -o none,name=foo cgroup cgroup/ 223 mkdir cgroup/0 224 rmdir cgroup/0 225 umount cgroup/ 226 227 if dmesg | grep -q "MAX_LOCKDEP_SUBCLASSES too low"; then 228 tst_res TFAIL "lockdep BUG was found" 229 return 230 fi 231 232 tst_res TPASS "no lockdep BUG was found" 233} 234 235#--------------------------------------------------------------------------- 236# Bug: When running 2 concurrent mount/umount threads, kernel WARNING 237# may be triggered, but it's VFS' issue but not cgroup. 238# Kernel: 2.6.24 - 2.6.29-rcX 239# Links: http://lkml.org/lkml/2009/1/4/354 240# Fix: commit 1a88b5364b535edaa321d70a566e358390ff0872 241#--------------------------------------------------------------------------- 242test5() 243{ 244 cgroup_regression_5_1.sh & 245 local pid1=$! 246 cgroup_regression_5_2.sh & 247 local pid2=$! 248 249 sleep 30 250 kill -USR1 $pid1 $pid2 251 wait $pid1 2>/dev/null 252 wait $pid2 2>/dev/null 253 254 mount -t cgroup none cgroup 2> /dev/null 255 mkdir cgroup/0 256 rmdir cgroup/0 257 umount cgroup/ 2> /dev/null 258 check_kernel_bug 259} 260 261#--------------------------------------------------------------------------- 262# Bug: There was a race between cgroup_clone and umount 263# Kernel: 2.6.24 - 2.6.28, 2.6.29-rcX 264# Links: http://lkml.org/lkml/2008/12/24/124 265# Fix: commit 7b574b7b0124ed344911f5d581e9bc2d83bbeb19 266#--------------------------------------------------------------------------- 267test6() 268{ 269 if tst_kvcmp -ge "3.0"; then 270 tst_res TCONF "CONFIG_CGROUP_NS is NOT supported in Kernels >= 3.0" 271 return 272 fi 273 274 if ! grep -q -w "ns" /proc/cgroups; then 275 tst_res TCONF "CONFIG_CGROUP_NS is NOT enabled" 276 return 277 fi 278 279 cgroup_regression_6_1.sh & 280 local pid1=$! 281 cgroup_regression_6_2 & 282 local pid2=$! 283 284 tst_res TINFO "run test for 30 sec" 285 sleep 30 286 kill -USR1 $pid1 287 kill -TERM $pid2 288 wait $pid1 2>/dev/null 289 wait $pid2 2>/dev/null 290 291 mount -t cgroup -o ns xxx cgroup/ > /dev/null 2>&1 292 rmdir cgroup/[1-9]* > /dev/null 2>&1 293 umount cgroup/ 294 check_kernel_bug 295} 296 297#--------------------------------------------------------------------------- 298# Bug: There was a bug when remount cgroup fs with some dead subdirs in 299# it (rmdir()ed but still has some refcnts on it). It caused memory 300# leak, and may cause oops when cat /proc/sched_debug. 301# Kernel: 2.6.24 - 2.6.27, 2.6.28-rcX 302# Links: http://lkml.org/lkml/2008/12/10/369 303# Fix: commit 307257cf475aac25db30b669987f13d90c934e3a 304#--------------------------------------------------------------------------- 305test_7_1() 306{ 307 local subsys=$1 308 # we should be careful to select a $subsys_path which is related to 309 # cgroup only: if cgroup debugging is enabled a 'debug' $subsys 310 # could be passed here as params and this will lead to ambiguity and 311 # errors when grepping simply for 'debug' in /proc/mounts since we'll 312 # find also /sys/kernel/debug. Helper takes care of this. 313 local subsys_path=$(get_cgroup_mountpoint $subsys) 314 315 if [ -z "$subsys_path" ]; then 316 mount -t cgroup -o $subsys xxx cgroup/ 317 if [ $? -ne 0 ]; then 318 tst_res TFAIL "failed to mount $subsys" 319 return 320 fi 321 subsys_path=cgroup 322 fi 323 324 mkdir $subsys_path/0 325 sleep 100 < $subsys_path/0 & # add refcnt to this dir 326 rmdir $subsys_path/0 327 328 # remount with new subsystems added 329 # since 2.6.28, this remount will fail 330 331 if [ "$subsys_path" = "cgroup" ]; then 332 mount -t cgroup -o remount xxx cgroup/ 2> /dev/null 333 kill -TERM $! 334 wait $! 2>/dev/null 335 umount cgroup/ 336 fi 337} 338 339test_7_2() 340{ 341 local subsys=$1 342 343 mount -t cgroup -o none,name=foo cgroup cgroup/ 344 if [ $? -ne 0 ]; then 345 tst_res TFAIL "failed to mount cgroup" 346 return 347 fi 348 349 mkdir cgroup/0 350 sleep 100 < cgroup/0 & # add refcnt to this dir 351 rmdir cgroup/0 352 353 # remount with some subsystems removed 354 # since 2.6.28, this remount will fail 355 mount -t cgroup -o remount,$subsys xxx cgroup/ 2> /dev/null 356 kill -TERM $! 357 wait $! 2>/dev/null 358 umount cgroup/ 359 360 grep -q -w "cpu" /proc/cgroups 361 if [ $? -ne 0 -o ! -e /proc/sched_debug ]; then 362 tst_res TCONF "skip rest of testing due possible oops triggered by reading /proc/sched_debug" 363 return 364 fi 365 366 tmp=0 367 while [ $tmp -lt 50 ]; do 368 echo 3 > /proc/sys/vm/drop_caches 369 cat /proc/sched_debug > /dev/null 370 tmp=$((tmp+1)) 371 done 372} 373 374test7() 375{ 376 local lines=`cat /proc/cgroups | wc -l` 377 local subsys 378 local i=1 379 380 if [ $lines -le 2 ]; then 381 tst_res TCONF "require at least 2 cgroup subsystems" 382 slt_result $SLT_Untested 383 return 384 fi 385 386 subsys=`tail -n 1 /proc/cgroups | awk '{ print $1 }'` 387 388 # remount to add new subsystems to the hierarchy 389 while [ $i -le 2 ]; do 390 test_7_$i $subsys || return 391 check_kernel_bug $i || return 392 i=$((i+1)) 393 done 394} 395 396#--------------------------------------------------------------------------- 397# Bug: oops when get cgroupstat of a cgroup control file 398# Kernel: 2.6.24 - 2.6.27, 2.6.28-rcX 399# Links: http://lkml.org/lkml/2008/11/19/53 400# Fix: commit 33d283bef23132c48195eafc21449f8ba88fce6b 401#--------------------------------------------------------------------------- 402test8() 403{ 404 mount -t cgroup -o none,name=foo cgroup cgroup/ 405 if [ $? -ne 0 ]; then 406 tst_res TFAIL "failed to mount cgroup filesystem" 407 return 408 fi 409 410 if cgroup_regression_getdelays -C cgroup/tasks > /dev/null 2>&1; then 411 tst_res TFAIL "should have failed to get cgroupstat of tasks file" 412 fi 413 414 umount cgroup/ 415 check_kernel_bug 416} 417 418#--------------------------------------------------------------------------- 419# Bug: When running 2 concurrent mount/umount threads, lockdep warning 420# may be triggered, it's a false positive, and it's VFS' issue but 421# not cgroup. 422# Kernel: 2.6.24 - 2.6.29-rcX 423# Links: http://lkml.org/lkml/2009/1/4/352 424# Fix: commit ada723dcd681e2dffd7d73345cc8fda0eb0df9bd 425#--------------------------------------------------------------------------- 426test9() 427{ 428 cgroup_regression_9_1.sh & 429 local pid1=$! 430 cgroup_regression_9_2.sh & 431 local pid2=$! 432 433 sleep 30 434 kill -USR1 $pid1 $pid2 435 wait $pid1 2>/dev/null 436 wait $pid2 2>/dev/null 437 438 umount cgroup/ 2> /dev/null 439 check_kernel_bug 440} 441 442tst_run 443