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