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