1#! /bin/sh 2 3################################################################################ 4## ## 5## Copyright (c) 2009 FUJITSU LIMITED ## 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 USA ## 20## ## 21## Author: Miao Xie <miaox@cn.fujitsu.com> ## 22## Restructure for LTP: Shi Weihua <shiwh@cn.fujitsu.com> ## 23## ## 24################################################################################ 25 26cd $LTPROOT/testcases/bin 27 28export TCID="cpuctl_test_fj" 29export TST_TOTAL=22 30export TST_COUNT=1 31 32CPUCTL="/dev/cpuctl" 33CPUCTL_TMP="/tmp/cpuctl_tmp" 34SLEEP_SEC=5 35 36# Create $CPUCTL & mount the cgroup file system with cpu controller 37# clean any group created earlier (if any) 38setup() 39{ 40 if [ -e $CPUCTL ] 41 then 42 tst_resm TWARN "WARN:$CPUCTL already exist..overwriting" 43 cleanup || { 44 tst_resm TFAIL "Err: Can't cleanup... Exiting" 45 exit -1; 46 } 47 fi 48 49 mkdir -p "$CPUCTL" || return 1 50 51 mount -t cgroup -o cpu cpuctl "$CPUCTL" || { 52 tst_resm TFAIL "failed to mount cpu subsytem... Exiting" 53 cleanup; 54 return 1; 55 } 56} 57 58# Write the cleanup function 59cleanup() 60{ 61 mount | grep "$CPUCTL" > /dev/null 2>&1 || { 62 rm -rf "$CPUCTL" > /dev/null 2>&1 63 return 0 64 } 65 66 find $CPUCTL -type d | sort | sed -n '2,$p' | tac | while read tmpdir 67 do 68 while read tmppid 69 do 70 echo $tmppid > $CPUCTL/tasks 71 done < $tmpdir/tasks 72 rmdir $tmpdir || return 1 73 done 74 75 umount $CPUCTL || return 1 76 rmdir $CPUCTL > /dev/null 2>&1 77} 78 79creat_process() 80{ 81 cat /dev/zero > /dev/null 2>/dev/null & 82 taskset -p 1 $! >/dev/null 2>&1 83 echo $! 84} 85 86get_cpu_usage() 87{ 88 # XXX (garrcoop): expr(1) can't do float point comparisons 89 # apparently... 90 # 91 # gcooper@optimus ~ $ expr 0 \< 42 \& 42 \< 100 92 # 1 93 # gcooper@optimus ~ $ expr 0 \< 42.0 \& 42.0 \< 100 94 # 0 95 # gcooper@optimus ~ $ expr 0.0 \< 42.0 \& 42.0 \< 100.0 96 # 0 97 # ... so we have to lop off the fractional piece. 98 # ps -p $1 pcpu | awk -F. '{ print $1 }' 99 top -bn1 -p $1 | sed -n "8p" | awk '{ print $9 }' | awk -F. '{ print $1 }' 100} 101 102kill_all_pid() 103{ 104 while read pid_to_be_killed 105 do 106 kill -9 $pid_to_be_killed 107 done 108} 109 110TESTUSER="`whoami`" 111if [ "$TESTUSER" != "root" ] 112then 113 tst_brkm TBROK ignored "Test must be run as root" 114 exit 0 115fi 116 117# only root directory 118case1 () 119{ 120 [ -f "$CPUCTL/cpu.shares" ] || { 121 tst_resm TFAIL "Err: No cpu.shares." 122 return 1 123 } 124 125 shares=`cat $CPUCTL/cpu.shares` 126 if [ $shares -ne 1024 ] 127 then 128 tst_resm TFAIL "Err: Init value is not 1024" 129 return 1; 130 fi 131 132 ps -eo pid,rtprio > /tmp/pids_file1 & 133 pspid=$! 134 wait $pspid 135 cat /tmp/pids_file1 | grep '-' | tr -d '-' | tr -d ' ' | \ 136 grep -v "$pspid" > /tmp/pids_file2 137 138 while read pid 139 do 140 task=`cat $CPUCTL/tasks | grep "\b$pid\b"` 141 if [ -z $task ] 142 then 143 tst_resm TFAIL "Err: Some normal tasks aren't in the root group" 144 return 1 145 fi 146 done < /tmp/pids_file2 147} 148 149# create a child directory 150case2 () 151{ 152 mkdir $CPUCTL/tmp 153 if [ $? -ne 0 ] 154 then 155 return 1; 156 fi 157 158 [ -d "$CPUCTL/tmp" ] || return 1 159 160 [ -f "$CPUCTL/tmp/cpu.shares" ] || return 1 161 162 shares=`cat $CPUCTL/tmp/cpu.shares` 163 if [ $shares -ne 1024 ] 164 then 165 return 1; 166 fi 167 168 task=`cat $CPUCTL/tmp/tasks` 169 if [ "$task" != "" ] 170 then 171 return 1 172 fi 173} 174 175# create a grand-directory 176case3 () 177{ 178 mkdir $CPUCTL/tmp 179 if [ $? -ne 0 ] 180 then 181 return 1; 182 fi 183 184 mkdir $CPUCTL/tmp/tmp1 185 if [ $? -ne 0 ] 186 then 187 return 1; 188 fi 189 190 [ -d "$CPUCTL/tmp/tmp1" ] || return 1 191 192 [ -f "$CPUCTL/tmp/tmp1/cpu.shares" ] || return 1 193 194 shares=`cat $CPUCTL/tmp/tmp1/cpu.shares` 195 if [ $shares -ne 1024 ] 196 then 197 return 1; 198 fi 199 200 task=`cat $CPUCTL/tmp/tmp1/tasks` 201 if [ "$task" != "" ] 202 then 203 return 1 204 fi 205} 206 207# attach general process 208case4 () 209{ 210 mkdir $CPUCTL/tmp 211 if [ $? -ne 0 ] 212 then 213 return 1; 214 fi 215 216 echo 1 > $CPUCTL/tmp/tasks 217 if [ $? -ne 0 ] 218 then 219 return 1; 220 fi 221 222 tasks=`cat $CPUCTL/tmp/tasks` 223 if [ $tasks -ne 1 ] 224 then 225 return 1; 226 fi 227} 228 229# attach realtime process 230case5 () 231{ 232 mkdir $CPUCTL/tmp 233 if [ $? -ne 0 ] 234 then 235 return 1; 236 fi 237 238 ./cpuctl_fj_simple_echo 3 $CPUCTL/tmp/tasks 239 if [ $? -ne 22 ] # define EINVAL 22 /* Invalid argument */ 240 then 241 return 1; 242 fi 243 244 tasks=`cat $CPUCTL/tmp/tasks` 245 if [ "$tasks" != "" ] 246 then 247 return 1; 248 fi 249} 250 251# modify the shares of the root group 252case6 () 253{ 254 ./cpuctl_fj_simple_echo 2048 $CPUCTL/cpu.shares 255 if [ $? -ne 22 ] # define EINVAL 22 /* Invalid argument */ 256 then 257 return 1; 258 fi 259 260 shares=`cat $CPUCTL/cpu.shares` 261 if [ $shares -ne 1024 ] 262 then 263 return 1; 264 fi 265} 266 267# echo negative into shares 268case7 () 269{ 270 mkdir $CPUCTL/tmp 271 272 ./cpuctl_fj_simple_echo -1 $CPUCTL/tmp/cpu.shares 273 if [ $? -ne 22 ] # define EINVAL 22 /* Invalid argument */ 274 then 275 return 1; 276 fi 277 278 shares=`cat $CPUCTL/tmp/cpu.shares` 279 if [ $shares -ne 1024 ] 280 then 281 return 1; 282 fi 283 284 ./cpuctl_fj_cpu-hog & 285 pid=$! 286 287 echo $pid > $CPUCTL/tmp/tasks 288 289 /bin/kill -s SIGUSR1 $pid 290 sleep $SLEEP_SEC 291 /bin/kill -s SIGUSR1 $pid 292 wait $pid 293} 294 295# echo 0 into shares 296case8 () 297{ 298 mkdir $CPUCTL/tmp 299 300 echo 0 > $CPUCTL/tmp/cpu.shares 301 if [ $? -ne 0 ] 302 then 303 return 1; 304 fi 305 306 shares=`cat $CPUCTL/tmp/cpu.shares` 307 if [ $shares -ne 2 ] 308 then 309 return 1; 310 fi 311 312 ./cpuctl_fj_cpu-hog & 313 pid=$! 314 315 echo $pid > $CPUCTL/tmp/tasks 316 317 /bin/kill -s SIGUSR1 $pid 318 sleep $SLEEP_SEC 319 /bin/kill -s SIGUSR1 $pid 320 wait $pid 321} 322 323# echo 1 into shares 324case9 () 325{ 326 mkdir $CPUCTL/tmp 327 328 echo 1 > $CPUCTL/tmp/cpu.shares 329 if [ $? -ne 0 ] 330 then 331 return 1; 332 fi 333 334 shares=`cat $CPUCTL/tmp/cpu.shares` 335 if [ $shares -ne 2 ] 336 then 337 return 1; 338 fi 339 340 ./cpuctl_fj_cpu-hog & 341 pid=$! 342 343 echo $pid > $CPUCTL/tmp/tasks 344 345 /bin/kill -s SIGUSR1 $pid 346 sleep $SLEEP_SEC 347 /bin/kill -s SIGUSR1 $pid 348 wait $pid 349} 350 351# echo 2 into shares 352case10 () 353{ 354 mkdir $CPUCTL/tmp 355 356 echo 2 > $CPUCTL/tmp/cpu.shares 357 if [ $? -ne 0 ] 358 then 359 return 1; 360 fi 361 362 shares=`cat $CPUCTL/tmp/cpu.shares` 363 if [ $shares -ne 2 ] 364 then 365 return 1; 366 fi 367 368 ./cpuctl_fj_cpu-hog & 369 pid=$! 370 371 echo $pid > $CPUCTL/tmp/tasks 372 373 /bin/kill -s SIGUSR1 $pid 374 sleep $SLEEP_SEC 375 /bin/kill -s SIGUSR1 $pid 376 wait $pid 377} 378 379# echo 3 into shares 380case11 () 381{ 382 mkdir $CPUCTL/tmp 383 384 echo 3 > $CPUCTL/tmp/cpu.shares 385 if [ $? -ne 0 ] 386 then 387 return 1; 388 fi 389 390 shares=`cat $CPUCTL/tmp/cpu.shares` 391 if [ $shares -ne 3 ] 392 then 393 return 1; 394 fi 395 396 ./cpuctl_fj_cpu-hog & 397 pid=$! 398 399 echo $pid > $CPUCTL/tmp/tasks 400 401 /bin/kill -s SIGUSR1 $pid 402 sleep $SLEEP_SEC 403 /bin/kill -s SIGUSR1 $pid 404 wait $pid 405} 406 407# echo 2048 into shares 408case12 () 409{ 410 mkdir $CPUCTL/tmp 411 412 echo 2048 > $CPUCTL/tmp/cpu.shares 413 if [ $? -ne 0 ] 414 then 415 return 1; 416 fi 417 418 shares=`cat $CPUCTL/tmp/cpu.shares` 419 if [ $shares -ne 2048 ] 420 then 421 return 1; 422 fi 423 424 ./cpuctl_fj_cpu-hog & 425 pid=$! 426 427 echo $pid > $CPUCTL/tmp/tasks 428 429 /bin/kill -s SIGUSR1 $pid 430 sleep $SLEEP_SEC 431 /bin/kill -s SIGUSR1 $pid 432 wait $pid 433} 434 435max_shares=$((1 << 18)) 436 437# echo MAX_SHARES into shares 438case13 () 439{ 440 mkdir $CPUCTL/tmp 441 442 echo $max_shares > $CPUCTL/tmp/cpu.shares 443 if [ $? -ne 0 ] 444 then 445 return 1; 446 fi 447 448 shares=`cat $CPUCTL/tmp/cpu.shares` 449 if [ "$shares" != "$max_shares" ] 450 then 451 return 1; 452 fi 453 454 ./cpuctl_fj_cpu-hog & 455 pid=$! 456 457 echo $pid > $CPUCTL/tmp/tasks 458 459 /bin/kill -s SIGUSR1 $pid 460 sleep $SLEEP_SEC 461 /bin/kill -s SIGUSR1 $pid 462 wait $pid 463} 464 465# echo MAX_SHARES+1 into shares 466case14 () 467{ 468 mkdir $CPUCTL/tmp 469 470 echo $(($max_shares+1)) > $CPUCTL/tmp/cpu.shares 471 if [ $? -ne 0 ] 472 then 473 return 1; 474 fi 475 476 shares=`cat $CPUCTL/tmp/cpu.shares` 477 if [ "$shares" != "$max_shares" ] 478 then 479 return 1; 480 fi 481 482 ./cpuctl_fj_cpu-hog & 483 pid=$! 484 485 echo $pid > $CPUCTL/tmp/tasks 486 487 /bin/kill -s SIGUSR1 $pid 488 sleep $SLEEP_SEC 489 /bin/kill -s SIGUSR1 $pid 490 wait $pid 491} 492 493# echo float number into shares 494case15 () 495{ 496 mkdir $CPUCTL/tmp 497 498 ./cpuctl_fj_simple_echo 2048.23 $CPUCTL/tmp/cpu.shares 499 if [ $? -ne 22 ] # define EINVAL 22 /* Invalid argument */ 500 then 501 return 1; 502 fi 503 504 shares=`cat $CPUCTL/tmp/cpu.shares` 505 if [ $shares -ne 1024 ] 506 then 507 return 1; 508 fi 509 510 ./cpuctl_fj_cpu-hog & 511 pid=$! 512 513 echo $pid > $CPUCTL/tmp/tasks 514 515 /bin/kill -s SIGUSR1 $pid 516 sleep $SLEEP_SEC 517 /bin/kill -s SIGUSR1 $pid 518 wait $pid 519} 520 521# echo a string into shares. This string begins with some number, and ends with 522# charactor. 523case16 () 524{ 525 mkdir $CPUCTL/tmp 526 527 ./cpuctl_fj_simple_echo 2048ABC $CPUCTL/tmp/cpu.shares 528 if [ $? -ne 22 ] # define EINVAL 22 /* Invalid argument */ 529 then 530 return 1; 531 fi 532 533 shares=`cat $CPUCTL/tmp/cpu.shares` 534 if [ $shares -ne 1024 ] 535 then 536 return 1; 537 fi 538 539 ./cpuctl_fj_cpu-hog & 540 pid=$! 541 542 echo $pid > $CPUCTL/tmp/tasks 543 544 /bin/kill -s SIGUSR1 $pid 545 sleep $SLEEP_SEC 546 /bin/kill -s SIGUSR1 $pid 547 wait $pid 548} 549 550# echo a string into shares. This string begins with charactors. 551case17 () 552{ 553 mkdir $CPUCTL/tmp 554 555 ./cpuctl_fj_simple_echo ABC $CPUCTL/tmp/cpu.shares 556 if [ $? -ne 22 ] # define EINVAL 22 /* Invalid argument */ 557 then 558 return 1; 559 fi 560 561 shares=`cat $CPUCTL/tmp/cpu.shares` 562 if [ $shares -ne 1024 ] 563 then 564 return 1; 565 fi 566 567 ./cpuctl_fj_cpu-hog & 568 pid=$! 569 570 echo $pid > $CPUCTL/tmp/tasks 571 572 /bin/kill -s SIGUSR1 $pid 573 sleep $SLEEP_SEC 574 /bin/kill -s SIGUSR1 $pid 575 wait $pid 576} 577 578case18() 579{ 580 mkdir "$CPUCTL/1" 581 echo 0x8000000000000000 > "$CPUCTL/1/cpu.shares" 582 pid=$(creat_process) 583 echo $pid > "$CPUCTL/1/tasks" 584 kill -9 $pid 585 return 0 586} 587 588case19() 589{ 590 mkdir "$CPUCTL/1" 591 pid=$(creat_process) 592 pid_other=$(creat_process) 593 594 echo 2000000000 > "$CPUCTL/1/cpu.shares" 595 echo $pid > "$CPUCTL/1/tasks" 596 cpu_usage=$(get_cpu_usage $pid) 597 echo "pid $pid cpu_usage $cpu_usage" 598 599 kill -9 $pid $pid_other 600 expr 96 \< "$cpu_usage" \& "$cpu_usage" \< 103 > /dev/null 2>&1 || return 1 601 return 0 602} 603 604case20() 605{ 606 mkdir "$CPUCTL/1" 607 pid=$(creat_process) 608 pid_other=$(creat_process) 609 610 echo 20000000000 > "$CPUCTL/1/cpu.shares" 611 echo $pid > "$CPUCTL/1/tasks" 612 cpu_usage=$(get_cpu_usage $pid) 613 echo "pid $pid cpu_usage $cpu_usage" 614 615 kill -9 $pid $pid_other 616 expr 96 \< "$cpu_usage" \& "$cpu_usage" \< 103 > /dev/null 2>&1 || return 1 617 return 0 618} 619 620case21() 621{ 622 mkdir "$CPUCTL/1" "$CPUCTL/1/2" 623 pid=$(creat_process) 624 echo $pid > "$CPUCTL/1/tasks" 625 626 while true 627 do 628 creat_process > "$CPUCTL/1/2/tasks" 629 sleep 1 630 done & 631 loop_pid=$! 632 633 sleep 10 634 ret=0 635 636 top_times=0 637 while [ "$top_times" -lt 10 -a "$ret" = 0 ] 638 do 639 cpu_usage=$(get_cpu_usage $pid) 640 echo "pid $pid cpu_usage $cpu_usage" 641 expr 44 \< "$cpu_usage" \& "$cpu_usage" \< 56 > /dev/null 2>&1 642 ret=$? 643 : $(( top_times+=1 )) 644 done 645 646 kill -9 $pid $loop_pid > /dev/null 2>&1 647 wait $pid $loop_pid >/dev/null 2>&1 648 sleep 2 649 kill_all_pid < "$CPUCTL/1/2/tasks" >/dev/null 2>&1 650 sleep 2 651 return $ret 652} 653 654case22() 655{ 656 mkdir "$CPUCTL/1" "$CPUCTL/1/2" 657 pid=$(creat_process) 658 while true 659 do 660 echo $pid > "$CPUCTL/1/tasks" 661 echo $pid > "$CPUCTL/1/2/tasks" 662 sleep 1 663 done & 664 loop_pid=$! 665 666 sleep 10 667 ret=0 668 669 top_times=0 670 while [ "$top_times" -lt 10 -a "$ret" = 0 ] 671 do 672 cpu_usage=$(get_cpu_usage $pid) 673 echo "pid $pid cpu_usage $cpu_usage" 674 expr 94 \< "$cpu_usage" \& "$cpu_usage" \< 106 > /dev/null 2>&1 675 ret=$? 676 : $(( top_times+=1 )) 677 done 678 679 kill -s KILL $pid $loop_pid > /dev/null 2>&1 680 wait $pid $loop_pid >/dev/null 2>&1 681 return $ret 682} 683 684rm -rf "$CPUCTL_TMP" >/dev/null 2>&1 || exit 1 685mkdir -p "$CPUCTL_TMP" || exit 1 686 687# test 688do_test () 689{ 690 for i in $(seq 1 $TST_TOTAL) 691 do 692 setup || { 693 tst_resm TFAIL "case$i FAIL" 694 continue 695 } 696 697 case$i || { 698 tst_resm TFAIL "case$i FAIL" 699 cleanup 700 continue 701 } 702 703 cleanup || { 704 tst_resm TFAIL "case$i FAIL" 705 } 706 707 tst_resm TPASS "case$i PASS" 708 done 709} 710 711do_test 712 713rm -rf "$CPUCTL_TMP" >/dev/null 2>&1 714 715