Home | History | Annotate | Download | only in cpuctl_fj
      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 (at] cn.fujitsu.com>                                    ##
     22 ## Restructure for LTP: Shi Weihua <shiwh (at] cn.fujitsu.com>                     ##
     23 ##                                                                            ##
     24 ################################################################################
     25 
     26 cd $LTPROOT/testcases/bin
     27 
     28 export TCID="cpuctl_test_fj"
     29 export TST_TOTAL=22
     30 export TST_COUNT=1
     31 
     32 CPUCTL="/dev/cpuctl"
     33 CPUCTL_TMP="/tmp/cpuctl_tmp"
     34 SLEEP_SEC=5
     35 
     36 # Create $CPUCTL &  mount the cgroup file system with cpu controller
     37 # clean any group created earlier (if any)
     38 setup()
     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
     59 cleanup()
     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 
     79 creat_process()
     80 {
     81 	cat /dev/zero > /dev/null 2>/dev/null &
     82 	taskset -p 1 $! >/dev/null 2>&1
     83 	echo $!
     84 }
     85 
     86 get_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 
    102 kill_all_pid()
    103 {
    104 	while read pid_to_be_killed
    105 	do
    106 		kill -9 $pid_to_be_killed
    107 	done
    108 }
    109 
    110 TESTUSER="`whoami`"
    111 if [ "$TESTUSER" != "root" ]
    112 then
    113 	tst_brkm TBROK ignored "Test must be run as root"
    114 	exit 0
    115 fi
    116 
    117 # only root directory
    118 case1 ()
    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
    150 case2 ()
    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
    176 case3 ()
    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
    208 case4 ()
    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
    230 case5 ()
    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
    252 case6 ()
    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
    268 case7 ()
    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
    296 case8 ()
    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
    324 case9 ()
    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
    352 case10 ()
    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
    380 case11 ()
    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
    408 case12 ()
    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 
    435 max_shares=$((1 << 18))
    436 
    437 # echo MAX_SHARES into shares
    438 case13 ()
    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
    466 case14 ()
    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
    494 case15 ()
    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.
    523 case16 ()
    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.
    551 case17 ()
    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 
    578 case18()
    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 
    588 case19()
    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 
    604 case20()
    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 
    620 case21()
    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 
    654 case22()
    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 
    684 rm -rf "$CPUCTL_TMP" >/dev/null 2>&1 || exit 1
    685 mkdir -p "$CPUCTL_TMP" || exit 1
    686 
    687 # test
    688 do_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 
    711 do_test
    712 
    713 rm -rf "$CPUCTL_TMP" >/dev/null 2>&1
    714 
    715