Back to home page

OSCL-LXR

 
 

    


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