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