xref: /openbmc/linux/tools/testing/ktest/ktest.pl (revision c4261d0f62ccbb42184d13b43807b36b100e8fb5)
1#!/usr/bin/perl -w
2#
3# Copyright 2010 - Steven Rostedt <srostedt@redhat.com>, Red Hat Inc.
4# Licensed under the terms of the GNU GPL License version 2
5#
6
7use strict;
8use IPC::Open2;
9use Fcntl qw(F_GETFL F_SETFL O_NONBLOCK);
10use File::Path qw(mkpath);
11use File::Copy qw(cp);
12use FileHandle;
13
14my $VERSION = "0.2";
15
16$| = 1;
17
18my %opt;
19my %repeat_tests;
20my %repeats;
21my %default;
22
23#default opts
24$default{"NUM_TESTS"}		= 1;
25$default{"TEST_TYPE"}		= "test";
26$default{"BUILD_TYPE"}		= "randconfig";
27$default{"MAKE_CMD"}		= "make";
28$default{"TIMEOUT"}		= 120;
29$default{"TMP_DIR"}		= "/tmp/ktest/\${MACHINE}";
30$default{"SLEEP_TIME"}		= 60;	# sleep time between tests
31$default{"BUILD_NOCLEAN"}	= 0;
32$default{"REBOOT_ON_ERROR"}	= 0;
33$default{"POWEROFF_ON_ERROR"}	= 0;
34$default{"REBOOT_ON_SUCCESS"}	= 1;
35$default{"POWEROFF_ON_SUCCESS"}	= 0;
36$default{"BUILD_OPTIONS"}	= "";
37$default{"BISECT_SLEEP_TIME"}	= 60;   # sleep time between bisects
38$default{"PATCHCHECK_SLEEP_TIME"} = 60; # sleep time between patch checks
39$default{"CLEAR_LOG"}		= 0;
40$default{"BISECT_MANUAL"}	= 0;
41$default{"BISECT_SKIP"}		= 1;
42$default{"SUCCESS_LINE"}	= "login:";
43$default{"DETECT_TRIPLE_FAULT"} = 1;
44$default{"NO_INSTALL"}		= 0;
45$default{"BOOTED_TIMEOUT"}	= 1;
46$default{"DIE_ON_FAILURE"}	= 1;
47$default{"SSH_EXEC"}		= "ssh \$SSH_USER\@\$MACHINE \$SSH_COMMAND";
48$default{"SCP_TO_TARGET"}	= "scp \$SRC_FILE \$SSH_USER\@\$MACHINE:\$DST_FILE";
49$default{"REBOOT"}		= "ssh \$SSH_USER\@\$MACHINE reboot";
50$default{"STOP_AFTER_SUCCESS"}	= 10;
51$default{"STOP_AFTER_FAILURE"}	= 60;
52$default{"STOP_TEST_AFTER"}	= 600;
53
54# required, and we will ask users if they don't have them but we keep the default
55# value something that is common.
56$default{"REBOOT_TYPE"}		= "grub";
57$default{"LOCALVERSION"}	= "-test";
58$default{"SSH_USER"}		= "root";
59$default{"BUILD_TARGET"} 	= "arch/x86/boot/bzImage";
60$default{"TARGET_IMAGE"}	= "/boot/vmlinuz-test";
61
62my $ktest_config;
63my $version;
64my $machine;
65my $ssh_user;
66my $tmpdir;
67my $builddir;
68my $outputdir;
69my $output_config;
70my $test_type;
71my $build_type;
72my $build_options;
73my $pre_build;
74my $post_build;
75my $pre_build_die;
76my $post_build_die;
77my $reboot_type;
78my $reboot_script;
79my $power_cycle;
80my $reboot;
81my $reboot_on_error;
82my $poweroff_on_error;
83my $die_on_failure;
84my $powercycle_after_reboot;
85my $poweroff_after_halt;
86my $ssh_exec;
87my $scp_to_target;
88my $power_off;
89my $grub_menu;
90my $grub_number;
91my $target;
92my $make;
93my $post_install;
94my $no_install;
95my $noclean;
96my $minconfig;
97my $start_minconfig;
98my $start_minconfig_defined;
99my $output_minconfig;
100my $ignore_config;
101my $addconfig;
102my $in_bisect = 0;
103my $bisect_bad = "";
104my $reverse_bisect;
105my $bisect_manual;
106my $bisect_skip;
107my $config_bisect_good;
108my $in_patchcheck = 0;
109my $run_test;
110my $redirect;
111my $buildlog;
112my $testlog;
113my $dmesg;
114my $monitor_fp;
115my $monitor_pid;
116my $monitor_cnt = 0;
117my $sleep_time;
118my $bisect_sleep_time;
119my $patchcheck_sleep_time;
120my $ignore_warnings;
121my $store_failures;
122my $store_successes;
123my $test_name;
124my $timeout;
125my $booted_timeout;
126my $detect_triplefault;
127my $console;
128my $reboot_success_line;
129my $success_line;
130my $stop_after_success;
131my $stop_after_failure;
132my $stop_test_after;
133my $build_target;
134my $target_image;
135my $localversion;
136my $iteration = 0;
137my $successes = 0;
138
139my %entered_configs;
140my %config_help;
141my %variable;
142my %force_config;
143
144# do not force reboots on config problems
145my $no_reboot = 1;
146
147# default variables that can be used
148chomp ($variable{"PWD"} = `pwd`);
149
150$config_help{"MACHINE"} = << "EOF"
151 The machine hostname that you will test.
152EOF
153    ;
154$config_help{"SSH_USER"} = << "EOF"
155 The box is expected to have ssh on normal bootup, provide the user
156  (most likely root, since you need privileged operations)
157EOF
158    ;
159$config_help{"BUILD_DIR"} = << "EOF"
160 The directory that contains the Linux source code (full path).
161 You can use \${PWD} that will be the path where ktest.pl is run, or use
162 \${THIS_DIR} which is assigned \${PWD} but may be changed later.
163EOF
164    ;
165$config_help{"OUTPUT_DIR"} = << "EOF"
166 The directory that the objects will be built (full path).
167 (can not be same as BUILD_DIR)
168 You can use \${PWD} that will be the path where ktest.pl is run, or use
169 \${THIS_DIR} which is assigned \${PWD} but may be changed later.
170EOF
171    ;
172$config_help{"BUILD_TARGET"} = << "EOF"
173 The location of the compiled file to copy to the target.
174 (relative to OUTPUT_DIR)
175EOF
176    ;
177$config_help{"TARGET_IMAGE"} = << "EOF"
178 The place to put your image on the test machine.
179EOF
180    ;
181$config_help{"POWER_CYCLE"} = << "EOF"
182 A script or command to reboot the box.
183
184 Here is a digital loggers power switch example
185 POWER_CYCLE = wget --no-proxy -O /dev/null -q  --auth-no-challenge 'http://admin:admin\@power/outlet?5=CCL'
186
187 Here is an example to reboot a virtual box on the current host
188 with the name "Guest".
189 POWER_CYCLE = virsh destroy Guest; sleep 5; virsh start Guest
190EOF
191    ;
192$config_help{"CONSOLE"} = << "EOF"
193 The script or command that reads the console
194
195  If you use ttywatch server, something like the following would work.
196CONSOLE = nc -d localhost 3001
197
198 For a virtual machine with guest name "Guest".
199CONSOLE =  virsh console Guest
200EOF
201    ;
202$config_help{"LOCALVERSION"} = << "EOF"
203 Required version ending to differentiate the test
204 from other linux builds on the system.
205EOF
206    ;
207$config_help{"REBOOT_TYPE"} = << "EOF"
208 Way to reboot the box to the test kernel.
209 Only valid options so far are "grub" and "script".
210
211 If you specify grub, it will assume grub version 1
212 and will search in /boot/grub/menu.lst for the title \$GRUB_MENU
213 and select that target to reboot to the kernel. If this is not
214 your setup, then specify "script" and have a command or script
215 specified in REBOOT_SCRIPT to boot to the target.
216
217 The entry in /boot/grub/menu.lst must be entered in manually.
218 The test will not modify that file.
219EOF
220    ;
221$config_help{"GRUB_MENU"} = << "EOF"
222 The grub title name for the test kernel to boot
223 (Only mandatory if REBOOT_TYPE = grub)
224
225 Note, ktest.pl will not update the grub menu.lst, you need to
226 manually add an option for the test. ktest.pl will search
227 the grub menu.lst for this option to find what kernel to
228 reboot into.
229
230 For example, if in the /boot/grub/menu.lst the test kernel title has:
231 title Test Kernel
232 kernel vmlinuz-test
233 GRUB_MENU = Test Kernel
234EOF
235    ;
236$config_help{"REBOOT_SCRIPT"} = << "EOF"
237 A script to reboot the target into the test kernel
238 (Only mandatory if REBOOT_TYPE = script)
239EOF
240    ;
241
242sub read_prompt {
243    my ($cancel, $prompt) = @_;
244
245    my $ans;
246
247    for (;;) {
248	if ($cancel) {
249	    print "$prompt [y/n/C] ";
250	} else {
251	    print "$prompt [Y/n] ";
252	}
253	$ans = <STDIN>;
254	chomp $ans;
255	if ($ans =~ /^\s*$/) {
256	    if ($cancel) {
257		$ans = "c";
258	    } else {
259		$ans = "y";
260	    }
261	}
262	last if ($ans =~ /^y$/i || $ans =~ /^n$/i);
263	if ($cancel) {
264	    last if ($ans =~ /^c$/i);
265	    print "Please answer either 'y', 'n' or 'c'.\n";
266	} else {
267	    print "Please answer either 'y' or 'n'.\n";
268	}
269    }
270    if ($ans =~ /^c/i) {
271	exit;
272    }
273    if ($ans !~ /^y$/i) {
274	return 0;
275    }
276    return 1;
277}
278
279sub read_yn {
280    my ($prompt) = @_;
281
282    return read_prompt 0, $prompt;
283}
284
285sub read_ync {
286    my ($prompt) = @_;
287
288    return read_prompt 1, $prompt;
289}
290
291sub get_ktest_config {
292    my ($config) = @_;
293    my $ans;
294
295    return if (defined($opt{$config}));
296
297    if (defined($config_help{$config})) {
298	print "\n";
299	print $config_help{$config};
300    }
301
302    for (;;) {
303	print "$config = ";
304	if (defined($default{$config})) {
305	    print "\[$default{$config}\] ";
306	}
307	$ans = <STDIN>;
308	$ans =~ s/^\s*(.*\S)\s*$/$1/;
309	if ($ans =~ /^\s*$/) {
310	    if ($default{$config}) {
311		$ans = $default{$config};
312	    } else {
313		print "Your answer can not be blank\n";
314		next;
315	    }
316	}
317	$entered_configs{$config} = ${ans};
318	last;
319    }
320}
321
322sub get_ktest_configs {
323    get_ktest_config("MACHINE");
324    get_ktest_config("SSH_USER");
325    get_ktest_config("BUILD_DIR");
326    get_ktest_config("OUTPUT_DIR");
327    get_ktest_config("BUILD_TARGET");
328    get_ktest_config("TARGET_IMAGE");
329    get_ktest_config("POWER_CYCLE");
330    get_ktest_config("CONSOLE");
331    get_ktest_config("LOCALVERSION");
332
333    my $rtype = $opt{"REBOOT_TYPE"};
334
335    if (!defined($rtype)) {
336	if (!defined($opt{"GRUB_MENU"})) {
337	    get_ktest_config("REBOOT_TYPE");
338	    $rtype = $entered_configs{"REBOOT_TYPE"};
339	} else {
340	    $rtype = "grub";
341	}
342    }
343
344    if ($rtype eq "grub") {
345	get_ktest_config("GRUB_MENU");
346    } else {
347	get_ktest_config("REBOOT_SCRIPT");
348    }
349}
350
351sub process_variables {
352    my ($value, $remove_undef) = @_;
353    my $retval = "";
354
355    # We want to check for '\', and it is just easier
356    # to check the previous characet of '$' and not need
357    # to worry if '$' is the first character. By adding
358    # a space to $value, we can just check [^\\]\$ and
359    # it will still work.
360    $value = " $value";
361
362    while ($value =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) {
363	my $begin = $1;
364	my $var = $2;
365	my $end = $3;
366	# append beginning of value to retval
367	$retval = "$retval$begin";
368	if (defined($variable{$var})) {
369	    $retval = "$retval$variable{$var}";
370	} elsif (defined($remove_undef) && $remove_undef) {
371	    # for if statements, any variable that is not defined,
372	    # we simple convert to 0
373	    $retval = "${retval}0";
374	} else {
375	    # put back the origin piece.
376	    $retval = "$retval\$\{$var\}";
377	}
378	$value = $end;
379    }
380    $retval = "$retval$value";
381
382    # remove the space added in the beginning
383    $retval =~ s/ //;
384
385    return "$retval"
386}
387
388sub set_value {
389    my ($lvalue, $rvalue, $override, $overrides, $name) = @_;
390
391    if (defined($opt{$lvalue})) {
392	if (!$override || defined(${$overrides}{$lvalue})) {
393	    my $extra = "";
394	    if ($override) {
395		$extra = "In the same override section!\n";
396	    }
397	    die "$name: $.: Option $lvalue defined more than once!\n$extra";
398	}
399	${$overrides}{$lvalue} = $rvalue;
400    }
401    if ($rvalue =~ /^\s*$/) {
402	delete $opt{$lvalue};
403    } else {
404	$rvalue = process_variables($rvalue);
405	$opt{$lvalue} = $rvalue;
406    }
407}
408
409sub set_variable {
410    my ($lvalue, $rvalue) = @_;
411
412    if ($rvalue =~ /^\s*$/) {
413	delete $variable{$lvalue};
414    } else {
415	$rvalue = process_variables($rvalue);
416	$variable{$lvalue} = $rvalue;
417    }
418}
419
420sub process_compare {
421    my ($lval, $cmp, $rval) = @_;
422
423    # remove whitespace
424
425    $lval =~ s/^\s*//;
426    $lval =~ s/\s*$//;
427
428    $rval =~ s/^\s*//;
429    $rval =~ s/\s*$//;
430
431    if ($cmp eq "==") {
432	return $lval eq $rval;
433    } elsif ($cmp eq "!=") {
434	return $lval ne $rval;
435    }
436
437    my $statement = "$lval $cmp $rval";
438    my $ret = eval $statement;
439
440    # $@ stores error of eval
441    if ($@) {
442	return -1;
443    }
444
445    return $ret;
446}
447
448sub value_defined {
449    my ($val) = @_;
450
451    return defined($variable{$2}) ||
452	defined($opt{$2});
453}
454
455my $d = 0;
456sub process_expression {
457    my ($name, $val) = @_;
458
459    my $c = $d++;
460
461    while ($val =~ s/\(([^\(]*?)\)/\&\&\&\&VAL\&\&\&\&/) {
462	my $express = $1;
463
464	if (process_expression($name, $express)) {
465	    $val =~ s/\&\&\&\&VAL\&\&\&\&/ 1 /;
466	} else {
467	    $val =~ s/\&\&\&\&VAL\&\&\&\&/ 0 /;
468	}
469    }
470
471    $d--;
472    my $OR = "\\|\\|";
473    my $AND = "\\&\\&";
474
475    while ($val =~ s/^(.*?)($OR|$AND)//) {
476	my $express = $1;
477	my $op = $2;
478
479	if (process_expression($name, $express)) {
480	    if ($op eq "||") {
481		return 1;
482	    }
483	} else {
484	    if ($op eq "&&") {
485		return 0;
486	    }
487	}
488    }
489
490    if ($val =~ /(.*)(==|\!=|>=|<=|>|<)(.*)/) {
491	my $ret = process_compare($1, $2, $3);
492	if ($ret < 0) {
493	    die "$name: $.: Unable to process comparison\n";
494	}
495	return $ret;
496    }
497
498    if ($val =~ /^\s*(NOT\s*)?DEFINED\s+(\S+)\s*$/) {
499	if (defined $1) {
500	    return !value_defined($2);
501	} else {
502	    return value_defined($2);
503	}
504    }
505
506    if ($val =~ /^\s*0\s*$/) {
507	return 0;
508    } elsif ($val =~ /^\s*\d+\s*$/) {
509	return 1;
510    }
511
512    die ("$name: $.: Undefined content $val in if statement\n");
513}
514
515sub process_if {
516    my ($name, $value) = @_;
517
518    # Convert variables and replace undefined ones with 0
519    my $val = process_variables($value, 1);
520    my $ret = process_expression $name, $val;
521
522    return $ret;
523}
524
525sub __read_config {
526    my ($config, $current_test_num) = @_;
527
528    my $in;
529    open($in, $config) || die "can't read file $config";
530
531    my $name = $config;
532    $name =~ s,.*/(.*),$1,;
533
534    my $test_num = $$current_test_num;
535    my $default = 1;
536    my $repeat = 1;
537    my $num_tests_set = 0;
538    my $skip = 0;
539    my $rest;
540    my $line;
541    my $test_case = 0;
542    my $if = 0;
543    my $if_set = 0;
544    my $override = 0;
545
546    my %overrides;
547
548    while (<$in>) {
549
550	# ignore blank lines and comments
551	next if (/^\s*$/ || /\s*\#/);
552
553	if (/^\s*(TEST_START|DEFAULTS)\b(.*)/) {
554
555	    my $type = $1;
556	    $rest = $2;
557	    $line = $2;
558
559	    my $old_test_num;
560	    my $old_repeat;
561	    $override = 0;
562
563	    if ($type eq "TEST_START") {
564
565		if ($num_tests_set) {
566		    die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
567		}
568
569		$old_test_num = $test_num;
570		$old_repeat = $repeat;
571
572		$test_num += $repeat;
573		$default = 0;
574		$repeat = 1;
575	    } else {
576		$default = 1;
577	    }
578
579	    # If SKIP is anywhere in the line, the command will be skipped
580	    if ($rest =~ s/\s+SKIP\b//) {
581		$skip = 1;
582	    } else {
583		$test_case = 1;
584		$skip = 0;
585	    }
586
587	    if ($rest =~ s/\sELSE\b//) {
588		if (!$if) {
589		    die "$name: $.: ELSE found with out matching IF section\n$_";
590		}
591		$if = 0;
592
593		if ($if_set) {
594		    $skip = 1;
595		} else {
596		    $skip = 0;
597		}
598	    }
599
600	    if ($rest =~ s/\sIF\s+(.*)//) {
601		if (process_if($name, $1)) {
602		    $if_set = 1;
603		} else {
604		    $skip = 1;
605		}
606		$if = 1;
607	    } else {
608		$if = 0;
609		$if_set = 0;
610	    }
611
612	    if (!$skip) {
613		if ($type eq "TEST_START") {
614		    if ($rest =~ s/\s+ITERATE\s+(\d+)//) {
615			$repeat = $1;
616			$repeat_tests{"$test_num"} = $repeat;
617		    }
618		} elsif ($rest =~ s/\sOVERRIDE\b//) {
619		    # DEFAULT only
620		    $override = 1;
621		    # Clear previous overrides
622		    %overrides = ();
623		}
624	    }
625
626	    if (!$skip && $rest !~ /^\s*$/) {
627		die "$name: $.: Gargbage found after $type\n$_";
628	    }
629
630	    if ($skip && $type eq "TEST_START") {
631		$test_num = $old_test_num;
632		$repeat = $old_repeat;
633	    }
634
635	} elsif (/^\s*ELSE\b(.*)$/) {
636	    if (!$if) {
637		die "$name: $.: ELSE found with out matching IF section\n$_";
638	    }
639	    $rest = $1;
640	    if ($if_set) {
641		$skip = 1;
642		$rest = "";
643	    } else {
644		$skip = 0;
645
646		if ($rest =~ /\sIF\s+(.*)/) {
647		    # May be a ELSE IF section.
648		    if (!process_if($name, $1)) {
649			$skip = 1;
650		    }
651		    $rest = "";
652		} else {
653		    $if = 0;
654		}
655	    }
656
657	    if ($rest !~ /^\s*$/) {
658		die "$name: $.: Gargbage found after DEFAULTS\n$_";
659	    }
660
661	} elsif (/^\s*INCLUDE\s+(\S+)/) {
662
663	    next if ($skip);
664
665	    if (!$default) {
666		die "$name: $.: INCLUDE can only be done in default sections\n$_";
667	    }
668
669	    my $file = process_variables($1);
670
671	    if ($file !~ m,^/,) {
672		# check the path of the config file first
673		if ($config =~ m,(.*)/,) {
674		    if (-f "$1/$file") {
675			$file = "$1/$file";
676		    }
677		}
678	    }
679
680	    if ( ! -r $file ) {
681		die "$name: $.: Can't read file $file\n$_";
682	    }
683
684	    if (__read_config($file, \$test_num)) {
685		$test_case = 1;
686	    }
687
688	} elsif (/^\s*([A-Z_\[\]\d]+)\s*=\s*(.*?)\s*$/) {
689
690	    next if ($skip);
691
692	    my $lvalue = $1;
693	    my $rvalue = $2;
694
695	    if (!$default &&
696		($lvalue eq "NUM_TESTS" ||
697		 $lvalue eq "LOG_FILE" ||
698		 $lvalue eq "CLEAR_LOG")) {
699		die "$name: $.: $lvalue must be set in DEFAULTS section\n";
700	    }
701
702	    if ($lvalue eq "NUM_TESTS") {
703		if ($test_num) {
704		    die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
705		}
706		if (!$default) {
707		    die "$name: $.: NUM_TESTS must be set in default section\n";
708		}
709		$num_tests_set = 1;
710	    }
711
712	    if ($default || $lvalue =~ /\[\d+\]$/) {
713		set_value($lvalue, $rvalue, $override, \%overrides, $name);
714	    } else {
715		my $val = "$lvalue\[$test_num\]";
716		set_value($val, $rvalue, $override, \%overrides, $name);
717
718		if ($repeat > 1) {
719		    $repeats{$val} = $repeat;
720		}
721	    }
722	} elsif (/^\s*([A-Z_\[\]\d]+)\s*:=\s*(.*?)\s*$/) {
723	    next if ($skip);
724
725	    my $lvalue = $1;
726	    my $rvalue = $2;
727
728	    # process config variables.
729	    # Config variables are only active while reading the
730	    # config and can be defined anywhere. They also ignore
731	    # TEST_START and DEFAULTS, but are skipped if they are in
732	    # on of these sections that have SKIP defined.
733	    # The save variable can be
734	    # defined multiple times and the new one simply overrides
735	    # the prevous one.
736	    set_variable($lvalue, $rvalue);
737
738	} else {
739	    die "$name: $.: Garbage found in config\n$_";
740	}
741    }
742
743    if ($test_num) {
744	$test_num += $repeat - 1;
745	$opt{"NUM_TESTS"} = $test_num;
746    }
747
748    close($in);
749
750    $$current_test_num = $test_num;
751
752    return $test_case;
753}
754
755sub get_test_case {
756	print "What test case would you like to run?\n";
757	print " (build, install or boot)\n";
758	print " Other tests are available but require editing the config file\n";
759	my $ans = <STDIN>;
760	chomp $ans;
761	$default{"TEST_TYPE"} = $ans;
762}
763
764sub read_config {
765    my ($config) = @_;
766
767    my $test_case;
768    my $test_num = 0;
769
770    $test_case = __read_config $config, \$test_num;
771
772    # make sure we have all mandatory configs
773    get_ktest_configs;
774
775    # was a test specified?
776    if (!$test_case) {
777	print "No test case specified.\n";
778	get_test_case;
779    }
780
781    # set any defaults
782
783    foreach my $default (keys %default) {
784	if (!defined($opt{$default})) {
785	    $opt{$default} = $default{$default};
786	}
787    }
788}
789
790sub __eval_option {
791    my ($option, $i) = @_;
792
793    # Add space to evaluate the character before $
794    $option = " $option";
795    my $retval = "";
796    my $repeated = 0;
797    my $parent = 0;
798
799    foreach my $test (keys %repeat_tests) {
800	if ($i >= $test &&
801	    $i < $test + $repeat_tests{$test}) {
802
803	    $repeated = 1;
804	    $parent = $test;
805	    last;
806	}
807    }
808
809    while ($option =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) {
810	my $start = $1;
811	my $var = $2;
812	my $end = $3;
813
814	# Append beginning of line
815	$retval = "$retval$start";
816
817	# If the iteration option OPT[$i] exists, then use that.
818	# otherwise see if the default OPT (without [$i]) exists.
819
820	my $o = "$var\[$i\]";
821	my $parento = "$var\[$parent\]";
822
823	if (defined($opt{$o})) {
824	    $o = $opt{$o};
825	    $retval = "$retval$o";
826	} elsif ($repeated && defined($opt{$parento})) {
827	    $o = $opt{$parento};
828	    $retval = "$retval$o";
829	} elsif (defined($opt{$var})) {
830	    $o = $opt{$var};
831	    $retval = "$retval$o";
832	} else {
833	    $retval = "$retval\$\{$var\}";
834	}
835
836	$option = $end;
837    }
838
839    $retval = "$retval$option";
840
841    $retval =~ s/^ //;
842
843    return $retval;
844}
845
846sub eval_option {
847    my ($option, $i) = @_;
848
849    my $prev = "";
850
851    # Since an option can evaluate to another option,
852    # keep iterating until we do not evaluate any more
853    # options.
854    my $r = 0;
855    while ($prev ne $option) {
856	# Check for recursive evaluations.
857	# 100 deep should be more than enough.
858	if ($r++ > 100) {
859	    die "Over 100 evaluations accurred with $option\n" .
860		"Check for recursive variables\n";
861	}
862	$prev = $option;
863	$option = __eval_option($option, $i);
864    }
865
866    return $option;
867}
868
869sub _logit {
870    if (defined($opt{"LOG_FILE"})) {
871	open(OUT, ">> $opt{LOG_FILE}") or die "Can't write to $opt{LOG_FILE}";
872	print OUT @_;
873	close(OUT);
874    }
875}
876
877sub logit {
878    if (defined($opt{"LOG_FILE"})) {
879	_logit @_;
880    } else {
881	print @_;
882    }
883}
884
885sub doprint {
886    print @_;
887    _logit @_;
888}
889
890sub run_command;
891sub start_monitor;
892sub end_monitor;
893sub wait_for_monitor;
894
895sub reboot {
896    my ($time) = @_;
897
898    if (defined($time)) {
899	start_monitor;
900	# flush out current monitor
901	# May contain the reboot success line
902	wait_for_monitor 1;
903    }
904
905    # try to reboot normally
906    if (run_command $reboot) {
907	if (defined($powercycle_after_reboot)) {
908	    sleep $powercycle_after_reboot;
909	    run_command "$power_cycle";
910	}
911    } else {
912	# nope? power cycle it.
913	run_command "$power_cycle";
914    }
915
916    if (defined($time)) {
917	wait_for_monitor($time, $reboot_success_line);
918	end_monitor;
919    }
920}
921
922sub do_not_reboot {
923    my $i = $iteration;
924
925    return $test_type eq "build" || $no_reboot ||
926	($test_type eq "patchcheck" && $opt{"PATCHCHECK_TYPE[$i]"} eq "build") ||
927	($test_type eq "bisect" && $opt{"BISECT_TYPE[$i]"} eq "build");
928}
929
930sub dodie {
931    doprint "CRITICAL FAILURE... ", @_, "\n";
932
933    my $i = $iteration;
934
935    if ($reboot_on_error && !do_not_reboot) {
936
937	doprint "REBOOTING\n";
938	reboot;
939
940    } elsif ($poweroff_on_error && defined($power_off)) {
941	doprint "POWERING OFF\n";
942	`$power_off`;
943    }
944
945    if (defined($opt{"LOG_FILE"})) {
946	print " See $opt{LOG_FILE} for more info.\n";
947    }
948
949    die @_, "\n";
950}
951
952sub open_console {
953    my ($fp) = @_;
954
955    my $flags;
956
957    my $pid = open($fp, "$console|") or
958	dodie "Can't open console $console";
959
960    $flags = fcntl($fp, F_GETFL, 0) or
961	dodie "Can't get flags for the socket: $!";
962    $flags = fcntl($fp, F_SETFL, $flags | O_NONBLOCK) or
963	dodie "Can't set flags for the socket: $!";
964
965    return $pid;
966}
967
968sub close_console {
969    my ($fp, $pid) = @_;
970
971    doprint "kill child process $pid\n";
972    kill 2, $pid;
973
974    print "closing!\n";
975    close($fp);
976}
977
978sub start_monitor {
979    if ($monitor_cnt++) {
980	return;
981    }
982    $monitor_fp = \*MONFD;
983    $monitor_pid = open_console $monitor_fp;
984
985    return;
986
987    open(MONFD, "Stop perl from warning about single use of MONFD");
988}
989
990sub end_monitor {
991    if (--$monitor_cnt) {
992	return;
993    }
994    close_console($monitor_fp, $monitor_pid);
995}
996
997sub wait_for_monitor {
998    my ($time, $stop) = @_;
999    my $full_line = "";
1000    my $line;
1001    my $booted = 0;
1002
1003    doprint "** Wait for monitor to settle down **\n";
1004
1005    # read the monitor and wait for the system to calm down
1006    while (!$booted) {
1007	$line = wait_for_input($monitor_fp, $time);
1008	last if (!defined($line));
1009	print "$line";
1010	$full_line .= $line;
1011
1012	if (defined($stop) && $full_line =~ /$stop/) {
1013	    doprint "wait for monitor detected $stop\n";
1014	    $booted = 1;
1015	}
1016
1017	if ($line =~ /\n/) {
1018	    $full_line = "";
1019	}
1020    }
1021    print "** Monitor flushed **\n";
1022}
1023
1024sub save_logs {
1025	my ($result, $basedir) = @_;
1026	my @t = localtime;
1027	my $date = sprintf "%04d%02d%02d%02d%02d%02d",
1028		1900+$t[5],$t[4],$t[3],$t[2],$t[1],$t[0];
1029
1030	my $type = $build_type;
1031	if ($type =~ /useconfig/) {
1032	    $type = "useconfig";
1033	}
1034
1035	my $dir = "$machine-$test_type-$type-$result-$date";
1036
1037	$dir = "$basedir/$dir";
1038
1039	if (!-d $dir) {
1040	    mkpath($dir) or
1041		die "can't create $dir";
1042	}
1043
1044	my %files = (
1045		"config" => $output_config,
1046		"buildlog" => $buildlog,
1047		"dmesg" => $dmesg,
1048		"testlog" => $testlog,
1049	);
1050
1051	while (my ($name, $source) = each(%files)) {
1052		if (-f "$source") {
1053			cp "$source", "$dir/$name" or
1054				die "failed to copy $source";
1055		}
1056	}
1057
1058	doprint "*** Saved info to $dir ***\n";
1059}
1060
1061sub fail {
1062
1063	if ($die_on_failure) {
1064		dodie @_;
1065	}
1066
1067	doprint "FAILED\n";
1068
1069	my $i = $iteration;
1070
1071	# no need to reboot for just building.
1072	if (!do_not_reboot) {
1073	    doprint "REBOOTING\n";
1074	    reboot $sleep_time;
1075	}
1076
1077	my $name = "";
1078
1079	if (defined($test_name)) {
1080	    $name = " ($test_name)";
1081	}
1082
1083	doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
1084	doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
1085	doprint "KTEST RESULT: TEST $i$name Failed: ", @_, "\n";
1086	doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
1087	doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
1088
1089	if (defined($store_failures)) {
1090	    save_logs "fail", $store_failures;
1091        }
1092
1093	return 1;
1094}
1095
1096sub run_command {
1097    my ($command) = @_;
1098    my $dolog = 0;
1099    my $dord = 0;
1100    my $pid;
1101
1102    $command =~ s/\$SSH_USER/$ssh_user/g;
1103    $command =~ s/\$MACHINE/$machine/g;
1104
1105    doprint("$command ... ");
1106
1107    $pid = open(CMD, "$command 2>&1 |") or
1108	(fail "unable to exec $command" and return 0);
1109
1110    if (defined($opt{"LOG_FILE"})) {
1111	open(LOG, ">>$opt{LOG_FILE}") or
1112	    dodie "failed to write to log";
1113	$dolog = 1;
1114    }
1115
1116    if (defined($redirect)) {
1117	open (RD, ">$redirect") or
1118	    dodie "failed to write to redirect $redirect";
1119	$dord = 1;
1120    }
1121
1122    while (<CMD>) {
1123	print LOG if ($dolog);
1124	print RD  if ($dord);
1125    }
1126
1127    waitpid($pid, 0);
1128    my $failed = $?;
1129
1130    close(CMD);
1131    close(LOG) if ($dolog);
1132    close(RD)  if ($dord);
1133
1134    if ($failed) {
1135	doprint "FAILED!\n";
1136    } else {
1137	doprint "SUCCESS\n";
1138    }
1139
1140    return !$failed;
1141}
1142
1143sub run_ssh {
1144    my ($cmd) = @_;
1145    my $cp_exec = $ssh_exec;
1146
1147    $cp_exec =~ s/\$SSH_COMMAND/$cmd/g;
1148    return run_command "$cp_exec";
1149}
1150
1151sub run_scp {
1152    my ($src, $dst) = @_;
1153    my $cp_scp = $scp_to_target;
1154
1155    $cp_scp =~ s/\$SRC_FILE/$src/g;
1156    $cp_scp =~ s/\$DST_FILE/$dst/g;
1157
1158    return run_command "$cp_scp";
1159}
1160
1161sub get_grub_index {
1162
1163    if ($reboot_type ne "grub") {
1164	return;
1165    }
1166    return if (defined($grub_number));
1167
1168    doprint "Find grub menu ... ";
1169    $grub_number = -1;
1170
1171    my $ssh_grub = $ssh_exec;
1172    $ssh_grub =~ s,\$SSH_COMMAND,cat /boot/grub/menu.lst,g;
1173
1174    open(IN, "$ssh_grub |")
1175	or die "unable to get menu.lst";
1176
1177    my $found = 0;
1178
1179    while (<IN>) {
1180	if (/^\s*title\s+$grub_menu\s*$/) {
1181	    $grub_number++;
1182	    $found = 1;
1183	    last;
1184	} elsif (/^\s*title\s/) {
1185	    $grub_number++;
1186	}
1187    }
1188    close(IN);
1189
1190    die "Could not find '$grub_menu' in /boot/grub/menu on $machine"
1191	if (!$found);
1192    doprint "$grub_number\n";
1193}
1194
1195sub wait_for_input
1196{
1197    my ($fp, $time) = @_;
1198    my $rin;
1199    my $ready;
1200    my $line;
1201    my $ch;
1202
1203    if (!defined($time)) {
1204	$time = $timeout;
1205    }
1206
1207    $rin = '';
1208    vec($rin, fileno($fp), 1) = 1;
1209    $ready = select($rin, undef, undef, $time);
1210
1211    $line = "";
1212
1213    # try to read one char at a time
1214    while (sysread $fp, $ch, 1) {
1215	$line .= $ch;
1216	last if ($ch eq "\n");
1217    }
1218
1219    if (!length($line)) {
1220	return undef;
1221    }
1222
1223    return $line;
1224}
1225
1226sub reboot_to {
1227    if ($reboot_type eq "grub") {
1228	run_ssh "'(echo \"savedefault --default=$grub_number --once\" | grub --batch)'";
1229	reboot;
1230	return;
1231    }
1232
1233    run_command "$reboot_script";
1234}
1235
1236sub get_sha1 {
1237    my ($commit) = @_;
1238
1239    doprint "git rev-list --max-count=1 $commit ... ";
1240    my $sha1 = `git rev-list --max-count=1 $commit`;
1241    my $ret = $?;
1242
1243    logit $sha1;
1244
1245    if ($ret) {
1246	doprint "FAILED\n";
1247	dodie "Failed to get git $commit";
1248    }
1249
1250    print "SUCCESS\n";
1251
1252    chomp $sha1;
1253
1254    return $sha1;
1255}
1256
1257sub monitor {
1258    my $booted = 0;
1259    my $bug = 0;
1260    my $skip_call_trace = 0;
1261    my $loops;
1262
1263    wait_for_monitor 5;
1264
1265    my $line;
1266    my $full_line = "";
1267
1268    open(DMESG, "> $dmesg") or
1269	die "unable to write to $dmesg";
1270
1271    reboot_to;
1272
1273    my $success_start;
1274    my $failure_start;
1275    my $monitor_start = time;
1276    my $done = 0;
1277    my $version_found = 0;
1278
1279    while (!$done) {
1280
1281	if ($bug && defined($stop_after_failure) &&
1282	    $stop_after_failure >= 0) {
1283	    my $time = $stop_after_failure - (time - $failure_start);
1284	    $line = wait_for_input($monitor_fp, $time);
1285	    if (!defined($line)) {
1286		doprint "bug timed out after $booted_timeout seconds\n";
1287		doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
1288		last;
1289	    }
1290	} elsif ($booted) {
1291	    $line = wait_for_input($monitor_fp, $booted_timeout);
1292	    if (!defined($line)) {
1293		my $s = $booted_timeout == 1 ? "" : "s";
1294		doprint "Successful boot found: break after $booted_timeout second$s\n";
1295		last;
1296	    }
1297	} else {
1298	    $line = wait_for_input($monitor_fp);
1299	    if (!defined($line)) {
1300		my $s = $timeout == 1 ? "" : "s";
1301		doprint "Timed out after $timeout second$s\n";
1302		last;
1303	    }
1304	}
1305
1306	doprint $line;
1307	print DMESG $line;
1308
1309	# we are not guaranteed to get a full line
1310	$full_line .= $line;
1311
1312	if ($full_line =~ /$success_line/) {
1313	    $booted = 1;
1314	    $success_start = time;
1315	}
1316
1317	if ($booted && defined($stop_after_success) &&
1318	    $stop_after_success >= 0) {
1319	    my $now = time;
1320	    if ($now - $success_start >= $stop_after_success) {
1321		doprint "Test forced to stop after $stop_after_success seconds after success\n";
1322		last;
1323	    }
1324	}
1325
1326	if ($full_line =~ /\[ backtrace testing \]/) {
1327	    $skip_call_trace = 1;
1328	}
1329
1330	if ($full_line =~ /call trace:/i) {
1331	    if (!$bug && !$skip_call_trace) {
1332		$bug = 1;
1333		$failure_start = time;
1334	    }
1335	}
1336
1337	if ($bug && defined($stop_after_failure) &&
1338	    $stop_after_failure >= 0) {
1339	    my $now = time;
1340	    if ($now - $failure_start >= $stop_after_failure) {
1341		doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
1342		last;
1343	    }
1344	}
1345
1346	if ($full_line =~ /\[ end of backtrace testing \]/) {
1347	    $skip_call_trace = 0;
1348	}
1349
1350	if ($full_line =~ /Kernel panic -/) {
1351	    $failure_start = time;
1352	    $bug = 1;
1353	}
1354
1355	# Detect triple faults by testing the banner
1356	if ($full_line =~ /\bLinux version (\S+).*\n/) {
1357	    if ($1 eq $version) {
1358		$version_found = 1;
1359	    } elsif ($version_found && $detect_triplefault) {
1360		# We already booted into the kernel we are testing,
1361		# but now we booted into another kernel?
1362		# Consider this a triple fault.
1363		doprint "Aleady booted in Linux kernel $version, but now\n";
1364		doprint "we booted into Linux kernel $1.\n";
1365		doprint "Assuming that this is a triple fault.\n";
1366		doprint "To disable this: set DETECT_TRIPLE_FAULT to 0\n";
1367		last;
1368	    }
1369	}
1370
1371	if ($line =~ /\n/) {
1372	    $full_line = "";
1373	}
1374
1375	if ($stop_test_after > 0 && !$booted && !$bug) {
1376	    if (time - $monitor_start > $stop_test_after) {
1377		doprint "STOP_TEST_AFTER ($stop_test_after seconds) timed out\n";
1378		$done = 1;
1379	    }
1380	}
1381    }
1382
1383    close(DMESG);
1384
1385    if ($bug) {
1386	return 0 if ($in_bisect);
1387	fail "failed - got a bug report" and return 0;
1388    }
1389
1390    if (!$booted) {
1391	return 0 if ($in_bisect);
1392	fail "failed - never got a boot prompt." and return 0;
1393    }
1394
1395    return 1;
1396}
1397
1398sub do_post_install {
1399
1400    return if (!defined($post_install));
1401
1402    my $cp_post_install = $post_install;
1403    $cp_post_install =~ s/\$KERNEL_VERSION/$version/g;
1404    run_command "$cp_post_install" or
1405	dodie "Failed to run post install";
1406}
1407
1408sub install {
1409
1410    return if ($no_install);
1411
1412    run_scp "$outputdir/$build_target", "$target_image" or
1413	dodie "failed to copy image";
1414
1415    my $install_mods = 0;
1416
1417    # should we process modules?
1418    $install_mods = 0;
1419    open(IN, "$output_config") or dodie("Can't read config file");
1420    while (<IN>) {
1421	if (/CONFIG_MODULES(=y)?/) {
1422	    $install_mods = 1 if (defined($1));
1423	    last;
1424	}
1425    }
1426    close(IN);
1427
1428    if (!$install_mods) {
1429	do_post_install;
1430	doprint "No modules needed\n";
1431	return;
1432    }
1433
1434    run_command "$make INSTALL_MOD_PATH=$tmpdir modules_install" or
1435	dodie "Failed to install modules";
1436
1437    my $modlib = "/lib/modules/$version";
1438    my $modtar = "ktest-mods.tar.bz2";
1439
1440    run_ssh "rm -rf $modlib" or
1441	dodie "failed to remove old mods: $modlib";
1442
1443    # would be nice if scp -r did not follow symbolic links
1444    run_command "cd $tmpdir && tar -cjf $modtar lib/modules/$version" or
1445	dodie "making tarball";
1446
1447    run_scp "$tmpdir/$modtar", "/tmp" or
1448	dodie "failed to copy modules";
1449
1450    unlink "$tmpdir/$modtar";
1451
1452    run_ssh "'(cd / && tar xjf /tmp/$modtar)'" or
1453	dodie "failed to tar modules";
1454
1455    run_ssh "rm -f /tmp/$modtar";
1456
1457    do_post_install;
1458}
1459
1460sub get_version {
1461    # get the release name
1462    doprint "$make kernelrelease ... ";
1463    $version = `$make kernelrelease | tail -1`;
1464    chomp($version);
1465    doprint "$version\n";
1466}
1467
1468sub start_monitor_and_boot {
1469    # Make sure the stable kernel has finished booting
1470    start_monitor;
1471    wait_for_monitor 5;
1472    end_monitor;
1473
1474    get_grub_index;
1475    get_version;
1476    install;
1477
1478    start_monitor;
1479    return monitor;
1480}
1481
1482sub check_buildlog {
1483    my ($patch) = @_;
1484
1485    my @files = `git show $patch | diffstat -l`;
1486
1487    open(IN, "git show $patch |") or
1488	dodie "failed to show $patch";
1489    while (<IN>) {
1490	if (m,^--- a/(.*),) {
1491	    chomp $1;
1492	    $files[$#files] = $1;
1493	}
1494    }
1495    close(IN);
1496
1497    open(IN, $buildlog) or dodie "Can't open $buildlog";
1498    while (<IN>) {
1499	if (/^\s*(.*?):.*(warning|error)/) {
1500	    my $err = $1;
1501	    foreach my $file (@files) {
1502		my $fullpath = "$builddir/$file";
1503		if ($file eq $err || $fullpath eq $err) {
1504		    fail "$file built with warnings" and return 0;
1505		}
1506	    }
1507	}
1508    }
1509    close(IN);
1510
1511    return 1;
1512}
1513
1514sub apply_min_config {
1515    my $outconfig = "$output_config.new";
1516
1517    # Read the config file and remove anything that
1518    # is in the force_config hash (from minconfig and others)
1519    # then add the force config back.
1520
1521    doprint "Applying minimum configurations into $output_config.new\n";
1522
1523    open (OUT, ">$outconfig") or
1524	dodie "Can't create $outconfig";
1525
1526    if (-f $output_config) {
1527	open (IN, $output_config) or
1528	    dodie "Failed to open $output_config";
1529	while (<IN>) {
1530	    if (/^(# )?(CONFIG_[^\s=]*)/) {
1531		next if (defined($force_config{$2}));
1532	    }
1533	    print OUT;
1534	}
1535	close IN;
1536    }
1537    foreach my $config (keys %force_config) {
1538	print OUT "$force_config{$config}\n";
1539    }
1540    close OUT;
1541
1542    run_command "mv $outconfig $output_config";
1543}
1544
1545sub make_oldconfig {
1546
1547    my @force_list = keys %force_config;
1548
1549    if ($#force_list >= 0) {
1550	apply_min_config;
1551    }
1552
1553    if (!run_command "$make oldnoconfig") {
1554	# Perhaps oldnoconfig doesn't exist in this version of the kernel
1555	# try a yes '' | oldconfig
1556	doprint "oldnoconfig failed, trying yes '' | make oldconfig\n";
1557	run_command "yes '' | $make oldconfig" or
1558	    dodie "failed make config oldconfig";
1559    }
1560}
1561
1562# read a config file and use this to force new configs.
1563sub load_force_config {
1564    my ($config) = @_;
1565
1566    open(IN, $config) or
1567	dodie "failed to read $config";
1568    while (<IN>) {
1569	chomp;
1570	if (/^(CONFIG[^\s=]*)(\s*=.*)/) {
1571	    $force_config{$1} = $_;
1572	} elsif (/^# (CONFIG_\S*) is not set/) {
1573	    $force_config{$1} = $_;
1574	}
1575    }
1576    close IN;
1577}
1578
1579sub build {
1580    my ($type) = @_;
1581
1582    unlink $buildlog;
1583
1584    # Failed builds should not reboot the target
1585    my $save_no_reboot = $no_reboot;
1586    $no_reboot = 1;
1587
1588    if (defined($pre_build)) {
1589	my $ret = run_command $pre_build;
1590	if (!$ret && defined($pre_build_die) &&
1591	    $pre_build_die) {
1592	    dodie "failed to pre_build\n";
1593	}
1594    }
1595
1596    if ($type =~ /^useconfig:(.*)/) {
1597	run_command "cp $1 $output_config" or
1598	    dodie "could not copy $1 to .config";
1599
1600	$type = "oldconfig";
1601    }
1602
1603    # old config can ask questions
1604    if ($type eq "oldconfig") {
1605	$type = "oldnoconfig";
1606
1607	# allow for empty configs
1608	run_command "touch $output_config";
1609
1610	if (!$noclean) {
1611	    run_command "mv $output_config $outputdir/config_temp" or
1612		dodie "moving .config";
1613
1614	    run_command "$make mrproper" or dodie "make mrproper";
1615
1616	    run_command "mv $outputdir/config_temp $output_config" or
1617		dodie "moving config_temp";
1618	}
1619
1620    } elsif (!$noclean) {
1621	unlink "$output_config";
1622	run_command "$make mrproper" or
1623	    dodie "make mrproper";
1624    }
1625
1626    # add something to distinguish this build
1627    open(OUT, "> $outputdir/localversion") or dodie("Can't make localversion file");
1628    print OUT "$localversion\n";
1629    close(OUT);
1630
1631    if (defined($minconfig)) {
1632	load_force_config($minconfig);
1633    }
1634
1635    if ($type ne "oldnoconfig") {
1636	run_command "$make $type" or
1637	    dodie "failed make config";
1638    }
1639    # Run old config regardless, to enforce min configurations
1640    make_oldconfig;
1641
1642    $redirect = "$buildlog";
1643    my $build_ret = run_command "$make $build_options";
1644    undef $redirect;
1645
1646    if (defined($post_build)) {
1647	my $ret = run_command $post_build;
1648	if (!$ret && defined($post_build_die) &&
1649	    $post_build_die) {
1650	    dodie "failed to post_build\n";
1651	}
1652    }
1653
1654    if (!$build_ret) {
1655	# bisect may need this to pass
1656	if ($in_bisect) {
1657	    $no_reboot = $save_no_reboot;
1658	    return 0;
1659	}
1660	fail "failed build" and return 0;
1661    }
1662
1663    $no_reboot = $save_no_reboot;
1664
1665    return 1;
1666}
1667
1668sub halt {
1669    if (!run_ssh "halt" or defined($power_off)) {
1670	if (defined($poweroff_after_halt)) {
1671	    sleep $poweroff_after_halt;
1672	    run_command "$power_off";
1673	}
1674    } else {
1675	# nope? the zap it!
1676	run_command "$power_off";
1677    }
1678}
1679
1680sub success {
1681    my ($i) = @_;
1682
1683    $successes++;
1684
1685    my $name = "";
1686
1687    if (defined($test_name)) {
1688	$name = " ($test_name)";
1689    }
1690
1691    doprint "\n\n*******************************************\n";
1692    doprint     "*******************************************\n";
1693    doprint     "KTEST RESULT: TEST $i$name SUCCESS!!!!         **\n";
1694    doprint     "*******************************************\n";
1695    doprint     "*******************************************\n";
1696
1697    if (defined($store_successes)) {
1698        save_logs "success", $store_successes;
1699    }
1700
1701    if ($i != $opt{"NUM_TESTS"} && !do_not_reboot) {
1702	doprint "Reboot and wait $sleep_time seconds\n";
1703	reboot $sleep_time;
1704    }
1705}
1706
1707sub answer_bisect {
1708    for (;;) {
1709	doprint "Pass or fail? [p/f]";
1710	my $ans = <STDIN>;
1711	chomp $ans;
1712	if ($ans eq "p" || $ans eq "P") {
1713	    return 1;
1714	} elsif ($ans eq "f" || $ans eq "F") {
1715	    return 0;
1716	} else {
1717	    print "Please answer 'P' or 'F'\n";
1718	}
1719    }
1720}
1721
1722sub child_run_test {
1723    my $failed = 0;
1724
1725    # child should have no power
1726    $reboot_on_error = 0;
1727    $poweroff_on_error = 0;
1728    $die_on_failure = 1;
1729
1730    $redirect = "$testlog";
1731    run_command $run_test or $failed = 1;
1732    undef $redirect;
1733
1734    exit $failed;
1735}
1736
1737my $child_done;
1738
1739sub child_finished {
1740    $child_done = 1;
1741}
1742
1743sub do_run_test {
1744    my $child_pid;
1745    my $child_exit;
1746    my $line;
1747    my $full_line;
1748    my $bug = 0;
1749
1750    wait_for_monitor 1;
1751
1752    doprint "run test $run_test\n";
1753
1754    $child_done = 0;
1755
1756    $SIG{CHLD} = qw(child_finished);
1757
1758    $child_pid = fork;
1759
1760    child_run_test if (!$child_pid);
1761
1762    $full_line = "";
1763
1764    do {
1765	$line = wait_for_input($monitor_fp, 1);
1766	if (defined($line)) {
1767
1768	    # we are not guaranteed to get a full line
1769	    $full_line .= $line;
1770	    doprint $line;
1771
1772	    if ($full_line =~ /call trace:/i) {
1773		$bug = 1;
1774	    }
1775
1776	    if ($full_line =~ /Kernel panic -/) {
1777		$bug = 1;
1778	    }
1779
1780	    if ($line =~ /\n/) {
1781		$full_line = "";
1782	    }
1783	}
1784    } while (!$child_done && !$bug);
1785
1786    if ($bug) {
1787	my $failure_start = time;
1788	my $now;
1789	do {
1790	    $line = wait_for_input($monitor_fp, 1);
1791	    if (defined($line)) {
1792		doprint $line;
1793	    }
1794	    $now = time;
1795	    if ($now - $failure_start >= $stop_after_failure) {
1796		last;
1797	    }
1798	} while (defined($line));
1799
1800	doprint "Detected kernel crash!\n";
1801	# kill the child with extreme prejudice
1802	kill 9, $child_pid;
1803    }
1804
1805    waitpid $child_pid, 0;
1806    $child_exit = $?;
1807
1808    if ($bug || $child_exit) {
1809	return 0 if $in_bisect;
1810	fail "test failed" and return 0;
1811    }
1812    return 1;
1813}
1814
1815sub run_git_bisect {
1816    my ($command) = @_;
1817
1818    doprint "$command ... ";
1819
1820    my $output = `$command 2>&1`;
1821    my $ret = $?;
1822
1823    logit $output;
1824
1825    if ($ret) {
1826	doprint "FAILED\n";
1827	dodie "Failed to git bisect";
1828    }
1829
1830    doprint "SUCCESS\n";
1831    if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\))\s+\[([[:xdigit:]]+)\]/) {
1832	doprint "$1 [$2]\n";
1833    } elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) {
1834	$bisect_bad = $1;
1835	doprint "Found bad commit... $1\n";
1836	return 0;
1837    } else {
1838	# we already logged it, just print it now.
1839	print $output;
1840    }
1841
1842    return 1;
1843}
1844
1845sub bisect_reboot {
1846    doprint "Reboot and sleep $bisect_sleep_time seconds\n";
1847    reboot $bisect_sleep_time;
1848}
1849
1850# returns 1 on success, 0 on failure, -1 on skip
1851sub run_bisect_test {
1852    my ($type, $buildtype) = @_;
1853
1854    my $failed = 0;
1855    my $result;
1856    my $output;
1857    my $ret;
1858
1859    $in_bisect = 1;
1860
1861    build $buildtype or $failed = 1;
1862
1863    if ($type ne "build") {
1864	if ($failed && $bisect_skip) {
1865	    $in_bisect = 0;
1866	    return -1;
1867	}
1868	dodie "Failed on build" if $failed;
1869
1870	# Now boot the box
1871	start_monitor_and_boot or $failed = 1;
1872
1873	if ($type ne "boot") {
1874	    if ($failed && $bisect_skip) {
1875		end_monitor;
1876		bisect_reboot;
1877		$in_bisect = 0;
1878		return -1;
1879	    }
1880	    dodie "Failed on boot" if $failed;
1881
1882	    do_run_test or $failed = 1;
1883	}
1884	end_monitor;
1885    }
1886
1887    if ($failed) {
1888	$result = 0;
1889    } else {
1890	$result = 1;
1891    }
1892
1893    # reboot the box to a kernel we can ssh to
1894    if ($type ne "build") {
1895	bisect_reboot;
1896    }
1897    $in_bisect = 0;
1898
1899    return $result;
1900}
1901
1902sub run_bisect {
1903    my ($type) = @_;
1904    my $buildtype = "oldconfig";
1905
1906    # We should have a minconfig to use?
1907    if (defined($minconfig)) {
1908	$buildtype = "useconfig:$minconfig";
1909    }
1910
1911    my $ret = run_bisect_test $type, $buildtype;
1912
1913    if ($bisect_manual) {
1914	$ret = answer_bisect;
1915    }
1916
1917    # Are we looking for where it worked, not failed?
1918    if ($reverse_bisect) {
1919	$ret = !$ret;
1920    }
1921
1922    if ($ret > 0) {
1923	return "good";
1924    } elsif ($ret == 0) {
1925	return  "bad";
1926    } elsif ($bisect_skip) {
1927	doprint "HIT A BAD COMMIT ... SKIPPING\n";
1928	return "skip";
1929    }
1930}
1931
1932sub update_bisect_replay {
1933    my $tmp_log = "$tmpdir/ktest_bisect_log";
1934    run_command "git bisect log > $tmp_log" or
1935	die "can't create bisect log";
1936    return $tmp_log;
1937}
1938
1939sub bisect {
1940    my ($i) = @_;
1941
1942    my $result;
1943
1944    die "BISECT_GOOD[$i] not defined\n"	if (!defined($opt{"BISECT_GOOD[$i]"}));
1945    die "BISECT_BAD[$i] not defined\n"	if (!defined($opt{"BISECT_BAD[$i]"}));
1946    die "BISECT_TYPE[$i] not defined\n"	if (!defined($opt{"BISECT_TYPE[$i]"}));
1947
1948    my $good = $opt{"BISECT_GOOD[$i]"};
1949    my $bad = $opt{"BISECT_BAD[$i]"};
1950    my $type = $opt{"BISECT_TYPE[$i]"};
1951    my $start = $opt{"BISECT_START[$i]"};
1952    my $replay = $opt{"BISECT_REPLAY[$i]"};
1953    my $start_files = $opt{"BISECT_FILES[$i]"};
1954
1955    if (defined($start_files)) {
1956	$start_files = " -- " . $start_files;
1957    } else {
1958	$start_files = "";
1959    }
1960
1961    # convert to true sha1's
1962    $good = get_sha1($good);
1963    $bad = get_sha1($bad);
1964
1965    if (defined($opt{"BISECT_REVERSE[$i]"}) &&
1966	$opt{"BISECT_REVERSE[$i]"} == 1) {
1967	doprint "Performing a reverse bisect (bad is good, good is bad!)\n";
1968	$reverse_bisect = 1;
1969    } else {
1970	$reverse_bisect = 0;
1971    }
1972
1973    # Can't have a test without having a test to run
1974    if ($type eq "test" && !defined($run_test)) {
1975	$type = "boot";
1976    }
1977
1978    # Check if a bisect was running
1979    my $bisect_start_file = "$builddir/.git/BISECT_START";
1980
1981    my $check = $opt{"BISECT_CHECK[$i]"};
1982    my $do_check = defined($check) && $check ne "0";
1983
1984    if ( -f $bisect_start_file ) {
1985	print "Bisect in progress found\n";
1986	if ($do_check) {
1987	    print " If you say yes, then no checks of good or bad will be done\n";
1988	}
1989	if (defined($replay)) {
1990	    print "** BISECT_REPLAY is defined in config file **";
1991	    print " Ignore config option and perform new git bisect log?\n";
1992	    if (read_ync " (yes, no, or cancel) ") {
1993		$replay = update_bisect_replay;
1994		$do_check = 0;
1995	    }
1996	} elsif (read_yn "read git log and continue?") {
1997	    $replay = update_bisect_replay;
1998	    $do_check = 0;
1999	}
2000    }
2001
2002    if ($do_check) {
2003
2004	# get current HEAD
2005	my $head = get_sha1("HEAD");
2006
2007	if ($check ne "good") {
2008	    doprint "TESTING BISECT BAD [$bad]\n";
2009	    run_command "git checkout $bad" or
2010		die "Failed to checkout $bad";
2011
2012	    $result = run_bisect $type;
2013
2014	    if ($result ne "bad") {
2015		fail "Tested BISECT_BAD [$bad] and it succeeded" and return 0;
2016	    }
2017	}
2018
2019	if ($check ne "bad") {
2020	    doprint "TESTING BISECT GOOD [$good]\n";
2021	    run_command "git checkout $good" or
2022		die "Failed to checkout $good";
2023
2024	    $result = run_bisect $type;
2025
2026	    if ($result ne "good") {
2027		fail "Tested BISECT_GOOD [$good] and it failed" and return 0;
2028	    }
2029	}
2030
2031	# checkout where we started
2032	run_command "git checkout $head" or
2033	    die "Failed to checkout $head";
2034    }
2035
2036    run_command "git bisect start$start_files" or
2037	dodie "could not start bisect";
2038
2039    run_command "git bisect good $good" or
2040	dodie "could not set bisect good to $good";
2041
2042    run_git_bisect "git bisect bad $bad" or
2043	dodie "could not set bisect bad to $bad";
2044
2045    if (defined($replay)) {
2046	run_command "git bisect replay $replay" or
2047	    dodie "failed to run replay";
2048    }
2049
2050    if (defined($start)) {
2051	run_command "git checkout $start" or
2052	    dodie "failed to checkout $start";
2053    }
2054
2055    my $test;
2056    do {
2057	$result = run_bisect $type;
2058	$test = run_git_bisect "git bisect $result";
2059    } while ($test);
2060
2061    run_command "git bisect log" or
2062	dodie "could not capture git bisect log";
2063
2064    run_command "git bisect reset" or
2065	dodie "could not reset git bisect";
2066
2067    doprint "Bad commit was [$bisect_bad]\n";
2068
2069    success $i;
2070}
2071
2072my %config_ignore;
2073my %config_set;
2074
2075my %config_list;
2076my %null_config;
2077
2078my %dependency;
2079
2080sub assign_configs {
2081    my ($hash, $config) = @_;
2082
2083    open (IN, $config)
2084	or dodie "Failed to read $config";
2085
2086    while (<IN>) {
2087	if (/^((CONFIG\S*)=.*)/) {
2088	    ${$hash}{$2} = $1;
2089	}
2090    }
2091
2092    close(IN);
2093}
2094
2095sub process_config_ignore {
2096    my ($config) = @_;
2097
2098    assign_configs \%config_ignore, $config;
2099}
2100
2101sub read_current_config {
2102    my ($config_ref) = @_;
2103
2104    %{$config_ref} = ();
2105    undef %{$config_ref};
2106
2107    my @key = keys %{$config_ref};
2108    if ($#key >= 0) {
2109	print "did not delete!\n";
2110	exit;
2111    }
2112    open (IN, "$output_config");
2113
2114    while (<IN>) {
2115	if (/^(CONFIG\S+)=(.*)/) {
2116	    ${$config_ref}{$1} = $2;
2117	}
2118    }
2119    close(IN);
2120}
2121
2122sub get_dependencies {
2123    my ($config) = @_;
2124
2125    my $arr = $dependency{$config};
2126    if (!defined($arr)) {
2127	return ();
2128    }
2129
2130    my @deps = @{$arr};
2131
2132    foreach my $dep (@{$arr}) {
2133	print "ADD DEP $dep\n";
2134	@deps = (@deps, get_dependencies $dep);
2135    }
2136
2137    return @deps;
2138}
2139
2140sub create_config {
2141    my @configs = @_;
2142
2143    open(OUT, ">$output_config") or dodie "Can not write to $output_config";
2144
2145    foreach my $config (@configs) {
2146	print OUT "$config_set{$config}\n";
2147	my @deps = get_dependencies $config;
2148	foreach my $dep (@deps) {
2149	    print OUT "$config_set{$dep}\n";
2150	}
2151    }
2152
2153    foreach my $config (keys %config_ignore) {
2154	print OUT "$config_ignore{$config}\n";
2155    }
2156    close(OUT);
2157
2158#    exit;
2159    make_oldconfig;
2160}
2161
2162sub compare_configs {
2163    my (%a, %b) = @_;
2164
2165    foreach my $item (keys %a) {
2166	if (!defined($b{$item})) {
2167	    print "diff $item\n";
2168	    return 1;
2169	}
2170	delete $b{$item};
2171    }
2172
2173    my @keys = keys %b;
2174    if ($#keys) {
2175	print "diff2 $keys[0]\n";
2176    }
2177    return -1 if ($#keys >= 0);
2178
2179    return 0;
2180}
2181
2182sub run_config_bisect_test {
2183    my ($type) = @_;
2184
2185    return run_bisect_test $type, "oldconfig";
2186}
2187
2188sub process_passed {
2189    my (%configs) = @_;
2190
2191    doprint "These configs had no failure: (Enabling them for further compiles)\n";
2192    # Passed! All these configs are part of a good compile.
2193    # Add them to the min options.
2194    foreach my $config (keys %configs) {
2195	if (defined($config_list{$config})) {
2196	    doprint " removing $config\n";
2197	    $config_ignore{$config} = $config_list{$config};
2198	    delete $config_list{$config};
2199	}
2200    }
2201    doprint "config copied to $outputdir/config_good\n";
2202    run_command "cp -f $output_config $outputdir/config_good";
2203}
2204
2205sub process_failed {
2206    my ($config) = @_;
2207
2208    doprint "\n\n***************************************\n";
2209    doprint "Found bad config: $config\n";
2210    doprint "***************************************\n\n";
2211}
2212
2213sub run_config_bisect {
2214
2215    my @start_list = keys %config_list;
2216
2217    if ($#start_list < 0) {
2218	doprint "No more configs to test!!!\n";
2219	return -1;
2220    }
2221
2222    doprint "***** RUN TEST ***\n";
2223    my $type = $opt{"CONFIG_BISECT_TYPE[$iteration]"};
2224    my $ret;
2225    my %current_config;
2226
2227    my $count = $#start_list + 1;
2228    doprint "  $count configs to test\n";
2229
2230    my $half = int($#start_list / 2);
2231
2232    do {
2233	my @tophalf = @start_list[0 .. $half];
2234
2235	create_config @tophalf;
2236	read_current_config \%current_config;
2237
2238	$count = $#tophalf + 1;
2239	doprint "Testing $count configs\n";
2240	my $found = 0;
2241	# make sure we test something
2242	foreach my $config (@tophalf) {
2243	    if (defined($current_config{$config})) {
2244		logit " $config\n";
2245		$found = 1;
2246	    }
2247	}
2248	if (!$found) {
2249	    # try the other half
2250	    doprint "Top half produced no set configs, trying bottom half\n";
2251	    @tophalf = @start_list[$half + 1 .. $#start_list];
2252	    create_config @tophalf;
2253	    read_current_config \%current_config;
2254	    foreach my $config (@tophalf) {
2255		if (defined($current_config{$config})) {
2256		    logit " $config\n";
2257		    $found = 1;
2258		}
2259	    }
2260	    if (!$found) {
2261		doprint "Failed: Can't make new config with current configs\n";
2262		foreach my $config (@start_list) {
2263		    doprint "  CONFIG: $config\n";
2264		}
2265		return -1;
2266	    }
2267	    $count = $#tophalf + 1;
2268	    doprint "Testing $count configs\n";
2269	}
2270
2271	$ret = run_config_bisect_test $type;
2272	if ($bisect_manual) {
2273	    $ret = answer_bisect;
2274	}
2275	if ($ret) {
2276	    process_passed %current_config;
2277	    return 0;
2278	}
2279
2280	doprint "This config had a failure.\n";
2281	doprint "Removing these configs that were not set in this config:\n";
2282	doprint "config copied to $outputdir/config_bad\n";
2283	run_command "cp -f $output_config $outputdir/config_bad";
2284
2285	# A config exists in this group that was bad.
2286	foreach my $config (keys %config_list) {
2287	    if (!defined($current_config{$config})) {
2288		doprint " removing $config\n";
2289		delete $config_list{$config};
2290	    }
2291	}
2292
2293	@start_list = @tophalf;
2294
2295	if ($#start_list == 0) {
2296	    process_failed $start_list[0];
2297	    return 1;
2298	}
2299
2300	# remove half the configs we are looking at and see if
2301	# they are good.
2302	$half = int($#start_list / 2);
2303    } while ($#start_list > 0);
2304
2305    # we found a single config, try it again unless we are running manually
2306
2307    if ($bisect_manual) {
2308	process_failed $start_list[0];
2309	return 1;
2310    }
2311
2312    my @tophalf = @start_list[0 .. 0];
2313
2314    $ret = run_config_bisect_test $type;
2315    if ($ret) {
2316	process_passed %current_config;
2317	return 0;
2318    }
2319
2320    process_failed $start_list[0];
2321    return 1;
2322}
2323
2324sub config_bisect {
2325    my ($i) = @_;
2326
2327    my $start_config = $opt{"CONFIG_BISECT[$i]"};
2328
2329    my $tmpconfig = "$tmpdir/use_config";
2330
2331    if (defined($config_bisect_good)) {
2332	process_config_ignore $config_bisect_good;
2333    }
2334
2335    # Make the file with the bad config and the min config
2336    if (defined($minconfig)) {
2337	# read the min config for things to ignore
2338	run_command "cp $minconfig $tmpconfig" or
2339	    dodie "failed to copy $minconfig to $tmpconfig";
2340    } else {
2341	unlink $tmpconfig;
2342    }
2343
2344    if (-f $tmpconfig) {
2345	load_force_config($tmpconfig);
2346	process_config_ignore $tmpconfig;
2347    }
2348
2349    # now process the start config
2350    run_command "cp $start_config $output_config" or
2351	dodie "failed to copy $start_config to $output_config";
2352
2353    # read directly what we want to check
2354    my %config_check;
2355    open (IN, $output_config)
2356	or dodie "faied to open $output_config";
2357
2358    while (<IN>) {
2359	if (/^((CONFIG\S*)=.*)/) {
2360	    $config_check{$2} = $1;
2361	}
2362    }
2363    close(IN);
2364
2365    # Now run oldconfig with the minconfig
2366    make_oldconfig;
2367
2368    # check to see what we lost (or gained)
2369    open (IN, $output_config)
2370	or dodie "Failed to read $start_config";
2371
2372    my %removed_configs;
2373    my %added_configs;
2374
2375    while (<IN>) {
2376	if (/^((CONFIG\S*)=.*)/) {
2377	    # save off all options
2378	    $config_set{$2} = $1;
2379	    if (defined($config_check{$2})) {
2380		if (defined($config_ignore{$2})) {
2381		    $removed_configs{$2} = $1;
2382		} else {
2383		    $config_list{$2} = $1;
2384		}
2385	    } elsif (!defined($config_ignore{$2})) {
2386		$added_configs{$2} = $1;
2387		$config_list{$2} = $1;
2388	    }
2389	}
2390    }
2391    close(IN);
2392
2393    my @confs = keys %removed_configs;
2394    if ($#confs >= 0) {
2395	doprint "Configs overridden by default configs and removed from check:\n";
2396	foreach my $config (@confs) {
2397	    doprint " $config\n";
2398	}
2399    }
2400    @confs = keys %added_configs;
2401    if ($#confs >= 0) {
2402	doprint "Configs appearing in make oldconfig and added:\n";
2403	foreach my $config (@confs) {
2404	    doprint " $config\n";
2405	}
2406    }
2407
2408    my %config_test;
2409    my $once = 0;
2410
2411    # Sometimes kconfig does weird things. We must make sure
2412    # that the config we autocreate has everything we need
2413    # to test, otherwise we may miss testing configs, or
2414    # may not be able to create a new config.
2415    # Here we create a config with everything set.
2416    create_config (keys %config_list);
2417    read_current_config \%config_test;
2418    foreach my $config (keys %config_list) {
2419	if (!defined($config_test{$config})) {
2420	    if (!$once) {
2421		$once = 1;
2422		doprint "Configs not produced by kconfig (will not be checked):\n";
2423	    }
2424	    doprint "  $config\n";
2425	    delete $config_list{$config};
2426	}
2427    }
2428    my $ret;
2429    do {
2430	$ret = run_config_bisect;
2431    } while (!$ret);
2432
2433    return $ret if ($ret < 0);
2434
2435    success $i;
2436}
2437
2438sub patchcheck_reboot {
2439    doprint "Reboot and sleep $patchcheck_sleep_time seconds\n";
2440    reboot $patchcheck_sleep_time;
2441}
2442
2443sub patchcheck {
2444    my ($i) = @_;
2445
2446    die "PATCHCHECK_START[$i] not defined\n"
2447	if (!defined($opt{"PATCHCHECK_START[$i]"}));
2448    die "PATCHCHECK_TYPE[$i] not defined\n"
2449	if (!defined($opt{"PATCHCHECK_TYPE[$i]"}));
2450
2451    my $start = $opt{"PATCHCHECK_START[$i]"};
2452
2453    my $end = "HEAD";
2454    if (defined($opt{"PATCHCHECK_END[$i]"})) {
2455	$end = $opt{"PATCHCHECK_END[$i]"};
2456    }
2457
2458    # Get the true sha1's since we can use things like HEAD~3
2459    $start = get_sha1($start);
2460    $end = get_sha1($end);
2461
2462    my $type = $opt{"PATCHCHECK_TYPE[$i]"};
2463
2464    # Can't have a test without having a test to run
2465    if ($type eq "test" && !defined($run_test)) {
2466	$type = "boot";
2467    }
2468
2469    open (IN, "git log --pretty=oneline $end|") or
2470	dodie "could not get git list";
2471
2472    my @list;
2473
2474    while (<IN>) {
2475	chomp;
2476	$list[$#list+1] = $_;
2477	last if (/^$start/);
2478    }
2479    close(IN);
2480
2481    if ($list[$#list] !~ /^$start/) {
2482	fail "SHA1 $start not found";
2483    }
2484
2485    # go backwards in the list
2486    @list = reverse @list;
2487
2488    my $save_clean = $noclean;
2489    my %ignored_warnings;
2490
2491    if (defined($ignore_warnings)) {
2492	foreach my $sha1 (split /\s+/, $ignore_warnings) {
2493	    $ignored_warnings{$sha1} = 1;
2494	}
2495    }
2496
2497    $in_patchcheck = 1;
2498    foreach my $item (@list) {
2499	my $sha1 = $item;
2500	$sha1 =~ s/^([[:xdigit:]]+).*/$1/;
2501
2502	doprint "\nProcessing commit $item\n\n";
2503
2504	run_command "git checkout $sha1" or
2505	    die "Failed to checkout $sha1";
2506
2507	# only clean on the first and last patch
2508	if ($item eq $list[0] ||
2509	    $item eq $list[$#list]) {
2510	    $noclean = $save_clean;
2511	} else {
2512	    $noclean = 1;
2513	}
2514
2515	if (defined($minconfig)) {
2516	    build "useconfig:$minconfig" or return 0;
2517	} else {
2518	    # ?? no config to use?
2519	    build "oldconfig" or return 0;
2520	}
2521
2522
2523	if (!defined($ignored_warnings{$sha1})) {
2524	    check_buildlog $sha1 or return 0;
2525	}
2526
2527	next if ($type eq "build");
2528
2529	my $failed = 0;
2530
2531	start_monitor_and_boot or $failed = 1;
2532
2533	if (!$failed && $type ne "boot"){
2534	    do_run_test or $failed = 1;
2535	}
2536	end_monitor;
2537	return 0 if ($failed);
2538
2539	patchcheck_reboot;
2540
2541    }
2542    $in_patchcheck = 0;
2543    success $i;
2544
2545    return 1;
2546}
2547
2548my %depends;
2549my %depcount;
2550my $iflevel = 0;
2551my @ifdeps;
2552
2553# prevent recursion
2554my %read_kconfigs;
2555
2556sub add_dep {
2557    # $config depends on $dep
2558    my ($config, $dep) = @_;
2559
2560    if (defined($depends{$config})) {
2561	$depends{$config} .= " " . $dep;
2562    } else {
2563	$depends{$config} = $dep;
2564    }
2565
2566    # record the number of configs depending on $dep
2567    if (defined $depcount{$dep}) {
2568	$depcount{$dep}++;
2569    } else {
2570	$depcount{$dep} = 1;
2571    }
2572}
2573
2574# taken from streamline_config.pl
2575sub read_kconfig {
2576    my ($kconfig) = @_;
2577
2578    my $state = "NONE";
2579    my $config;
2580    my @kconfigs;
2581
2582    my $cont = 0;
2583    my $line;
2584
2585
2586    if (! -f $kconfig) {
2587	doprint "file $kconfig does not exist, skipping\n";
2588	return;
2589    }
2590
2591    open(KIN, "$kconfig")
2592	or die "Can't open $kconfig";
2593    while (<KIN>) {
2594	chomp;
2595
2596	# Make sure that lines ending with \ continue
2597	if ($cont) {
2598	    $_ = $line . " " . $_;
2599	}
2600
2601	if (s/\\$//) {
2602	    $cont = 1;
2603	    $line = $_;
2604	    next;
2605	}
2606
2607	$cont = 0;
2608
2609	# collect any Kconfig sources
2610	if (/^source\s*"(.*)"/) {
2611	    $kconfigs[$#kconfigs+1] = $1;
2612	}
2613
2614	# configs found
2615	if (/^\s*(menu)?config\s+(\S+)\s*$/) {
2616	    $state = "NEW";
2617	    $config = $2;
2618
2619	    for (my $i = 0; $i < $iflevel; $i++) {
2620		add_dep $config, $ifdeps[$i];
2621	    }
2622
2623	# collect the depends for the config
2624	} elsif ($state eq "NEW" && /^\s*depends\s+on\s+(.*)$/) {
2625
2626	    add_dep $config, $1;
2627
2628	# Get the configs that select this config
2629	} elsif ($state eq "NEW" && /^\s*select\s+(\S+)/) {
2630
2631	    # selected by depends on config
2632	    add_dep $1, $config;
2633
2634	# Check for if statements
2635	} elsif (/^if\s+(.*\S)\s*$/) {
2636	    my $deps = $1;
2637	    # remove beginning and ending non text
2638	    $deps =~ s/^[^a-zA-Z0-9_]*//;
2639	    $deps =~ s/[^a-zA-Z0-9_]*$//;
2640
2641	    my @deps = split /[^a-zA-Z0-9_]+/, $deps;
2642
2643	    $ifdeps[$iflevel++] = join ':', @deps;
2644
2645	} elsif (/^endif/) {
2646
2647	    $iflevel-- if ($iflevel);
2648
2649	# stop on "help"
2650	} elsif (/^\s*help\s*$/) {
2651	    $state = "NONE";
2652	}
2653    }
2654    close(KIN);
2655
2656    # read in any configs that were found.
2657    foreach $kconfig (@kconfigs) {
2658	if (!defined($read_kconfigs{$kconfig})) {
2659	    $read_kconfigs{$kconfig} = 1;
2660	    read_kconfig("$builddir/$kconfig");
2661	}
2662    }
2663}
2664
2665sub read_depends {
2666    # find out which arch this is by the kconfig file
2667    open (IN, $output_config)
2668	or dodie "Failed to read $output_config";
2669    my $arch;
2670    while (<IN>) {
2671	if (m,Linux/(\S+)\s+\S+\s+Kernel Configuration,) {
2672	    $arch = $1;
2673	    last;
2674	}
2675    }
2676    close IN;
2677
2678    if (!defined($arch)) {
2679	doprint "Could not find arch from config file\n";
2680	doprint "no dependencies used\n";
2681	return;
2682    }
2683
2684    # arch is really the subarch, we need to know
2685    # what directory to look at.
2686    if ($arch eq "i386" || $arch eq "x86_64") {
2687	$arch = "x86";
2688    } elsif ($arch =~ /^tile/) {
2689	$arch = "tile";
2690    }
2691
2692    my $kconfig = "$builddir/arch/$arch/Kconfig";
2693
2694    if (! -f $kconfig && $arch =~ /\d$/) {
2695	my $orig = $arch;
2696 	# some subarchs have numbers, truncate them
2697	$arch =~ s/\d*$//;
2698	$kconfig = "$builddir/arch/$arch/Kconfig";
2699	if (! -f $kconfig) {
2700	    doprint "No idea what arch dir $orig is for\n";
2701	    doprint "no dependencies used\n";
2702	    return;
2703	}
2704    }
2705
2706    read_kconfig($kconfig);
2707}
2708
2709sub read_config_list {
2710    my ($config) = @_;
2711
2712    open (IN, $config)
2713	or dodie "Failed to read $config";
2714
2715    while (<IN>) {
2716	if (/^((CONFIG\S*)=.*)/) {
2717	    if (!defined($config_ignore{$2})) {
2718		$config_list{$2} = $1;
2719	    }
2720	}
2721    }
2722
2723    close(IN);
2724}
2725
2726sub read_output_config {
2727    my ($config) = @_;
2728
2729    assign_configs \%config_ignore, $config;
2730}
2731
2732sub make_new_config {
2733    my @configs = @_;
2734
2735    open (OUT, ">$output_config")
2736	or dodie "Failed to write $output_config";
2737
2738    foreach my $config (@configs) {
2739	print OUT "$config\n";
2740    }
2741    close OUT;
2742}
2743
2744sub chomp_config {
2745    my ($config) = @_;
2746
2747    $config =~ s/CONFIG_//;
2748
2749    return $config;
2750}
2751
2752sub get_depends {
2753    my ($dep) = @_;
2754
2755    my $kconfig = chomp_config $dep;
2756
2757    $dep = $depends{"$kconfig"};
2758
2759    # the dep string we have saves the dependencies as they
2760    # were found, including expressions like ! && ||. We
2761    # want to split this out into just an array of configs.
2762
2763    my $valid = "A-Za-z_0-9";
2764
2765    my @configs;
2766
2767    while ($dep =~ /[$valid]/) {
2768
2769	if ($dep =~ /^[^$valid]*([$valid]+)/) {
2770	    my $conf = "CONFIG_" . $1;
2771
2772	    $configs[$#configs + 1] = $conf;
2773
2774	    $dep =~ s/^[^$valid]*[$valid]+//;
2775	} else {
2776	    die "this should never happen";
2777	}
2778    }
2779
2780    return @configs;
2781}
2782
2783my %min_configs;
2784my %keep_configs;
2785my %save_configs;
2786my %processed_configs;
2787my %nochange_config;
2788
2789sub test_this_config {
2790    my ($config) = @_;
2791
2792    my $found;
2793
2794    # if we already processed this config, skip it
2795    if (defined($processed_configs{$config})) {
2796	return undef;
2797    }
2798    $processed_configs{$config} = 1;
2799
2800    # if this config failed during this round, skip it
2801    if (defined($nochange_config{$config})) {
2802	return undef;
2803    }
2804
2805    my $kconfig = chomp_config $config;
2806
2807    # Test dependencies first
2808    if (defined($depends{"$kconfig"})) {
2809	my @parents = get_depends $config;
2810	foreach my $parent (@parents) {
2811	    # if the parent is in the min config, check it first
2812	    next if (!defined($min_configs{$parent}));
2813	    $found = test_this_config($parent);
2814	    if (defined($found)) {
2815		return $found;
2816	    }
2817	}
2818    }
2819
2820    # Remove this config from the list of configs
2821    # do a make oldnoconfig and then read the resulting
2822    # .config to make sure it is missing the config that
2823    # we had before
2824    my %configs = %min_configs;
2825    delete $configs{$config};
2826    make_new_config ((values %configs), (values %keep_configs));
2827    make_oldconfig;
2828    undef %configs;
2829    assign_configs \%configs, $output_config;
2830
2831    return $config if (!defined($configs{$config}));
2832
2833    doprint "disabling config $config did not change .config\n";
2834
2835    $nochange_config{$config} = 1;
2836
2837    return undef;
2838}
2839
2840sub make_min_config {
2841    my ($i) = @_;
2842
2843    if (!defined($output_minconfig)) {
2844	fail "OUTPUT_MIN_CONFIG not defined" and return;
2845    }
2846
2847    # If output_minconfig exists, and the start_minconfig
2848    # came from min_config, than ask if we should use
2849    # that instead.
2850    if (-f $output_minconfig && !$start_minconfig_defined) {
2851	print "$output_minconfig exists\n";
2852	if (read_yn " Use it as minconfig?") {
2853	    $start_minconfig = $output_minconfig;
2854	}
2855    }
2856
2857    if (!defined($start_minconfig)) {
2858	fail "START_MIN_CONFIG or MIN_CONFIG not defined" and return;
2859    }
2860
2861    my $temp_config = "$tmpdir/temp_config";
2862
2863    # First things first. We build an allnoconfig to find
2864    # out what the defaults are that we can't touch.
2865    # Some are selections, but we really can't handle selections.
2866
2867    my $save_minconfig = $minconfig;
2868    undef $minconfig;
2869
2870    run_command "$make allnoconfig" or return 0;
2871
2872    read_depends;
2873
2874    process_config_ignore $output_config;
2875
2876    undef %save_configs;
2877    undef %min_configs;
2878
2879    if (defined($ignore_config)) {
2880	# make sure the file exists
2881	`touch $ignore_config`;
2882	assign_configs \%save_configs, $ignore_config;
2883    }
2884
2885    %keep_configs = %save_configs;
2886
2887    doprint "Load initial configs from $start_minconfig\n";
2888
2889    # Look at the current min configs, and save off all the
2890    # ones that were set via the allnoconfig
2891    assign_configs \%min_configs, $start_minconfig;
2892
2893    my @config_keys = keys %min_configs;
2894
2895    # All configs need a depcount
2896    foreach my $config (@config_keys) {
2897	my $kconfig = chomp_config $config;
2898	if (!defined $depcount{$kconfig}) {
2899		$depcount{$kconfig} = 0;
2900	}
2901    }
2902
2903    # Remove anything that was set by the make allnoconfig
2904    # we shouldn't need them as they get set for us anyway.
2905    foreach my $config (@config_keys) {
2906	# Remove anything in the ignore_config
2907	if (defined($keep_configs{$config})) {
2908	    my $file = $ignore_config;
2909	    $file =~ s,.*/(.*?)$,$1,;
2910	    doprint "$config set by $file ... ignored\n";
2911	    delete $min_configs{$config};
2912	    next;
2913	}
2914	# But make sure the settings are the same. If a min config
2915	# sets a selection, we do not want to get rid of it if
2916	# it is not the same as what we have. Just move it into
2917	# the keep configs.
2918	if (defined($config_ignore{$config})) {
2919	    if ($config_ignore{$config} ne $min_configs{$config}) {
2920		doprint "$config is in allnoconfig as '$config_ignore{$config}'";
2921		doprint " but it is '$min_configs{$config}' in minconfig .. keeping\n";
2922		$keep_configs{$config} = $min_configs{$config};
2923	    } else {
2924		doprint "$config set by allnoconfig ... ignored\n";
2925	    }
2926	    delete $min_configs{$config};
2927	}
2928    }
2929
2930    my $done = 0;
2931    my $take_two = 0;
2932
2933    while (!$done) {
2934
2935	my $config;
2936	my $found;
2937
2938	# Now disable each config one by one and do a make oldconfig
2939	# till we find a config that changes our list.
2940
2941	my @test_configs = keys %min_configs;
2942
2943	# Sort keys by who is most dependent on
2944	@test_configs = sort  { $depcount{chomp_config($b)} <=> $depcount{chomp_config($a)} }
2945			  @test_configs ;
2946
2947	# Put configs that did not modify the config at the end.
2948	my $reset = 1;
2949	for (my $i = 0; $i < $#test_configs; $i++) {
2950	    if (!defined($nochange_config{$test_configs[0]})) {
2951		$reset = 0;
2952		last;
2953	    }
2954	    # This config didn't change the .config last time.
2955	    # Place it at the end
2956	    my $config = shift @test_configs;
2957	    push @test_configs, $config;
2958	}
2959
2960	# if every test config has failed to modify the .config file
2961	# in the past, then reset and start over.
2962	if ($reset) {
2963	    undef %nochange_config;
2964	}
2965
2966	undef %processed_configs;
2967
2968	foreach my $config (@test_configs) {
2969
2970	    $found = test_this_config $config;
2971
2972	    last if (defined($found));
2973
2974	    # oh well, try another config
2975	}
2976
2977	if (!defined($found)) {
2978	    # we could have failed due to the nochange_config hash
2979	    # reset and try again
2980	    if (!$take_two) {
2981		undef %nochange_config;
2982		$take_two = 1;
2983		next;
2984	    }
2985	    doprint "No more configs found that we can disable\n";
2986	    $done = 1;
2987	    last;
2988	}
2989	$take_two = 0;
2990
2991	$config = $found;
2992
2993	doprint "Test with $config disabled\n";
2994
2995	# set in_bisect to keep build and monitor from dieing
2996	$in_bisect = 1;
2997
2998	my $failed = 0;
2999	build "oldconfig";
3000	start_monitor_and_boot or $failed = 1;
3001	end_monitor;
3002
3003	$in_bisect = 0;
3004
3005	if ($failed) {
3006	    doprint "$min_configs{$config} is needed to boot the box... keeping\n";
3007	    # this config is needed, add it to the ignore list.
3008	    $keep_configs{$config} = $min_configs{$config};
3009	    $save_configs{$config} = $min_configs{$config};
3010	    delete $min_configs{$config};
3011
3012	    # update new ignore configs
3013	    if (defined($ignore_config)) {
3014		open (OUT, ">$temp_config")
3015		    or die "Can't write to $temp_config";
3016		foreach my $config (keys %save_configs) {
3017		    print OUT "$save_configs{$config}\n";
3018		}
3019		close OUT;
3020		run_command "mv $temp_config $ignore_config" or
3021		    dodie "failed to copy update to $ignore_config";
3022	    }
3023
3024	} else {
3025	    # We booted without this config, remove it from the minconfigs.
3026	    doprint "$config is not needed, disabling\n";
3027
3028	    delete $min_configs{$config};
3029
3030	    # Also disable anything that is not enabled in this config
3031	    my %configs;
3032	    assign_configs \%configs, $output_config;
3033	    my @config_keys = keys %min_configs;
3034	    foreach my $config (@config_keys) {
3035		if (!defined($configs{$config})) {
3036		    doprint "$config is not set, disabling\n";
3037		    delete $min_configs{$config};
3038		}
3039	    }
3040
3041	    # Save off all the current mandidory configs
3042	    open (OUT, ">$temp_config")
3043		or die "Can't write to $temp_config";
3044	    foreach my $config (keys %keep_configs) {
3045		print OUT "$keep_configs{$config}\n";
3046	    }
3047	    foreach my $config (keys %min_configs) {
3048		print OUT "$min_configs{$config}\n";
3049	    }
3050	    close OUT;
3051
3052	    run_command "mv $temp_config $output_minconfig" or
3053		dodie "failed to copy update to $output_minconfig";
3054	}
3055
3056	doprint "Reboot and wait $sleep_time seconds\n";
3057	reboot $sleep_time;
3058    }
3059
3060    success $i;
3061    return 1;
3062}
3063
3064$#ARGV < 1 or die "ktest.pl version: $VERSION\n   usage: ktest.pl config-file\n";
3065
3066if ($#ARGV == 0) {
3067    $ktest_config = $ARGV[0];
3068    if (! -f $ktest_config) {
3069	print "$ktest_config does not exist.\n";
3070	if (!read_yn "Create it?") {
3071	    exit 0;
3072	}
3073    }
3074} else {
3075    $ktest_config = "ktest.conf";
3076}
3077
3078if (! -f $ktest_config) {
3079    get_test_case;
3080    open(OUT, ">$ktest_config") or die "Can not create $ktest_config";
3081    print OUT << "EOF"
3082# Generated by ktest.pl
3083#
3084
3085# PWD is a ktest.pl variable that will result in the process working
3086# directory that ktest.pl is executed in.
3087
3088# THIS_DIR is automatically assigned the PWD of the path that generated
3089# the config file. It is best to use this variable when assigning other
3090# directory paths within this directory. This allows you to easily
3091# move the test cases to other locations or to other machines.
3092#
3093THIS_DIR := $variable{"PWD"}
3094
3095# Define each test with TEST_START
3096# The config options below it will override the defaults
3097TEST_START
3098TEST_TYPE = $default{"TEST_TYPE"}
3099
3100DEFAULTS
3101EOF
3102;
3103    close(OUT);
3104}
3105read_config $ktest_config;
3106
3107if (defined($opt{"LOG_FILE"})) {
3108    $opt{"LOG_FILE"} = eval_option($opt{"LOG_FILE"}, -1);
3109}
3110
3111# Append any configs entered in manually to the config file.
3112my @new_configs = keys %entered_configs;
3113if ($#new_configs >= 0) {
3114    print "\nAppending entered in configs to $ktest_config\n";
3115    open(OUT, ">>$ktest_config") or die "Can not append to $ktest_config";
3116    foreach my $config (@new_configs) {
3117	print OUT "$config = $entered_configs{$config}\n";
3118	$opt{$config} = process_variables($entered_configs{$config});
3119    }
3120}
3121
3122if ($opt{"CLEAR_LOG"} && defined($opt{"LOG_FILE"})) {
3123    unlink $opt{"LOG_FILE"};
3124}
3125
3126doprint "\n\nSTARTING AUTOMATED TESTS\n\n";
3127
3128for (my $i = 0, my $repeat = 1; $i <= $opt{"NUM_TESTS"}; $i += $repeat) {
3129
3130    if (!$i) {
3131	doprint "DEFAULT OPTIONS:\n";
3132    } else {
3133	doprint "\nTEST $i OPTIONS";
3134	if (defined($repeat_tests{$i})) {
3135	    $repeat = $repeat_tests{$i};
3136	    doprint " ITERATE $repeat";
3137	}
3138	doprint "\n";
3139    }
3140
3141    foreach my $option (sort keys %opt) {
3142
3143	if ($option =~ /\[(\d+)\]$/) {
3144	    next if ($i != $1);
3145	} else {
3146	    next if ($i);
3147	}
3148
3149	doprint "$option = $opt{$option}\n";
3150    }
3151}
3152
3153sub __set_test_option {
3154    my ($name, $i) = @_;
3155
3156    my $option = "$name\[$i\]";
3157
3158    if (defined($opt{$option})) {
3159	return $opt{$option};
3160    }
3161
3162    foreach my $test (keys %repeat_tests) {
3163	if ($i >= $test &&
3164	    $i < $test + $repeat_tests{$test}) {
3165	    $option = "$name\[$test\]";
3166	    if (defined($opt{$option})) {
3167		return $opt{$option};
3168	    }
3169	}
3170    }
3171
3172    if (defined($opt{$name})) {
3173	return $opt{$name};
3174    }
3175
3176    return undef;
3177}
3178
3179sub set_test_option {
3180    my ($name, $i) = @_;
3181
3182    my $option = __set_test_option($name, $i);
3183    return $option if (!defined($option));
3184
3185    return eval_option($option, $i);
3186}
3187
3188# First we need to do is the builds
3189for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
3190
3191    # Do not reboot on failing test options
3192    $no_reboot = 1;
3193
3194    $iteration = $i;
3195
3196    my $makecmd = set_test_option("MAKE_CMD", $i);
3197
3198    $machine = set_test_option("MACHINE", $i);
3199    $ssh_user = set_test_option("SSH_USER", $i);
3200    $tmpdir = set_test_option("TMP_DIR", $i);
3201    $outputdir = set_test_option("OUTPUT_DIR", $i);
3202    $builddir = set_test_option("BUILD_DIR", $i);
3203    $test_type = set_test_option("TEST_TYPE", $i);
3204    $build_type = set_test_option("BUILD_TYPE", $i);
3205    $build_options = set_test_option("BUILD_OPTIONS", $i);
3206    $pre_build = set_test_option("PRE_BUILD", $i);
3207    $post_build = set_test_option("POST_BUILD", $i);
3208    $pre_build_die = set_test_option("PRE_BUILD_DIE", $i);
3209    $post_build_die = set_test_option("POST_BUILD_DIE", $i);
3210    $power_cycle = set_test_option("POWER_CYCLE", $i);
3211    $reboot = set_test_option("REBOOT", $i);
3212    $noclean = set_test_option("BUILD_NOCLEAN", $i);
3213    $minconfig = set_test_option("MIN_CONFIG", $i);
3214    $output_minconfig = set_test_option("OUTPUT_MIN_CONFIG", $i);
3215    $start_minconfig = set_test_option("START_MIN_CONFIG", $i);
3216    $ignore_config = set_test_option("IGNORE_CONFIG", $i);
3217    $run_test = set_test_option("TEST", $i);
3218    $addconfig = set_test_option("ADD_CONFIG", $i);
3219    $reboot_type = set_test_option("REBOOT_TYPE", $i);
3220    $grub_menu = set_test_option("GRUB_MENU", $i);
3221    $post_install = set_test_option("POST_INSTALL", $i);
3222    $no_install = set_test_option("NO_INSTALL", $i);
3223    $reboot_script = set_test_option("REBOOT_SCRIPT", $i);
3224    $reboot_on_error = set_test_option("REBOOT_ON_ERROR", $i);
3225    $poweroff_on_error = set_test_option("POWEROFF_ON_ERROR", $i);
3226    $die_on_failure = set_test_option("DIE_ON_FAILURE", $i);
3227    $power_off = set_test_option("POWER_OFF", $i);
3228    $powercycle_after_reboot = set_test_option("POWERCYCLE_AFTER_REBOOT", $i);
3229    $poweroff_after_halt = set_test_option("POWEROFF_AFTER_HALT", $i);
3230    $sleep_time = set_test_option("SLEEP_TIME", $i);
3231    $bisect_sleep_time = set_test_option("BISECT_SLEEP_TIME", $i);
3232    $patchcheck_sleep_time = set_test_option("PATCHCHECK_SLEEP_TIME", $i);
3233    $ignore_warnings = set_test_option("IGNORE_WARNINGS", $i);
3234    $bisect_manual = set_test_option("BISECT_MANUAL", $i);
3235    $bisect_skip = set_test_option("BISECT_SKIP", $i);
3236    $config_bisect_good = set_test_option("CONFIG_BISECT_GOOD", $i);
3237    $store_failures = set_test_option("STORE_FAILURES", $i);
3238    $store_successes = set_test_option("STORE_SUCCESSES", $i);
3239    $test_name = set_test_option("TEST_NAME", $i);
3240    $timeout = set_test_option("TIMEOUT", $i);
3241    $booted_timeout = set_test_option("BOOTED_TIMEOUT", $i);
3242    $console = set_test_option("CONSOLE", $i);
3243    $detect_triplefault = set_test_option("DETECT_TRIPLE_FAULT", $i);
3244    $success_line = set_test_option("SUCCESS_LINE", $i);
3245    $reboot_success_line = set_test_option("REBOOT_SUCCESS_LINE", $i);
3246    $stop_after_success = set_test_option("STOP_AFTER_SUCCESS", $i);
3247    $stop_after_failure = set_test_option("STOP_AFTER_FAILURE", $i);
3248    $stop_test_after = set_test_option("STOP_TEST_AFTER", $i);
3249    $build_target = set_test_option("BUILD_TARGET", $i);
3250    $ssh_exec = set_test_option("SSH_EXEC", $i);
3251    $scp_to_target = set_test_option("SCP_TO_TARGET", $i);
3252    $target_image = set_test_option("TARGET_IMAGE", $i);
3253    $localversion = set_test_option("LOCALVERSION", $i);
3254
3255    $start_minconfig_defined = 1;
3256
3257    if (!defined($start_minconfig)) {
3258	$start_minconfig_defined = 0;
3259	$start_minconfig = $minconfig;
3260    }
3261
3262    chdir $builddir || die "can't change directory to $builddir";
3263
3264    foreach my $dir ($tmpdir, $outputdir) {
3265	if (!-d $dir) {
3266	    mkpath($dir) or
3267		die "can't create $dir";
3268	}
3269    }
3270
3271    $ENV{"SSH_USER"} = $ssh_user;
3272    $ENV{"MACHINE"} = $machine;
3273
3274    $target = "$ssh_user\@$machine";
3275
3276    $buildlog = "$tmpdir/buildlog-$machine";
3277    $testlog = "$tmpdir/testlog-$machine";
3278    $dmesg = "$tmpdir/dmesg-$machine";
3279    $make = "$makecmd O=$outputdir";
3280    $output_config = "$outputdir/.config";
3281
3282    if ($reboot_type eq "grub") {
3283	dodie "GRUB_MENU not defined" if (!defined($grub_menu));
3284    } elsif (!defined($reboot_script)) {
3285	dodie "REBOOT_SCRIPT not defined"
3286    }
3287
3288    my $run_type = $build_type;
3289    if ($test_type eq "patchcheck") {
3290	$run_type = $opt{"PATCHCHECK_TYPE[$i]"};
3291    } elsif ($test_type eq "bisect") {
3292	$run_type = $opt{"BISECT_TYPE[$i]"};
3293    } elsif ($test_type eq "config_bisect") {
3294	$run_type = $opt{"CONFIG_BISECT_TYPE[$i]"};
3295    }
3296
3297    if ($test_type eq "make_min_config") {
3298	$run_type = "";
3299    }
3300
3301    # mistake in config file?
3302    if (!defined($run_type)) {
3303	$run_type = "ERROR";
3304    }
3305
3306    my $installme = "";
3307    $installme = " no_install" if ($no_install);
3308
3309    doprint "\n\n";
3310    doprint "RUNNING TEST $i of $opt{NUM_TESTS} with option $test_type $run_type$installme\n\n";
3311
3312    unlink $dmesg;
3313    unlink $buildlog;
3314    unlink $testlog;
3315
3316    if (defined($addconfig)) {
3317	my $min = $minconfig;
3318	if (!defined($minconfig)) {
3319	    $min = "";
3320	}
3321	run_command "cat $addconfig $min > $tmpdir/add_config" or
3322	    dodie "Failed to create temp config";
3323	$minconfig = "$tmpdir/add_config";
3324    }
3325
3326    my $checkout = $opt{"CHECKOUT[$i]"};
3327    if (defined($checkout)) {
3328	run_command "git checkout $checkout" or
3329	    die "failed to checkout $checkout";
3330    }
3331
3332    $no_reboot = 0;
3333
3334
3335    if ($test_type eq "bisect") {
3336	bisect $i;
3337	next;
3338    } elsif ($test_type eq "config_bisect") {
3339	config_bisect $i;
3340	next;
3341    } elsif ($test_type eq "patchcheck") {
3342	patchcheck $i;
3343	next;
3344    } elsif ($test_type eq "make_min_config") {
3345	make_min_config $i;
3346	next;
3347    }
3348
3349    if ($build_type ne "nobuild") {
3350	build $build_type or next;
3351    }
3352
3353    if ($test_type eq "install") {
3354	get_version;
3355	install;
3356	success $i;
3357	next;
3358    }
3359
3360    if ($test_type ne "build") {
3361	my $failed = 0;
3362	start_monitor_and_boot or $failed = 1;
3363
3364	if (!$failed && $test_type ne "boot" && defined($run_test)) {
3365	    do_run_test or $failed = 1;
3366	}
3367	end_monitor;
3368	next if ($failed);
3369    }
3370
3371    success $i;
3372}
3373
3374if ($opt{"POWEROFF_ON_SUCCESS"}) {
3375    halt;
3376} elsif ($opt{"REBOOT_ON_SUCCESS"} && !do_not_reboot) {
3377    reboot;
3378}
3379
3380doprint "\n    $successes of $opt{NUM_TESTS} tests were successful\n\n";
3381
3382exit 0;
3383