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