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