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