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