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