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