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