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