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