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