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