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