• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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