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