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