Back to home page

LXR

 
 

    


0001 #!/usr/bin/perl -w
0002 #
0003 # Copyright 2010 - Steven Rostedt <srostedt@redhat.com>, Red Hat Inc.
0004 # Licensed under the terms of the GNU GPL License version 2
0005 #
0006 
0007 use strict;
0008 use IPC::Open2;
0009 use Fcntl qw(F_GETFL F_SETFL O_NONBLOCK);
0010 use File::Path qw(mkpath);
0011 use File::Copy qw(cp);
0012 use FileHandle;
0013 
0014 my $VERSION = "0.2";
0015 
0016 $| = 1;
0017 
0018 my %opt;
0019 my %repeat_tests;
0020 my %repeats;
0021 my %evals;
0022 
0023 #default opts
0024 my %default = (
0025     "NUM_TESTS"         => 1,
0026     "TEST_TYPE"         => "build",
0027     "BUILD_TYPE"        => "randconfig",
0028     "MAKE_CMD"          => "make",
0029     "CLOSE_CONSOLE_SIGNAL"  => "INT",
0030     "TIMEOUT"           => 120,
0031     "TMP_DIR"           => "/tmp/ktest/\${MACHINE}",
0032     "SLEEP_TIME"        => 60,  # sleep time between tests
0033     "BUILD_NOCLEAN"     => 0,
0034     "REBOOT_ON_ERROR"       => 0,
0035     "POWEROFF_ON_ERROR"     => 0,
0036     "REBOOT_ON_SUCCESS"     => 1,
0037     "POWEROFF_ON_SUCCESS"   => 0,
0038     "BUILD_OPTIONS"     => "",
0039     "BISECT_SLEEP_TIME"     => 60,   # sleep time between bisects
0040     "PATCHCHECK_SLEEP_TIME" => 60, # sleep time between patch checks
0041     "CLEAR_LOG"         => 0,
0042     "BISECT_MANUAL"     => 0,
0043     "BISECT_SKIP"       => 1,
0044     "BISECT_TRIES"      => 1,
0045     "MIN_CONFIG_TYPE"       => "boot",
0046     "SUCCESS_LINE"      => "login:",
0047     "DETECT_TRIPLE_FAULT"   => 1,
0048     "NO_INSTALL"        => 0,
0049     "BOOTED_TIMEOUT"        => 1,
0050     "DIE_ON_FAILURE"        => 1,
0051     "SSH_EXEC"          => "ssh \$SSH_USER\@\$MACHINE \$SSH_COMMAND",
0052     "SCP_TO_TARGET"     => "scp \$SRC_FILE \$SSH_USER\@\$MACHINE:\$DST_FILE",
0053     "SCP_TO_TARGET_INSTALL" => "\${SCP_TO_TARGET}",
0054     "REBOOT"            => "ssh \$SSH_USER\@\$MACHINE reboot",
0055     "STOP_AFTER_SUCCESS"    => 10,
0056     "STOP_AFTER_FAILURE"    => 60,
0057     "STOP_TEST_AFTER"       => 600,
0058     "MAX_MONITOR_WAIT"      => 1800,
0059     "GRUB_REBOOT"       => "grub2-reboot",
0060     "SYSLINUX"          => "extlinux",
0061     "SYSLINUX_PATH"     => "/boot/extlinux",
0062 
0063 # required, and we will ask users if they don't have them but we keep the default
0064 # value something that is common.
0065     "REBOOT_TYPE"       => "grub",
0066     "LOCALVERSION"      => "-test",
0067     "SSH_USER"          => "root",
0068     "BUILD_TARGET"      => "arch/x86/boot/bzImage",
0069     "TARGET_IMAGE"      => "/boot/vmlinuz-test",
0070 
0071     "LOG_FILE"          => undef,
0072     "IGNORE_UNUSED"     => 0,
0073 );
0074 
0075 my $ktest_config = "ktest.conf";
0076 my $version;
0077 my $have_version = 0;
0078 my $machine;
0079 my $last_machine;
0080 my $ssh_user;
0081 my $tmpdir;
0082 my $builddir;
0083 my $outputdir;
0084 my $output_config;
0085 my $test_type;
0086 my $build_type;
0087 my $build_options;
0088 my $final_post_ktest;
0089 my $pre_ktest;
0090 my $post_ktest;
0091 my $pre_test;
0092 my $post_test;
0093 my $pre_build;
0094 my $post_build;
0095 my $pre_build_die;
0096 my $post_build_die;
0097 my $reboot_type;
0098 my $reboot_script;
0099 my $power_cycle;
0100 my $reboot;
0101 my $reboot_on_error;
0102 my $switch_to_good;
0103 my $switch_to_test;
0104 my $poweroff_on_error;
0105 my $reboot_on_success;
0106 my $die_on_failure;
0107 my $powercycle_after_reboot;
0108 my $poweroff_after_halt;
0109 my $max_monitor_wait;
0110 my $ssh_exec;
0111 my $scp_to_target;
0112 my $scp_to_target_install;
0113 my $power_off;
0114 my $grub_menu;
0115 my $last_grub_menu;
0116 my $grub_file;
0117 my $grub_number;
0118 my $grub_reboot;
0119 my $syslinux;
0120 my $syslinux_path;
0121 my $syslinux_label;
0122 my $target;
0123 my $make;
0124 my $pre_install;
0125 my $post_install;
0126 my $no_install;
0127 my $noclean;
0128 my $minconfig;
0129 my $start_minconfig;
0130 my $start_minconfig_defined;
0131 my $output_minconfig;
0132 my $minconfig_type;
0133 my $use_output_minconfig;
0134 my $warnings_file;
0135 my $ignore_config;
0136 my $ignore_errors;
0137 my $addconfig;
0138 my $in_bisect = 0;
0139 my $bisect_bad_commit = "";
0140 my $reverse_bisect;
0141 my $bisect_manual;
0142 my $bisect_skip;
0143 my $bisect_tries;
0144 my $config_bisect_good;
0145 my $bisect_ret_good;
0146 my $bisect_ret_bad;
0147 my $bisect_ret_skip;
0148 my $bisect_ret_abort;
0149 my $bisect_ret_default;
0150 my $in_patchcheck = 0;
0151 my $run_test;
0152 my $buildlog;
0153 my $testlog;
0154 my $dmesg;
0155 my $monitor_fp;
0156 my $monitor_pid;
0157 my $monitor_cnt = 0;
0158 my $sleep_time;
0159 my $bisect_sleep_time;
0160 my $patchcheck_sleep_time;
0161 my $ignore_warnings;
0162 my $store_failures;
0163 my $store_successes;
0164 my $test_name;
0165 my $timeout;
0166 my $booted_timeout;
0167 my $detect_triplefault;
0168 my $console;
0169 my $close_console_signal;
0170 my $reboot_success_line;
0171 my $success_line;
0172 my $stop_after_success;
0173 my $stop_after_failure;
0174 my $stop_test_after;
0175 my $build_target;
0176 my $target_image;
0177 my $checkout;
0178 my $localversion;
0179 my $iteration = 0;
0180 my $successes = 0;
0181 my $stty_orig;
0182 
0183 my $bisect_good;
0184 my $bisect_bad;
0185 my $bisect_type;
0186 my $bisect_start;
0187 my $bisect_replay;
0188 my $bisect_files;
0189 my $bisect_reverse;
0190 my $bisect_check;
0191 
0192 my $config_bisect;
0193 my $config_bisect_type;
0194 my $config_bisect_check;
0195 
0196 my $patchcheck_type;
0197 my $patchcheck_start;
0198 my $patchcheck_cherry;
0199 my $patchcheck_end;
0200 
0201 my $build_time;
0202 my $install_time;
0203 my $reboot_time;
0204 my $test_time;
0205 
0206 # set when a test is something other that just building or install
0207 # which would require more options.
0208 my $buildonly = 1;
0209 
0210 # tell build not to worry about warnings, even when WARNINGS_FILE is set
0211 my $warnings_ok = 0;
0212 
0213 # set when creating a new config
0214 my $newconfig = 0;
0215 
0216 my %entered_configs;
0217 my %config_help;
0218 my %variable;
0219 
0220 # force_config is the list of configs that we force enabled (or disabled)
0221 # in a .config file. The MIN_CONFIG and ADD_CONFIG configs.
0222 my %force_config;
0223 
0224 # do not force reboots on config problems
0225 my $no_reboot = 1;
0226 
0227 # reboot on success
0228 my $reboot_success = 0;
0229 
0230 my %option_map = (
0231     "MACHINE"           => \$machine,
0232     "SSH_USER"          => \$ssh_user,
0233     "TMP_DIR"           => \$tmpdir,
0234     "OUTPUT_DIR"        => \$outputdir,
0235     "BUILD_DIR"         => \$builddir,
0236     "TEST_TYPE"         => \$test_type,
0237     "PRE_KTEST"         => \$pre_ktest,
0238     "POST_KTEST"        => \$post_ktest,
0239     "PRE_TEST"          => \$pre_test,
0240     "POST_TEST"         => \$post_test,
0241     "BUILD_TYPE"        => \$build_type,
0242     "BUILD_OPTIONS"     => \$build_options,
0243     "PRE_BUILD"         => \$pre_build,
0244     "POST_BUILD"        => \$post_build,
0245     "PRE_BUILD_DIE"     => \$pre_build_die,
0246     "POST_BUILD_DIE"        => \$post_build_die,
0247     "POWER_CYCLE"       => \$power_cycle,
0248     "REBOOT"            => \$reboot,
0249     "BUILD_NOCLEAN"     => \$noclean,
0250     "MIN_CONFIG"        => \$minconfig,
0251     "OUTPUT_MIN_CONFIG"     => \$output_minconfig,
0252     "START_MIN_CONFIG"      => \$start_minconfig,
0253     "MIN_CONFIG_TYPE"       => \$minconfig_type,
0254     "USE_OUTPUT_MIN_CONFIG" => \$use_output_minconfig,
0255     "WARNINGS_FILE"     => \$warnings_file,
0256     "IGNORE_CONFIG"     => \$ignore_config,
0257     "TEST"          => \$run_test,
0258     "ADD_CONFIG"        => \$addconfig,
0259     "REBOOT_TYPE"       => \$reboot_type,
0260     "GRUB_MENU"         => \$grub_menu,
0261     "GRUB_FILE"         => \$grub_file,
0262     "GRUB_REBOOT"       => \$grub_reboot,
0263     "SYSLINUX"          => \$syslinux,
0264     "SYSLINUX_PATH"     => \$syslinux_path,
0265     "SYSLINUX_LABEL"        => \$syslinux_label,
0266     "PRE_INSTALL"       => \$pre_install,
0267     "POST_INSTALL"      => \$post_install,
0268     "NO_INSTALL"        => \$no_install,
0269     "REBOOT_SCRIPT"     => \$reboot_script,
0270     "REBOOT_ON_ERROR"       => \$reboot_on_error,
0271     "SWITCH_TO_GOOD"        => \$switch_to_good,
0272     "SWITCH_TO_TEST"        => \$switch_to_test,
0273     "POWEROFF_ON_ERROR"     => \$poweroff_on_error,
0274     "REBOOT_ON_SUCCESS"     => \$reboot_on_success,
0275     "DIE_ON_FAILURE"        => \$die_on_failure,
0276     "POWER_OFF"         => \$power_off,
0277     "POWERCYCLE_AFTER_REBOOT"   => \$powercycle_after_reboot,
0278     "POWEROFF_AFTER_HALT"   => \$poweroff_after_halt,
0279     "MAX_MONITOR_WAIT"      => \$max_monitor_wait,
0280     "SLEEP_TIME"        => \$sleep_time,
0281     "BISECT_SLEEP_TIME"     => \$bisect_sleep_time,
0282     "PATCHCHECK_SLEEP_TIME" => \$patchcheck_sleep_time,
0283     "IGNORE_WARNINGS"       => \$ignore_warnings,
0284     "IGNORE_ERRORS"     => \$ignore_errors,
0285     "BISECT_MANUAL"     => \$bisect_manual,
0286     "BISECT_SKIP"       => \$bisect_skip,
0287     "BISECT_TRIES"      => \$bisect_tries,
0288     "CONFIG_BISECT_GOOD"    => \$config_bisect_good,
0289     "BISECT_RET_GOOD"       => \$bisect_ret_good,
0290     "BISECT_RET_BAD"        => \$bisect_ret_bad,
0291     "BISECT_RET_SKIP"       => \$bisect_ret_skip,
0292     "BISECT_RET_ABORT"      => \$bisect_ret_abort,
0293     "BISECT_RET_DEFAULT"    => \$bisect_ret_default,
0294     "STORE_FAILURES"        => \$store_failures,
0295     "STORE_SUCCESSES"       => \$store_successes,
0296     "TEST_NAME"         => \$test_name,
0297     "TIMEOUT"           => \$timeout,
0298     "BOOTED_TIMEOUT"        => \$booted_timeout,
0299     "CONSOLE"           => \$console,
0300     "CLOSE_CONSOLE_SIGNAL"  => \$close_console_signal,
0301     "DETECT_TRIPLE_FAULT"   => \$detect_triplefault,
0302     "SUCCESS_LINE"      => \$success_line,
0303     "REBOOT_SUCCESS_LINE"   => \$reboot_success_line,
0304     "STOP_AFTER_SUCCESS"    => \$stop_after_success,
0305     "STOP_AFTER_FAILURE"    => \$stop_after_failure,
0306     "STOP_TEST_AFTER"       => \$stop_test_after,
0307     "BUILD_TARGET"      => \$build_target,
0308     "SSH_EXEC"          => \$ssh_exec,
0309     "SCP_TO_TARGET"     => \$scp_to_target,
0310     "SCP_TO_TARGET_INSTALL" => \$scp_to_target_install,
0311     "CHECKOUT"          => \$checkout,
0312     "TARGET_IMAGE"      => \$target_image,
0313     "LOCALVERSION"      => \$localversion,
0314 
0315     "BISECT_GOOD"       => \$bisect_good,
0316     "BISECT_BAD"        => \$bisect_bad,
0317     "BISECT_TYPE"       => \$bisect_type,
0318     "BISECT_START"      => \$bisect_start,
0319     "BISECT_REPLAY"     => \$bisect_replay,
0320     "BISECT_FILES"      => \$bisect_files,
0321     "BISECT_REVERSE"        => \$bisect_reverse,
0322     "BISECT_CHECK"      => \$bisect_check,
0323 
0324     "CONFIG_BISECT"     => \$config_bisect,
0325     "CONFIG_BISECT_TYPE"    => \$config_bisect_type,
0326     "CONFIG_BISECT_CHECK"   => \$config_bisect_check,
0327 
0328     "PATCHCHECK_TYPE"       => \$patchcheck_type,
0329     "PATCHCHECK_START"      => \$patchcheck_start,
0330     "PATCHCHECK_CHERRY"     => \$patchcheck_cherry,
0331     "PATCHCHECK_END"        => \$patchcheck_end,
0332 );
0333 
0334 # Options may be used by other options, record them.
0335 my %used_options;
0336 
0337 # default variables that can be used
0338 chomp ($variable{"PWD"} = `pwd`);
0339 
0340 $config_help{"MACHINE"} = << "EOF"
0341  The machine hostname that you will test.
0342  For build only tests, it is still needed to differentiate log files.
0343 EOF
0344     ;
0345 $config_help{"SSH_USER"} = << "EOF"
0346  The box is expected to have ssh on normal bootup, provide the user
0347   (most likely root, since you need privileged operations)
0348 EOF
0349     ;
0350 $config_help{"BUILD_DIR"} = << "EOF"
0351  The directory that contains the Linux source code (full path).
0352  You can use \${PWD} that will be the path where ktest.pl is run, or use
0353  \${THIS_DIR} which is assigned \${PWD} but may be changed later.
0354 EOF
0355     ;$config_help{"OUTPUT_DIR"} = << "EOF"
0356 
0357  The directory that the objects will be built (full path).
0358  (can not be same as BUILD_DIR)
0359  You can use \${PWD} that will be the path where ktest.pl is run, or use
0360  \${THIS_DIR} which is assigned \${PWD} but may be changed later.
0361 EOF
0362     ;$config_help{"BUILD_TARGET"} = << "EOF"
0363 
0364  The location of the compiled file to copy to the target.
0365  (relative to OUTPUT_DIR)
0366 EOF
0367     ;
0368 $config_help{"BUILD_OPTIONS"} = << "EOF"
0369  Options to add to \"make\" when building.
0370  i.e.  -j20
0371 EOF
0372     ;
0373 $config_help{"TARGET_IMAGE"} = << "EOF"
0374  The place to put your image on the test machine.
0375 EOF
0376     ;
0377 $config_help{"POWER_CYCLE"} = << "EOF"
0378  A script or command to reboot the box.
0379 
0380  Here is a digital loggers power switch example
0381  POWER_CYCLE = wget --no-proxy -O /dev/null -q  --auth-no-challenge 'http://admin:admin\@power/outlet?5=CCL'
0382 
0383  Here is an example to reboot a virtual box on the current host
0384  with the name "Guest".
0385  POWER_CYCLE = virsh destroy Guest; sleep 5; virsh start Guest
0386 EOF
0387     ;
0388 $config_help{"CONSOLE"} = << "EOF"
0389  The script or command that reads the console
0390 
0391   If you use ttywatch server, something like the following would work.
0392 CONSOLE = nc -d localhost 3001
0393 
0394  For a virtual machine with guest name "Guest".
0395 CONSOLE =  virsh console Guest
0396 EOF
0397     ;
0398 $config_help{"LOCALVERSION"} = << "EOF"
0399  Required version ending to differentiate the test
0400  from other linux builds on the system.
0401 EOF
0402     ;
0403 $config_help{"REBOOT_TYPE"} = << "EOF"
0404  Way to reboot the box to the test kernel.
0405  Only valid options so far are "grub", "grub2", "syslinux", and "script".
0406 
0407  If you specify grub, it will assume grub version 1
0408  and will search in /boot/grub/menu.lst for the title \$GRUB_MENU
0409  and select that target to reboot to the kernel. If this is not
0410  your setup, then specify "script" and have a command or script
0411  specified in REBOOT_SCRIPT to boot to the target.
0412 
0413  The entry in /boot/grub/menu.lst must be entered in manually.
0414  The test will not modify that file.
0415 
0416  If you specify grub2, then you also need to specify both \$GRUB_MENU
0417  and \$GRUB_FILE.
0418 
0419  If you specify syslinux, then you may use SYSLINUX to define the syslinux
0420  command (defaults to extlinux), and SYSLINUX_PATH to specify the path to
0421  the syslinux install (defaults to /boot/extlinux). But you have to specify
0422  SYSLINUX_LABEL to define the label to boot to for the test kernel.
0423 EOF
0424     ;
0425 $config_help{"GRUB_MENU"} = << "EOF"
0426  The grub title name for the test kernel to boot
0427  (Only mandatory if REBOOT_TYPE = grub or grub2)
0428 
0429  Note, ktest.pl will not update the grub menu.lst, you need to
0430  manually add an option for the test. ktest.pl will search
0431  the grub menu.lst for this option to find what kernel to
0432  reboot into.
0433 
0434  For example, if in the /boot/grub/menu.lst the test kernel title has:
0435  title Test Kernel
0436  kernel vmlinuz-test
0437  GRUB_MENU = Test Kernel
0438 
0439  For grub2, a search of \$GRUB_FILE is performed for the lines
0440  that begin with "menuentry". It will not detect submenus. The
0441  menu must be a non-nested menu. Add the quotes used in the menu
0442  to guarantee your selection, as the first menuentry with the content
0443  of \$GRUB_MENU that is found will be used.
0444 EOF
0445     ;
0446 $config_help{"GRUB_FILE"} = << "EOF"
0447  If grub2 is used, the full path for the grub.cfg file is placed
0448  here. Use something like /boot/grub2/grub.cfg to search.
0449 EOF
0450     ;
0451 $config_help{"SYSLINUX_LABEL"} = << "EOF"
0452  If syslinux is used, the label that boots the target kernel must
0453  be specified with SYSLINUX_LABEL.
0454 EOF
0455     ;
0456 $config_help{"REBOOT_SCRIPT"} = << "EOF"
0457  A script to reboot the target into the test kernel
0458  (Only mandatory if REBOOT_TYPE = script)
0459 EOF
0460     ;
0461 
0462 sub _logit {
0463     if (defined($opt{"LOG_FILE"})) {
0464     open(OUT, ">> $opt{LOG_FILE}") or die "Can't write to $opt{LOG_FILE}";
0465     print OUT @_;
0466     close(OUT);
0467     }
0468 }
0469 
0470 sub logit {
0471     if (defined($opt{"LOG_FILE"})) {
0472     _logit @_;
0473     } else {
0474     print @_;
0475     }
0476 }
0477 
0478 sub doprint {
0479     print @_;
0480     _logit @_;
0481 }
0482 
0483 sub read_prompt {
0484     my ($cancel, $prompt) = @_;
0485 
0486     my $ans;
0487 
0488     for (;;) {
0489     if ($cancel) {
0490         print "$prompt [y/n/C] ";
0491     } else {
0492         print "$prompt [Y/n] ";
0493     }
0494     $ans = <STDIN>;
0495     chomp $ans;
0496     if ($ans =~ /^\s*$/) {
0497         if ($cancel) {
0498         $ans = "c";
0499         } else {
0500         $ans = "y";
0501         }
0502     }
0503     last if ($ans =~ /^y$/i || $ans =~ /^n$/i);
0504     if ($cancel) {
0505         last if ($ans =~ /^c$/i);
0506         print "Please answer either 'y', 'n' or 'c'.\n";
0507     } else {
0508         print "Please answer either 'y' or 'n'.\n";
0509     }
0510     }
0511     if ($ans =~ /^c/i) {
0512     exit;
0513     }
0514     if ($ans !~ /^y$/i) {
0515     return 0;
0516     }
0517     return 1;
0518 }
0519 
0520 sub read_yn {
0521     my ($prompt) = @_;
0522 
0523     return read_prompt 0, $prompt;
0524 }
0525 
0526 sub read_ync {
0527     my ($prompt) = @_;
0528 
0529     return read_prompt 1, $prompt;
0530 }
0531 
0532 sub get_mandatory_config {
0533     my ($config) = @_;
0534     my $ans;
0535 
0536     return if (defined($opt{$config}));
0537 
0538     if (defined($config_help{$config})) {
0539     print "\n";
0540     print $config_help{$config};
0541     }
0542 
0543     for (;;) {
0544     print "$config = ";
0545     if (defined($default{$config}) && length($default{$config})) {
0546         print "\[$default{$config}\] ";
0547     }
0548     $ans = <STDIN>;
0549     $ans =~ s/^\s*(.*\S)\s*$/$1/;
0550     if ($ans =~ /^\s*$/) {
0551         if ($default{$config}) {
0552         $ans = $default{$config};
0553         } else {
0554         print "Your answer can not be blank\n";
0555         next;
0556         }
0557     }
0558     $entered_configs{$config} = ${ans};
0559     last;
0560     }
0561 }
0562 
0563 sub show_time {
0564     my ($time) = @_;
0565 
0566     my $hours = 0;
0567     my $minutes = 0;
0568 
0569     if ($time > 3600) {
0570     $hours = int($time / 3600);
0571     $time -= $hours * 3600;
0572     }
0573     if ($time > 60) {
0574     $minutes = int($time / 60);
0575     $time -= $minutes * 60;
0576     }
0577 
0578     if ($hours > 0) {
0579     doprint "$hours hour";
0580     doprint "s" if ($hours > 1);
0581     doprint " ";
0582     }
0583 
0584     if ($minutes > 0) {
0585     doprint "$minutes minute";
0586     doprint "s" if ($minutes > 1);
0587     doprint " ";
0588     }
0589 
0590     doprint "$time second";
0591     doprint "s" if ($time != 1);
0592 }
0593 
0594 sub print_times {
0595     doprint "\n";
0596     if ($build_time) {
0597     doprint "Build time:   ";
0598     show_time($build_time);
0599     doprint "\n";
0600     }
0601     if ($install_time) {
0602     doprint "Install time: ";
0603     show_time($install_time);
0604     doprint "\n";
0605     }
0606     if ($reboot_time) {
0607     doprint "Reboot time:  ";
0608     show_time($reboot_time);
0609     doprint "\n";
0610     }
0611     if ($test_time) {
0612     doprint "Test time:    ";
0613     show_time($test_time);
0614     doprint "\n";
0615     }
0616     # reset for iterations like bisect
0617     $build_time = 0;
0618     $install_time = 0;
0619     $reboot_time = 0;
0620     $test_time = 0;
0621 }
0622 
0623 sub get_mandatory_configs {
0624     get_mandatory_config("MACHINE");
0625     get_mandatory_config("BUILD_DIR");
0626     get_mandatory_config("OUTPUT_DIR");
0627 
0628     if ($newconfig) {
0629     get_mandatory_config("BUILD_OPTIONS");
0630     }
0631 
0632     # options required for other than just building a kernel
0633     if (!$buildonly) {
0634     get_mandatory_config("POWER_CYCLE");
0635     get_mandatory_config("CONSOLE");
0636     }
0637 
0638     # options required for install and more
0639     if ($buildonly != 1) {
0640     get_mandatory_config("SSH_USER");
0641     get_mandatory_config("BUILD_TARGET");
0642     get_mandatory_config("TARGET_IMAGE");
0643     }
0644 
0645     get_mandatory_config("LOCALVERSION");
0646 
0647     return if ($buildonly);
0648 
0649     my $rtype = $opt{"REBOOT_TYPE"};
0650 
0651     if (!defined($rtype)) {
0652     if (!defined($opt{"GRUB_MENU"})) {
0653         get_mandatory_config("REBOOT_TYPE");
0654         $rtype = $entered_configs{"REBOOT_TYPE"};
0655     } else {
0656         $rtype = "grub";
0657     }
0658     }
0659 
0660     if ($rtype eq "grub") {
0661     get_mandatory_config("GRUB_MENU");
0662     }
0663 
0664     if ($rtype eq "grub2") {
0665     get_mandatory_config("GRUB_MENU");
0666     get_mandatory_config("GRUB_FILE");
0667     }
0668 
0669     if ($rtype eq "syslinux") {
0670     get_mandatory_config("SYSLINUX_LABEL");
0671     }
0672 }
0673 
0674 sub process_variables {
0675     my ($value, $remove_undef) = @_;
0676     my $retval = "";
0677 
0678     # We want to check for '\', and it is just easier
0679     # to check the previous characet of '$' and not need
0680     # to worry if '$' is the first character. By adding
0681     # a space to $value, we can just check [^\\]\$ and
0682     # it will still work.
0683     $value = " $value";
0684 
0685     while ($value =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) {
0686     my $begin = $1;
0687     my $var = $2;
0688     my $end = $3;
0689     # append beginning of value to retval
0690     $retval = "$retval$begin";
0691     if (defined($variable{$var})) {
0692         $retval = "$retval$variable{$var}";
0693     } elsif (defined($remove_undef) && $remove_undef) {
0694         # for if statements, any variable that is not defined,
0695         # we simple convert to 0
0696         $retval = "${retval}0";
0697     } else {
0698         # put back the origin piece.
0699         $retval = "$retval\$\{$var\}";
0700         # This could be an option that is used later, save
0701         # it so we don't warn if this option is not one of
0702         # ktests options.
0703         $used_options{$var} = 1;
0704     }
0705     $value = $end;
0706     }
0707     $retval = "$retval$value";
0708 
0709     # remove the space added in the beginning
0710     $retval =~ s/ //;
0711 
0712     return "$retval"
0713 }
0714 
0715 sub set_value {
0716     my ($lvalue, $rvalue, $override, $overrides, $name) = @_;
0717 
0718     my $prvalue = process_variables($rvalue);
0719 
0720     if ($buildonly && $lvalue =~ /^TEST_TYPE(\[.*\])?$/ && $prvalue ne "build") {
0721     # Note if a test is something other than build, then we
0722     # will need other mandatory options.
0723     if ($prvalue ne "install") {
0724         # for bisect, we need to check BISECT_TYPE
0725         if ($prvalue ne "bisect") {
0726         $buildonly = 0;
0727         }
0728     } else {
0729         # install still limits some mandatory options.
0730         $buildonly = 2;
0731     }
0732     }
0733 
0734     if ($buildonly && $lvalue =~ /^BISECT_TYPE(\[.*\])?$/ && $prvalue ne "build") {
0735     if ($prvalue ne "install") {
0736         $buildonly = 0;
0737     } else {
0738         # install still limits some mandatory options.
0739         $buildonly = 2;
0740     }
0741     }
0742 
0743     if (defined($opt{$lvalue})) {
0744     if (!$override || defined(${$overrides}{$lvalue})) {
0745         my $extra = "";
0746         if ($override) {
0747         $extra = "In the same override section!\n";
0748         }
0749         die "$name: $.: Option $lvalue defined more than once!\n$extra";
0750     }
0751     ${$overrides}{$lvalue} = $prvalue;
0752     }
0753 
0754     $opt{$lvalue} = $prvalue;
0755 }
0756 
0757 sub set_eval {
0758     my ($lvalue, $rvalue, $name) = @_;
0759 
0760     my $prvalue = process_variables($rvalue);
0761     my $arr;
0762 
0763     if (defined($evals{$lvalue})) {
0764     $arr = $evals{$lvalue};
0765     } else {
0766     $arr = [];
0767     $evals{$lvalue} = $arr;
0768     }
0769 
0770     push @{$arr}, $rvalue;
0771 }
0772 
0773 sub set_variable {
0774     my ($lvalue, $rvalue) = @_;
0775 
0776     if ($rvalue =~ /^\s*$/) {
0777     delete $variable{$lvalue};
0778     } else {
0779     $rvalue = process_variables($rvalue);
0780     $variable{$lvalue} = $rvalue;
0781     }
0782 }
0783 
0784 sub process_compare {
0785     my ($lval, $cmp, $rval) = @_;
0786 
0787     # remove whitespace
0788 
0789     $lval =~ s/^\s*//;
0790     $lval =~ s/\s*$//;
0791 
0792     $rval =~ s/^\s*//;
0793     $rval =~ s/\s*$//;
0794 
0795     if ($cmp eq "==") {
0796     return $lval eq $rval;
0797     } elsif ($cmp eq "!=") {
0798     return $lval ne $rval;
0799     } elsif ($cmp eq "=~") {
0800     return $lval =~ m/$rval/;
0801     } elsif ($cmp eq "!~") {
0802     return $lval !~ m/$rval/;
0803     }
0804 
0805     my $statement = "$lval $cmp $rval";
0806     my $ret = eval $statement;
0807 
0808     # $@ stores error of eval
0809     if ($@) {
0810     return -1;
0811     }
0812 
0813     return $ret;
0814 }
0815 
0816 sub value_defined {
0817     my ($val) = @_;
0818 
0819     return defined($variable{$2}) ||
0820     defined($opt{$2});
0821 }
0822 
0823 my $d = 0;
0824 sub process_expression {
0825     my ($name, $val) = @_;
0826 
0827     my $c = $d++;
0828 
0829     while ($val =~ s/\(([^\(]*?)\)/\&\&\&\&VAL\&\&\&\&/) {
0830     my $express = $1;
0831 
0832     if (process_expression($name, $express)) {
0833         $val =~ s/\&\&\&\&VAL\&\&\&\&/ 1 /;
0834     } else {
0835         $val =~ s/\&\&\&\&VAL\&\&\&\&/ 0 /;
0836     }
0837     }
0838 
0839     $d--;
0840     my $OR = "\\|\\|";
0841     my $AND = "\\&\\&";
0842 
0843     while ($val =~ s/^(.*?)($OR|$AND)//) {
0844     my $express = $1;
0845     my $op = $2;
0846 
0847     if (process_expression($name, $express)) {
0848         if ($op eq "||") {
0849         return 1;
0850         }
0851     } else {
0852         if ($op eq "&&") {
0853         return 0;
0854         }
0855     }
0856     }
0857 
0858     if ($val =~ /(.*)(==|\!=|>=|<=|>|<|=~|\!~)(.*)/) {
0859     my $ret = process_compare($1, $2, $3);
0860     if ($ret < 0) {
0861         die "$name: $.: Unable to process comparison\n";
0862     }
0863     return $ret;
0864     }
0865 
0866     if ($val =~ /^\s*(NOT\s*)?DEFINED\s+(\S+)\s*$/) {
0867     if (defined $1) {
0868         return !value_defined($2);
0869     } else {
0870         return value_defined($2);
0871     }
0872     }
0873 
0874     if ($val =~ /^\s*0\s*$/) {
0875     return 0;
0876     } elsif ($val =~ /^\s*\d+\s*$/) {
0877     return 1;
0878     }
0879 
0880     die ("$name: $.: Undefined content $val in if statement\n");
0881 }
0882 
0883 sub process_if {
0884     my ($name, $value) = @_;
0885 
0886     # Convert variables and replace undefined ones with 0
0887     my $val = process_variables($value, 1);
0888     my $ret = process_expression $name, $val;
0889 
0890     return $ret;
0891 }
0892 
0893 sub __read_config {
0894     my ($config, $current_test_num) = @_;
0895 
0896     my $in;
0897     open($in, $config) || die "can't read file $config";
0898 
0899     my $name = $config;
0900     $name =~ s,.*/(.*),$1,;
0901 
0902     my $test_num = $$current_test_num;
0903     my $default = 1;
0904     my $repeat = 1;
0905     my $num_tests_set = 0;
0906     my $skip = 0;
0907     my $rest;
0908     my $line;
0909     my $test_case = 0;
0910     my $if = 0;
0911     my $if_set = 0;
0912     my $override = 0;
0913 
0914     my %overrides;
0915 
0916     while (<$in>) {
0917 
0918     # ignore blank lines and comments
0919     next if (/^\s*$/ || /\s*\#/);
0920 
0921     if (/^\s*(TEST_START|DEFAULTS)\b(.*)/) {
0922 
0923         my $type = $1;
0924         $rest = $2;
0925         $line = $2;
0926 
0927         my $old_test_num;
0928         my $old_repeat;
0929         $override = 0;
0930 
0931         if ($type eq "TEST_START") {
0932 
0933         if ($num_tests_set) {
0934             die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
0935         }
0936 
0937         $old_test_num = $test_num;
0938         $old_repeat = $repeat;
0939 
0940         $test_num += $repeat;
0941         $default = 0;
0942         $repeat = 1;
0943         } else {
0944         $default = 1;
0945         }
0946 
0947         # If SKIP is anywhere in the line, the command will be skipped
0948         if ($rest =~ s/\s+SKIP\b//) {
0949         $skip = 1;
0950         } else {
0951         $test_case = 1;
0952         $skip = 0;
0953         }
0954 
0955         if ($rest =~ s/\sELSE\b//) {
0956         if (!$if) {
0957             die "$name: $.: ELSE found with out matching IF section\n$_";
0958         }
0959         $if = 0;
0960 
0961         if ($if_set) {
0962             $skip = 1;
0963         } else {
0964             $skip = 0;
0965         }
0966         }
0967 
0968         if ($rest =~ s/\sIF\s+(.*)//) {
0969         if (process_if($name, $1)) {
0970             $if_set = 1;
0971         } else {
0972             $skip = 1;
0973         }
0974         $if = 1;
0975         } else {
0976         $if = 0;
0977         $if_set = 0;
0978         }
0979 
0980         if (!$skip) {
0981         if ($type eq "TEST_START") {
0982             if ($rest =~ s/\s+ITERATE\s+(\d+)//) {
0983             $repeat = $1;
0984             $repeat_tests{"$test_num"} = $repeat;
0985             }
0986         } elsif ($rest =~ s/\sOVERRIDE\b//) {
0987             # DEFAULT only
0988             $override = 1;
0989             # Clear previous overrides
0990             %overrides = ();
0991         }
0992         }
0993 
0994         if (!$skip && $rest !~ /^\s*$/) {
0995         die "$name: $.: Gargbage found after $type\n$_";
0996         }
0997 
0998         if ($skip && $type eq "TEST_START") {
0999         $test_num = $old_test_num;
1000         $repeat = $old_repeat;
1001         }
1002 
1003     } elsif (/^\s*ELSE\b(.*)$/) {
1004         if (!$if) {
1005         die "$name: $.: ELSE found with out matching IF section\n$_";
1006         }
1007         $rest = $1;
1008         if ($if_set) {
1009         $skip = 1;
1010         $rest = "";
1011         } else {
1012         $skip = 0;
1013 
1014         if ($rest =~ /\sIF\s+(.*)/) {
1015             # May be a ELSE IF section.
1016             if (process_if($name, $1)) {
1017             $if_set = 1;
1018             } else {
1019             $skip = 1;
1020             }
1021             $rest = "";
1022         } else {
1023             $if = 0;
1024         }
1025         }
1026 
1027         if ($rest !~ /^\s*$/) {
1028         die "$name: $.: Gargbage found after DEFAULTS\n$_";
1029         }
1030 
1031     } elsif (/^\s*INCLUDE\s+(\S+)/) {
1032 
1033         next if ($skip);
1034 
1035         if (!$default) {
1036         die "$name: $.: INCLUDE can only be done in default sections\n$_";
1037         }
1038 
1039         my $file = process_variables($1);
1040 
1041         if ($file !~ m,^/,) {
1042         # check the path of the config file first
1043         if ($config =~ m,(.*)/,) {
1044             if (-f "$1/$file") {
1045             $file = "$1/$file";
1046             }
1047         }
1048         }
1049         
1050         if ( ! -r $file ) {
1051         die "$name: $.: Can't read file $file\n$_";
1052         }
1053 
1054         if (__read_config($file, \$test_num)) {
1055         $test_case = 1;
1056         }
1057 
1058     } elsif (/^\s*([A-Z_\[\]\d]+)\s*=~\s*(.*?)\s*$/) {
1059 
1060         next if ($skip);
1061 
1062         my $lvalue = $1;
1063         my $rvalue = $2;
1064 
1065         if ($default || $lvalue =~ /\[\d+\]$/) {
1066         set_eval($lvalue, $rvalue, $name);
1067         } else {
1068         my $val = "$lvalue\[$test_num\]";
1069         set_eval($val, $rvalue, $name);
1070         }
1071 
1072     } elsif (/^\s*([A-Z_\[\]\d]+)\s*=\s*(.*?)\s*$/) {
1073 
1074         next if ($skip);
1075 
1076         my $lvalue = $1;
1077         my $rvalue = $2;
1078 
1079         if (!$default &&
1080         ($lvalue eq "NUM_TESTS" ||
1081          $lvalue eq "LOG_FILE" ||
1082          $lvalue eq "CLEAR_LOG")) {
1083         die "$name: $.: $lvalue must be set in DEFAULTS section\n";
1084         }
1085 
1086         if ($lvalue eq "NUM_TESTS") {
1087         if ($test_num) {
1088             die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
1089         }
1090         if (!$default) {
1091             die "$name: $.: NUM_TESTS must be set in default section\n";
1092         }
1093         $num_tests_set = 1;
1094         }
1095 
1096         if ($default || $lvalue =~ /\[\d+\]$/) {
1097         set_value($lvalue, $rvalue, $override, \%overrides, $name);
1098         } else {
1099         my $val = "$lvalue\[$test_num\]";
1100         set_value($val, $rvalue, $override, \%overrides, $name);
1101 
1102         if ($repeat > 1) {
1103             $repeats{$val} = $repeat;
1104         }
1105         }
1106     } elsif (/^\s*([A-Z_\[\]\d]+)\s*:=\s*(.*?)\s*$/) {
1107         next if ($skip);
1108 
1109         my $lvalue = $1;
1110         my $rvalue = $2;
1111 
1112         # process config variables.
1113         # Config variables are only active while reading the
1114         # config and can be defined anywhere. They also ignore
1115         # TEST_START and DEFAULTS, but are skipped if they are in
1116         # on of these sections that have SKIP defined.
1117         # The save variable can be
1118         # defined multiple times and the new one simply overrides
1119         # the prevous one.
1120         set_variable($lvalue, $rvalue);
1121 
1122     } else {
1123         die "$name: $.: Garbage found in config\n$_";
1124     }
1125     }
1126 
1127     if ($test_num) {
1128     $test_num += $repeat - 1;
1129     $opt{"NUM_TESTS"} = $test_num;
1130     }
1131 
1132     close($in);
1133 
1134     $$current_test_num = $test_num;
1135 
1136     return $test_case;
1137 }
1138 
1139 sub get_test_case {
1140     print "What test case would you like to run?\n";
1141     print " (build, install or boot)\n";
1142     print " Other tests are available but require editing the config file\n";
1143     my $ans = <STDIN>;
1144     chomp $ans;
1145     $default{"TEST_TYPE"} = $ans;
1146 }
1147 
1148 sub read_config {
1149     my ($config) = @_;
1150 
1151     my $test_case;
1152     my $test_num = 0;
1153 
1154     $test_case = __read_config $config, \$test_num;
1155 
1156     # make sure we have all mandatory configs
1157     get_mandatory_configs;
1158 
1159     # was a test specified?
1160     if (!$test_case) {
1161     print "No test case specified.\n";
1162     get_test_case;
1163     }
1164 
1165     # set any defaults
1166 
1167     foreach my $default (keys %default) {
1168     if (!defined($opt{$default})) {
1169         $opt{$default} = $default{$default};
1170     }
1171     }
1172 
1173     if ($opt{"IGNORE_UNUSED"} == 1) {
1174     return;
1175     }
1176 
1177     my %not_used;
1178 
1179     # check if there are any stragglers (typos?)
1180     foreach my $option (keys %opt) {
1181     my $op = $option;
1182     # remove per test labels.
1183     $op =~ s/\[.*\]//;
1184     if (!exists($option_map{$op}) &&
1185         !exists($default{$op}) &&
1186         !exists($used_options{$op})) {
1187         $not_used{$op} = 1;
1188     }
1189     }
1190 
1191     if (%not_used) {
1192     my $s = "s are";
1193     $s = " is" if (keys %not_used == 1);
1194     print "The following option$s not used; could be a typo:\n";
1195     foreach my $option (keys %not_used) {
1196         print "$option\n";
1197     }
1198     print "Set IGRNORE_UNUSED = 1 to have ktest ignore unused variables\n";
1199     if (!read_yn "Do you want to continue?") {
1200         exit -1;
1201     }
1202     }
1203 }
1204 
1205 sub __eval_option {
1206     my ($name, $option, $i) = @_;
1207 
1208     # Add space to evaluate the character before $
1209     $option = " $option";
1210     my $retval = "";
1211     my $repeated = 0;
1212     my $parent = 0;
1213 
1214     foreach my $test (keys %repeat_tests) {
1215     if ($i >= $test &&
1216         $i < $test + $repeat_tests{$test}) {
1217 
1218         $repeated = 1;
1219         $parent = $test;
1220         last;
1221     }
1222     }
1223 
1224     while ($option =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) {
1225     my $start = $1;
1226     my $var = $2;
1227     my $end = $3;
1228 
1229     # Append beginning of line
1230     $retval = "$retval$start";
1231 
1232     # If the iteration option OPT[$i] exists, then use that.
1233     # otherwise see if the default OPT (without [$i]) exists.
1234 
1235     my $o = "$var\[$i\]";
1236     my $parento = "$var\[$parent\]";
1237 
1238     # If a variable contains itself, use the default var
1239     if (($var eq $name) && defined($opt{$var})) {
1240         $o = $opt{$var};
1241         $retval = "$retval$o";
1242     } elsif (defined($opt{$o})) {
1243         $o = $opt{$o};
1244         $retval = "$retval$o";
1245     } elsif ($repeated && defined($opt{$parento})) {
1246         $o = $opt{$parento};
1247         $retval = "$retval$o";
1248     } elsif (defined($opt{$var})) {
1249         $o = $opt{$var};
1250         $retval = "$retval$o";
1251     } elsif ($var eq "KERNEL_VERSION" && defined($make)) {
1252         # special option KERNEL_VERSION uses kernel version
1253         get_version();
1254         $retval = "$retval$version";
1255     } else {
1256         $retval = "$retval\$\{$var\}";
1257     }
1258 
1259     $option = $end;
1260     }
1261 
1262     $retval = "$retval$option";
1263 
1264     $retval =~ s/^ //;
1265 
1266     return $retval;
1267 }
1268 
1269 sub process_evals {
1270     my ($name, $option, $i) = @_;
1271 
1272     my $option_name = "$name\[$i\]";
1273     my $ev;
1274 
1275     my $old_option = $option;
1276 
1277     if (defined($evals{$option_name})) {
1278     $ev = $evals{$option_name};
1279     } elsif (defined($evals{$name})) {
1280     $ev = $evals{$name};
1281     } else {
1282     return $option;
1283     }
1284 
1285     for my $e (@{$ev}) {
1286     eval "\$option =~ $e";
1287     }
1288 
1289     if ($option ne $old_option) {
1290     doprint("$name changed from '$old_option' to '$option'\n");
1291     }
1292 
1293     return $option;
1294 }
1295 
1296 sub eval_option {
1297     my ($name, $option, $i) = @_;
1298 
1299     my $prev = "";
1300 
1301     # Since an option can evaluate to another option,
1302     # keep iterating until we do not evaluate any more
1303     # options.
1304     my $r = 0;
1305     while ($prev ne $option) {
1306     # Check for recursive evaluations.
1307     # 100 deep should be more than enough.
1308     if ($r++ > 100) {
1309         die "Over 100 evaluations accurred with $option\n" .
1310         "Check for recursive variables\n";
1311     }
1312     $prev = $option;
1313     $option = __eval_option($name, $option, $i);
1314     }
1315 
1316     $option = process_evals($name, $option, $i);
1317 
1318     return $option;
1319 }
1320 
1321 sub run_command;
1322 sub start_monitor;
1323 sub end_monitor;
1324 sub wait_for_monitor;
1325 
1326 sub reboot {
1327     my ($time) = @_;
1328 
1329     # Make sure everything has been written to disk
1330     run_ssh("sync");
1331 
1332     if (defined($time)) {
1333     start_monitor;
1334     # flush out current monitor
1335     # May contain the reboot success line
1336     wait_for_monitor 1;
1337     }
1338 
1339     # try to reboot normally
1340     if (run_command $reboot) {
1341     if (defined($powercycle_after_reboot)) {
1342         sleep $powercycle_after_reboot;
1343         run_command "$power_cycle";
1344     }
1345     } else {
1346     # nope? power cycle it.
1347     run_command "$power_cycle";
1348     }
1349 
1350     if (defined($time)) {
1351 
1352     # We only want to get to the new kernel, don't fail
1353     # if we stumble over a call trace.
1354     my $save_ignore_errors = $ignore_errors;
1355     $ignore_errors = 1;
1356 
1357     # Look for the good kernel to boot
1358     if (wait_for_monitor($time, "Linux version")) {
1359         # reboot got stuck?
1360         doprint "Reboot did not finish. Forcing power cycle\n";
1361         run_command "$power_cycle";
1362     }
1363 
1364     $ignore_errors = $save_ignore_errors;
1365 
1366     # Still need to wait for the reboot to finish
1367     wait_for_monitor($time, $reboot_success_line);
1368 
1369     end_monitor;
1370     }
1371 }
1372 
1373 sub reboot_to_good {
1374     my ($time) = @_;
1375 
1376     if (defined($switch_to_good)) {
1377     run_command $switch_to_good;
1378     }
1379 
1380     reboot $time;
1381 }
1382 
1383 sub do_not_reboot {
1384     my $i = $iteration;
1385 
1386     return $test_type eq "build" || $no_reboot ||
1387     ($test_type eq "patchcheck" && $opt{"PATCHCHECK_TYPE[$i]"} eq "build") ||
1388     ($test_type eq "bisect" && $opt{"BISECT_TYPE[$i]"} eq "build");
1389 }
1390 
1391 sub dodie {
1392     doprint "CRITICAL FAILURE... ", @_, "\n";
1393 
1394     my $i = $iteration;
1395 
1396     if ($reboot_on_error && !do_not_reboot) {
1397 
1398     doprint "REBOOTING\n";
1399     reboot_to_good;
1400 
1401     } elsif ($poweroff_on_error && defined($power_off)) {
1402     doprint "POWERING OFF\n";
1403     `$power_off`;
1404     }
1405 
1406     if (defined($opt{"LOG_FILE"})) {
1407     print " See $opt{LOG_FILE} for more info.\n";
1408     }
1409 
1410     if ($monitor_cnt) {
1411         # restore terminal settings
1412         system("stty $stty_orig");
1413     }
1414 
1415     die @_, "\n";
1416 }
1417 
1418 sub create_pty {
1419     my ($ptm, $pts) = @_;
1420     my $tmp;
1421     my $TIOCSPTLCK = 0x40045431;
1422     my $TIOCGPTN = 0x80045430;
1423 
1424     sysopen($ptm, "/dev/ptmx", O_RDWR | O_NONBLOCK) or
1425     dodie "Cant open /dev/ptmx";
1426 
1427     # unlockpt()
1428     $tmp = pack("i", 0);
1429     ioctl($ptm, $TIOCSPTLCK, $tmp) or
1430     dodie "ioctl TIOCSPTLCK for /dev/ptmx failed";
1431 
1432     # ptsname()
1433     ioctl($ptm, $TIOCGPTN, $tmp) or
1434     dodie "ioctl TIOCGPTN for /dev/ptmx failed";
1435     $tmp = unpack("i", $tmp);
1436 
1437     sysopen($pts, "/dev/pts/$tmp", O_RDWR | O_NONBLOCK) or
1438     dodie "Can't open /dev/pts/$tmp";
1439 }
1440 
1441 sub exec_console {
1442     my ($ptm, $pts) = @_;
1443 
1444     close($ptm);
1445 
1446     close(\*STDIN);
1447     close(\*STDOUT);
1448     close(\*STDERR);
1449 
1450     open(\*STDIN, '<&', $pts);
1451     open(\*STDOUT, '>&', $pts);
1452     open(\*STDERR, '>&', $pts);
1453 
1454     close($pts);
1455 
1456     exec $console or
1457     die "Can't open console $console";
1458 }
1459 
1460 sub open_console {
1461     my ($ptm) = @_;
1462     my $pts = \*PTSFD;
1463     my $pid;
1464 
1465     # save terminal settings
1466     $stty_orig = `stty -g`;
1467 
1468     # place terminal in cbreak mode so that stdin can be read one character at
1469     # a time without having to wait for a newline
1470     system("stty -icanon -echo -icrnl");
1471 
1472     create_pty($ptm, $pts);
1473 
1474     $pid = fork;
1475 
1476     if (!$pid) {
1477     # child
1478     exec_console($ptm, $pts)
1479     }
1480 
1481     # parent
1482     close($pts);
1483 
1484     return $pid;
1485 
1486     open(PTSFD, "Stop perl from warning about single use of PTSFD");
1487 }
1488 
1489 sub close_console {
1490     my ($fp, $pid) = @_;
1491 
1492     doprint "kill child process $pid\n";
1493     kill $close_console_signal, $pid;
1494 
1495     print "closing!\n";
1496     close($fp);
1497 
1498     # restore terminal settings
1499     system("stty $stty_orig");
1500 }
1501 
1502 sub start_monitor {
1503     if ($monitor_cnt++) {
1504     return;
1505     }
1506     $monitor_fp = \*MONFD;
1507     $monitor_pid = open_console $monitor_fp;
1508 
1509     return;
1510 
1511     open(MONFD, "Stop perl from warning about single use of MONFD");
1512 }
1513 
1514 sub end_monitor {
1515     return if (!defined $console);
1516     if (--$monitor_cnt) {
1517     return;
1518     }
1519     close_console($monitor_fp, $monitor_pid);
1520 }
1521 
1522 sub wait_for_monitor {
1523     my ($time, $stop) = @_;
1524     my $full_line = "";
1525     my $line;
1526     my $booted = 0;
1527     my $start_time = time;
1528     my $skip_call_trace = 0;
1529     my $bug = 0;
1530     my $bug_ignored = 0;
1531     my $now;
1532 
1533     doprint "** Wait for monitor to settle down **\n";
1534 
1535     # read the monitor and wait for the system to calm down
1536     while (!$booted) {
1537     $line = wait_for_input($monitor_fp, $time);
1538     last if (!defined($line));
1539     print "$line";
1540     $full_line .= $line;
1541 
1542     if (defined($stop) && $full_line =~ /$stop/) {
1543         doprint "wait for monitor detected $stop\n";
1544         $booted = 1;
1545     }
1546 
1547     if ($full_line =~ /\[ backtrace testing \]/) {
1548         $skip_call_trace = 1;
1549     }
1550 
1551     if ($full_line =~ /call trace:/i) {
1552         if (!$bug && !$skip_call_trace) {
1553         if ($ignore_errors) {
1554             $bug_ignored = 1;
1555         } else {
1556             $bug = 1;
1557         }
1558         }
1559     }
1560 
1561     if ($full_line =~ /\[ end of backtrace testing \]/) {
1562         $skip_call_trace = 0;
1563     }
1564 
1565     if ($full_line =~ /Kernel panic -/) {
1566         $bug = 1;
1567     }
1568 
1569     if ($line =~ /\n/) {
1570         $full_line = "";
1571     }
1572     $now = time;
1573     if ($now - $start_time >= $max_monitor_wait) {
1574         doprint "Exiting monitor flush due to hitting MAX_MONITOR_WAIT\n";
1575         return 1;
1576     }
1577     }
1578     print "** Monitor flushed **\n";
1579 
1580     # if stop is defined but wasn't hit, return error
1581     # used by reboot (which wants to see a reboot)
1582     if (defined($stop) && !$booted) {
1583     $bug = 1;
1584     }
1585     return $bug;
1586 }
1587 
1588 sub save_logs {
1589     my ($result, $basedir) = @_;
1590     my @t = localtime;
1591     my $date = sprintf "%04d%02d%02d%02d%02d%02d",
1592         1900+$t[5],$t[4],$t[3],$t[2],$t[1],$t[0];
1593 
1594     my $type = $build_type;
1595     if ($type =~ /useconfig/) {
1596         $type = "useconfig";
1597     }
1598 
1599     my $dir = "$machine-$test_type-$type-$result-$date";
1600 
1601     $dir = "$basedir/$dir";
1602 
1603     if (!-d $dir) {
1604         mkpath($dir) or
1605         die "can't create $dir";
1606     }
1607 
1608     my %files = (
1609         "config" => $output_config,
1610         "buildlog" => $buildlog,
1611         "dmesg" => $dmesg,
1612         "testlog" => $testlog,
1613     );
1614 
1615     while (my ($name, $source) = each(%files)) {
1616         if (-f "$source") {
1617             cp "$source", "$dir/$name" or
1618                 die "failed to copy $source";
1619         }
1620     }
1621 
1622     doprint "*** Saved info to $dir ***\n";
1623 }
1624 
1625 sub fail {
1626 
1627     if (defined($post_test)) {
1628         run_command $post_test;
1629     }
1630 
1631     if ($die_on_failure) {
1632         dodie @_;
1633     }
1634 
1635     doprint "FAILED\n";
1636 
1637     my $i = $iteration;
1638 
1639     # no need to reboot for just building.
1640     if (!do_not_reboot) {
1641         doprint "REBOOTING\n";
1642         reboot_to_good $sleep_time;
1643     }
1644 
1645     my $name = "";
1646 
1647     if (defined($test_name)) {
1648         $name = " ($test_name)";
1649     }
1650 
1651     print_times;
1652 
1653     doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
1654     doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
1655     doprint "KTEST RESULT: TEST $i$name Failed: ", @_, "\n";
1656     doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
1657     doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
1658 
1659     if (defined($store_failures)) {
1660         save_logs "fail", $store_failures;
1661         }
1662 
1663     return 1;
1664 }
1665 
1666 sub run_command {
1667     my ($command, $redirect) = @_;
1668     my $start_time;
1669     my $end_time;
1670     my $dolog = 0;
1671     my $dord = 0;
1672     my $pid;
1673 
1674     $start_time = time;
1675 
1676     $command =~ s/\$SSH_USER/$ssh_user/g;
1677     $command =~ s/\$MACHINE/$machine/g;
1678 
1679     doprint("$command ... ");
1680 
1681     $pid = open(CMD, "$command 2>&1 |") or
1682     (fail "unable to exec $command" and return 0);
1683 
1684     if (defined($opt{"LOG_FILE"})) {
1685     open(LOG, ">>$opt{LOG_FILE}") or
1686         dodie "failed to write to log";
1687     $dolog = 1;
1688     }
1689 
1690     if (defined($redirect)) {
1691     open (RD, ">$redirect") or
1692         dodie "failed to write to redirect $redirect";
1693     $dord = 1;
1694     }
1695 
1696     while (<CMD>) {
1697     print LOG if ($dolog);
1698     print RD  if ($dord);
1699     }
1700 
1701     waitpid($pid, 0);
1702     my $failed = $?;
1703 
1704     close(CMD);
1705     close(LOG) if ($dolog);
1706     close(RD)  if ($dord);
1707 
1708     $end_time = time;
1709     my $delta = $end_time - $start_time;
1710 
1711     if ($delta == 1) {
1712     doprint "[1 second] ";
1713     } else {
1714     doprint "[$delta seconds] ";
1715     }
1716 
1717     if ($failed) {
1718     doprint "FAILED!\n";
1719     } else {
1720     doprint "SUCCESS\n";
1721     }
1722 
1723     return !$failed;
1724 }
1725 
1726 sub run_ssh {
1727     my ($cmd) = @_;
1728     my $cp_exec = $ssh_exec;
1729 
1730     $cp_exec =~ s/\$SSH_COMMAND/$cmd/g;
1731     return run_command "$cp_exec";
1732 }
1733 
1734 sub run_scp {
1735     my ($src, $dst, $cp_scp) = @_;
1736 
1737     $cp_scp =~ s/\$SRC_FILE/$src/g;
1738     $cp_scp =~ s/\$DST_FILE/$dst/g;
1739 
1740     return run_command "$cp_scp";
1741 }
1742 
1743 sub run_scp_install {
1744     my ($src, $dst) = @_;
1745 
1746     my $cp_scp = $scp_to_target_install;
1747 
1748     return run_scp($src, $dst, $cp_scp);
1749 }
1750 
1751 sub run_scp_mod {
1752     my ($src, $dst) = @_;
1753 
1754     my $cp_scp = $scp_to_target;
1755 
1756     return run_scp($src, $dst, $cp_scp);
1757 }
1758 
1759 sub get_grub2_index {
1760 
1761     return if (defined($grub_number) && defined($last_grub_menu) &&
1762            $last_grub_menu eq $grub_menu && defined($last_machine) &&
1763            $last_machine eq $machine);
1764 
1765     doprint "Find grub2 menu ... ";
1766     $grub_number = -1;
1767 
1768     my $ssh_grub = $ssh_exec;
1769     $ssh_grub =~ s,\$SSH_COMMAND,cat $grub_file,g;
1770 
1771     open(IN, "$ssh_grub |")
1772     or die "unable to get $grub_file";
1773 
1774     my $found = 0;
1775 
1776     while (<IN>) {
1777     if (/^menuentry.*$grub_menu/) {
1778         $grub_number++;
1779         $found = 1;
1780         last;
1781     } elsif (/^menuentry\s/) {
1782         $grub_number++;
1783     }
1784     }
1785     close(IN);
1786 
1787     die "Could not find '$grub_menu' in $grub_file on $machine"
1788     if (!$found);
1789     doprint "$grub_number\n";
1790     $last_grub_menu = $grub_menu;
1791     $last_machine = $machine;
1792 }
1793 
1794 sub get_grub_index {
1795 
1796     if ($reboot_type eq "grub2") {
1797     get_grub2_index;
1798     return;
1799     }
1800 
1801     if ($reboot_type ne "grub") {
1802     return;
1803     }
1804     return if (defined($grub_number) && defined($last_grub_menu) &&
1805            $last_grub_menu eq $grub_menu && defined($last_machine) &&
1806            $last_machine eq $machine);
1807 
1808     doprint "Find grub menu ... ";
1809     $grub_number = -1;
1810 
1811     my $ssh_grub = $ssh_exec;
1812     $ssh_grub =~ s,\$SSH_COMMAND,cat /boot/grub/menu.lst,g;
1813 
1814     open(IN, "$ssh_grub |")
1815     or die "unable to get menu.lst";
1816 
1817     my $found = 0;
1818 
1819     while (<IN>) {
1820     if (/^\s*title\s+$grub_menu\s*$/) {
1821         $grub_number++;
1822         $found = 1;
1823         last;
1824     } elsif (/^\s*title\s/) {
1825         $grub_number++;
1826     }
1827     }
1828     close(IN);
1829 
1830     die "Could not find '$grub_menu' in /boot/grub/menu on $machine"
1831     if (!$found);
1832     doprint "$grub_number\n";
1833     $last_grub_menu = $grub_menu;
1834     $last_machine = $machine;
1835 }
1836 
1837 sub wait_for_input
1838 {
1839     my ($fp, $time) = @_;
1840     my $rin;
1841     my $rout;
1842     my $nr;
1843     my $buf;
1844     my $line;
1845     my $ch;
1846 
1847     if (!defined($time)) {
1848     $time = $timeout;
1849     }
1850 
1851     $rin = '';
1852     vec($rin, fileno($fp), 1) = 1;
1853     vec($rin, fileno(\*STDIN), 1) = 1;
1854 
1855     while (1) {
1856     $nr = select($rout=$rin, undef, undef, $time);
1857 
1858     if ($nr <= 0) {
1859         return undef;
1860     }
1861 
1862     # copy data from stdin to the console
1863     if (vec($rout, fileno(\*STDIN), 1) == 1) {
1864         sysread(\*STDIN, $buf, 1000);
1865         syswrite($fp, $buf, 1000);
1866         next;
1867     }
1868 
1869     $line = "";
1870 
1871     # try to read one char at a time
1872     while (sysread $fp, $ch, 1) {
1873         $line .= $ch;
1874         last if ($ch eq "\n");
1875     }
1876 
1877     if (!length($line)) {
1878         return undef;
1879     }
1880 
1881     return $line;
1882     }
1883 }
1884 
1885 sub reboot_to {
1886     if (defined($switch_to_test)) {
1887     run_command $switch_to_test;
1888     }
1889 
1890     if ($reboot_type eq "grub") {
1891     run_ssh "'(echo \"savedefault --default=$grub_number --once\" | grub --batch)'";
1892     } elsif ($reboot_type eq "grub2") {
1893     run_ssh "$grub_reboot $grub_number";
1894     } elsif ($reboot_type eq "syslinux") {
1895     run_ssh "$syslinux --once \\\"$syslinux_label\\\" $syslinux_path";
1896     } elsif (defined $reboot_script) {
1897     run_command "$reboot_script";
1898     }
1899     reboot;
1900 }
1901 
1902 sub get_sha1 {
1903     my ($commit) = @_;
1904 
1905     doprint "git rev-list --max-count=1 $commit ... ";
1906     my $sha1 = `git rev-list --max-count=1 $commit`;
1907     my $ret = $?;
1908 
1909     logit $sha1;
1910 
1911     if ($ret) {
1912     doprint "FAILED\n";
1913     dodie "Failed to get git $commit";
1914     }
1915 
1916     print "SUCCESS\n";
1917 
1918     chomp $sha1;
1919 
1920     return $sha1;
1921 }
1922 
1923 sub monitor {
1924     my $booted = 0;
1925     my $bug = 0;
1926     my $bug_ignored = 0;
1927     my $skip_call_trace = 0;
1928     my $loops;
1929 
1930     my $start_time = time;
1931 
1932     wait_for_monitor 5;
1933 
1934     my $line;
1935     my $full_line = "";
1936 
1937     open(DMESG, "> $dmesg") or
1938     die "unable to write to $dmesg";
1939 
1940     reboot_to;
1941 
1942     my $success_start;
1943     my $failure_start;
1944     my $monitor_start = time;
1945     my $done = 0;
1946     my $version_found = 0;
1947 
1948     while (!$done) {
1949 
1950     if ($bug && defined($stop_after_failure) &&
1951         $stop_after_failure >= 0) {
1952         my $time = $stop_after_failure - (time - $failure_start);
1953         $line = wait_for_input($monitor_fp, $time);
1954         if (!defined($line)) {
1955         doprint "bug timed out after $booted_timeout seconds\n";
1956         doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
1957         last;
1958         }
1959     } elsif ($booted) {
1960         $line = wait_for_input($monitor_fp, $booted_timeout);
1961         if (!defined($line)) {
1962         my $s = $booted_timeout == 1 ? "" : "s";
1963         doprint "Successful boot found: break after $booted_timeout second$s\n";
1964         last;
1965         }
1966     } else {
1967         $line = wait_for_input($monitor_fp);
1968         if (!defined($line)) {
1969         my $s = $timeout == 1 ? "" : "s";
1970         doprint "Timed out after $timeout second$s\n";
1971         last;
1972         }
1973     }
1974 
1975     doprint $line;
1976     print DMESG $line;
1977 
1978     # we are not guaranteed to get a full line
1979     $full_line .= $line;
1980 
1981     if ($full_line =~ /$success_line/) {
1982         $booted = 1;
1983         $success_start = time;
1984     }
1985 
1986     if ($booted && defined($stop_after_success) &&
1987         $stop_after_success >= 0) {
1988         my $now = time;
1989         if ($now - $success_start >= $stop_after_success) {
1990         doprint "Test forced to stop after $stop_after_success seconds after success\n";
1991         last;
1992         }
1993     }
1994 
1995     if ($full_line =~ /\[ backtrace testing \]/) {
1996         $skip_call_trace = 1;
1997     }
1998 
1999     if ($full_line =~ /call trace:/i) {
2000         if (!$bug && !$skip_call_trace) {
2001         if ($ignore_errors) {
2002             $bug_ignored = 1;
2003         } else {
2004             $bug = 1;
2005             $failure_start = time;
2006         }
2007         }
2008     }
2009 
2010     if ($bug && defined($stop_after_failure) &&
2011         $stop_after_failure >= 0) {
2012         my $now = time;
2013         if ($now - $failure_start >= $stop_after_failure) {
2014         doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
2015         last;
2016         }
2017     }
2018 
2019     if ($full_line =~ /\[ end of backtrace testing \]/) {
2020         $skip_call_trace = 0;
2021     }
2022 
2023     if ($full_line =~ /Kernel panic -/) {
2024         $failure_start = time;
2025         $bug = 1;
2026     }
2027 
2028     # Detect triple faults by testing the banner
2029     if ($full_line =~ /\bLinux version (\S+).*\n/) {
2030         if ($1 eq $version) {
2031         $version_found = 1;
2032         } elsif ($version_found && $detect_triplefault) {
2033         # We already booted into the kernel we are testing,
2034         # but now we booted into another kernel?
2035         # Consider this a triple fault.
2036         doprint "Already booted in Linux kernel $version, but now\n";
2037         doprint "we booted into Linux kernel $1.\n";
2038         doprint "Assuming that this is a triple fault.\n";
2039         doprint "To disable this: set DETECT_TRIPLE_FAULT to 0\n";
2040         last;
2041         }
2042     }
2043 
2044     if ($line =~ /\n/) {
2045         $full_line = "";
2046     }
2047 
2048     if ($stop_test_after > 0 && !$booted && !$bug) {
2049         if (time - $monitor_start > $stop_test_after) {
2050         doprint "STOP_TEST_AFTER ($stop_test_after seconds) timed out\n";
2051         $done = 1;
2052         }
2053     }
2054     }
2055 
2056     my $end_time = time;
2057     $reboot_time = $end_time - $start_time;
2058 
2059     close(DMESG);
2060 
2061     if ($bug) {
2062     return 0 if ($in_bisect);
2063     fail "failed - got a bug report" and return 0;
2064     }
2065 
2066     if (!$booted) {
2067     return 0 if ($in_bisect);
2068     fail "failed - never got a boot prompt." and return 0;
2069     }
2070 
2071     if ($bug_ignored) {
2072     doprint "WARNING: Call Trace detected but ignored due to IGNORE_ERRORS=1\n";
2073     }
2074 
2075     return 1;
2076 }
2077 
2078 sub eval_kernel_version {
2079     my ($option) = @_;
2080 
2081     $option =~ s/\$KERNEL_VERSION/$version/g;
2082 
2083     return $option;
2084 }
2085 
2086 sub do_post_install {
2087 
2088     return if (!defined($post_install));
2089 
2090     my $cp_post_install = eval_kernel_version $post_install;
2091     run_command "$cp_post_install" or
2092     dodie "Failed to run post install";
2093 }
2094 
2095 # Sometimes the reboot fails, and will hang. We try to ssh to the box
2096 # and if we fail, we force another reboot, that should powercycle it.
2097 sub test_booted {
2098     if (!run_ssh "echo testing connection") {
2099     reboot $sleep_time;
2100     }
2101 }
2102 
2103 sub install {
2104 
2105     return if ($no_install);
2106 
2107     my $start_time = time;
2108 
2109     if (defined($pre_install)) {
2110     my $cp_pre_install = eval_kernel_version $pre_install;
2111     run_command "$cp_pre_install" or
2112         dodie "Failed to run pre install";
2113     }
2114 
2115     my $cp_target = eval_kernel_version $target_image;
2116 
2117     test_booted;
2118 
2119     run_scp_install "$outputdir/$build_target", "$cp_target" or
2120     dodie "failed to copy image";
2121 
2122     my $install_mods = 0;
2123 
2124     # should we process modules?
2125     $install_mods = 0;
2126     open(IN, "$output_config") or dodie("Can't read config file");
2127     while (<IN>) {
2128     if (/CONFIG_MODULES(=y)?/) {
2129         if (defined($1)) {
2130         $install_mods = 1;
2131         last;
2132         }
2133     }
2134     }
2135     close(IN);
2136 
2137     if (!$install_mods) {
2138     do_post_install;
2139     doprint "No modules needed\n";
2140     my $end_time = time;
2141     $install_time = $end_time - $start_time;
2142     return;
2143     }
2144 
2145     run_command "$make INSTALL_MOD_STRIP=1 INSTALL_MOD_PATH=$tmpdir modules_install" or
2146     dodie "Failed to install modules";
2147 
2148     my $modlib = "/lib/modules/$version";
2149     my $modtar = "ktest-mods.tar.bz2";
2150 
2151     run_ssh "rm -rf $modlib" or
2152     dodie "failed to remove old mods: $modlib";
2153 
2154     # would be nice if scp -r did not follow symbolic links
2155     run_command "cd $tmpdir && tar -cjf $modtar lib/modules/$version" or
2156     dodie "making tarball";
2157 
2158     run_scp_mod "$tmpdir/$modtar", "/tmp" or
2159     dodie "failed to copy modules";
2160 
2161     unlink "$tmpdir/$modtar";
2162 
2163     run_ssh "'(cd / && tar xjf /tmp/$modtar)'" or
2164     dodie "failed to tar modules";
2165 
2166     run_ssh "rm -f /tmp/$modtar";
2167 
2168     do_post_install;
2169 
2170     my $end_time = time;
2171     $install_time = $end_time - $start_time;
2172 }
2173 
2174 sub get_version {
2175     # get the release name
2176     return if ($have_version);
2177     doprint "$make kernelrelease ... ";
2178     $version = `$make -s kernelrelease | tail -1`;
2179     chomp($version);
2180     doprint "$version\n";
2181     $have_version = 1;
2182 }
2183 
2184 sub start_monitor_and_install {
2185     # Make sure the stable kernel has finished booting
2186 
2187     # Install bisects, don't need console
2188     if (defined $console) {
2189     start_monitor;
2190     wait_for_monitor 5;
2191     end_monitor;
2192     }
2193 
2194     get_grub_index;
2195     get_version;
2196     install;
2197 
2198     start_monitor if (defined $console);
2199     return monitor;
2200 }
2201 
2202 my $check_build_re = ".*:.*(warning|error|Error):.*";
2203 my $utf8_quote = "\\x{e2}\\x{80}(\\x{98}|\\x{99})";
2204 
2205 sub process_warning_line {
2206     my ($line) = @_;
2207 
2208     chomp $line;
2209 
2210     # for distcc heterogeneous systems, some compilers
2211     # do things differently causing warning lines
2212     # to be slightly different. This makes an attempt
2213     # to fixe those issues.
2214 
2215     # chop off the index into the line
2216     # using distcc, some compilers give different indexes
2217     # depending on white space
2218     $line =~ s/^(\s*\S+:\d+:)\d+/$1/;
2219 
2220     # Some compilers use UTF-8 extended for quotes and some don't.
2221     $line =~ s/$utf8_quote/'/g;
2222 
2223     return $line;
2224 }
2225 
2226 # Read buildlog and check against warnings file for any
2227 # new warnings.
2228 #
2229 # Returns 1 if OK
2230 #         0 otherwise
2231 sub check_buildlog {
2232     return 1 if (!defined $warnings_file);
2233 
2234     my %warnings_list;
2235 
2236     # Failed builds should not reboot the target
2237     my $save_no_reboot = $no_reboot;
2238     $no_reboot = 1;
2239 
2240     if (-f $warnings_file) {
2241     open(IN, $warnings_file) or
2242         dodie "Error opening $warnings_file";
2243 
2244     while (<IN>) {
2245         if (/$check_build_re/) {
2246         my $warning = process_warning_line $_;
2247         
2248         $warnings_list{$warning} = 1;
2249         }
2250     }
2251     close(IN);
2252     }
2253 
2254     # If warnings file didn't exist, and WARNINGS_FILE exist,
2255     # then we fail on any warning!
2256 
2257     open(IN, $buildlog) or dodie "Can't open $buildlog";
2258     while (<IN>) {
2259     if (/$check_build_re/) {
2260         my $warning = process_warning_line $_;
2261 
2262         if (!defined $warnings_list{$warning}) {
2263         fail "New warning found (not in $warnings_file)\n$_\n";
2264         $no_reboot = $save_no_reboot;
2265         return 0;
2266         }
2267     }
2268     }
2269     $no_reboot = $save_no_reboot;
2270     close(IN);
2271 }
2272 
2273 sub check_patch_buildlog {
2274     my ($patch) = @_;
2275 
2276     my @files = `git show $patch | diffstat -l`;
2277 
2278     foreach my $file (@files) {
2279     chomp $file;
2280     }
2281 
2282     open(IN, "git show $patch |") or
2283     dodie "failed to show $patch";
2284     while (<IN>) {
2285     if (m,^--- a/(.*),) {
2286         chomp $1;
2287         $files[$#files] = $1;
2288     }
2289     }
2290     close(IN);
2291 
2292     open(IN, $buildlog) or dodie "Can't open $buildlog";
2293     while (<IN>) {
2294     if (/^\s*(.*?):.*(warning|error)/) {
2295         my $err = $1;
2296         foreach my $file (@files) {
2297         my $fullpath = "$builddir/$file";
2298         if ($file eq $err || $fullpath eq $err) {
2299             fail "$file built with warnings" and return 0;
2300         }
2301         }
2302     }
2303     }
2304     close(IN);
2305 
2306     return 1;
2307 }
2308 
2309 sub apply_min_config {
2310     my $outconfig = "$output_config.new";
2311 
2312     # Read the config file and remove anything that
2313     # is in the force_config hash (from minconfig and others)
2314     # then add the force config back.
2315 
2316     doprint "Applying minimum configurations into $output_config.new\n";
2317 
2318     open (OUT, ">$outconfig") or
2319     dodie "Can't create $outconfig";
2320 
2321     if (-f $output_config) {
2322     open (IN, $output_config) or
2323         dodie "Failed to open $output_config";
2324     while (<IN>) {
2325         if (/^(# )?(CONFIG_[^\s=]*)/) {
2326         next if (defined($force_config{$2}));
2327         }
2328         print OUT;
2329     }
2330     close IN;
2331     }
2332     foreach my $config (keys %force_config) {
2333     print OUT "$force_config{$config}\n";
2334     }
2335     close OUT;
2336 
2337     run_command "mv $outconfig $output_config";
2338 }
2339 
2340 sub make_oldconfig {
2341 
2342     my @force_list = keys %force_config;
2343 
2344     if ($#force_list >= 0) {
2345     apply_min_config;
2346     }
2347 
2348     if (!run_command "$make olddefconfig") {
2349     # Perhaps olddefconfig doesn't exist in this version of the kernel
2350     # try oldnoconfig
2351     doprint "olddefconfig failed, trying make oldnoconfig\n";
2352     if (!run_command "$make oldnoconfig") {
2353         doprint "oldnoconfig failed, trying yes '' | make oldconfig\n";
2354         # try a yes '' | oldconfig
2355         run_command "yes '' | $make oldconfig" or
2356         dodie "failed make config oldconfig";
2357     }
2358     }
2359 }
2360 
2361 # read a config file and use this to force new configs.
2362 sub load_force_config {
2363     my ($config) = @_;
2364 
2365     doprint "Loading force configs from $config\n";
2366     open(IN, $config) or
2367     dodie "failed to read $config";
2368     while (<IN>) {
2369     chomp;
2370     if (/^(CONFIG[^\s=]*)(\s*=.*)/) {
2371         $force_config{$1} = $_;
2372     } elsif (/^# (CONFIG_\S*) is not set/) {
2373         $force_config{$1} = $_;
2374     }
2375     }
2376     close IN;
2377 }
2378 
2379 sub build {
2380     my ($type) = @_;
2381 
2382     unlink $buildlog;
2383 
2384     my $start_time = time;
2385 
2386     # Failed builds should not reboot the target
2387     my $save_no_reboot = $no_reboot;
2388     $no_reboot = 1;
2389 
2390     # Calculate a new version from here.
2391     $have_version = 0;
2392 
2393     if (defined($pre_build)) {
2394     my $ret = run_command $pre_build;
2395     if (!$ret && defined($pre_build_die) &&
2396         $pre_build_die) {
2397         dodie "failed to pre_build\n";
2398     }
2399     }
2400 
2401     if ($type =~ /^useconfig:(.*)/) {
2402     run_command "cp $1 $output_config" or
2403         dodie "could not copy $1 to .config";
2404 
2405     $type = "oldconfig";
2406     }
2407 
2408     # old config can ask questions
2409     if ($type eq "oldconfig") {
2410     $type = "olddefconfig";
2411 
2412     # allow for empty configs
2413     run_command "touch $output_config";
2414 
2415     if (!$noclean) {
2416         run_command "mv $output_config $outputdir/config_temp" or
2417         dodie "moving .config";
2418 
2419         run_command "$make mrproper" or dodie "make mrproper";
2420 
2421         run_command "mv $outputdir/config_temp $output_config" or
2422         dodie "moving config_temp";
2423     }
2424 
2425     } elsif (!$noclean) {
2426     unlink "$output_config";
2427     run_command "$make mrproper" or
2428         dodie "make mrproper";
2429     }
2430 
2431     # add something to distinguish this build
2432     open(OUT, "> $outputdir/localversion") or dodie("Can't make localversion file");
2433     print OUT "$localversion\n";
2434     close(OUT);
2435 
2436     if (defined($minconfig)) {
2437     load_force_config($minconfig);
2438     }
2439 
2440     if ($type ne "olddefconfig") {
2441     run_command "$make $type" or
2442         dodie "failed make config";
2443     }
2444     # Run old config regardless, to enforce min configurations
2445     make_oldconfig;
2446 
2447     my $build_ret = run_command "$make $build_options", $buildlog;
2448 
2449     if (defined($post_build)) {
2450     # Because a post build may change the kernel version
2451     # do it now.
2452     get_version;
2453     my $ret = run_command $post_build;
2454     if (!$ret && defined($post_build_die) &&
2455         $post_build_die) {
2456         dodie "failed to post_build\n";
2457     }
2458     }
2459 
2460     if (!$build_ret) {
2461     # bisect may need this to pass
2462     if ($in_bisect) {
2463         $no_reboot = $save_no_reboot;
2464         return 0;
2465     }
2466     fail "failed build" and return 0;
2467     }
2468 
2469     $no_reboot = $save_no_reboot;
2470 
2471     my $end_time = time;
2472     $build_time = $end_time - $start_time;
2473 
2474     return 1;
2475 }
2476 
2477 sub halt {
2478     if (!run_ssh "halt" or defined($power_off)) {
2479     if (defined($poweroff_after_halt)) {
2480         sleep $poweroff_after_halt;
2481         run_command "$power_off";
2482     }
2483     } else {
2484     # nope? the zap it!
2485     run_command "$power_off";
2486     }
2487 }
2488 
2489 sub success {
2490     my ($i) = @_;
2491 
2492     if (defined($post_test)) {
2493     run_command $post_test;
2494     }
2495 
2496     $successes++;
2497 
2498     my $name = "";
2499 
2500     if (defined($test_name)) {
2501     $name = " ($test_name)";
2502     }
2503 
2504     print_times;
2505 
2506     doprint "\n\n*******************************************\n";
2507     doprint     "*******************************************\n";
2508     doprint     "KTEST RESULT: TEST $i$name SUCCESS!!!!         **\n";
2509     doprint     "*******************************************\n";
2510     doprint     "*******************************************\n";
2511 
2512     if (defined($store_successes)) {
2513         save_logs "success", $store_successes;
2514     }
2515 
2516     if ($i != $opt{"NUM_TESTS"} && !do_not_reboot) {
2517     doprint "Reboot and wait $sleep_time seconds\n";
2518     reboot_to_good $sleep_time;
2519     }
2520 }
2521 
2522 sub answer_bisect {
2523     for (;;) {
2524     doprint "Pass, fail, or skip? [p/f/s]";
2525     my $ans = <STDIN>;
2526     chomp $ans;
2527     if ($ans eq "p" || $ans eq "P") {
2528         return 1;
2529     } elsif ($ans eq "f" || $ans eq "F") {
2530         return 0;
2531     } elsif ($ans eq "s" || $ans eq "S") {
2532         return -1;
2533     } else {
2534         print "Please answer 'p', 'f', or 's'\n";
2535     }
2536     }
2537 }
2538 
2539 sub child_run_test {
2540     my $failed = 0;
2541 
2542     # child should have no power
2543     $reboot_on_error = 0;
2544     $poweroff_on_error = 0;
2545     $die_on_failure = 1;
2546 
2547     run_command $run_test, $testlog or $failed = 1;
2548 
2549     exit $failed;
2550 }
2551 
2552 my $child_done;
2553 
2554 sub child_finished {
2555     $child_done = 1;
2556 }
2557 
2558 sub do_run_test {
2559     my $child_pid;
2560     my $child_exit;
2561     my $line;
2562     my $full_line;
2563     my $bug = 0;
2564     my $bug_ignored = 0;
2565 
2566     my $start_time = time;
2567 
2568     wait_for_monitor 1;
2569 
2570     doprint "run test $run_test\n";
2571 
2572     $child_done = 0;
2573 
2574     $SIG{CHLD} = qw(child_finished);
2575 
2576     $child_pid = fork;
2577 
2578     child_run_test if (!$child_pid);
2579 
2580     $full_line = "";
2581 
2582     do {
2583     $line = wait_for_input($monitor_fp, 1);
2584     if (defined($line)) {
2585 
2586         # we are not guaranteed to get a full line
2587         $full_line .= $line;
2588         doprint $line;
2589 
2590         if ($full_line =~ /call trace:/i) {
2591         if ($ignore_errors) {
2592             $bug_ignored = 1;
2593         } else {
2594             $bug = 1;
2595         }
2596         }
2597 
2598         if ($full_line =~ /Kernel panic -/) {
2599         $bug = 1;
2600         }
2601 
2602         if ($line =~ /\n/) {
2603         $full_line = "";
2604         }
2605     }
2606     } while (!$child_done && !$bug);
2607 
2608     if (!$bug && $bug_ignored) {
2609     doprint "WARNING: Call Trace detected but ignored due to IGNORE_ERRORS=1\n";
2610     }
2611 
2612     if ($bug) {
2613     my $failure_start = time;
2614     my $now;
2615     do {
2616         $line = wait_for_input($monitor_fp, 1);
2617         if (defined($line)) {
2618         doprint $line;
2619         }
2620         $now = time;
2621         if ($now - $failure_start >= $stop_after_failure) {
2622         last;
2623         }
2624     } while (defined($line));
2625 
2626     doprint "Detected kernel crash!\n";
2627     # kill the child with extreme prejudice
2628     kill 9, $child_pid;
2629     }
2630 
2631     waitpid $child_pid, 0;
2632     $child_exit = $?;
2633 
2634     my $end_time = time;
2635     $test_time = $end_time - $start_time;
2636 
2637     if (!$bug && $in_bisect) {
2638     if (defined($bisect_ret_good)) {
2639         if ($child_exit == $bisect_ret_good) {
2640         return 1;
2641         }
2642     }
2643     if (defined($bisect_ret_skip)) {
2644         if ($child_exit == $bisect_ret_skip) {
2645         return -1;
2646         }
2647     }
2648     if (defined($bisect_ret_abort)) {
2649         if ($child_exit == $bisect_ret_abort) {
2650         fail "test abort" and return -2;
2651         }
2652     }
2653     if (defined($bisect_ret_bad)) {
2654         if ($child_exit == $bisect_ret_skip) {
2655         return 0;
2656         }
2657     }
2658     if (defined($bisect_ret_default)) {
2659         if ($bisect_ret_default eq "good") {
2660         return 1;
2661         } elsif ($bisect_ret_default eq "bad") {
2662         return 0;
2663         } elsif ($bisect_ret_default eq "skip") {
2664         return -1;
2665         } elsif ($bisect_ret_default eq "abort") {
2666         return -2;
2667         } else {
2668         fail "unknown default action: $bisect_ret_default"
2669             and return -2;
2670         }
2671     }
2672     }
2673 
2674     if ($bug || $child_exit) {
2675     return 0 if $in_bisect;
2676     fail "test failed" and return 0;
2677     }
2678     return 1;
2679 }
2680 
2681 sub run_git_bisect {
2682     my ($command) = @_;
2683 
2684     doprint "$command ... ";
2685 
2686     my $output = `$command 2>&1`;
2687     my $ret = $?;
2688 
2689     logit $output;
2690 
2691     if ($ret) {
2692     doprint "FAILED\n";
2693     dodie "Failed to git bisect";
2694     }
2695 
2696     doprint "SUCCESS\n";
2697     if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\))\s+\[([[:xdigit:]]+)\]/) {
2698     doprint "$1 [$2]\n";
2699     } elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) {
2700     $bisect_bad_commit = $1;
2701     doprint "Found bad commit... $1\n";
2702     return 0;
2703     } else {
2704     # we already logged it, just print it now.
2705     print $output;
2706     }
2707 
2708     return 1;
2709 }
2710 
2711 sub bisect_reboot {
2712     doprint "Reboot and sleep $bisect_sleep_time seconds\n";
2713     reboot_to_good $bisect_sleep_time;
2714 }
2715 
2716 # returns 1 on success, 0 on failure, -1 on skip
2717 sub run_bisect_test {
2718     my ($type, $buildtype) = @_;
2719 
2720     my $failed = 0;
2721     my $result;
2722     my $output;
2723     my $ret;
2724 
2725     $in_bisect = 1;
2726 
2727     build $buildtype or $failed = 1;
2728 
2729     if ($type ne "build") {
2730     if ($failed && $bisect_skip) {
2731         $in_bisect = 0;
2732         return -1;
2733     }
2734     dodie "Failed on build" if $failed;
2735 
2736     # Now boot the box
2737     start_monitor_and_install or $failed = 1;
2738 
2739     if ($type ne "boot") {
2740         if ($failed && $bisect_skip) {
2741         end_monitor;
2742         bisect_reboot;
2743         $in_bisect = 0;
2744         return -1;
2745         }
2746         dodie "Failed on boot" if $failed;
2747 
2748         do_run_test or $failed = 1;
2749     }
2750     end_monitor;
2751     }
2752 
2753     if ($failed) {
2754     $result = 0;
2755     } else {
2756     $result = 1;
2757     }
2758 
2759     # reboot the box to a kernel we can ssh to
2760     if ($type ne "build") {
2761     bisect_reboot;
2762     }
2763     $in_bisect = 0;
2764 
2765     return $result;
2766 }
2767 
2768 sub run_bisect {
2769     my ($type) = @_;
2770     my $buildtype = "oldconfig";
2771 
2772     # We should have a minconfig to use?
2773     if (defined($minconfig)) {
2774     $buildtype = "useconfig:$minconfig";
2775     }
2776 
2777     # If the user sets bisect_tries to less than 1, then no tries
2778     # is a success.
2779     my $ret = 1;
2780 
2781     # Still let the user manually decide that though.
2782     if ($bisect_tries < 1 && $bisect_manual) {
2783     $ret = answer_bisect;
2784     }
2785 
2786     for (my $i = 0; $i < $bisect_tries; $i++) {
2787     if ($bisect_tries > 1) {
2788         my $t = $i + 1;
2789         doprint("Running bisect trial $t of $bisect_tries:\n");
2790     }
2791     $ret = run_bisect_test $type, $buildtype;
2792 
2793     if ($bisect_manual) {
2794         $ret = answer_bisect;
2795     }
2796 
2797     last if (!$ret);
2798     }
2799 
2800     # Are we looking for where it worked, not failed?
2801     if ($reverse_bisect && $ret >= 0) {
2802     $ret = !$ret;
2803     }
2804 
2805     if ($ret > 0) {
2806     return "good";
2807     } elsif ($ret == 0) {
2808     return  "bad";
2809     } elsif ($bisect_skip) {
2810     doprint "HIT A BAD COMMIT ... SKIPPING\n";
2811     return "skip";
2812     }
2813 }
2814 
2815 sub update_bisect_replay {
2816     my $tmp_log = "$tmpdir/ktest_bisect_log";
2817     run_command "git bisect log > $tmp_log" or
2818     die "can't create bisect log";
2819     return $tmp_log;
2820 }
2821 
2822 sub bisect {
2823     my ($i) = @_;
2824 
2825     my $result;
2826 
2827     die "BISECT_GOOD[$i] not defined\n" if (!defined($bisect_good));
2828     die "BISECT_BAD[$i] not defined\n"  if (!defined($bisect_bad));
2829     die "BISECT_TYPE[$i] not defined\n" if (!defined($bisect_type));
2830 
2831     my $good = $bisect_good;
2832     my $bad = $bisect_bad;
2833     my $type = $bisect_type;
2834     my $start = $bisect_start;
2835     my $replay = $bisect_replay;
2836     my $start_files = $bisect_files;
2837 
2838     if (defined($start_files)) {
2839     $start_files = " -- " . $start_files;
2840     } else {
2841     $start_files = "";
2842     }
2843 
2844     # convert to true sha1's
2845     $good = get_sha1($good);
2846     $bad = get_sha1($bad);
2847 
2848     if (defined($bisect_reverse) && $bisect_reverse == 1) {
2849     doprint "Performing a reverse bisect (bad is good, good is bad!)\n";
2850     $reverse_bisect = 1;
2851     } else {
2852     $reverse_bisect = 0;
2853     }
2854 
2855     # Can't have a test without having a test to run
2856     if ($type eq "test" && !defined($run_test)) {
2857     $type = "boot";
2858     }
2859 
2860     # Check if a bisect was running
2861     my $bisect_start_file = "$builddir/.git/BISECT_START";
2862 
2863     my $check = $bisect_check;
2864     my $do_check = defined($check) && $check ne "0";
2865 
2866     if ( -f $bisect_start_file ) {
2867     print "Bisect in progress found\n";
2868     if ($do_check) {
2869         print " If you say yes, then no checks of good or bad will be done\n";
2870     }
2871     if (defined($replay)) {
2872         print "** BISECT_REPLAY is defined in config file **";
2873         print " Ignore config option and perform new git bisect log?\n";
2874         if (read_ync " (yes, no, or cancel) ") {
2875         $replay = update_bisect_replay;
2876         $do_check = 0;
2877         }
2878     } elsif (read_yn "read git log and continue?") {
2879         $replay = update_bisect_replay;
2880         $do_check = 0;
2881     }
2882     }
2883 
2884     if ($do_check) {
2885 
2886     # get current HEAD
2887     my $head = get_sha1("HEAD");
2888 
2889     if ($check ne "good") {
2890         doprint "TESTING BISECT BAD [$bad]\n";
2891         run_command "git checkout $bad" or
2892         die "Failed to checkout $bad";
2893 
2894         $result = run_bisect $type;
2895 
2896         if ($result ne "bad") {
2897         fail "Tested BISECT_BAD [$bad] and it succeeded" and return 0;
2898         }
2899     }
2900 
2901     if ($check ne "bad") {
2902         doprint "TESTING BISECT GOOD [$good]\n";
2903         run_command "git checkout $good" or
2904         die "Failed to checkout $good";
2905 
2906         $result = run_bisect $type;
2907 
2908         if ($result ne "good") {
2909         fail "Tested BISECT_GOOD [$good] and it failed" and return 0;
2910         }
2911     }
2912 
2913     # checkout where we started
2914     run_command "git checkout $head" or
2915         die "Failed to checkout $head";
2916     }
2917 
2918     run_command "git bisect start$start_files" or
2919     dodie "could not start bisect";
2920 
2921     if (defined($replay)) {
2922     run_command "git bisect replay $replay" or
2923         dodie "failed to run replay";
2924     } else {
2925 
2926     run_command "git bisect good $good" or
2927         dodie "could not set bisect good to $good";
2928 
2929     run_git_bisect "git bisect bad $bad" or
2930         dodie "could not set bisect bad to $bad";
2931 
2932     }
2933 
2934     if (defined($start)) {
2935     run_command "git checkout $start" or
2936         dodie "failed to checkout $start";
2937     }
2938 
2939     my $test;
2940     do {
2941     $result = run_bisect $type;
2942     $test = run_git_bisect "git bisect $result";
2943     print_times;
2944     } while ($test);
2945 
2946     run_command "git bisect log" or
2947     dodie "could not capture git bisect log";
2948 
2949     run_command "git bisect reset" or
2950     dodie "could not reset git bisect";
2951 
2952     doprint "Bad commit was [$bisect_bad_commit]\n";
2953 
2954     success $i;
2955 }
2956 
2957 # config_ignore holds the configs that were set (or unset) for
2958 # a good config and we will ignore these configs for the rest
2959 # of a config bisect. These configs stay as they were.
2960 my %config_ignore;
2961 
2962 # config_set holds what all configs were set as.
2963 my %config_set;
2964 
2965 # config_off holds the set of configs that the bad config had disabled.
2966 # We need to record them and set them in the .config when running
2967 # olddefconfig, because olddefconfig keeps the defaults.
2968 my %config_off;
2969 
2970 # config_off_tmp holds a set of configs to turn off for now
2971 my @config_off_tmp;
2972 
2973 # config_list is the set of configs that are being tested
2974 my %config_list;
2975 my %null_config;
2976 
2977 my %dependency;
2978 
2979 sub assign_configs {
2980     my ($hash, $config) = @_;
2981 
2982     doprint "Reading configs from $config\n";
2983 
2984     open (IN, $config)
2985     or dodie "Failed to read $config";
2986 
2987     while (<IN>) {
2988     chomp;
2989     if (/^((CONFIG\S*)=.*)/) {
2990         ${$hash}{$2} = $1;
2991     } elsif (/^(# (CONFIG\S*) is not set)/) {
2992         ${$hash}{$2} = $1;
2993     }
2994     }
2995 
2996     close(IN);
2997 }
2998 
2999 sub process_config_ignore {
3000     my ($config) = @_;
3001 
3002     assign_configs \%config_ignore, $config;
3003 }
3004 
3005 sub get_dependencies {
3006     my ($config) = @_;
3007 
3008     my $arr = $dependency{$config};
3009     if (!defined($arr)) {
3010     return ();
3011     }
3012 
3013     my @deps = @{$arr};
3014 
3015     foreach my $dep (@{$arr}) {
3016     print "ADD DEP $dep\n";
3017     @deps = (@deps, get_dependencies $dep);
3018     }
3019 
3020     return @deps;
3021 }
3022 
3023 sub save_config {
3024     my ($pc, $file) = @_;
3025 
3026     my %configs = %{$pc};
3027 
3028     doprint "Saving configs into $file\n";
3029 
3030     open(OUT, ">$file") or dodie "Can not write to $file";
3031 
3032     foreach my $config (keys %configs) {
3033     print OUT "$configs{$config}\n";
3034     }
3035     close(OUT);
3036 }
3037 
3038 sub create_config {
3039     my ($name, $pc) = @_;
3040 
3041     doprint "Creating old config from $name configs\n";
3042 
3043     save_config $pc, $output_config;
3044 
3045     make_oldconfig;
3046 }
3047 
3048 # compare two config hashes, and return configs with different vals.
3049 # It returns B's config values, but you can use A to see what A was.
3050 sub diff_config_vals {
3051     my ($pa, $pb) = @_;
3052 
3053     # crappy Perl way to pass in hashes.
3054     my %a = %{$pa};
3055     my %b = %{$pb};
3056 
3057     my %ret;
3058 
3059     foreach my $item (keys %a) {
3060     if (defined($b{$item}) && $b{$item} ne $a{$item}) {
3061         $ret{$item} = $b{$item};
3062     }
3063     }
3064 
3065     return %ret;
3066 }
3067 
3068 # compare two config hashes and return the configs in B but not A
3069 sub diff_configs {
3070     my ($pa, $pb) = @_;
3071 
3072     my %ret;
3073 
3074     # crappy Perl way to pass in hashes.
3075     my %a = %{$pa};
3076     my %b = %{$pb};
3077 
3078     foreach my $item (keys %b) {
3079     if (!defined($a{$item})) {
3080         $ret{$item} = $b{$item};
3081     }
3082     }
3083 
3084     return %ret;
3085 }
3086 
3087 # return if two configs are equal or not
3088 # 0 is equal +1 b has something a does not
3089 # +1 if a and b have a different item.
3090 # -1 if a has something b does not
3091 sub compare_configs {
3092     my ($pa, $pb) = @_;
3093 
3094     my %ret;
3095 
3096     # crappy Perl way to pass in hashes.
3097     my %a = %{$pa};
3098     my %b = %{$pb};
3099 
3100     foreach my $item (keys %b) {
3101     if (!defined($a{$item})) {
3102         return 1;
3103     }
3104     if ($a{$item} ne $b{$item}) {
3105         return 1;
3106     }
3107     }
3108 
3109     foreach my $item (keys %a) {
3110     if (!defined($b{$item})) {
3111         return -1;
3112     }
3113     }
3114 
3115     return 0;
3116 }
3117 
3118 sub run_config_bisect_test {
3119     my ($type) = @_;
3120 
3121     my $ret = run_bisect_test $type, "oldconfig";
3122 
3123     if ($bisect_manual) {
3124     $ret = answer_bisect;
3125     }
3126 
3127     return $ret;
3128 }
3129 
3130 sub process_failed {
3131     my ($config) = @_;
3132 
3133     doprint "\n\n***************************************\n";
3134     doprint "Found bad config: $config\n";
3135     doprint "***************************************\n\n";
3136 }
3137 
3138 # used for config bisecting
3139 my $good_config;
3140 my $bad_config;
3141 
3142 sub process_new_config {
3143     my ($tc, $nc, $gc, $bc) = @_;
3144 
3145     my %tmp_config = %{$tc};
3146     my %good_configs = %{$gc};
3147     my %bad_configs = %{$bc};
3148 
3149     my %new_configs;
3150 
3151     my $runtest = 1;
3152     my $ret;
3153 
3154     create_config "tmp_configs", \%tmp_config;
3155     assign_configs \%new_configs, $output_config;
3156 
3157     $ret = compare_configs \%new_configs, \%bad_configs;
3158     if (!$ret) {
3159     doprint "New config equals bad config, try next test\n";
3160     $runtest = 0;
3161     }
3162 
3163     if ($runtest) {
3164     $ret = compare_configs \%new_configs, \%good_configs;
3165     if (!$ret) {
3166         doprint "New config equals good config, try next test\n";
3167         $runtest = 0;
3168     }
3169     }
3170 
3171     %{$nc} = %new_configs;
3172 
3173     return $runtest;
3174 }
3175 
3176 sub run_config_bisect {
3177     my ($pgood, $pbad) = @_;
3178 
3179     my $type = $config_bisect_type;
3180 
3181     my %good_configs = %{$pgood};
3182     my %bad_configs = %{$pbad};
3183 
3184     my %diff_configs = diff_config_vals \%good_configs, \%bad_configs;
3185     my %b_configs = diff_configs \%good_configs, \%bad_configs;
3186     my %g_configs = diff_configs \%bad_configs, \%good_configs;
3187 
3188     my @diff_arr = keys %diff_configs;
3189     my $len_diff = $#diff_arr + 1;
3190 
3191     my @b_arr = keys %b_configs;
3192     my $len_b = $#b_arr + 1;
3193 
3194     my @g_arr = keys %g_configs;
3195     my $len_g = $#g_arr + 1;
3196 
3197     my $runtest = 1;
3198     my %new_configs;
3199     my $ret;
3200 
3201     # First, lets get it down to a single subset.
3202     # Is the problem with a difference in values?
3203     # Is the problem with a missing config?
3204     # Is the problem with a config that breaks things?
3205 
3206     # Enable all of one set and see if we get a new bad
3207     # or good config.
3208 
3209     # first set the good config to the bad values.
3210 
3211     doprint "d=$len_diff g=$len_g b=$len_b\n";
3212 
3213     # first lets enable things in bad config that are enabled in good config
3214 
3215     if ($len_diff > 0) {
3216     if ($len_b > 0 || $len_g > 0) {
3217         my %tmp_config = %bad_configs;
3218 
3219         doprint "Set tmp config to be bad config with good config values\n";
3220         foreach my $item (@diff_arr) {
3221         $tmp_config{$item} = $good_configs{$item};
3222         }
3223 
3224         $runtest = process_new_config \%tmp_config, \%new_configs,
3225                 \%good_configs, \%bad_configs;
3226     }
3227     }
3228 
3229     if (!$runtest && $len_diff > 0) {
3230 
3231     if ($len_diff == 1) {
3232         process_failed $diff_arr[0];
3233         return 1;
3234     }
3235     my %tmp_config = %bad_configs;
3236 
3237     my $half = int($#diff_arr / 2);
3238     my @tophalf = @diff_arr[0 .. $half];
3239 
3240     doprint "Settings bisect with top half:\n";
3241     doprint "Set tmp config to be bad config with some good config values\n";
3242     foreach my $item (@tophalf) {
3243         $tmp_config{$item} = $good_configs{$item};
3244     }
3245 
3246     $runtest = process_new_config \%tmp_config, \%new_configs,
3247                 \%good_configs, \%bad_configs;
3248 
3249     if (!$runtest) {
3250         my %tmp_config = %bad_configs;
3251 
3252         doprint "Try bottom half\n";
3253 
3254         my @bottomhalf = @diff_arr[$half+1 .. $#diff_arr];
3255 
3256         foreach my $item (@bottomhalf) {
3257         $tmp_config{$item} = $good_configs{$item};
3258         }
3259 
3260         $runtest = process_new_config \%tmp_config, \%new_configs,
3261                 \%good_configs, \%bad_configs;
3262     }
3263     }
3264 
3265     if ($runtest) {
3266     $ret = run_config_bisect_test $type;
3267     if ($ret) {
3268         doprint "NEW GOOD CONFIG\n";
3269         %good_configs = %new_configs;
3270         run_command "mv $good_config ${good_config}.last";
3271         save_config \%good_configs, $good_config;
3272         %{$pgood} = %good_configs;
3273     } else {
3274         doprint "NEW BAD CONFIG\n";
3275         %bad_configs = %new_configs;
3276         run_command "mv $bad_config ${bad_config}.last";
3277         save_config \%bad_configs, $bad_config;
3278         %{$pbad} = %bad_configs;
3279     }
3280     return 0;
3281     }
3282 
3283     fail "Hmm, need to do a mix match?\n";
3284     return -1;
3285 }
3286 
3287 sub config_bisect {
3288     my ($i) = @_;
3289 
3290     my $type = $config_bisect_type;
3291     my $ret;
3292 
3293     $bad_config = $config_bisect;
3294 
3295     if (defined($config_bisect_good)) {
3296     $good_config = $config_bisect_good;
3297     } elsif (defined($minconfig)) {
3298     $good_config = $minconfig;
3299     } else {
3300     doprint "No config specified, checking if defconfig works";
3301     $ret = run_bisect_test $type, "defconfig";
3302     if (!$ret) {
3303         fail "Have no good config to compare with, please set CONFIG_BISECT_GOOD";
3304         return 1;
3305     }
3306     $good_config = $output_config;
3307     }
3308 
3309     # we don't want min configs to cause issues here.
3310     doprint "Disabling 'MIN_CONFIG' for this test\n";
3311     undef $minconfig;
3312 
3313     my %good_configs;
3314     my %bad_configs;
3315     my %tmp_configs;
3316 
3317     doprint "Run good configs through make oldconfig\n";
3318     assign_configs \%tmp_configs, $good_config;
3319     create_config "$good_config", \%tmp_configs;
3320     assign_configs \%good_configs, $output_config;
3321 
3322     doprint "Run bad configs through make oldconfig\n";
3323     assign_configs \%tmp_configs, $bad_config;
3324     create_config "$bad_config", \%tmp_configs;
3325     assign_configs \%bad_configs, $output_config;
3326 
3327     $good_config = "$tmpdir/good_config";
3328     $bad_config = "$tmpdir/bad_config";
3329 
3330     save_config \%good_configs, $good_config;
3331     save_config \%bad_configs, $bad_config;
3332 
3333 
3334     if (defined($config_bisect_check) && $config_bisect_check ne "0") {
3335     if ($config_bisect_check ne "good") {
3336         doprint "Testing bad config\n";
3337 
3338         $ret = run_bisect_test $type, "useconfig:$bad_config";
3339         if ($ret) {
3340         fail "Bad config succeeded when expected to fail!";
3341         return 0;
3342         }
3343     }
3344     if ($config_bisect_check ne "bad") {
3345         doprint "Testing good config\n";
3346 
3347         $ret = run_bisect_test $type, "useconfig:$good_config";
3348         if (!$ret) {
3349         fail "Good config failed when expected to succeed!";
3350         return 0;
3351         }
3352     }
3353     }
3354 
3355     do {
3356     $ret = run_config_bisect \%good_configs, \%bad_configs;
3357     print_times;
3358     } while (!$ret);
3359 
3360     return $ret if ($ret < 0);
3361 
3362     success $i;
3363 }
3364 
3365 sub patchcheck_reboot {
3366     doprint "Reboot and sleep $patchcheck_sleep_time seconds\n";
3367     reboot_to_good $patchcheck_sleep_time;
3368 }
3369 
3370 sub patchcheck {
3371     my ($i) = @_;
3372 
3373     die "PATCHCHECK_START[$i] not defined\n"
3374     if (!defined($patchcheck_start));
3375     die "PATCHCHECK_TYPE[$i] not defined\n"
3376     if (!defined($patchcheck_type));
3377 
3378     my $start = $patchcheck_start;
3379 
3380     my $cherry = $patchcheck_cherry;
3381     if (!defined($cherry)) {
3382     $cherry = 0;
3383     }
3384 
3385     my $end = "HEAD";
3386     if (defined($patchcheck_end)) {
3387     $end = $patchcheck_end;
3388     } elsif ($cherry) {
3389     die "PATCHCHECK_END must be defined with PATCHCHECK_CHERRY\n";
3390     }
3391 
3392     # Get the true sha1's since we can use things like HEAD~3
3393     $start = get_sha1($start);
3394     $end = get_sha1($end);
3395 
3396     my $type = $patchcheck_type;
3397 
3398     # Can't have a test without having a test to run
3399     if ($type eq "test" && !defined($run_test)) {
3400     $type = "boot";
3401     }
3402 
3403     if ($cherry) {
3404     open (IN, "git cherry -v $start $end|") or
3405         dodie "could not get git list";
3406     } else {
3407     open (IN, "git log --pretty=oneline $end|") or
3408         dodie "could not get git list";
3409     }
3410 
3411     my @list;
3412 
3413     while (<IN>) {
3414     chomp;
3415     # git cherry adds a '+' we want to remove
3416     s/^\+ //;
3417     $list[$#list+1] = $_;
3418     last if (/^$start/);
3419     }
3420     close(IN);
3421 
3422     if (!$cherry) {
3423     if ($list[$#list] !~ /^$start/) {
3424         fail "SHA1 $start not found";
3425     }
3426 
3427     # go backwards in the list
3428     @list = reverse @list;
3429     }
3430 
3431     doprint("Going to test the following commits:\n");
3432     foreach my $l (@list) {
3433     doprint "$l\n";
3434     }
3435 
3436     my $save_clean = $noclean;
3437     my %ignored_warnings;
3438 
3439     if (defined($ignore_warnings)) {
3440     foreach my $sha1 (split /\s+/, $ignore_warnings) {
3441         $ignored_warnings{$sha1} = 1;
3442     }
3443     }
3444 
3445     $in_patchcheck = 1;
3446     foreach my $item (@list) {
3447     my $sha1 = $item;
3448     $sha1 =~ s/^([[:xdigit:]]+).*/$1/;
3449 
3450     doprint "\nProcessing commit \"$item\"\n\n";
3451 
3452     run_command "git checkout $sha1" or
3453         die "Failed to checkout $sha1";
3454 
3455     # only clean on the first and last patch
3456     if ($item eq $list[0] ||
3457         $item eq $list[$#list]) {
3458         $noclean = $save_clean;
3459     } else {
3460         $noclean = 1;
3461     }
3462 
3463     if (defined($minconfig)) {
3464         build "useconfig:$minconfig" or return 0;
3465     } else {
3466         # ?? no config to use?
3467         build "oldconfig" or return 0;
3468     }
3469 
3470     # No need to do per patch checking if warnings file exists
3471     if (!defined($warnings_file) && !defined($ignored_warnings{$sha1})) {
3472         check_patch_buildlog $sha1 or return 0;
3473     }
3474 
3475     check_buildlog or return 0;
3476 
3477     next if ($type eq "build");
3478 
3479     my $failed = 0;
3480 
3481     start_monitor_and_install or $failed = 1;
3482 
3483     if (!$failed && $type ne "boot"){
3484         do_run_test or $failed = 1;
3485     }
3486     end_monitor;
3487     if ($failed) {
3488         print_times;
3489         return 0;
3490     }
3491     patchcheck_reboot;
3492     print_times;
3493     }
3494     $in_patchcheck = 0;
3495     success $i;
3496 
3497     return 1;
3498 }
3499 
3500 my %depends;
3501 my %depcount;
3502 my $iflevel = 0;
3503 my @ifdeps;
3504 
3505 # prevent recursion
3506 my %read_kconfigs;
3507 
3508 sub add_dep {
3509     # $config depends on $dep
3510     my ($config, $dep) = @_;
3511 
3512     if (defined($depends{$config})) {
3513     $depends{$config} .= " " . $dep;
3514     } else {
3515     $depends{$config} = $dep;
3516     }
3517 
3518     # record the number of configs depending on $dep
3519     if (defined $depcount{$dep}) {
3520     $depcount{$dep}++;
3521     } else {
3522     $depcount{$dep} = 1;
3523     } 
3524 }
3525 
3526 # taken from streamline_config.pl
3527 sub read_kconfig {
3528     my ($kconfig) = @_;
3529 
3530     my $state = "NONE";
3531     my $config;
3532     my @kconfigs;
3533 
3534     my $cont = 0;
3535     my $line;
3536 
3537 
3538     if (! -f $kconfig) {
3539     doprint "file $kconfig does not exist, skipping\n";
3540     return;
3541     }
3542 
3543     open(KIN, "$kconfig")
3544     or die "Can't open $kconfig";
3545     while (<KIN>) {
3546     chomp;
3547 
3548     # Make sure that lines ending with \ continue
3549     if ($cont) {
3550         $_ = $line . " " . $_;
3551     }
3552 
3553     if (s/\\$//) {
3554         $cont = 1;
3555         $line = $_;
3556         next;
3557     }
3558 
3559     $cont = 0;
3560 
3561     # collect any Kconfig sources
3562     if (/^source\s*"(.*)"/) {
3563         $kconfigs[$#kconfigs+1] = $1;
3564     }
3565 
3566     # configs found
3567     if (/^\s*(menu)?config\s+(\S+)\s*$/) {
3568         $state = "NEW";
3569         $config = $2;
3570 
3571         for (my $i = 0; $i < $iflevel; $i++) {
3572         add_dep $config, $ifdeps[$i];
3573         }
3574 
3575     # collect the depends for the config
3576     } elsif ($state eq "NEW" && /^\s*depends\s+on\s+(.*)$/) {
3577 
3578         add_dep $config, $1;
3579 
3580     # Get the configs that select this config
3581     } elsif ($state eq "NEW" && /^\s*select\s+(\S+)/) {
3582 
3583         # selected by depends on config
3584         add_dep $1, $config;
3585 
3586     # Check for if statements
3587     } elsif (/^if\s+(.*\S)\s*$/) {
3588         my $deps = $1;
3589         # remove beginning and ending non text
3590         $deps =~ s/^[^a-zA-Z0-9_]*//;
3591         $deps =~ s/[^a-zA-Z0-9_]*$//;
3592 
3593         my @deps = split /[^a-zA-Z0-9_]+/, $deps;
3594 
3595         $ifdeps[$iflevel++] = join ':', @deps;
3596 
3597     } elsif (/^endif/) {
3598 
3599         $iflevel-- if ($iflevel);
3600 
3601     # stop on "help"
3602     } elsif (/^\s*help\s*$/) {
3603         $state = "NONE";
3604     }
3605     }
3606     close(KIN);
3607 
3608     # read in any configs that were found.
3609     foreach $kconfig (@kconfigs) {
3610     if (!defined($read_kconfigs{$kconfig})) {
3611         $read_kconfigs{$kconfig} = 1;
3612         read_kconfig("$builddir/$kconfig");
3613     }
3614     }
3615 }
3616 
3617 sub read_depends {
3618     # find out which arch this is by the kconfig file
3619     open (IN, $output_config)
3620     or dodie "Failed to read $output_config";
3621     my $arch;
3622     while (<IN>) {
3623     if (m,Linux/(\S+)\s+\S+\s+Kernel Configuration,) {
3624         $arch = $1;
3625         last;
3626     }
3627     }
3628     close IN;
3629 
3630     if (!defined($arch)) {
3631     doprint "Could not find arch from config file\n";
3632     doprint "no dependencies used\n";
3633     return;
3634     }
3635 
3636     # arch is really the subarch, we need to know
3637     # what directory to look at.
3638     if ($arch eq "i386" || $arch eq "x86_64") {
3639     $arch = "x86";
3640     } elsif ($arch =~ /^tile/) {
3641     $arch = "tile";
3642     }
3643 
3644     my $kconfig = "$builddir/arch/$arch/Kconfig";
3645 
3646     if (! -f $kconfig && $arch =~ /\d$/) {
3647     my $orig = $arch;
3648     # some subarchs have numbers, truncate them
3649     $arch =~ s/\d*$//;
3650     $kconfig = "$builddir/arch/$arch/Kconfig";
3651     if (! -f $kconfig) {
3652         doprint "No idea what arch dir $orig is for\n";
3653         doprint "no dependencies used\n";
3654         return;
3655     }
3656     }
3657 
3658     read_kconfig($kconfig);
3659 }
3660 
3661 sub make_new_config {
3662     my @configs = @_;
3663 
3664     open (OUT, ">$output_config")
3665     or dodie "Failed to write $output_config";
3666 
3667     foreach my $config (@configs) {
3668     print OUT "$config\n";
3669     }
3670     close OUT;
3671 }
3672 
3673 sub chomp_config {
3674     my ($config) = @_;
3675 
3676     $config =~ s/CONFIG_//;
3677 
3678     return $config;
3679 }
3680 
3681 sub get_depends {
3682     my ($dep) = @_;
3683 
3684     my $kconfig = chomp_config $dep;
3685 
3686     $dep = $depends{"$kconfig"};
3687 
3688     # the dep string we have saves the dependencies as they
3689     # were found, including expressions like ! && ||. We
3690     # want to split this out into just an array of configs.
3691 
3692     my $valid = "A-Za-z_0-9";
3693 
3694     my @configs;
3695 
3696     while ($dep =~ /[$valid]/) {
3697 
3698     if ($dep =~ /^[^$valid]*([$valid]+)/) {
3699         my $conf = "CONFIG_" . $1;
3700 
3701         $configs[$#configs + 1] = $conf;
3702 
3703         $dep =~ s/^[^$valid]*[$valid]+//;
3704     } else {
3705         die "this should never happen";
3706     }
3707     }
3708 
3709     return @configs;
3710 }
3711 
3712 my %min_configs;
3713 my %keep_configs;
3714 my %save_configs;
3715 my %processed_configs;
3716 my %nochange_config;
3717 
3718 sub test_this_config {
3719     my ($config) = @_;
3720 
3721     my $found;
3722 
3723     # if we already processed this config, skip it
3724     if (defined($processed_configs{$config})) {
3725     return undef;
3726     }
3727     $processed_configs{$config} = 1;
3728 
3729     # if this config failed during this round, skip it
3730     if (defined($nochange_config{$config})) {
3731     return undef;
3732     }
3733 
3734     my $kconfig = chomp_config $config;
3735 
3736     # Test dependencies first
3737     if (defined($depends{"$kconfig"})) {
3738     my @parents = get_depends $config;
3739     foreach my $parent (@parents) {
3740         # if the parent is in the min config, check it first
3741         next if (!defined($min_configs{$parent}));
3742         $found = test_this_config($parent);
3743         if (defined($found)) {
3744         return $found;
3745         }
3746     }
3747     }
3748 
3749     # Remove this config from the list of configs
3750     # do a make olddefconfig and then read the resulting
3751     # .config to make sure it is missing the config that
3752     # we had before
3753     my %configs = %min_configs;
3754     delete $configs{$config};
3755     make_new_config ((values %configs), (values %keep_configs));
3756     make_oldconfig;
3757     undef %configs;
3758     assign_configs \%configs, $output_config;
3759 
3760     if (!defined($configs{$config}) || $configs{$config} =~ /^#/) {
3761     return $config;
3762     }
3763 
3764     doprint "disabling config $config did not change .config\n";
3765 
3766     $nochange_config{$config} = 1;
3767 
3768     return undef;
3769 }
3770 
3771 sub make_min_config {
3772     my ($i) = @_;
3773 
3774     my $type = $minconfig_type;
3775     if ($type ne "boot" && $type ne "test") {
3776     fail "Invalid MIN_CONFIG_TYPE '$minconfig_type'\n" .
3777         " make_min_config works only with 'boot' and 'test'\n" and return;
3778     }
3779 
3780     if (!defined($output_minconfig)) {
3781     fail "OUTPUT_MIN_CONFIG not defined" and return;
3782     }
3783 
3784     # If output_minconfig exists, and the start_minconfig
3785     # came from min_config, than ask if we should use
3786     # that instead.
3787     if (-f $output_minconfig && !$start_minconfig_defined) {
3788     print "$output_minconfig exists\n";
3789     if (!defined($use_output_minconfig)) {
3790         if (read_yn " Use it as minconfig?") {
3791         $start_minconfig = $output_minconfig;
3792         }
3793     } elsif ($use_output_minconfig > 0) {
3794         doprint "Using $output_minconfig as MIN_CONFIG\n";
3795         $start_minconfig = $output_minconfig;
3796     } else {
3797         doprint "Set to still use MIN_CONFIG as starting point\n";
3798     }
3799     }
3800 
3801     if (!defined($start_minconfig)) {
3802     fail "START_MIN_CONFIG or MIN_CONFIG not defined" and return;
3803     }
3804 
3805     my $temp_config = "$tmpdir/temp_config";
3806 
3807     # First things first. We build an allnoconfig to find
3808     # out what the defaults are that we can't touch.
3809     # Some are selections, but we really can't handle selections.
3810 
3811     my $save_minconfig = $minconfig;
3812     undef $minconfig;
3813 
3814     run_command "$make allnoconfig" or return 0;
3815 
3816     read_depends;
3817 
3818     process_config_ignore $output_config;
3819 
3820     undef %save_configs;
3821     undef %min_configs;
3822 
3823     if (defined($ignore_config)) {
3824     # make sure the file exists
3825     `touch $ignore_config`;
3826     assign_configs \%save_configs, $ignore_config;
3827     }
3828 
3829     %keep_configs = %save_configs;
3830 
3831     doprint "Load initial configs from $start_minconfig\n";
3832 
3833     # Look at the current min configs, and save off all the
3834     # ones that were set via the allnoconfig
3835     assign_configs \%min_configs, $start_minconfig;
3836 
3837     my @config_keys = keys %min_configs;
3838 
3839     # All configs need a depcount
3840     foreach my $config (@config_keys) {
3841     my $kconfig = chomp_config $config;
3842     if (!defined $depcount{$kconfig}) {
3843         $depcount{$kconfig} = 0;
3844     }
3845     }
3846 
3847     # Remove anything that was set by the make allnoconfig
3848     # we shouldn't need them as they get set for us anyway.
3849     foreach my $config (@config_keys) {
3850     # Remove anything in the ignore_config
3851     if (defined($keep_configs{$config})) {
3852         my $file = $ignore_config;
3853         $file =~ s,.*/(.*?)$,$1,;
3854         doprint "$config set by $file ... ignored\n";
3855         delete $min_configs{$config};
3856         next;
3857     }
3858     # But make sure the settings are the same. If a min config
3859     # sets a selection, we do not want to get rid of it if
3860     # it is not the same as what we have. Just move it into
3861     # the keep configs.
3862     if (defined($config_ignore{$config})) {
3863         if ($config_ignore{$config} ne $min_configs{$config}) {
3864         doprint "$config is in allnoconfig as '$config_ignore{$config}'";
3865         doprint " but it is '$min_configs{$config}' in minconfig .. keeping\n";
3866         $keep_configs{$config} = $min_configs{$config};
3867         } else {
3868         doprint "$config set by allnoconfig ... ignored\n";
3869         }
3870         delete $min_configs{$config};
3871     }
3872     }
3873 
3874     my $done = 0;
3875     my $take_two = 0;
3876 
3877     while (!$done) {
3878 
3879     my $config;
3880     my $found;
3881 
3882     # Now disable each config one by one and do a make oldconfig
3883     # till we find a config that changes our list.
3884 
3885     my @test_configs = keys %min_configs;
3886 
3887     # Sort keys by who is most dependent on
3888     @test_configs = sort  { $depcount{chomp_config($b)} <=> $depcount{chomp_config($a)} }
3889               @test_configs ;
3890 
3891     # Put configs that did not modify the config at the end.
3892     my $reset = 1;
3893     for (my $i = 0; $i < $#test_configs; $i++) {
3894         if (!defined($nochange_config{$test_configs[0]})) {
3895         $reset = 0;
3896         last;
3897         }
3898         # This config didn't change the .config last time.
3899         # Place it at the end
3900         my $config = shift @test_configs;
3901         push @test_configs, $config;
3902     }
3903 
3904     # if every test config has failed to modify the .config file
3905     # in the past, then reset and start over.
3906     if ($reset) {
3907         undef %nochange_config;
3908     }
3909 
3910     undef %processed_configs;
3911 
3912     foreach my $config (@test_configs) {
3913 
3914         $found = test_this_config $config;
3915 
3916         last if (defined($found));
3917 
3918         # oh well, try another config
3919     }
3920 
3921     if (!defined($found)) {
3922         # we could have failed due to the nochange_config hash
3923         # reset and try again
3924         if (!$take_two) {
3925         undef %nochange_config;
3926         $take_two = 1;
3927         next;
3928         }
3929         doprint "No more configs found that we can disable\n";
3930         $done = 1;
3931         last;
3932     }
3933     $take_two = 0;
3934 
3935     $config = $found;
3936 
3937     doprint "Test with $config disabled\n";
3938 
3939     # set in_bisect to keep build and monitor from dieing
3940     $in_bisect = 1;
3941 
3942     my $failed = 0;
3943     build "oldconfig" or $failed = 1;
3944     if (!$failed) {
3945         start_monitor_and_install or $failed = 1;
3946 
3947         if ($type eq "test" && !$failed) {
3948             do_run_test or $failed = 1;
3949         }
3950 
3951         end_monitor;
3952     }
3953 
3954     $in_bisect = 0;
3955 
3956     if ($failed) {
3957         doprint "$min_configs{$config} is needed to boot the box... keeping\n";
3958         # this config is needed, add it to the ignore list.
3959         $keep_configs{$config} = $min_configs{$config};
3960         $save_configs{$config} = $min_configs{$config};
3961         delete $min_configs{$config};
3962 
3963         # update new ignore configs
3964         if (defined($ignore_config)) {
3965         open (OUT, ">$temp_config")
3966             or die "Can't write to $temp_config";
3967         foreach my $config (keys %save_configs) {
3968             print OUT "$save_configs{$config}\n";
3969         }
3970         close OUT;
3971         run_command "mv $temp_config $ignore_config" or
3972             dodie "failed to copy update to $ignore_config";
3973         }
3974 
3975     } else {
3976         # We booted without this config, remove it from the minconfigs.
3977         doprint "$config is not needed, disabling\n";
3978 
3979         delete $min_configs{$config};
3980 
3981         # Also disable anything that is not enabled in this config
3982         my %configs;
3983         assign_configs \%configs, $output_config;
3984         my @config_keys = keys %min_configs;
3985         foreach my $config (@config_keys) {
3986         if (!defined($configs{$config})) {
3987             doprint "$config is not set, disabling\n";
3988             delete $min_configs{$config};
3989         }
3990         }
3991 
3992         # Save off all the current mandatory configs
3993         open (OUT, ">$temp_config")
3994         or die "Can't write to $temp_config";
3995         foreach my $config (keys %keep_configs) {
3996         print OUT "$keep_configs{$config}\n";
3997         }
3998         foreach my $config (keys %min_configs) {
3999         print OUT "$min_configs{$config}\n";
4000         }
4001         close OUT;
4002 
4003         run_command "mv $temp_config $output_minconfig" or
4004         dodie "failed to copy update to $output_minconfig";
4005     }
4006 
4007     doprint "Reboot and wait $sleep_time seconds\n";
4008     reboot_to_good $sleep_time;
4009     }
4010 
4011     success $i;
4012     return 1;
4013 }
4014 
4015 sub make_warnings_file {
4016     my ($i) = @_;
4017 
4018     if (!defined($warnings_file)) {
4019     dodie "Must define WARNINGS_FILE for make_warnings_file test";
4020     }
4021 
4022     if ($build_type eq "nobuild") {
4023     dodie "BUILD_TYPE can not be 'nobuild' for make_warnings_file test";
4024     }
4025 
4026     build $build_type or dodie "Failed to build";
4027 
4028     open(OUT, ">$warnings_file") or dodie "Can't create $warnings_file";
4029 
4030     open(IN, $buildlog) or dodie "Can't open $buildlog";
4031     while (<IN>) {
4032 
4033     # Some compilers use UTF-8 extended for quotes
4034     # for distcc heterogeneous systems, this causes issues
4035     s/$utf8_quote/'/g;
4036 
4037     if (/$check_build_re/) {
4038         print OUT;
4039     }
4040     }
4041     close(IN);
4042 
4043     close(OUT);
4044 
4045     success $i;
4046 }
4047 
4048 $#ARGV < 1 or die "ktest.pl version: $VERSION\n   usage: ktest.pl [config-file]\n";
4049 
4050 if ($#ARGV == 0) {
4051     $ktest_config = $ARGV[0];
4052     if (! -f $ktest_config) {
4053     print "$ktest_config does not exist.\n";
4054     if (!read_yn "Create it?") {
4055         exit 0;
4056     }
4057     }
4058 }
4059 
4060 if (! -f $ktest_config) {
4061     $newconfig = 1;
4062     get_test_case;
4063     open(OUT, ">$ktest_config") or die "Can not create $ktest_config";
4064     print OUT << "EOF"
4065 # Generated by ktest.pl
4066 #
4067 
4068 # PWD is a ktest.pl variable that will result in the process working
4069 # directory that ktest.pl is executed in.
4070 
4071 # THIS_DIR is automatically assigned the PWD of the path that generated
4072 # the config file. It is best to use this variable when assigning other
4073 # directory paths within this directory. This allows you to easily
4074 # move the test cases to other locations or to other machines.
4075 #
4076 THIS_DIR := $variable{"PWD"}
4077 
4078 # Define each test with TEST_START
4079 # The config options below it will override the defaults
4080 TEST_START
4081 TEST_TYPE = $default{"TEST_TYPE"}
4082 
4083 DEFAULTS
4084 EOF
4085 ;
4086     close(OUT);
4087 }
4088 read_config $ktest_config;
4089 
4090 if (defined($opt{"LOG_FILE"})) {
4091     $opt{"LOG_FILE"} = eval_option("LOG_FILE", $opt{"LOG_FILE"}, -1);
4092 }
4093 
4094 # Append any configs entered in manually to the config file.
4095 my @new_configs = keys %entered_configs;
4096 if ($#new_configs >= 0) {
4097     print "\nAppending entered in configs to $ktest_config\n";
4098     open(OUT, ">>$ktest_config") or die "Can not append to $ktest_config";
4099     foreach my $config (@new_configs) {
4100     print OUT "$config = $entered_configs{$config}\n";
4101     $opt{$config} = process_variables($entered_configs{$config});
4102     }
4103 }
4104 
4105 if ($opt{"CLEAR_LOG"} && defined($opt{"LOG_FILE"})) {
4106     unlink $opt{"LOG_FILE"};
4107 }
4108 
4109 doprint "\n\nSTARTING AUTOMATED TESTS\n\n";
4110 
4111 for (my $i = 0, my $repeat = 1; $i <= $opt{"NUM_TESTS"}; $i += $repeat) {
4112 
4113     if (!$i) {
4114     doprint "DEFAULT OPTIONS:\n";
4115     } else {
4116     doprint "\nTEST $i OPTIONS";
4117     if (defined($repeat_tests{$i})) {
4118         $repeat = $repeat_tests{$i};
4119         doprint " ITERATE $repeat";
4120     }
4121     doprint "\n";
4122     }
4123 
4124     foreach my $option (sort keys %opt) {
4125 
4126     if ($option =~ /\[(\d+)\]$/) {
4127         next if ($i != $1);
4128     } else {
4129         next if ($i);
4130     }
4131 
4132     doprint "$option = $opt{$option}\n";
4133     }
4134 }
4135 
4136 sub option_defined {
4137     my ($option) = @_;
4138 
4139     if (defined($opt{$option}) && $opt{$option} !~ /^\s*$/) {
4140     return 1;
4141     }
4142 
4143     return 0;
4144 }
4145 
4146 sub __set_test_option {
4147     my ($name, $i) = @_;
4148 
4149     my $option = "$name\[$i\]";
4150 
4151     if (option_defined($option)) {
4152     return $opt{$option};
4153     }
4154 
4155     foreach my $test (keys %repeat_tests) {
4156     if ($i >= $test &&
4157         $i < $test + $repeat_tests{$test}) {
4158         $option = "$name\[$test\]";
4159         if (option_defined($option)) {
4160         return $opt{$option};
4161         }
4162     }
4163     }
4164 
4165     if (option_defined($name)) {
4166     return $opt{$name};
4167     }
4168 
4169     return undef;
4170 }
4171 
4172 sub set_test_option {
4173     my ($name, $i) = @_;
4174 
4175     my $option = __set_test_option($name, $i);
4176     return $option if (!defined($option));
4177 
4178     return eval_option($name, $option, $i);
4179 }
4180 
4181 # First we need to do is the builds
4182 for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
4183 
4184     # Do not reboot on failing test options
4185     $no_reboot = 1;
4186     $reboot_success = 0;
4187 
4188     $have_version = 0;
4189 
4190     $iteration = $i;
4191 
4192     $build_time = 0;
4193     $install_time = 0;
4194     $reboot_time = 0;
4195     $test_time = 0;
4196 
4197     undef %force_config;
4198 
4199     my $makecmd = set_test_option("MAKE_CMD", $i);
4200 
4201     $outputdir = set_test_option("OUTPUT_DIR", $i);
4202     $builddir = set_test_option("BUILD_DIR", $i);
4203 
4204     chdir $builddir || die "can't change directory to $builddir";
4205 
4206     if (!-d $outputdir) {
4207     mkpath($outputdir) or
4208         die "can't create $outputdir";
4209     }
4210 
4211     $make = "$makecmd O=$outputdir";
4212 
4213     # Load all the options into their mapped variable names
4214     foreach my $opt (keys %option_map) {
4215     ${$option_map{$opt}} = set_test_option($opt, $i);
4216     }
4217 
4218     $start_minconfig_defined = 1;
4219 
4220     # The first test may override the PRE_KTEST option
4221     if (defined($pre_ktest) && $i == 1) {
4222     doprint "\n";
4223     run_command $pre_ktest;
4224     }
4225 
4226     # Any test can override the POST_KTEST option
4227     # The last test takes precedence.
4228     if (defined($post_ktest)) {
4229     $final_post_ktest = $post_ktest;
4230     }
4231 
4232     if (!defined($start_minconfig)) {
4233     $start_minconfig_defined = 0;
4234     $start_minconfig = $minconfig;
4235     }
4236 
4237     if (!-d $tmpdir) {
4238     mkpath($tmpdir) or
4239         die "can't create $tmpdir";
4240     }
4241 
4242     $ENV{"SSH_USER"} = $ssh_user;
4243     $ENV{"MACHINE"} = $machine;
4244 
4245     $buildlog = "$tmpdir/buildlog-$machine";
4246     $testlog = "$tmpdir/testlog-$machine";
4247     $dmesg = "$tmpdir/dmesg-$machine";
4248     $output_config = "$outputdir/.config";
4249 
4250     if (!$buildonly) {
4251     $target = "$ssh_user\@$machine";
4252     if ($reboot_type eq "grub") {
4253         dodie "GRUB_MENU not defined" if (!defined($grub_menu));
4254     } elsif ($reboot_type eq "grub2") {
4255         dodie "GRUB_MENU not defined" if (!defined($grub_menu));
4256         dodie "GRUB_FILE not defined" if (!defined($grub_file));
4257     } elsif ($reboot_type eq "syslinux") {
4258         dodie "SYSLINUX_LABEL not defined" if (!defined($syslinux_label));
4259     }
4260     }
4261 
4262     my $run_type = $build_type;
4263     if ($test_type eq "patchcheck") {
4264     $run_type = $patchcheck_type;
4265     } elsif ($test_type eq "bisect") {
4266     $run_type = $bisect_type;
4267     } elsif ($test_type eq "config_bisect") {
4268     $run_type = $config_bisect_type;
4269     } elsif ($test_type eq "make_min_config") {
4270     $run_type = "";
4271     } elsif ($test_type eq "make_warnings_file") {
4272     $run_type = "";
4273     }
4274 
4275     # mistake in config file?
4276     if (!defined($run_type)) {
4277     $run_type = "ERROR";
4278     }
4279 
4280     my $installme = "";
4281     $installme = " no_install" if ($no_install);
4282 
4283     my $name = "";
4284 
4285     if (defined($test_name)) {
4286     $name = " ($test_name)";
4287     }
4288 
4289     doprint "\n\n";
4290     doprint "RUNNING TEST $i of $opt{NUM_TESTS}$name with option $test_type $run_type$installme\n\n";
4291 
4292     if (defined($pre_test)) {
4293     run_command $pre_test;
4294     }
4295 
4296     unlink $dmesg;
4297     unlink $buildlog;
4298     unlink $testlog;
4299 
4300     if (defined($addconfig)) {
4301     my $min = $minconfig;
4302     if (!defined($minconfig)) {
4303         $min = "";
4304     }
4305     run_command "cat $addconfig $min > $tmpdir/add_config" or
4306         dodie "Failed to create temp config";
4307     $minconfig = "$tmpdir/add_config";
4308     }
4309 
4310     if (defined($checkout)) {
4311     run_command "git checkout $checkout" or
4312         die "failed to checkout $checkout";
4313     }
4314 
4315     $no_reboot = 0;
4316 
4317     # A test may opt to not reboot the box
4318     if ($reboot_on_success) {
4319     $reboot_success = 1;
4320     }
4321 
4322     if ($test_type eq "bisect") {
4323     bisect $i;
4324     next;
4325     } elsif ($test_type eq "config_bisect") {
4326     config_bisect $i;
4327     next;
4328     } elsif ($test_type eq "patchcheck") {
4329     patchcheck $i;
4330     next;
4331     } elsif ($test_type eq "make_min_config") {
4332     make_min_config $i;
4333     next;
4334     } elsif ($test_type eq "make_warnings_file") {
4335     $no_reboot = 1;
4336     make_warnings_file $i;
4337     next;
4338     }
4339 
4340     if ($build_type ne "nobuild") {
4341     build $build_type or next;
4342     check_buildlog or next;
4343     }
4344 
4345     if ($test_type eq "install") {
4346     get_version;
4347     install;
4348     success $i;
4349     next;
4350     }
4351 
4352     if ($test_type ne "build") {
4353     my $failed = 0;
4354     start_monitor_and_install or $failed = 1;
4355 
4356     if (!$failed && $test_type ne "boot" && defined($run_test)) {
4357         do_run_test or $failed = 1;
4358     }
4359     end_monitor;
4360     if ($failed) {
4361         print_times;
4362         next;
4363     }
4364     }
4365 
4366     print_times;
4367 
4368     success $i;
4369 }
4370 
4371 if (defined($final_post_ktest)) {
4372     run_command $final_post_ktest;
4373 }
4374 
4375 if ($opt{"POWEROFF_ON_SUCCESS"}) {
4376     halt;
4377 } elsif ($opt{"REBOOT_ON_SUCCESS"} && !do_not_reboot && $reboot_success) {
4378     reboot_to_good;
4379 } elsif (defined($switch_to_good)) {
4380     # still need to get to the good kernel
4381     run_command $switch_to_good;
4382 }
4383 
4384 
4385 doprint "\n    $successes of $opt{NUM_TESTS} tests were successful\n\n";
4386 
4387 exit 0;