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