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