12545eb61SSteven Rostedt#!/usr/bin/perl -w 2d6ce2a0bSSteven Rostedt# 3cce1dac8SUwe Kleine-König# Copyright 2010 - Steven Rostedt <srostedt@redhat.com>, Red Hat Inc. 4d6ce2a0bSSteven Rostedt# Licensed under the terms of the GNU GPL License version 2 5d6ce2a0bSSteven Rostedt# 62545eb61SSteven Rostedt 72545eb61SSteven Rostedtuse strict; 82545eb61SSteven Rostedtuse IPC::Open2; 92545eb61SSteven Rostedtuse Fcntl qw(F_GETFL F_SETFL O_NONBLOCK); 107faafbd6SSteven Rostedtuse File::Path qw(mkpath); 117faafbd6SSteven Rostedtuse File::Copy qw(cp); 122545eb61SSteven Rostedtuse FileHandle; 132545eb61SSteven Rostedt 14e48c5293SSteven Rostedtmy $VERSION = "0.2"; 15e48c5293SSteven Rostedt 162545eb61SSteven Rostedt$| = 1; 172545eb61SSteven Rostedt 182545eb61SSteven Rostedtmy %opt; 19a57419b3SSteven Rostedtmy %repeat_tests; 20a57419b3SSteven Rostedtmy %repeats; 212545eb61SSteven Rostedt 222545eb61SSteven Rostedt#default opts 234f43e0dcSSteven Rostedtmy %default = ( 244f43e0dcSSteven Rostedt "NUM_TESTS" => 1, 254f43e0dcSSteven Rostedt "TEST_TYPE" => "build", 264f43e0dcSSteven Rostedt "BUILD_TYPE" => "randconfig", 274f43e0dcSSteven Rostedt "MAKE_CMD" => "make", 284f43e0dcSSteven Rostedt "TIMEOUT" => 120, 294f43e0dcSSteven Rostedt "TMP_DIR" => "/tmp/ktest/\${MACHINE}", 304f43e0dcSSteven Rostedt "SLEEP_TIME" => 60, # sleep time between tests 314f43e0dcSSteven Rostedt "BUILD_NOCLEAN" => 0, 324f43e0dcSSteven Rostedt "REBOOT_ON_ERROR" => 0, 334f43e0dcSSteven Rostedt "POWEROFF_ON_ERROR" => 0, 344f43e0dcSSteven Rostedt "REBOOT_ON_SUCCESS" => 1, 354f43e0dcSSteven Rostedt "POWEROFF_ON_SUCCESS" => 0, 364f43e0dcSSteven Rostedt "BUILD_OPTIONS" => "", 374f43e0dcSSteven Rostedt "BISECT_SLEEP_TIME" => 60, # sleep time between bisects 384f43e0dcSSteven Rostedt "PATCHCHECK_SLEEP_TIME" => 60, # sleep time between patch checks 394f43e0dcSSteven Rostedt "CLEAR_LOG" => 0, 404f43e0dcSSteven Rostedt "BISECT_MANUAL" => 0, 414f43e0dcSSteven Rostedt "BISECT_SKIP" => 1, 42ccc513b6SSteven Rostedt "MIN_CONFIG_TYPE" => "boot", 434f43e0dcSSteven Rostedt "SUCCESS_LINE" => "login:", 444f43e0dcSSteven Rostedt "DETECT_TRIPLE_FAULT" => 1, 454f43e0dcSSteven Rostedt "NO_INSTALL" => 0, 464f43e0dcSSteven Rostedt "BOOTED_TIMEOUT" => 1, 474f43e0dcSSteven Rostedt "DIE_ON_FAILURE" => 1, 484f43e0dcSSteven Rostedt "SSH_EXEC" => "ssh \$SSH_USER\@\$MACHINE \$SSH_COMMAND", 494f43e0dcSSteven Rostedt "SCP_TO_TARGET" => "scp \$SRC_FILE \$SSH_USER\@\$MACHINE:\$DST_FILE", 5002ad2617SSteven Rostedt "SCP_TO_TARGET_INSTALL" => "\${SCP_TO_TARGET}", 514f43e0dcSSteven Rostedt "REBOOT" => "ssh \$SSH_USER\@\$MACHINE reboot", 524f43e0dcSSteven Rostedt "STOP_AFTER_SUCCESS" => 10, 534f43e0dcSSteven Rostedt "STOP_AFTER_FAILURE" => 60, 544f43e0dcSSteven Rostedt "STOP_TEST_AFTER" => 600, 55407b95b7SSteven Rostedt "MAX_MONITOR_WAIT" => 1800, 56a15ba913SSteven Rostedt "GRUB_REBOOT" => "grub2-reboot", 577786954cSSteven Rostedt "SYSLINUX" => "extlinux", 587786954cSSteven Rostedt "SYSLINUX_PATH" => "/boot/extlinux", 59600bbf0aSSteven Rostedt 60600bbf0aSSteven Rostedt# required, and we will ask users if they don't have them but we keep the default 61600bbf0aSSteven Rostedt# value something that is common. 624f43e0dcSSteven Rostedt "REBOOT_TYPE" => "grub", 634f43e0dcSSteven Rostedt "LOCALVERSION" => "-test", 644f43e0dcSSteven Rostedt "SSH_USER" => "root", 654f43e0dcSSteven Rostedt "BUILD_TARGET" => "arch/x86/boot/bzImage", 664f43e0dcSSteven Rostedt "TARGET_IMAGE" => "/boot/vmlinuz-test", 679cc9e091SSteven Rostedt 689cc9e091SSteven Rostedt "LOG_FILE" => undef, 699cc9e091SSteven Rostedt "IGNORE_UNUSED" => 0, 704f43e0dcSSteven Rostedt); 712545eb61SSteven Rostedt 728d1491baSSteven Rostedtmy $ktest_config; 732545eb61SSteven Rostedtmy $version; 74683a3e64SSteven Rostedtmy $have_version = 0; 75a75fececSSteven Rostedtmy $machine; 76e48c5293SSteven Rostedtmy $ssh_user; 77a75fececSSteven Rostedtmy $tmpdir; 78a75fececSSteven Rostedtmy $builddir; 79a75fececSSteven Rostedtmy $outputdir; 8051ad1dd1SSteven Rostedtmy $output_config; 81a75fececSSteven Rostedtmy $test_type; 827faafbd6SSteven Rostedtmy $build_type; 83a75fececSSteven Rostedtmy $build_options; 84921ed4c7SSteven Rostedtmy $final_post_ktest; 85921ed4c7SSteven Rostedtmy $pre_ktest; 86921ed4c7SSteven Rostedtmy $post_ktest; 87921ed4c7SSteven Rostedtmy $pre_test; 88921ed4c7SSteven Rostedtmy $post_test; 890bd6c1a3SSteven Rostedtmy $pre_build; 900bd6c1a3SSteven Rostedtmy $post_build; 910bd6c1a3SSteven Rostedtmy $pre_build_die; 920bd6c1a3SSteven Rostedtmy $post_build_die; 93a75fececSSteven Rostedtmy $reboot_type; 94a75fececSSteven Rostedtmy $reboot_script; 95a75fececSSteven Rostedtmy $power_cycle; 96e48c5293SSteven Rostedtmy $reboot; 97a75fececSSteven Rostedtmy $reboot_on_error; 98bc7c5803SSteven Rostedtmy $switch_to_good; 99bc7c5803SSteven Rostedtmy $switch_to_test; 100a75fececSSteven Rostedtmy $poweroff_on_error; 101648a182cSSteven Rostedtmy $reboot_on_success; 102a75fececSSteven Rostedtmy $die_on_failure; 103576f627cSSteven Rostedtmy $powercycle_after_reboot; 104576f627cSSteven Rostedtmy $poweroff_after_halt; 105407b95b7SSteven Rostedtmy $max_monitor_wait; 106e48c5293SSteven Rostedtmy $ssh_exec; 107e48c5293SSteven Rostedtmy $scp_to_target; 10802ad2617SSteven Rostedtmy $scp_to_target_install; 109a75fececSSteven Rostedtmy $power_off; 110a75fececSSteven Rostedtmy $grub_menu; 111a15ba913SSteven Rostedtmy $grub_file; 1122545eb61SSteven Rostedtmy $grub_number; 113a15ba913SSteven Rostedtmy $grub_reboot; 1147786954cSSteven Rostedtmy $syslinux; 1157786954cSSteven Rostedtmy $syslinux_path; 1167786954cSSteven Rostedtmy $syslinux_label; 1172545eb61SSteven Rostedtmy $target; 1182545eb61SSteven Rostedtmy $make; 119e5c2ec11SSteven Rostedtmy $pre_install; 1208b37ca8cSSteven Rostedtmy $post_install; 121e0a8742eSSteven Rostedtmy $no_install; 1225c42fc5bSSteven Rostedtmy $noclean; 1235f9b6cedSSteven Rostedtmy $minconfig; 1244c4ab120SSteven Rostedtmy $start_minconfig; 12535ce5952SSteven Rostedtmy $start_minconfig_defined; 1264c4ab120SSteven Rostedtmy $output_minconfig; 127ccc513b6SSteven Rostedtmy $minconfig_type; 12843de3316SSteven Rostedtmy $use_output_minconfig; 1294c4ab120SSteven Rostedtmy $ignore_config; 130be405f95SSteven Rostedtmy $ignore_errors; 1312b7d9b21SSteven Rostedtmy $addconfig; 1325f9b6cedSSteven Rostedtmy $in_bisect = 0; 133b5f4aea6SSteven Rostedtmy $bisect_bad_commit = ""; 134d6ce2a0bSSteven Rostedtmy $reverse_bisect; 135c960bb9fSSteven Rostedtmy $bisect_manual; 136c23dca7cSSteven Rostedtmy $bisect_skip; 13730f75da5SSteven Rostedtmy $config_bisect_good; 138c5dacb88SSteven Rostedtmy $bisect_ret_good; 139c5dacb88SSteven Rostedtmy $bisect_ret_bad; 140c5dacb88SSteven Rostedtmy $bisect_ret_skip; 141c5dacb88SSteven Rostedtmy $bisect_ret_abort; 142c5dacb88SSteven Rostedtmy $bisect_ret_default; 1436c5ee0beSSteven Rostedtmy $in_patchcheck = 0; 1445a391fbfSSteven Rostedtmy $run_test; 1456c5ee0beSSteven Rostedtmy $redirect; 1467faafbd6SSteven Rostedtmy $buildlog; 147a9dd5d63SRabin Vincentmy $testlog; 1487faafbd6SSteven Rostedtmy $dmesg; 1497faafbd6SSteven Rostedtmy $monitor_fp; 1507faafbd6SSteven Rostedtmy $monitor_pid; 1517faafbd6SSteven Rostedtmy $monitor_cnt = 0; 152a75fececSSteven Rostedtmy $sleep_time; 153a75fececSSteven Rostedtmy $bisect_sleep_time; 15427d934b2SSteven Rostedtmy $patchcheck_sleep_time; 1551990207dSSteven Rostedtmy $ignore_warnings; 156a75fececSSteven Rostedtmy $store_failures; 157de5b6e3bSRabin Vincentmy $store_successes; 1589064af52SSteven Rostedtmy $test_name; 159a75fececSSteven Rostedtmy $timeout; 160a75fececSSteven Rostedtmy $booted_timeout; 161f1a5b962SSteven Rostedtmy $detect_triplefault; 162a75fececSSteven Rostedtmy $console; 1632b803365SSteven Rostedtmy $reboot_success_line; 164a75fececSSteven Rostedtmy $success_line; 1651c8a617aSSteven Rostedtmy $stop_after_success; 1661c8a617aSSteven Rostedtmy $stop_after_failure; 1672d01b26aSSteven Rostedtmy $stop_test_after; 168a75fececSSteven Rostedtmy $build_target; 169a75fececSSteven Rostedtmy $target_image; 170b5f4aea6SSteven Rostedtmy $checkout; 171a75fececSSteven Rostedtmy $localversion; 172576f627cSSteven Rostedtmy $iteration = 0; 173e48c5293SSteven Rostedtmy $successes = 0; 1742545eb61SSteven Rostedt 175b5f4aea6SSteven Rostedtmy $bisect_good; 176b5f4aea6SSteven Rostedtmy $bisect_bad; 177b5f4aea6SSteven Rostedtmy $bisect_type; 178b5f4aea6SSteven Rostedtmy $bisect_start; 179b5f4aea6SSteven Rostedtmy $bisect_replay; 180b5f4aea6SSteven Rostedtmy $bisect_files; 181b5f4aea6SSteven Rostedtmy $bisect_reverse; 182b5f4aea6SSteven Rostedtmy $bisect_check; 183b5f4aea6SSteven Rostedt 184b5f4aea6SSteven Rostedtmy $config_bisect; 185b5f4aea6SSteven Rostedtmy $config_bisect_type; 186b0918612SSteven Rostedtmy $config_bisect_check; 187b5f4aea6SSteven Rostedt 188b5f4aea6SSteven Rostedtmy $patchcheck_type; 189b5f4aea6SSteven Rostedtmy $patchcheck_start; 190b5f4aea6SSteven Rostedtmy $patchcheck_end; 191b5f4aea6SSteven Rostedt 192165708b2SSteven Rostedt# set when a test is something other that just building or install 193bb8474b1SSteven Rostedt# which would require more options. 194bb8474b1SSteven Rostedtmy $buildonly = 1; 195bb8474b1SSteven Rostedt 196dbd3783bSSteven Rostedt# set when creating a new config 197dbd3783bSSteven Rostedtmy $newconfig = 0; 198dbd3783bSSteven Rostedt 1998d1491baSSteven Rostedtmy %entered_configs; 2008d1491baSSteven Rostedtmy %config_help; 20177d942ceSSteven Rostedtmy %variable; 202cf79fab6SSteven Rostedt 203cf79fab6SSteven Rostedt# force_config is the list of configs that we force enabled (or disabled) 204cf79fab6SSteven Rostedt# in a .config file. The MIN_CONFIG and ADD_CONFIG configs. 205fcb3f16aSSteven Rostedtmy %force_config; 2068d1491baSSteven Rostedt 2074ab1cce5SSteven Rostedt# do not force reboots on config problems 2084ab1cce5SSteven Rostedtmy $no_reboot = 1; 2094ab1cce5SSteven Rostedt 210759a3cc6SSteven Rostedt# reboot on success 211759a3cc6SSteven Rostedtmy $reboot_success = 0; 212759a3cc6SSteven Rostedt 2139cc9e091SSteven Rostedtmy %option_map = ( 2149cc9e091SSteven Rostedt "MACHINE" => \$machine, 2159cc9e091SSteven Rostedt "SSH_USER" => \$ssh_user, 2169cc9e091SSteven Rostedt "TMP_DIR" => \$tmpdir, 2179cc9e091SSteven Rostedt "OUTPUT_DIR" => \$outputdir, 2189cc9e091SSteven Rostedt "BUILD_DIR" => \$builddir, 2199cc9e091SSteven Rostedt "TEST_TYPE" => \$test_type, 220921ed4c7SSteven Rostedt "PRE_KTEST" => \$pre_ktest, 221921ed4c7SSteven Rostedt "POST_KTEST" => \$post_ktest, 222921ed4c7SSteven Rostedt "PRE_TEST" => \$pre_test, 223921ed4c7SSteven Rostedt "POST_TEST" => \$post_test, 2249cc9e091SSteven Rostedt "BUILD_TYPE" => \$build_type, 2259cc9e091SSteven Rostedt "BUILD_OPTIONS" => \$build_options, 2269cc9e091SSteven Rostedt "PRE_BUILD" => \$pre_build, 2279cc9e091SSteven Rostedt "POST_BUILD" => \$post_build, 2289cc9e091SSteven Rostedt "PRE_BUILD_DIE" => \$pre_build_die, 2299cc9e091SSteven Rostedt "POST_BUILD_DIE" => \$post_build_die, 2309cc9e091SSteven Rostedt "POWER_CYCLE" => \$power_cycle, 2319cc9e091SSteven Rostedt "REBOOT" => \$reboot, 2329cc9e091SSteven Rostedt "BUILD_NOCLEAN" => \$noclean, 2339cc9e091SSteven Rostedt "MIN_CONFIG" => \$minconfig, 2349cc9e091SSteven Rostedt "OUTPUT_MIN_CONFIG" => \$output_minconfig, 2359cc9e091SSteven Rostedt "START_MIN_CONFIG" => \$start_minconfig, 236ccc513b6SSteven Rostedt "MIN_CONFIG_TYPE" => \$minconfig_type, 23743de3316SSteven Rostedt "USE_OUTPUT_MIN_CONFIG" => \$use_output_minconfig, 2389cc9e091SSteven Rostedt "IGNORE_CONFIG" => \$ignore_config, 2399cc9e091SSteven Rostedt "TEST" => \$run_test, 2409cc9e091SSteven Rostedt "ADD_CONFIG" => \$addconfig, 2419cc9e091SSteven Rostedt "REBOOT_TYPE" => \$reboot_type, 2429cc9e091SSteven Rostedt "GRUB_MENU" => \$grub_menu, 243a15ba913SSteven Rostedt "GRUB_FILE" => \$grub_file, 244a15ba913SSteven Rostedt "GRUB_REBOOT" => \$grub_reboot, 2457786954cSSteven Rostedt "SYSLINUX" => \$syslinux, 2467786954cSSteven Rostedt "SYSLINUX_PATH" => \$syslinux_path, 2477786954cSSteven Rostedt "SYSLINUX_LABEL" => \$syslinux_label, 248e5c2ec11SSteven Rostedt "PRE_INSTALL" => \$pre_install, 2499cc9e091SSteven Rostedt "POST_INSTALL" => \$post_install, 2509cc9e091SSteven Rostedt "NO_INSTALL" => \$no_install, 2519cc9e091SSteven Rostedt "REBOOT_SCRIPT" => \$reboot_script, 2529cc9e091SSteven Rostedt "REBOOT_ON_ERROR" => \$reboot_on_error, 2539cc9e091SSteven Rostedt "SWITCH_TO_GOOD" => \$switch_to_good, 2549cc9e091SSteven Rostedt "SWITCH_TO_TEST" => \$switch_to_test, 2559cc9e091SSteven Rostedt "POWEROFF_ON_ERROR" => \$poweroff_on_error, 256648a182cSSteven Rostedt "REBOOT_ON_SUCCESS" => \$reboot_on_success, 2579cc9e091SSteven Rostedt "DIE_ON_FAILURE" => \$die_on_failure, 2589cc9e091SSteven Rostedt "POWER_OFF" => \$power_off, 2599cc9e091SSteven Rostedt "POWERCYCLE_AFTER_REBOOT" => \$powercycle_after_reboot, 2609cc9e091SSteven Rostedt "POWEROFF_AFTER_HALT" => \$poweroff_after_halt, 261407b95b7SSteven Rostedt "MAX_MONITOR_WAIT" => \$max_monitor_wait, 2629cc9e091SSteven Rostedt "SLEEP_TIME" => \$sleep_time, 2639cc9e091SSteven Rostedt "BISECT_SLEEP_TIME" => \$bisect_sleep_time, 2649cc9e091SSteven Rostedt "PATCHCHECK_SLEEP_TIME" => \$patchcheck_sleep_time, 2659cc9e091SSteven Rostedt "IGNORE_WARNINGS" => \$ignore_warnings, 266be405f95SSteven Rostedt "IGNORE_ERRORS" => \$ignore_errors, 2679cc9e091SSteven Rostedt "BISECT_MANUAL" => \$bisect_manual, 2689cc9e091SSteven Rostedt "BISECT_SKIP" => \$bisect_skip, 2699cc9e091SSteven Rostedt "CONFIG_BISECT_GOOD" => \$config_bisect_good, 2709cc9e091SSteven Rostedt "BISECT_RET_GOOD" => \$bisect_ret_good, 2719cc9e091SSteven Rostedt "BISECT_RET_BAD" => \$bisect_ret_bad, 2729cc9e091SSteven Rostedt "BISECT_RET_SKIP" => \$bisect_ret_skip, 2739cc9e091SSteven Rostedt "BISECT_RET_ABORT" => \$bisect_ret_abort, 2749cc9e091SSteven Rostedt "BISECT_RET_DEFAULT" => \$bisect_ret_default, 2759cc9e091SSteven Rostedt "STORE_FAILURES" => \$store_failures, 2769cc9e091SSteven Rostedt "STORE_SUCCESSES" => \$store_successes, 2779cc9e091SSteven Rostedt "TEST_NAME" => \$test_name, 2789cc9e091SSteven Rostedt "TIMEOUT" => \$timeout, 2799cc9e091SSteven Rostedt "BOOTED_TIMEOUT" => \$booted_timeout, 2809cc9e091SSteven Rostedt "CONSOLE" => \$console, 2819cc9e091SSteven Rostedt "DETECT_TRIPLE_FAULT" => \$detect_triplefault, 2829cc9e091SSteven Rostedt "SUCCESS_LINE" => \$success_line, 2839cc9e091SSteven Rostedt "REBOOT_SUCCESS_LINE" => \$reboot_success_line, 2849cc9e091SSteven Rostedt "STOP_AFTER_SUCCESS" => \$stop_after_success, 2859cc9e091SSteven Rostedt "STOP_AFTER_FAILURE" => \$stop_after_failure, 2869cc9e091SSteven Rostedt "STOP_TEST_AFTER" => \$stop_test_after, 2879cc9e091SSteven Rostedt "BUILD_TARGET" => \$build_target, 2889cc9e091SSteven Rostedt "SSH_EXEC" => \$ssh_exec, 2899cc9e091SSteven Rostedt "SCP_TO_TARGET" => \$scp_to_target, 29002ad2617SSteven Rostedt "SCP_TO_TARGET_INSTALL" => \$scp_to_target_install, 2919cc9e091SSteven Rostedt "CHECKOUT" => \$checkout, 2929cc9e091SSteven Rostedt "TARGET_IMAGE" => \$target_image, 2939cc9e091SSteven Rostedt "LOCALVERSION" => \$localversion, 2949cc9e091SSteven Rostedt 2959cc9e091SSteven Rostedt "BISECT_GOOD" => \$bisect_good, 2969cc9e091SSteven Rostedt "BISECT_BAD" => \$bisect_bad, 2979cc9e091SSteven Rostedt "BISECT_TYPE" => \$bisect_type, 2989cc9e091SSteven Rostedt "BISECT_START" => \$bisect_start, 2999cc9e091SSteven Rostedt "BISECT_REPLAY" => \$bisect_replay, 3009cc9e091SSteven Rostedt "BISECT_FILES" => \$bisect_files, 3019cc9e091SSteven Rostedt "BISECT_REVERSE" => \$bisect_reverse, 3029cc9e091SSteven Rostedt "BISECT_CHECK" => \$bisect_check, 3039cc9e091SSteven Rostedt 3049cc9e091SSteven Rostedt "CONFIG_BISECT" => \$config_bisect, 3059cc9e091SSteven Rostedt "CONFIG_BISECT_TYPE" => \$config_bisect_type, 306b0918612SSteven Rostedt "CONFIG_BISECT_CHECK" => \$config_bisect_check, 3079cc9e091SSteven Rostedt 3089cc9e091SSteven Rostedt "PATCHCHECK_TYPE" => \$patchcheck_type, 3099cc9e091SSteven Rostedt "PATCHCHECK_START" => \$patchcheck_start, 3109cc9e091SSteven Rostedt "PATCHCHECK_END" => \$patchcheck_end, 3119cc9e091SSteven Rostedt); 3129cc9e091SSteven Rostedt 3139cc9e091SSteven Rostedt# Options may be used by other options, record them. 3149cc9e091SSteven Rostedtmy %used_options; 3159cc9e091SSteven Rostedt 3167bf51073SSteven Rostedt# default variables that can be used 3177bf51073SSteven Rostedtchomp ($variable{"PWD"} = `pwd`); 3187bf51073SSteven Rostedt 3198d1491baSSteven Rostedt$config_help{"MACHINE"} = << "EOF" 3208d1491baSSteven Rostedt The machine hostname that you will test. 321bb8474b1SSteven Rostedt For build only tests, it is still needed to differentiate log files. 3228d1491baSSteven RostedtEOF 3238d1491baSSteven Rostedt ; 3248d1491baSSteven Rostedt$config_help{"SSH_USER"} = << "EOF" 3258d1491baSSteven Rostedt The box is expected to have ssh on normal bootup, provide the user 3268d1491baSSteven Rostedt (most likely root, since you need privileged operations) 3278d1491baSSteven RostedtEOF 3288d1491baSSteven Rostedt ; 3298d1491baSSteven Rostedt$config_help{"BUILD_DIR"} = << "EOF" 3308d1491baSSteven Rostedt The directory that contains the Linux source code (full path). 3310e7a22deSSteven Rostedt You can use \${PWD} that will be the path where ktest.pl is run, or use 3320e7a22deSSteven Rostedt \${THIS_DIR} which is assigned \${PWD} but may be changed later. 3338d1491baSSteven RostedtEOF 3348d1491baSSteven Rostedt ; 3358d1491baSSteven Rostedt$config_help{"OUTPUT_DIR"} = << "EOF" 3368d1491baSSteven Rostedt The directory that the objects will be built (full path). 3378d1491baSSteven Rostedt (can not be same as BUILD_DIR) 3380e7a22deSSteven Rostedt You can use \${PWD} that will be the path where ktest.pl is run, or use 3390e7a22deSSteven Rostedt \${THIS_DIR} which is assigned \${PWD} but may be changed later. 3408d1491baSSteven RostedtEOF 3418d1491baSSteven Rostedt ; 3428d1491baSSteven Rostedt$config_help{"BUILD_TARGET"} = << "EOF" 3438d1491baSSteven Rostedt The location of the compiled file to copy to the target. 3448d1491baSSteven Rostedt (relative to OUTPUT_DIR) 3458d1491baSSteven RostedtEOF 3468d1491baSSteven Rostedt ; 347dbd3783bSSteven Rostedt$config_help{"BUILD_OPTIONS"} = << "EOF" 348dbd3783bSSteven Rostedt Options to add to \"make\" when building. 349dbd3783bSSteven Rostedt i.e. -j20 350dbd3783bSSteven RostedtEOF 351dbd3783bSSteven Rostedt ; 3528d1491baSSteven Rostedt$config_help{"TARGET_IMAGE"} = << "EOF" 3538d1491baSSteven Rostedt The place to put your image on the test machine. 3548d1491baSSteven RostedtEOF 3558d1491baSSteven Rostedt ; 3568d1491baSSteven Rostedt$config_help{"POWER_CYCLE"} = << "EOF" 3578d1491baSSteven Rostedt A script or command to reboot the box. 3588d1491baSSteven Rostedt 3598d1491baSSteven Rostedt Here is a digital loggers power switch example 3608d1491baSSteven Rostedt POWER_CYCLE = wget --no-proxy -O /dev/null -q --auth-no-challenge 'http://admin:admin\@power/outlet?5=CCL' 3618d1491baSSteven Rostedt 3628d1491baSSteven Rostedt Here is an example to reboot a virtual box on the current host 3638d1491baSSteven Rostedt with the name "Guest". 3648d1491baSSteven Rostedt POWER_CYCLE = virsh destroy Guest; sleep 5; virsh start Guest 3658d1491baSSteven RostedtEOF 3668d1491baSSteven Rostedt ; 3678d1491baSSteven Rostedt$config_help{"CONSOLE"} = << "EOF" 3688d1491baSSteven Rostedt The script or command that reads the console 3698d1491baSSteven Rostedt 3708d1491baSSteven Rostedt If you use ttywatch server, something like the following would work. 3718d1491baSSteven RostedtCONSOLE = nc -d localhost 3001 3728d1491baSSteven Rostedt 3738d1491baSSteven Rostedt For a virtual machine with guest name "Guest". 3748d1491baSSteven RostedtCONSOLE = virsh console Guest 3758d1491baSSteven RostedtEOF 3768d1491baSSteven Rostedt ; 3778d1491baSSteven Rostedt$config_help{"LOCALVERSION"} = << "EOF" 3788d1491baSSteven Rostedt Required version ending to differentiate the test 3798d1491baSSteven Rostedt from other linux builds on the system. 3808d1491baSSteven RostedtEOF 3818d1491baSSteven Rostedt ; 3828d1491baSSteven Rostedt$config_help{"REBOOT_TYPE"} = << "EOF" 3838d1491baSSteven Rostedt Way to reboot the box to the test kernel. 3847786954cSSteven Rostedt Only valid options so far are "grub", "grub2", "syslinux", and "script". 3858d1491baSSteven Rostedt 3868d1491baSSteven Rostedt If you specify grub, it will assume grub version 1 3878d1491baSSteven Rostedt and will search in /boot/grub/menu.lst for the title \$GRUB_MENU 3888d1491baSSteven Rostedt and select that target to reboot to the kernel. If this is not 3898d1491baSSteven Rostedt your setup, then specify "script" and have a command or script 3908d1491baSSteven Rostedt specified in REBOOT_SCRIPT to boot to the target. 3918d1491baSSteven Rostedt 3928d1491baSSteven Rostedt The entry in /boot/grub/menu.lst must be entered in manually. 3938d1491baSSteven Rostedt The test will not modify that file. 394a15ba913SSteven Rostedt 395a15ba913SSteven Rostedt If you specify grub2, then you also need to specify both \$GRUB_MENU 396a15ba913SSteven Rostedt and \$GRUB_FILE. 3977786954cSSteven Rostedt 3987786954cSSteven Rostedt If you specify syslinux, then you may use SYSLINUX to define the syslinux 3997786954cSSteven Rostedt command (defaults to extlinux), and SYSLINUX_PATH to specify the path to 4007786954cSSteven Rostedt the syslinux install (defaults to /boot/extlinux). But you have to specify 4017786954cSSteven Rostedt SYSLINUX_LABEL to define the label to boot to for the test kernel. 4028d1491baSSteven RostedtEOF 4038d1491baSSteven Rostedt ; 4048d1491baSSteven Rostedt$config_help{"GRUB_MENU"} = << "EOF" 4058d1491baSSteven Rostedt The grub title name for the test kernel to boot 406a15ba913SSteven Rostedt (Only mandatory if REBOOT_TYPE = grub or grub2) 4078d1491baSSteven Rostedt 4088d1491baSSteven Rostedt Note, ktest.pl will not update the grub menu.lst, you need to 4098d1491baSSteven Rostedt manually add an option for the test. ktest.pl will search 4108d1491baSSteven Rostedt the grub menu.lst for this option to find what kernel to 4118d1491baSSteven Rostedt reboot into. 4128d1491baSSteven Rostedt 4138d1491baSSteven Rostedt For example, if in the /boot/grub/menu.lst the test kernel title has: 4148d1491baSSteven Rostedt title Test Kernel 4158d1491baSSteven Rostedt kernel vmlinuz-test 4168d1491baSSteven Rostedt GRUB_MENU = Test Kernel 417a15ba913SSteven Rostedt 418a15ba913SSteven Rostedt For grub2, a search of \$GRUB_FILE is performed for the lines 419a15ba913SSteven Rostedt that begin with "menuentry". It will not detect submenus. The 420a15ba913SSteven Rostedt menu must be a non-nested menu. Add the quotes used in the menu 421a15ba913SSteven Rostedt to guarantee your selection, as the first menuentry with the content 422a15ba913SSteven Rostedt of \$GRUB_MENU that is found will be used. 423a15ba913SSteven RostedtEOF 424a15ba913SSteven Rostedt ; 425a15ba913SSteven Rostedt$config_help{"GRUB_FILE"} = << "EOF" 426a15ba913SSteven Rostedt If grub2 is used, the full path for the grub.cfg file is placed 427a15ba913SSteven Rostedt here. Use something like /boot/grub2/grub.cfg to search. 4288d1491baSSteven RostedtEOF 4298d1491baSSteven Rostedt ; 4307786954cSSteven Rostedt$config_help{"SYSLINUX_LABEL"} = << "EOF" 4317786954cSSteven Rostedt If syslinux is used, the label that boots the target kernel must 4327786954cSSteven Rostedt be specified with SYSLINUX_LABEL. 4337786954cSSteven RostedtEOF 4347786954cSSteven Rostedt ; 4358d1491baSSteven Rostedt$config_help{"REBOOT_SCRIPT"} = << "EOF" 4368d1491baSSteven Rostedt A script to reboot the target into the test kernel 4378d1491baSSteven Rostedt (Only mandatory if REBOOT_TYPE = script) 4388d1491baSSteven RostedtEOF 4398d1491baSSteven Rostedt ; 4408d1491baSSteven Rostedt 441dad98754SSteven Rostedtsub read_prompt { 442dad98754SSteven Rostedt my ($cancel, $prompt) = @_; 44335ce5952SSteven Rostedt 44435ce5952SSteven Rostedt my $ans; 44535ce5952SSteven Rostedt 44635ce5952SSteven Rostedt for (;;) { 447dad98754SSteven Rostedt if ($cancel) { 448dad98754SSteven Rostedt print "$prompt [y/n/C] "; 449dad98754SSteven Rostedt } else { 45035ce5952SSteven Rostedt print "$prompt [Y/n] "; 451dad98754SSteven Rostedt } 45235ce5952SSteven Rostedt $ans = <STDIN>; 45335ce5952SSteven Rostedt chomp $ans; 45435ce5952SSteven Rostedt if ($ans =~ /^\s*$/) { 455dad98754SSteven Rostedt if ($cancel) { 456dad98754SSteven Rostedt $ans = "c"; 457dad98754SSteven Rostedt } else { 45835ce5952SSteven Rostedt $ans = "y"; 45935ce5952SSteven Rostedt } 460dad98754SSteven Rostedt } 46135ce5952SSteven Rostedt last if ($ans =~ /^y$/i || $ans =~ /^n$/i); 462dad98754SSteven Rostedt if ($cancel) { 463dad98754SSteven Rostedt last if ($ans =~ /^c$/i); 464dad98754SSteven Rostedt print "Please answer either 'y', 'n' or 'c'.\n"; 465dad98754SSteven Rostedt } else { 46635ce5952SSteven Rostedt print "Please answer either 'y' or 'n'.\n"; 46735ce5952SSteven Rostedt } 468dad98754SSteven Rostedt } 469dad98754SSteven Rostedt if ($ans =~ /^c/i) { 470dad98754SSteven Rostedt exit; 471dad98754SSteven Rostedt } 47235ce5952SSteven Rostedt if ($ans !~ /^y$/i) { 47335ce5952SSteven Rostedt return 0; 47435ce5952SSteven Rostedt } 47535ce5952SSteven Rostedt return 1; 47635ce5952SSteven Rostedt} 4778d1491baSSteven Rostedt 478dad98754SSteven Rostedtsub read_yn { 479dad98754SSteven Rostedt my ($prompt) = @_; 480dad98754SSteven Rostedt 481dad98754SSteven Rostedt return read_prompt 0, $prompt; 482dad98754SSteven Rostedt} 483dad98754SSteven Rostedt 484dad98754SSteven Rostedtsub read_ync { 485dad98754SSteven Rostedt my ($prompt) = @_; 486dad98754SSteven Rostedt 487dad98754SSteven Rostedt return read_prompt 1, $prompt; 488dad98754SSteven Rostedt} 489dad98754SSteven Rostedt 4908d1491baSSteven Rostedtsub get_ktest_config { 4918d1491baSSteven Rostedt my ($config) = @_; 492815e2bd7SSteven Rostedt my $ans; 4938d1491baSSteven Rostedt 4948d1491baSSteven Rostedt return if (defined($opt{$config})); 4958d1491baSSteven Rostedt 4968d1491baSSteven Rostedt if (defined($config_help{$config})) { 4978d1491baSSteven Rostedt print "\n"; 4988d1491baSSteven Rostedt print $config_help{$config}; 4998d1491baSSteven Rostedt } 5008d1491baSSteven Rostedt 5018d1491baSSteven Rostedt for (;;) { 5028d1491baSSteven Rostedt print "$config = "; 503dbd3783bSSteven Rostedt if (defined($default{$config}) && length($default{$config})) { 5048d1491baSSteven Rostedt print "\[$default{$config}\] "; 5058d1491baSSteven Rostedt } 506815e2bd7SSteven Rostedt $ans = <STDIN>; 507815e2bd7SSteven Rostedt $ans =~ s/^\s*(.*\S)\s*$/$1/; 508815e2bd7SSteven Rostedt if ($ans =~ /^\s*$/) { 5098d1491baSSteven Rostedt if ($default{$config}) { 510815e2bd7SSteven Rostedt $ans = $default{$config}; 5118d1491baSSteven Rostedt } else { 5128d1491baSSteven Rostedt print "Your answer can not be blank\n"; 5138d1491baSSteven Rostedt next; 5148d1491baSSteven Rostedt } 5158d1491baSSteven Rostedt } 5160e7a22deSSteven Rostedt $entered_configs{$config} = ${ans}; 5178d1491baSSteven Rostedt last; 5188d1491baSSteven Rostedt } 5198d1491baSSteven Rostedt} 5208d1491baSSteven Rostedt 5218d1491baSSteven Rostedtsub get_ktest_configs { 5228d1491baSSteven Rostedt get_ktest_config("MACHINE"); 5238d1491baSSteven Rostedt get_ktest_config("BUILD_DIR"); 5248d1491baSSteven Rostedt get_ktest_config("OUTPUT_DIR"); 525bb8474b1SSteven Rostedt 526dbd3783bSSteven Rostedt if ($newconfig) { 527dbd3783bSSteven Rostedt get_ktest_config("BUILD_OPTIONS"); 528dbd3783bSSteven Rostedt } 529dbd3783bSSteven Rostedt 530bb8474b1SSteven Rostedt # options required for other than just building a kernel 531bb8474b1SSteven Rostedt if (!$buildonly) { 532165708b2SSteven Rostedt get_ktest_config("POWER_CYCLE"); 533165708b2SSteven Rostedt get_ktest_config("CONSOLE"); 534165708b2SSteven Rostedt } 535165708b2SSteven Rostedt 536165708b2SSteven Rostedt # options required for install and more 537165708b2SSteven Rostedt if ($buildonly != 1) { 538bb8474b1SSteven Rostedt get_ktest_config("SSH_USER"); 5398d1491baSSteven Rostedt get_ktest_config("BUILD_TARGET"); 5408d1491baSSteven Rostedt get_ktest_config("TARGET_IMAGE"); 541bb8474b1SSteven Rostedt } 542bb8474b1SSteven Rostedt 5438d1491baSSteven Rostedt get_ktest_config("LOCALVERSION"); 5448d1491baSSteven Rostedt 545bb8474b1SSteven Rostedt return if ($buildonly); 546bb8474b1SSteven Rostedt 5478d1491baSSteven Rostedt my $rtype = $opt{"REBOOT_TYPE"}; 5488d1491baSSteven Rostedt 5498d1491baSSteven Rostedt if (!defined($rtype)) { 5508d1491baSSteven Rostedt if (!defined($opt{"GRUB_MENU"})) { 5518d1491baSSteven Rostedt get_ktest_config("REBOOT_TYPE"); 5528d1491baSSteven Rostedt $rtype = $entered_configs{"REBOOT_TYPE"}; 5538d1491baSSteven Rostedt } else { 5548d1491baSSteven Rostedt $rtype = "grub"; 5558d1491baSSteven Rostedt } 5568d1491baSSteven Rostedt } 5578d1491baSSteven Rostedt 5588d1491baSSteven Rostedt if ($rtype eq "grub") { 5598d1491baSSteven Rostedt get_ktest_config("GRUB_MENU"); 5608d1491baSSteven Rostedt } 561a15ba913SSteven Rostedt 562a15ba913SSteven Rostedt if ($rtype eq "grub2") { 563a15ba913SSteven Rostedt get_ktest_config("GRUB_MENU"); 564a15ba913SSteven Rostedt get_ktest_config("GRUB_FILE"); 565a15ba913SSteven Rostedt } 5667786954cSSteven Rostedt 5677786954cSSteven Rostedt if ($rtype eq "syslinux") { 5687786954cSSteven Rostedt get_ktest_config("SYSLINUX_LABEL"); 5697786954cSSteven Rostedt } 5708d1491baSSteven Rostedt} 5718d1491baSSteven Rostedt 57277d942ceSSteven Rostedtsub process_variables { 5738d735212SSteven Rostedt my ($value, $remove_undef) = @_; 57477d942ceSSteven Rostedt my $retval = ""; 57577d942ceSSteven Rostedt 57677d942ceSSteven Rostedt # We want to check for '\', and it is just easier 57777d942ceSSteven Rostedt # to check the previous characet of '$' and not need 57877d942ceSSteven Rostedt # to worry if '$' is the first character. By adding 57977d942ceSSteven Rostedt # a space to $value, we can just check [^\\]\$ and 58077d942ceSSteven Rostedt # it will still work. 58177d942ceSSteven Rostedt $value = " $value"; 58277d942ceSSteven Rostedt 58377d942ceSSteven Rostedt while ($value =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) { 58477d942ceSSteven Rostedt my $begin = $1; 58577d942ceSSteven Rostedt my $var = $2; 58677d942ceSSteven Rostedt my $end = $3; 58777d942ceSSteven Rostedt # append beginning of value to retval 58877d942ceSSteven Rostedt $retval = "$retval$begin"; 58977d942ceSSteven Rostedt if (defined($variable{$var})) { 59077d942ceSSteven Rostedt $retval = "$retval$variable{$var}"; 5918d735212SSteven Rostedt } elsif (defined($remove_undef) && $remove_undef) { 5928d735212SSteven Rostedt # for if statements, any variable that is not defined, 5938d735212SSteven Rostedt # we simple convert to 0 5948d735212SSteven Rostedt $retval = "${retval}0"; 59577d942ceSSteven Rostedt } else { 59677d942ceSSteven Rostedt # put back the origin piece. 59777d942ceSSteven Rostedt $retval = "$retval\$\{$var\}"; 5989cc9e091SSteven Rostedt # This could be an option that is used later, save 5999cc9e091SSteven Rostedt # it so we don't warn if this option is not one of 6009cc9e091SSteven Rostedt # ktests options. 6019cc9e091SSteven Rostedt $used_options{$var} = 1; 60277d942ceSSteven Rostedt } 60377d942ceSSteven Rostedt $value = $end; 60477d942ceSSteven Rostedt } 60577d942ceSSteven Rostedt $retval = "$retval$value"; 60677d942ceSSteven Rostedt 60777d942ceSSteven Rostedt # remove the space added in the beginning 60877d942ceSSteven Rostedt $retval =~ s/ //; 60977d942ceSSteven Rostedt 61077d942ceSSteven Rostedt return "$retval" 61177d942ceSSteven Rostedt} 61277d942ceSSteven Rostedt 613a57419b3SSteven Rostedtsub set_value { 6143d1cc414SSteven Rostedt my ($lvalue, $rvalue, $override, $overrides, $name) = @_; 6152545eb61SSteven Rostedt 616cad96669SSteven Rostedt my $prvalue = process_variables($rvalue); 617cad96669SSteven Rostedt 618cad96669SSteven Rostedt if ($buildonly && $lvalue =~ /^TEST_TYPE(\[.*\])?$/ && $prvalue ne "build") { 619bb8474b1SSteven Rostedt # Note if a test is something other than build, then we 620bb8474b1SSteven Rostedt # will need other manditory options. 621cad96669SSteven Rostedt if ($prvalue ne "install") { 622bb8474b1SSteven Rostedt $buildonly = 0; 623165708b2SSteven Rostedt } else { 624165708b2SSteven Rostedt # install still limits some manditory options. 625165708b2SSteven Rostedt $buildonly = 2; 626165708b2SSteven Rostedt } 627bb8474b1SSteven Rostedt } 628bb8474b1SSteven Rostedt 629a75fececSSteven Rostedt if (defined($opt{$lvalue})) { 6303d1cc414SSteven Rostedt if (!$override || defined(${$overrides}{$lvalue})) { 6313d1cc414SSteven Rostedt my $extra = ""; 6323d1cc414SSteven Rostedt if ($override) { 6333d1cc414SSteven Rostedt $extra = "In the same override section!\n"; 6343d1cc414SSteven Rostedt } 6353d1cc414SSteven Rostedt die "$name: $.: Option $lvalue defined more than once!\n$extra"; 6363d1cc414SSteven Rostedt } 637cad96669SSteven Rostedt ${$overrides}{$lvalue} = $prvalue; 638a75fececSSteven Rostedt } 63921a9679fSSteven Rostedt if ($rvalue =~ /^\s*$/) { 64021a9679fSSteven Rostedt delete $opt{$lvalue}; 64121a9679fSSteven Rostedt } else { 642cad96669SSteven Rostedt $opt{$lvalue} = $prvalue; 64321a9679fSSteven Rostedt } 6442545eb61SSteven Rostedt} 645a57419b3SSteven Rostedt 64677d942ceSSteven Rostedtsub set_variable { 64777d942ceSSteven Rostedt my ($lvalue, $rvalue) = @_; 64877d942ceSSteven Rostedt 64977d942ceSSteven Rostedt if ($rvalue =~ /^\s*$/) { 65077d942ceSSteven Rostedt delete $variable{$lvalue}; 65177d942ceSSteven Rostedt } else { 65277d942ceSSteven Rostedt $rvalue = process_variables($rvalue); 65377d942ceSSteven Rostedt $variable{$lvalue} = $rvalue; 65477d942ceSSteven Rostedt } 65577d942ceSSteven Rostedt} 65677d942ceSSteven Rostedt 657ab7a3f52SSteven Rostedtsub process_compare { 658ab7a3f52SSteven Rostedt my ($lval, $cmp, $rval) = @_; 659ab7a3f52SSteven Rostedt 660ab7a3f52SSteven Rostedt # remove whitespace 661ab7a3f52SSteven Rostedt 662ab7a3f52SSteven Rostedt $lval =~ s/^\s*//; 663ab7a3f52SSteven Rostedt $lval =~ s/\s*$//; 664ab7a3f52SSteven Rostedt 665ab7a3f52SSteven Rostedt $rval =~ s/^\s*//; 666ab7a3f52SSteven Rostedt $rval =~ s/\s*$//; 667ab7a3f52SSteven Rostedt 668ab7a3f52SSteven Rostedt if ($cmp eq "==") { 669ab7a3f52SSteven Rostedt return $lval eq $rval; 670ab7a3f52SSteven Rostedt } elsif ($cmp eq "!=") { 671ab7a3f52SSteven Rostedt return $lval ne $rval; 6728fddbe9bSSteven Rostedt } elsif ($cmp eq "=~") { 6738fddbe9bSSteven Rostedt return $lval =~ m/$rval/; 6748fddbe9bSSteven Rostedt } elsif ($cmp eq "!~") { 6758fddbe9bSSteven Rostedt return $lval !~ m/$rval/; 676ab7a3f52SSteven Rostedt } 677ab7a3f52SSteven Rostedt 678ab7a3f52SSteven Rostedt my $statement = "$lval $cmp $rval"; 679ab7a3f52SSteven Rostedt my $ret = eval $statement; 680ab7a3f52SSteven Rostedt 681ab7a3f52SSteven Rostedt # $@ stores error of eval 682ab7a3f52SSteven Rostedt if ($@) { 683ab7a3f52SSteven Rostedt return -1; 684ab7a3f52SSteven Rostedt } 685ab7a3f52SSteven Rostedt 686ab7a3f52SSteven Rostedt return $ret; 687ab7a3f52SSteven Rostedt} 688ab7a3f52SSteven Rostedt 6899900b5dcSSteven Rostedtsub value_defined { 6909900b5dcSSteven Rostedt my ($val) = @_; 6919900b5dcSSteven Rostedt 6929900b5dcSSteven Rostedt return defined($variable{$2}) || 6939900b5dcSSteven Rostedt defined($opt{$2}); 6949900b5dcSSteven Rostedt} 6959900b5dcSSteven Rostedt 6968d735212SSteven Rostedtmy $d = 0; 6978d735212SSteven Rostedtsub process_expression { 6988d735212SSteven Rostedt my ($name, $val) = @_; 69945d73a5dSSteven Rostedt 7008d735212SSteven Rostedt my $c = $d++; 7018d735212SSteven Rostedt 7028d735212SSteven Rostedt while ($val =~ s/\(([^\(]*?)\)/\&\&\&\&VAL\&\&\&\&/) { 7038d735212SSteven Rostedt my $express = $1; 7048d735212SSteven Rostedt 7058d735212SSteven Rostedt if (process_expression($name, $express)) { 7068d735212SSteven Rostedt $val =~ s/\&\&\&\&VAL\&\&\&\&/ 1 /; 7078d735212SSteven Rostedt } else { 7088d735212SSteven Rostedt $val =~ s/\&\&\&\&VAL\&\&\&\&/ 0 /; 7098d735212SSteven Rostedt } 7108d735212SSteven Rostedt } 7118d735212SSteven Rostedt 7128d735212SSteven Rostedt $d--; 7138d735212SSteven Rostedt my $OR = "\\|\\|"; 7148d735212SSteven Rostedt my $AND = "\\&\\&"; 7158d735212SSteven Rostedt 7168d735212SSteven Rostedt while ($val =~ s/^(.*?)($OR|$AND)//) { 7178d735212SSteven Rostedt my $express = $1; 7188d735212SSteven Rostedt my $op = $2; 7198d735212SSteven Rostedt 7208d735212SSteven Rostedt if (process_expression($name, $express)) { 7218d735212SSteven Rostedt if ($op eq "||") { 7228d735212SSteven Rostedt return 1; 7238d735212SSteven Rostedt } 7248d735212SSteven Rostedt } else { 7258d735212SSteven Rostedt if ($op eq "&&") { 7268d735212SSteven Rostedt return 0; 7278d735212SSteven Rostedt } 7288d735212SSteven Rostedt } 7298d735212SSteven Rostedt } 73045d73a5dSSteven Rostedt 7318fddbe9bSSteven Rostedt if ($val =~ /(.*)(==|\!=|>=|<=|>|<|=~|\!~)(.*)/) { 732ab7a3f52SSteven Rostedt my $ret = process_compare($1, $2, $3); 733ab7a3f52SSteven Rostedt if ($ret < 0) { 734ab7a3f52SSteven Rostedt die "$name: $.: Unable to process comparison\n"; 735ab7a3f52SSteven Rostedt } 736ab7a3f52SSteven Rostedt return $ret; 737ab7a3f52SSteven Rostedt } 738ab7a3f52SSteven Rostedt 7399900b5dcSSteven Rostedt if ($val =~ /^\s*(NOT\s*)?DEFINED\s+(\S+)\s*$/) { 7409900b5dcSSteven Rostedt if (defined $1) { 7419900b5dcSSteven Rostedt return !value_defined($2); 7429900b5dcSSteven Rostedt } else { 7439900b5dcSSteven Rostedt return value_defined($2); 7449900b5dcSSteven Rostedt } 7459900b5dcSSteven Rostedt } 7469900b5dcSSteven Rostedt 74745d73a5dSSteven Rostedt if ($val =~ /^\s*0\s*$/) { 74845d73a5dSSteven Rostedt return 0; 74945d73a5dSSteven Rostedt } elsif ($val =~ /^\s*\d+\s*$/) { 75045d73a5dSSteven Rostedt return 1; 75145d73a5dSSteven Rostedt } 75245d73a5dSSteven Rostedt 7539900b5dcSSteven Rostedt die ("$name: $.: Undefined content $val in if statement\n"); 7548d735212SSteven Rostedt} 7558d735212SSteven Rostedt 7568d735212SSteven Rostedtsub process_if { 7578d735212SSteven Rostedt my ($name, $value) = @_; 7588d735212SSteven Rostedt 7598d735212SSteven Rostedt # Convert variables and replace undefined ones with 0 7608d735212SSteven Rostedt my $val = process_variables($value, 1); 7618d735212SSteven Rostedt my $ret = process_expression $name, $val; 7628d735212SSteven Rostedt 7638d735212SSteven Rostedt return $ret; 76445d73a5dSSteven Rostedt} 76545d73a5dSSteven Rostedt 7662ed3b161SSteven Rostedtsub __read_config { 7672ed3b161SSteven Rostedt my ($config, $current_test_num) = @_; 768a57419b3SSteven Rostedt 7692ed3b161SSteven Rostedt my $in; 7702ed3b161SSteven Rostedt open($in, $config) || die "can't read file $config"; 771a57419b3SSteven Rostedt 772a57419b3SSteven Rostedt my $name = $config; 773a57419b3SSteven Rostedt $name =~ s,.*/(.*),$1,; 774a57419b3SSteven Rostedt 7752ed3b161SSteven Rostedt my $test_num = $$current_test_num; 776a57419b3SSteven Rostedt my $default = 1; 777a57419b3SSteven Rostedt my $repeat = 1; 778a57419b3SSteven Rostedt my $num_tests_set = 0; 779a57419b3SSteven Rostedt my $skip = 0; 780a57419b3SSteven Rostedt my $rest; 781a9f84424SSteven Rostedt my $line; 7820df213caSSteven Rostedt my $test_case = 0; 78345d73a5dSSteven Rostedt my $if = 0; 78445d73a5dSSteven Rostedt my $if_set = 0; 7853d1cc414SSteven Rostedt my $override = 0; 7863d1cc414SSteven Rostedt 7873d1cc414SSteven Rostedt my %overrides; 788a57419b3SSteven Rostedt 7892ed3b161SSteven Rostedt while (<$in>) { 790a57419b3SSteven Rostedt 791a57419b3SSteven Rostedt # ignore blank lines and comments 792a57419b3SSteven Rostedt next if (/^\s*$/ || /\s*\#/); 793a57419b3SSteven Rostedt 7940050b6bbSSteven Rostedt if (/^\s*(TEST_START|DEFAULTS)\b(.*)/) { 795a57419b3SSteven Rostedt 7960050b6bbSSteven Rostedt my $type = $1; 7970050b6bbSSteven Rostedt $rest = $2; 798a9f84424SSteven Rostedt $line = $2; 7990050b6bbSSteven Rostedt 8000050b6bbSSteven Rostedt my $old_test_num; 8010050b6bbSSteven Rostedt my $old_repeat; 8023d1cc414SSteven Rostedt $override = 0; 8030050b6bbSSteven Rostedt 8040050b6bbSSteven Rostedt if ($type eq "TEST_START") { 805a57419b3SSteven Rostedt 806a57419b3SSteven Rostedt if ($num_tests_set) { 807a57419b3SSteven Rostedt die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n"; 808a57419b3SSteven Rostedt } 809a57419b3SSteven Rostedt 8100050b6bbSSteven Rostedt $old_test_num = $test_num; 8110050b6bbSSteven Rostedt $old_repeat = $repeat; 812a57419b3SSteven Rostedt 813a57419b3SSteven Rostedt $test_num += $repeat; 814a57419b3SSteven Rostedt $default = 0; 815a57419b3SSteven Rostedt $repeat = 1; 8160050b6bbSSteven Rostedt } else { 8170050b6bbSSteven Rostedt $default = 1; 8180050b6bbSSteven Rostedt } 819a57419b3SSteven Rostedt 820a9f84424SSteven Rostedt # If SKIP is anywhere in the line, the command will be skipped 821a9f84424SSteven Rostedt if ($rest =~ s/\s+SKIP\b//) { 822a57419b3SSteven Rostedt $skip = 1; 823a57419b3SSteven Rostedt } else { 8240df213caSSteven Rostedt $test_case = 1; 825a57419b3SSteven Rostedt $skip = 0; 826a57419b3SSteven Rostedt } 827a57419b3SSteven Rostedt 828a9f84424SSteven Rostedt if ($rest =~ s/\sELSE\b//) { 829a9f84424SSteven Rostedt if (!$if) { 830a9f84424SSteven Rostedt die "$name: $.: ELSE found with out matching IF section\n$_"; 831a57419b3SSteven Rostedt } 832a9f84424SSteven Rostedt $if = 0; 833a9f84424SSteven Rostedt 834a9f84424SSteven Rostedt if ($if_set) { 835a9f84424SSteven Rostedt $skip = 1; 836a9f84424SSteven Rostedt } else { 837a9f84424SSteven Rostedt $skip = 0; 8383d1cc414SSteven Rostedt } 8393d1cc414SSteven Rostedt } 840a57419b3SSteven Rostedt 841a9f84424SSteven Rostedt if ($rest =~ s/\sIF\s+(.*)//) { 84245d73a5dSSteven Rostedt if (process_if($name, $1)) { 84345d73a5dSSteven Rostedt $if_set = 1; 84445d73a5dSSteven Rostedt } else { 845a57419b3SSteven Rostedt $skip = 1; 846a57419b3SSteven Rostedt } 84745d73a5dSSteven Rostedt $if = 1; 84845d73a5dSSteven Rostedt } else { 84945d73a5dSSteven Rostedt $if = 0; 850a9f84424SSteven Rostedt $if_set = 0; 85145d73a5dSSteven Rostedt } 852a57419b3SSteven Rostedt 853a9f84424SSteven Rostedt if (!$skip) { 854a9f84424SSteven Rostedt if ($type eq "TEST_START") { 855a9f84424SSteven Rostedt if ($rest =~ s/\s+ITERATE\s+(\d+)//) { 856a9f84424SSteven Rostedt $repeat = $1; 857a9f84424SSteven Rostedt $repeat_tests{"$test_num"} = $repeat; 858a9f84424SSteven Rostedt } 859a9f84424SSteven Rostedt } elsif ($rest =~ s/\sOVERRIDE\b//) { 860a9f84424SSteven Rostedt # DEFAULT only 861a9f84424SSteven Rostedt $override = 1; 862a9f84424SSteven Rostedt # Clear previous overrides 863a9f84424SSteven Rostedt %overrides = (); 864a9f84424SSteven Rostedt } 865a9f84424SSteven Rostedt } 866a9f84424SSteven Rostedt 867a9f84424SSteven Rostedt if (!$skip && $rest !~ /^\s*$/) { 8680050b6bbSSteven Rostedt die "$name: $.: Gargbage found after $type\n$_"; 869a57419b3SSteven Rostedt } 870a57419b3SSteven Rostedt 8710050b6bbSSteven Rostedt if ($skip && $type eq "TEST_START") { 872a57419b3SSteven Rostedt $test_num = $old_test_num; 873e48c5293SSteven Rostedt $repeat = $old_repeat; 874a57419b3SSteven Rostedt } 875a57419b3SSteven Rostedt 876ab7a3f52SSteven Rostedt } elsif (/^\s*ELSE\b(.*)$/) { 87745d73a5dSSteven Rostedt if (!$if) { 87845d73a5dSSteven Rostedt die "$name: $.: ELSE found with out matching IF section\n$_"; 87945d73a5dSSteven Rostedt } 88045d73a5dSSteven Rostedt $rest = $1; 88145d73a5dSSteven Rostedt if ($if_set) { 88245d73a5dSSteven Rostedt $skip = 1; 883ab7a3f52SSteven Rostedt $rest = ""; 88445d73a5dSSteven Rostedt } else { 88545d73a5dSSteven Rostedt $skip = 0; 88645d73a5dSSteven Rostedt 887ab7a3f52SSteven Rostedt if ($rest =~ /\sIF\s+(.*)/) { 88845d73a5dSSteven Rostedt # May be a ELSE IF section. 88995f57838SSteven Rostedt if (process_if($name, $1)) { 89095f57838SSteven Rostedt $if_set = 1; 89195f57838SSteven Rostedt } else { 89245d73a5dSSteven Rostedt $skip = 1; 89345d73a5dSSteven Rostedt } 894ab7a3f52SSteven Rostedt $rest = ""; 89545d73a5dSSteven Rostedt } else { 89645d73a5dSSteven Rostedt $if = 0; 89745d73a5dSSteven Rostedt } 89845d73a5dSSteven Rostedt } 89945d73a5dSSteven Rostedt 900ab7a3f52SSteven Rostedt if ($rest !~ /^\s*$/) { 901ab7a3f52SSteven Rostedt die "$name: $.: Gargbage found after DEFAULTS\n$_"; 902ab7a3f52SSteven Rostedt } 903ab7a3f52SSteven Rostedt 9042ed3b161SSteven Rostedt } elsif (/^\s*INCLUDE\s+(\S+)/) { 9052ed3b161SSteven Rostedt 9062ed3b161SSteven Rostedt next if ($skip); 9072ed3b161SSteven Rostedt 9082ed3b161SSteven Rostedt if (!$default) { 9092ed3b161SSteven Rostedt die "$name: $.: INCLUDE can only be done in default sections\n$_"; 9102ed3b161SSteven Rostedt } 9112ed3b161SSteven Rostedt 9122ed3b161SSteven Rostedt my $file = process_variables($1); 9132ed3b161SSteven Rostedt 9142ed3b161SSteven Rostedt if ($file !~ m,^/,) { 9152ed3b161SSteven Rostedt # check the path of the config file first 9162ed3b161SSteven Rostedt if ($config =~ m,(.*)/,) { 9172ed3b161SSteven Rostedt if (-f "$1/$file") { 9182ed3b161SSteven Rostedt $file = "$1/$file"; 9192ed3b161SSteven Rostedt } 9202ed3b161SSteven Rostedt } 9212ed3b161SSteven Rostedt } 9222ed3b161SSteven Rostedt 9232ed3b161SSteven Rostedt if ( ! -r $file ) { 9242ed3b161SSteven Rostedt die "$name: $.: Can't read file $file\n$_"; 9252ed3b161SSteven Rostedt } 9262ed3b161SSteven Rostedt 9272ed3b161SSteven Rostedt if (__read_config($file, \$test_num)) { 9282ed3b161SSteven Rostedt $test_case = 1; 9292ed3b161SSteven Rostedt } 9302ed3b161SSteven Rostedt 931a57419b3SSteven Rostedt } elsif (/^\s*([A-Z_\[\]\d]+)\s*=\s*(.*?)\s*$/) { 932a57419b3SSteven Rostedt 933a57419b3SSteven Rostedt next if ($skip); 934a57419b3SSteven Rostedt 935a57419b3SSteven Rostedt my $lvalue = $1; 936a57419b3SSteven Rostedt my $rvalue = $2; 937a57419b3SSteven Rostedt 938a57419b3SSteven Rostedt if (!$default && 939a57419b3SSteven Rostedt ($lvalue eq "NUM_TESTS" || 940a57419b3SSteven Rostedt $lvalue eq "LOG_FILE" || 941a57419b3SSteven Rostedt $lvalue eq "CLEAR_LOG")) { 942a57419b3SSteven Rostedt die "$name: $.: $lvalue must be set in DEFAULTS section\n"; 943a57419b3SSteven Rostedt } 944a57419b3SSteven Rostedt 945a57419b3SSteven Rostedt if ($lvalue eq "NUM_TESTS") { 946a57419b3SSteven Rostedt if ($test_num) { 947a57419b3SSteven Rostedt die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n"; 948a57419b3SSteven Rostedt } 949a57419b3SSteven Rostedt if (!$default) { 950a57419b3SSteven Rostedt die "$name: $.: NUM_TESTS must be set in default section\n"; 951a57419b3SSteven Rostedt } 952a57419b3SSteven Rostedt $num_tests_set = 1; 953a57419b3SSteven Rostedt } 954a57419b3SSteven Rostedt 955a57419b3SSteven Rostedt if ($default || $lvalue =~ /\[\d+\]$/) { 9563d1cc414SSteven Rostedt set_value($lvalue, $rvalue, $override, \%overrides, $name); 957a57419b3SSteven Rostedt } else { 958a57419b3SSteven Rostedt my $val = "$lvalue\[$test_num\]"; 9593d1cc414SSteven Rostedt set_value($val, $rvalue, $override, \%overrides, $name); 960a57419b3SSteven Rostedt 961a57419b3SSteven Rostedt if ($repeat > 1) { 962a57419b3SSteven Rostedt $repeats{$val} = $repeat; 963a57419b3SSteven Rostedt } 964a57419b3SSteven Rostedt } 96577d942ceSSteven Rostedt } elsif (/^\s*([A-Z_\[\]\d]+)\s*:=\s*(.*?)\s*$/) { 96677d942ceSSteven Rostedt next if ($skip); 96777d942ceSSteven Rostedt 96877d942ceSSteven Rostedt my $lvalue = $1; 96977d942ceSSteven Rostedt my $rvalue = $2; 97077d942ceSSteven Rostedt 97177d942ceSSteven Rostedt # process config variables. 97277d942ceSSteven Rostedt # Config variables are only active while reading the 97377d942ceSSteven Rostedt # config and can be defined anywhere. They also ignore 97477d942ceSSteven Rostedt # TEST_START and DEFAULTS, but are skipped if they are in 97577d942ceSSteven Rostedt # on of these sections that have SKIP defined. 97677d942ceSSteven Rostedt # The save variable can be 97777d942ceSSteven Rostedt # defined multiple times and the new one simply overrides 97877d942ceSSteven Rostedt # the prevous one. 97977d942ceSSteven Rostedt set_variable($lvalue, $rvalue); 98077d942ceSSteven Rostedt 981a57419b3SSteven Rostedt } else { 982a57419b3SSteven Rostedt die "$name: $.: Garbage found in config\n$_"; 983a57419b3SSteven Rostedt } 9842545eb61SSteven Rostedt } 9852545eb61SSteven Rostedt 986a57419b3SSteven Rostedt if ($test_num) { 987a57419b3SSteven Rostedt $test_num += $repeat - 1; 988a57419b3SSteven Rostedt $opt{"NUM_TESTS"} = $test_num; 989a57419b3SSteven Rostedt } 990a57419b3SSteven Rostedt 9912ed3b161SSteven Rostedt close($in); 9922ed3b161SSteven Rostedt 9932ed3b161SSteven Rostedt $$current_test_num = $test_num; 9942ed3b161SSteven Rostedt 9952ed3b161SSteven Rostedt return $test_case; 9962ed3b161SSteven Rostedt} 9972ed3b161SSteven Rostedt 998c4261d0fSSteven Rostedtsub get_test_case { 999c4261d0fSSteven Rostedt print "What test case would you like to run?\n"; 1000c4261d0fSSteven Rostedt print " (build, install or boot)\n"; 1001c4261d0fSSteven Rostedt print " Other tests are available but require editing the config file\n"; 1002c4261d0fSSteven Rostedt my $ans = <STDIN>; 1003c4261d0fSSteven Rostedt chomp $ans; 1004c4261d0fSSteven Rostedt $default{"TEST_TYPE"} = $ans; 1005c4261d0fSSteven Rostedt} 1006c4261d0fSSteven Rostedt 10072ed3b161SSteven Rostedtsub read_config { 10082ed3b161SSteven Rostedt my ($config) = @_; 10092ed3b161SSteven Rostedt 10102ed3b161SSteven Rostedt my $test_case; 10112ed3b161SSteven Rostedt my $test_num = 0; 10122ed3b161SSteven Rostedt 10132ed3b161SSteven Rostedt $test_case = __read_config $config, \$test_num; 10142ed3b161SSteven Rostedt 10158d1491baSSteven Rostedt # make sure we have all mandatory configs 10168d1491baSSteven Rostedt get_ktest_configs; 10178d1491baSSteven Rostedt 10180df213caSSteven Rostedt # was a test specified? 10190df213caSSteven Rostedt if (!$test_case) { 10200df213caSSteven Rostedt print "No test case specified.\n"; 1021c4261d0fSSteven Rostedt get_test_case; 10220df213caSSteven Rostedt } 10230df213caSSteven Rostedt 1024a75fececSSteven Rostedt # set any defaults 1025a75fececSSteven Rostedt 1026a75fececSSteven Rostedt foreach my $default (keys %default) { 1027a75fececSSteven Rostedt if (!defined($opt{$default})) { 1028a75fececSSteven Rostedt $opt{$default} = $default{$default}; 1029a75fececSSteven Rostedt } 1030a75fececSSteven Rostedt } 10319cc9e091SSteven Rostedt 10329cc9e091SSteven Rostedt if ($opt{"IGNORE_UNUSED"} == 1) { 10339cc9e091SSteven Rostedt return; 10349cc9e091SSteven Rostedt } 10359cc9e091SSteven Rostedt 10369cc9e091SSteven Rostedt my %not_used; 10379cc9e091SSteven Rostedt 10389cc9e091SSteven Rostedt # check if there are any stragglers (typos?) 10399cc9e091SSteven Rostedt foreach my $option (keys %opt) { 10409cc9e091SSteven Rostedt my $op = $option; 10419cc9e091SSteven Rostedt # remove per test labels. 10429cc9e091SSteven Rostedt $op =~ s/\[.*\]//; 10439cc9e091SSteven Rostedt if (!exists($option_map{$op}) && 10449cc9e091SSteven Rostedt !exists($default{$op}) && 10459cc9e091SSteven Rostedt !exists($used_options{$op})) { 10469cc9e091SSteven Rostedt $not_used{$op} = 1; 10479cc9e091SSteven Rostedt } 10489cc9e091SSteven Rostedt } 10499cc9e091SSteven Rostedt 10509cc9e091SSteven Rostedt if (%not_used) { 10519cc9e091SSteven Rostedt my $s = "s are"; 10529cc9e091SSteven Rostedt $s = " is" if (keys %not_used == 1); 10539cc9e091SSteven Rostedt print "The following option$s not used; could be a typo:\n"; 10549cc9e091SSteven Rostedt foreach my $option (keys %not_used) { 10559cc9e091SSteven Rostedt print "$option\n"; 10569cc9e091SSteven Rostedt } 10579cc9e091SSteven Rostedt print "Set IGRNORE_UNUSED = 1 to have ktest ignore unused variables\n"; 10589cc9e091SSteven Rostedt if (!read_yn "Do you want to continue?") { 10599cc9e091SSteven Rostedt exit -1; 10609cc9e091SSteven Rostedt } 10619cc9e091SSteven Rostedt } 10622545eb61SSteven Rostedt} 10632545eb61SSteven Rostedt 106423715c3cSSteven Rostedtsub __eval_option { 106523715c3cSSteven Rostedt my ($option, $i) = @_; 106623715c3cSSteven Rostedt 106723715c3cSSteven Rostedt # Add space to evaluate the character before $ 106823715c3cSSteven Rostedt $option = " $option"; 106923715c3cSSteven Rostedt my $retval = ""; 1070f9dfb65bSRabin Vincent my $repeated = 0; 1071f9dfb65bSRabin Vincent my $parent = 0; 1072f9dfb65bSRabin Vincent 1073f9dfb65bSRabin Vincent foreach my $test (keys %repeat_tests) { 1074f9dfb65bSRabin Vincent if ($i >= $test && 1075f9dfb65bSRabin Vincent $i < $test + $repeat_tests{$test}) { 1076f9dfb65bSRabin Vincent 1077f9dfb65bSRabin Vincent $repeated = 1; 1078f9dfb65bSRabin Vincent $parent = $test; 1079f9dfb65bSRabin Vincent last; 1080f9dfb65bSRabin Vincent } 1081f9dfb65bSRabin Vincent } 108223715c3cSSteven Rostedt 108323715c3cSSteven Rostedt while ($option =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) { 108423715c3cSSteven Rostedt my $start = $1; 108523715c3cSSteven Rostedt my $var = $2; 108623715c3cSSteven Rostedt my $end = $3; 108723715c3cSSteven Rostedt 108823715c3cSSteven Rostedt # Append beginning of line 108923715c3cSSteven Rostedt $retval = "$retval$start"; 109023715c3cSSteven Rostedt 109123715c3cSSteven Rostedt # If the iteration option OPT[$i] exists, then use that. 109223715c3cSSteven Rostedt # otherwise see if the default OPT (without [$i]) exists. 109323715c3cSSteven Rostedt 109423715c3cSSteven Rostedt my $o = "$var\[$i\]"; 1095f9dfb65bSRabin Vincent my $parento = "$var\[$parent\]"; 109623715c3cSSteven Rostedt 109723715c3cSSteven Rostedt if (defined($opt{$o})) { 109823715c3cSSteven Rostedt $o = $opt{$o}; 109923715c3cSSteven Rostedt $retval = "$retval$o"; 1100f9dfb65bSRabin Vincent } elsif ($repeated && defined($opt{$parento})) { 1101f9dfb65bSRabin Vincent $o = $opt{$parento}; 1102f9dfb65bSRabin Vincent $retval = "$retval$o"; 110323715c3cSSteven Rostedt } elsif (defined($opt{$var})) { 110423715c3cSSteven Rostedt $o = $opt{$var}; 110523715c3cSSteven Rostedt $retval = "$retval$o"; 110623715c3cSSteven Rostedt } else { 110723715c3cSSteven Rostedt $retval = "$retval\$\{$var\}"; 110823715c3cSSteven Rostedt } 110923715c3cSSteven Rostedt 111023715c3cSSteven Rostedt $option = $end; 111123715c3cSSteven Rostedt } 111223715c3cSSteven Rostedt 111323715c3cSSteven Rostedt $retval = "$retval$option"; 111423715c3cSSteven Rostedt 111523715c3cSSteven Rostedt $retval =~ s/^ //; 111623715c3cSSteven Rostedt 111723715c3cSSteven Rostedt return $retval; 111823715c3cSSteven Rostedt} 111923715c3cSSteven Rostedt 112023715c3cSSteven Rostedtsub eval_option { 112123715c3cSSteven Rostedt my ($option, $i) = @_; 112223715c3cSSteven Rostedt 112323715c3cSSteven Rostedt my $prev = ""; 112423715c3cSSteven Rostedt 112523715c3cSSteven Rostedt # Since an option can evaluate to another option, 112623715c3cSSteven Rostedt # keep iterating until we do not evaluate any more 112723715c3cSSteven Rostedt # options. 112823715c3cSSteven Rostedt my $r = 0; 112923715c3cSSteven Rostedt while ($prev ne $option) { 113023715c3cSSteven Rostedt # Check for recursive evaluations. 113123715c3cSSteven Rostedt # 100 deep should be more than enough. 113223715c3cSSteven Rostedt if ($r++ > 100) { 113323715c3cSSteven Rostedt die "Over 100 evaluations accurred with $option\n" . 113423715c3cSSteven Rostedt "Check for recursive variables\n"; 113523715c3cSSteven Rostedt } 113623715c3cSSteven Rostedt $prev = $option; 113723715c3cSSteven Rostedt $option = __eval_option($option, $i); 113823715c3cSSteven Rostedt } 113923715c3cSSteven Rostedt 114023715c3cSSteven Rostedt return $option; 114123715c3cSSteven Rostedt} 114223715c3cSSteven Rostedt 1143d1e2f22aSSteven Rostedtsub _logit { 11442545eb61SSteven Rostedt if (defined($opt{"LOG_FILE"})) { 11452545eb61SSteven Rostedt open(OUT, ">> $opt{LOG_FILE}") or die "Can't write to $opt{LOG_FILE}"; 11462545eb61SSteven Rostedt print OUT @_; 11472545eb61SSteven Rostedt close(OUT); 11482545eb61SSteven Rostedt } 11492545eb61SSteven Rostedt} 11502545eb61SSteven Rostedt 1151d1e2f22aSSteven Rostedtsub logit { 1152d1e2f22aSSteven Rostedt if (defined($opt{"LOG_FILE"})) { 1153d1e2f22aSSteven Rostedt _logit @_; 1154d1e2f22aSSteven Rostedt } else { 1155d1e2f22aSSteven Rostedt print @_; 1156d1e2f22aSSteven Rostedt } 1157d1e2f22aSSteven Rostedt} 1158d1e2f22aSSteven Rostedt 11595f9b6cedSSteven Rostedtsub doprint { 11605f9b6cedSSteven Rostedt print @_; 1161d1e2f22aSSteven Rostedt _logit @_; 11625f9b6cedSSteven Rostedt} 11635f9b6cedSSteven Rostedt 11647faafbd6SSteven Rostedtsub run_command; 11652728be41SAndrew Jonessub start_monitor; 11662728be41SAndrew Jonessub end_monitor; 11672728be41SAndrew Jonessub wait_for_monitor; 11687faafbd6SSteven Rostedt 11697faafbd6SSteven Rostedtsub reboot { 11702728be41SAndrew Jones my ($time) = @_; 11712728be41SAndrew Jones 1172a4968722SSteven Rostedt # Make sure everything has been written to disk 1173a4968722SSteven Rostedt run_ssh("sync"); 1174a4968722SSteven Rostedt 11752b803365SSteven Rostedt if (defined($time)) { 11762b803365SSteven Rostedt start_monitor; 11772b803365SSteven Rostedt # flush out current monitor 11782b803365SSteven Rostedt # May contain the reboot success line 11792b803365SSteven Rostedt wait_for_monitor 1; 11802b803365SSteven Rostedt } 11812b803365SSteven Rostedt 11827faafbd6SSteven Rostedt # try to reboot normally 1183e48c5293SSteven Rostedt if (run_command $reboot) { 1184576f627cSSteven Rostedt if (defined($powercycle_after_reboot)) { 1185576f627cSSteven Rostedt sleep $powercycle_after_reboot; 1186576f627cSSteven Rostedt run_command "$power_cycle"; 1187576f627cSSteven Rostedt } 1188576f627cSSteven Rostedt } else { 11897faafbd6SSteven Rostedt # nope? power cycle it. 1190a75fececSSteven Rostedt run_command "$power_cycle"; 11917faafbd6SSteven Rostedt } 11922728be41SAndrew Jones 11932728be41SAndrew Jones if (defined($time)) { 1194407b95b7SSteven Rostedt if (wait_for_monitor($time, $reboot_success_line)) { 1195407b95b7SSteven Rostedt # reboot got stuck? 11968a80c727SSteven Rostedt doprint "Reboot did not finish. Forcing power cycle\n"; 1197407b95b7SSteven Rostedt run_command "$power_cycle"; 1198407b95b7SSteven Rostedt } 11992728be41SAndrew Jones end_monitor; 12002728be41SAndrew Jones } 12017faafbd6SSteven Rostedt} 12027faafbd6SSteven Rostedt 1203bc7c5803SSteven Rostedtsub reboot_to_good { 1204bc7c5803SSteven Rostedt my ($time) = @_; 1205bc7c5803SSteven Rostedt 1206bc7c5803SSteven Rostedt if (defined($switch_to_good)) { 1207bc7c5803SSteven Rostedt run_command $switch_to_good; 1208bc7c5803SSteven Rostedt } 1209bc7c5803SSteven Rostedt 1210bc7c5803SSteven Rostedt reboot $time; 1211bc7c5803SSteven Rostedt} 1212bc7c5803SSteven Rostedt 1213576f627cSSteven Rostedtsub do_not_reboot { 1214576f627cSSteven Rostedt my $i = $iteration; 1215576f627cSSteven Rostedt 12164ab1cce5SSteven Rostedt return $test_type eq "build" || $no_reboot || 1217576f627cSSteven Rostedt ($test_type eq "patchcheck" && $opt{"PATCHCHECK_TYPE[$i]"} eq "build") || 1218576f627cSSteven Rostedt ($test_type eq "bisect" && $opt{"BISECT_TYPE[$i]"} eq "build"); 1219576f627cSSteven Rostedt} 1220576f627cSSteven Rostedt 12215c42fc5bSSteven Rostedtsub dodie { 12225a391fbfSSteven Rostedt doprint "CRITICAL FAILURE... ", @_, "\n"; 12235c42fc5bSSteven Rostedt 1224576f627cSSteven Rostedt my $i = $iteration; 1225576f627cSSteven Rostedt 1226576f627cSSteven Rostedt if ($reboot_on_error && !do_not_reboot) { 1227576f627cSSteven Rostedt 122875c3fda7SSteven Rostedt doprint "REBOOTING\n"; 1229bc7c5803SSteven Rostedt reboot_to_good; 123075c3fda7SSteven Rostedt 1231a75fececSSteven Rostedt } elsif ($poweroff_on_error && defined($power_off)) { 12325c42fc5bSSteven Rostedt doprint "POWERING OFF\n"; 1233a75fececSSteven Rostedt `$power_off`; 12345c42fc5bSSteven Rostedt } 123575c3fda7SSteven Rostedt 1236f80802cbSSteven Rostedt if (defined($opt{"LOG_FILE"})) { 1237f80802cbSSteven Rostedt print " See $opt{LOG_FILE} for more info.\n"; 1238f80802cbSSteven Rostedt } 1239f80802cbSSteven Rostedt 1240576f627cSSteven Rostedt die @_, "\n"; 12415c42fc5bSSteven Rostedt} 12425c42fc5bSSteven Rostedt 12437faafbd6SSteven Rostedtsub open_console { 12447faafbd6SSteven Rostedt my ($fp) = @_; 12457faafbd6SSteven Rostedt 12467faafbd6SSteven Rostedt my $flags; 12477faafbd6SSteven Rostedt 1248a75fececSSteven Rostedt my $pid = open($fp, "$console|") or 1249a75fececSSteven Rostedt dodie "Can't open console $console"; 12507faafbd6SSteven Rostedt 12517faafbd6SSteven Rostedt $flags = fcntl($fp, F_GETFL, 0) or 1252576f627cSSteven Rostedt dodie "Can't get flags for the socket: $!"; 12537faafbd6SSteven Rostedt $flags = fcntl($fp, F_SETFL, $flags | O_NONBLOCK) or 1254576f627cSSteven Rostedt dodie "Can't set flags for the socket: $!"; 12557faafbd6SSteven Rostedt 12567faafbd6SSteven Rostedt return $pid; 12577faafbd6SSteven Rostedt} 12587faafbd6SSteven Rostedt 12597faafbd6SSteven Rostedtsub close_console { 12607faafbd6SSteven Rostedt my ($fp, $pid) = @_; 12617faafbd6SSteven Rostedt 12627faafbd6SSteven Rostedt doprint "kill child process $pid\n"; 12637faafbd6SSteven Rostedt kill 2, $pid; 12647faafbd6SSteven Rostedt 12657faafbd6SSteven Rostedt print "closing!\n"; 12667faafbd6SSteven Rostedt close($fp); 12677faafbd6SSteven Rostedt} 12687faafbd6SSteven Rostedt 12697faafbd6SSteven Rostedtsub start_monitor { 12707faafbd6SSteven Rostedt if ($monitor_cnt++) { 12717faafbd6SSteven Rostedt return; 12727faafbd6SSteven Rostedt } 12737faafbd6SSteven Rostedt $monitor_fp = \*MONFD; 12747faafbd6SSteven Rostedt $monitor_pid = open_console $monitor_fp; 1275a75fececSSteven Rostedt 1276a75fececSSteven Rostedt return; 1277a75fececSSteven Rostedt 1278a75fececSSteven Rostedt open(MONFD, "Stop perl from warning about single use of MONFD"); 12797faafbd6SSteven Rostedt} 12807faafbd6SSteven Rostedt 12817faafbd6SSteven Rostedtsub end_monitor { 12827faafbd6SSteven Rostedt if (--$monitor_cnt) { 12837faafbd6SSteven Rostedt return; 12847faafbd6SSteven Rostedt } 12857faafbd6SSteven Rostedt close_console($monitor_fp, $monitor_pid); 12867faafbd6SSteven Rostedt} 12877faafbd6SSteven Rostedt 12887faafbd6SSteven Rostedtsub wait_for_monitor { 12892b803365SSteven Rostedt my ($time, $stop) = @_; 12902b803365SSteven Rostedt my $full_line = ""; 12917faafbd6SSteven Rostedt my $line; 12922b803365SSteven Rostedt my $booted = 0; 1293407b95b7SSteven Rostedt my $start_time = time; 12948a80c727SSteven Rostedt my $skip_call_trace = 0; 12958a80c727SSteven Rostedt my $bug = 0; 12968a80c727SSteven Rostedt my $bug_ignored = 0; 1297407b95b7SSteven Rostedt my $now; 12987faafbd6SSteven Rostedt 1299a75fececSSteven Rostedt doprint "** Wait for monitor to settle down **\n"; 13007faafbd6SSteven Rostedt 13017faafbd6SSteven Rostedt # read the monitor and wait for the system to calm down 13022b803365SSteven Rostedt while (!$booted) { 13037faafbd6SSteven Rostedt $line = wait_for_input($monitor_fp, $time); 13042b803365SSteven Rostedt last if (!defined($line)); 13052b803365SSteven Rostedt print "$line"; 13062b803365SSteven Rostedt $full_line .= $line; 13072b803365SSteven Rostedt 13082b803365SSteven Rostedt if (defined($stop) && $full_line =~ /$stop/) { 13092b803365SSteven Rostedt doprint "wait for monitor detected $stop\n"; 13102b803365SSteven Rostedt $booted = 1; 13112b803365SSteven Rostedt } 13122b803365SSteven Rostedt 13138a80c727SSteven Rostedt if ($full_line =~ /\[ backtrace testing \]/) { 13148a80c727SSteven Rostedt $skip_call_trace = 1; 13158a80c727SSteven Rostedt } 13168a80c727SSteven Rostedt 13178a80c727SSteven Rostedt if ($full_line =~ /call trace:/i) { 13188a80c727SSteven Rostedt if (!$bug && !$skip_call_trace) { 13198a80c727SSteven Rostedt if ($ignore_errors) { 13208a80c727SSteven Rostedt $bug_ignored = 1; 13218a80c727SSteven Rostedt } else { 13228a80c727SSteven Rostedt $bug = 1; 13238a80c727SSteven Rostedt } 13248a80c727SSteven Rostedt } 13258a80c727SSteven Rostedt } 13268a80c727SSteven Rostedt 13278a80c727SSteven Rostedt if ($full_line =~ /\[ end of backtrace testing \]/) { 13288a80c727SSteven Rostedt $skip_call_trace = 0; 13298a80c727SSteven Rostedt } 13308a80c727SSteven Rostedt 13318a80c727SSteven Rostedt if ($full_line =~ /Kernel panic -/) { 13328a80c727SSteven Rostedt $bug = 1; 13338a80c727SSteven Rostedt } 13348a80c727SSteven Rostedt 13352b803365SSteven Rostedt if ($line =~ /\n/) { 13362b803365SSteven Rostedt $full_line = ""; 13372b803365SSteven Rostedt } 1338407b95b7SSteven Rostedt $now = time; 1339407b95b7SSteven Rostedt if ($now - $start_time >= $max_monitor_wait) { 1340407b95b7SSteven Rostedt doprint "Exiting monitor flush due to hitting MAX_MONITOR_WAIT\n"; 1341407b95b7SSteven Rostedt return 1; 1342407b95b7SSteven Rostedt } 13432b803365SSteven Rostedt } 1344a75fececSSteven Rostedt print "** Monitor flushed **\n"; 13458a80c727SSteven Rostedt return $bug; 13467faafbd6SSteven Rostedt} 13477faafbd6SSteven Rostedt 1348de5b6e3bSRabin Vincentsub save_logs { 1349de5b6e3bSRabin Vincent my ($result, $basedir) = @_; 1350de5b6e3bSRabin Vincent my @t = localtime; 1351de5b6e3bSRabin Vincent my $date = sprintf "%04d%02d%02d%02d%02d%02d", 1352de5b6e3bSRabin Vincent 1900+$t[5],$t[4],$t[3],$t[2],$t[1],$t[0]; 1353de5b6e3bSRabin Vincent 1354de5b6e3bSRabin Vincent my $type = $build_type; 1355de5b6e3bSRabin Vincent if ($type =~ /useconfig/) { 1356de5b6e3bSRabin Vincent $type = "useconfig"; 1357de5b6e3bSRabin Vincent } 1358de5b6e3bSRabin Vincent 1359de5b6e3bSRabin Vincent my $dir = "$machine-$test_type-$type-$result-$date"; 1360de5b6e3bSRabin Vincent 1361de5b6e3bSRabin Vincent $dir = "$basedir/$dir"; 1362de5b6e3bSRabin Vincent 1363de5b6e3bSRabin Vincent if (!-d $dir) { 1364de5b6e3bSRabin Vincent mkpath($dir) or 1365de5b6e3bSRabin Vincent die "can't create $dir"; 1366de5b6e3bSRabin Vincent } 1367de5b6e3bSRabin Vincent 1368de5b6e3bSRabin Vincent my %files = ( 1369de5b6e3bSRabin Vincent "config" => $output_config, 1370de5b6e3bSRabin Vincent "buildlog" => $buildlog, 1371de5b6e3bSRabin Vincent "dmesg" => $dmesg, 1372de5b6e3bSRabin Vincent "testlog" => $testlog, 1373de5b6e3bSRabin Vincent ); 1374de5b6e3bSRabin Vincent 1375de5b6e3bSRabin Vincent while (my ($name, $source) = each(%files)) { 1376de5b6e3bSRabin Vincent if (-f "$source") { 1377de5b6e3bSRabin Vincent cp "$source", "$dir/$name" or 1378de5b6e3bSRabin Vincent die "failed to copy $source"; 1379de5b6e3bSRabin Vincent } 1380de5b6e3bSRabin Vincent } 1381de5b6e3bSRabin Vincent 1382de5b6e3bSRabin Vincent doprint "*** Saved info to $dir ***\n"; 1383de5b6e3bSRabin Vincent} 1384de5b6e3bSRabin Vincent 13852b7d9b21SSteven Rostedtsub fail { 13862b7d9b21SSteven Rostedt 1387921ed4c7SSteven Rostedt if (defined($post_test)) { 1388921ed4c7SSteven Rostedt run_command $post_test; 1389921ed4c7SSteven Rostedt } 1390921ed4c7SSteven Rostedt 1391a75fececSSteven Rostedt if ($die_on_failure) { 13922b7d9b21SSteven Rostedt dodie @_; 13932b7d9b21SSteven Rostedt } 13942b7d9b21SSteven Rostedt 1395a75fececSSteven Rostedt doprint "FAILED\n"; 13967faafbd6SSteven Rostedt 1397576f627cSSteven Rostedt my $i = $iteration; 1398576f627cSSteven Rostedt 1399a75fececSSteven Rostedt # no need to reboot for just building. 1400576f627cSSteven Rostedt if (!do_not_reboot) { 14017faafbd6SSteven Rostedt doprint "REBOOTING\n"; 1402bc7c5803SSteven Rostedt reboot_to_good $sleep_time; 1403a75fececSSteven Rostedt } 14047faafbd6SSteven Rostedt 14059064af52SSteven Rostedt my $name = ""; 14069064af52SSteven Rostedt 14079064af52SSteven Rostedt if (defined($test_name)) { 14089064af52SSteven Rostedt $name = " ($test_name)"; 14099064af52SSteven Rostedt } 14109064af52SSteven Rostedt 1411576f627cSSteven Rostedt doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"; 1412576f627cSSteven Rostedt doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"; 14139064af52SSteven Rostedt doprint "KTEST RESULT: TEST $i$name Failed: ", @_, "\n"; 1414576f627cSSteven Rostedt doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"; 1415576f627cSSteven Rostedt doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"; 1416a75fececSSteven Rostedt 1417de5b6e3bSRabin Vincent if (defined($store_failures)) { 1418de5b6e3bSRabin Vincent save_logs "fail", $store_failures; 1419cccae1a6SSteven Rostedt } 1420cccae1a6SSteven Rostedt 14212b7d9b21SSteven Rostedt return 1; 14222b7d9b21SSteven Rostedt} 14232b7d9b21SSteven Rostedt 14242545eb61SSteven Rostedtsub run_command { 14252545eb61SSteven Rostedt my ($command) = @_; 1426d6ce2a0bSSteven Rostedt my $dolog = 0; 1427d6ce2a0bSSteven Rostedt my $dord = 0; 1428d6ce2a0bSSteven Rostedt my $pid; 1429d6ce2a0bSSteven Rostedt 1430e48c5293SSteven Rostedt $command =~ s/\$SSH_USER/$ssh_user/g; 1431e48c5293SSteven Rostedt $command =~ s/\$MACHINE/$machine/g; 1432e48c5293SSteven Rostedt 1433d6ce2a0bSSteven Rostedt doprint("$command ... "); 1434d6ce2a0bSSteven Rostedt 1435d6ce2a0bSSteven Rostedt $pid = open(CMD, "$command 2>&1 |") or 14362b7d9b21SSteven Rostedt (fail "unable to exec $command" and return 0); 14372545eb61SSteven Rostedt 14382545eb61SSteven Rostedt if (defined($opt{"LOG_FILE"})) { 1439d6ce2a0bSSteven Rostedt open(LOG, ">>$opt{LOG_FILE}") or 1440d6ce2a0bSSteven Rostedt dodie "failed to write to log"; 1441d6ce2a0bSSteven Rostedt $dolog = 1; 14426c5ee0beSSteven Rostedt } 14436c5ee0beSSteven Rostedt 14446c5ee0beSSteven Rostedt if (defined($redirect)) { 1445d6ce2a0bSSteven Rostedt open (RD, ">$redirect") or 1446d6ce2a0bSSteven Rostedt dodie "failed to write to redirect $redirect"; 1447d6ce2a0bSSteven Rostedt $dord = 1; 14482545eb61SSteven Rostedt } 14492545eb61SSteven Rostedt 1450d6ce2a0bSSteven Rostedt while (<CMD>) { 1451d6ce2a0bSSteven Rostedt print LOG if ($dolog); 1452d6ce2a0bSSteven Rostedt print RD if ($dord); 1453d6ce2a0bSSteven Rostedt } 14542545eb61SSteven Rostedt 1455d6ce2a0bSSteven Rostedt waitpid($pid, 0); 14562545eb61SSteven Rostedt my $failed = $?; 14572545eb61SSteven Rostedt 1458d6ce2a0bSSteven Rostedt close(CMD); 1459d6ce2a0bSSteven Rostedt close(LOG) if ($dolog); 1460d6ce2a0bSSteven Rostedt close(RD) if ($dord); 1461d6ce2a0bSSteven Rostedt 14622545eb61SSteven Rostedt if ($failed) { 14632545eb61SSteven Rostedt doprint "FAILED!\n"; 14642545eb61SSteven Rostedt } else { 14652545eb61SSteven Rostedt doprint "SUCCESS\n"; 14662545eb61SSteven Rostedt } 14672545eb61SSteven Rostedt 14685f9b6cedSSteven Rostedt return !$failed; 14695f9b6cedSSteven Rostedt} 14705f9b6cedSSteven Rostedt 1471e48c5293SSteven Rostedtsub run_ssh { 1472e48c5293SSteven Rostedt my ($cmd) = @_; 1473e48c5293SSteven Rostedt my $cp_exec = $ssh_exec; 1474e48c5293SSteven Rostedt 1475e48c5293SSteven Rostedt $cp_exec =~ s/\$SSH_COMMAND/$cmd/g; 1476e48c5293SSteven Rostedt return run_command "$cp_exec"; 1477e48c5293SSteven Rostedt} 1478e48c5293SSteven Rostedt 1479e48c5293SSteven Rostedtsub run_scp { 148002ad2617SSteven Rostedt my ($src, $dst, $cp_scp) = @_; 1481e48c5293SSteven Rostedt 1482e48c5293SSteven Rostedt $cp_scp =~ s/\$SRC_FILE/$src/g; 1483e48c5293SSteven Rostedt $cp_scp =~ s/\$DST_FILE/$dst/g; 1484e48c5293SSteven Rostedt 1485e48c5293SSteven Rostedt return run_command "$cp_scp"; 1486e48c5293SSteven Rostedt} 1487e48c5293SSteven Rostedt 148802ad2617SSteven Rostedtsub run_scp_install { 148902ad2617SSteven Rostedt my ($src, $dst) = @_; 149002ad2617SSteven Rostedt 149102ad2617SSteven Rostedt my $cp_scp = $scp_to_target_install; 149202ad2617SSteven Rostedt 149302ad2617SSteven Rostedt return run_scp($src, $dst, $cp_scp); 149402ad2617SSteven Rostedt} 149502ad2617SSteven Rostedt 149602ad2617SSteven Rostedtsub run_scp_mod { 149702ad2617SSteven Rostedt my ($src, $dst) = @_; 149802ad2617SSteven Rostedt 149902ad2617SSteven Rostedt my $cp_scp = $scp_to_target; 150002ad2617SSteven Rostedt 150102ad2617SSteven Rostedt return run_scp($src, $dst, $cp_scp); 150202ad2617SSteven Rostedt} 150302ad2617SSteven Rostedt 1504a15ba913SSteven Rostedtsub get_grub2_index { 1505a15ba913SSteven Rostedt 1506a15ba913SSteven Rostedt return if (defined($grub_number)); 1507a15ba913SSteven Rostedt 1508a15ba913SSteven Rostedt doprint "Find grub2 menu ... "; 1509a15ba913SSteven Rostedt $grub_number = -1; 1510a15ba913SSteven Rostedt 1511a15ba913SSteven Rostedt my $ssh_grub = $ssh_exec; 1512a15ba913SSteven Rostedt $ssh_grub =~ s,\$SSH_COMMAND,cat $grub_file,g; 1513a15ba913SSteven Rostedt 1514a15ba913SSteven Rostedt open(IN, "$ssh_grub |") 1515a15ba913SSteven Rostedt or die "unable to get $grub_file"; 1516a15ba913SSteven Rostedt 1517a15ba913SSteven Rostedt my $found = 0; 1518a15ba913SSteven Rostedt 1519a15ba913SSteven Rostedt while (<IN>) { 1520a15ba913SSteven Rostedt if (/^menuentry.*$grub_menu/) { 1521a15ba913SSteven Rostedt $grub_number++; 1522a15ba913SSteven Rostedt $found = 1; 1523a15ba913SSteven Rostedt last; 1524a15ba913SSteven Rostedt } elsif (/^menuentry\s/) { 1525a15ba913SSteven Rostedt $grub_number++; 1526a15ba913SSteven Rostedt } 1527a15ba913SSteven Rostedt } 1528a15ba913SSteven Rostedt close(IN); 1529a15ba913SSteven Rostedt 1530a15ba913SSteven Rostedt die "Could not find '$grub_menu' in $grub_file on $machine" 1531a15ba913SSteven Rostedt if (!$found); 1532a15ba913SSteven Rostedt doprint "$grub_number\n"; 1533a15ba913SSteven Rostedt} 1534a15ba913SSteven Rostedt 15355f9b6cedSSteven Rostedtsub get_grub_index { 15365f9b6cedSSteven Rostedt 1537a15ba913SSteven Rostedt if ($reboot_type eq "grub2") { 1538a15ba913SSteven Rostedt get_grub2_index; 1539a15ba913SSteven Rostedt return; 1540a15ba913SSteven Rostedt } 1541a15ba913SSteven Rostedt 1542a75fececSSteven Rostedt if ($reboot_type ne "grub") { 1543a75fececSSteven Rostedt return; 1544a75fececSSteven Rostedt } 15455a391fbfSSteven Rostedt return if (defined($grub_number)); 15465f9b6cedSSteven Rostedt 15475f9b6cedSSteven Rostedt doprint "Find grub menu ... "; 15485f9b6cedSSteven Rostedt $grub_number = -1; 1549e48c5293SSteven Rostedt 1550e48c5293SSteven Rostedt my $ssh_grub = $ssh_exec; 1551e48c5293SSteven Rostedt $ssh_grub =~ s,\$SSH_COMMAND,cat /boot/grub/menu.lst,g; 1552e48c5293SSteven Rostedt 1553e48c5293SSteven Rostedt open(IN, "$ssh_grub |") 15545f9b6cedSSteven Rostedt or die "unable to get menu.lst"; 1555e48c5293SSteven Rostedt 1556eaa1fe25SSteven Rostedt my $found = 0; 1557eaa1fe25SSteven Rostedt 15585f9b6cedSSteven Rostedt while (<IN>) { 1559a75fececSSteven Rostedt if (/^\s*title\s+$grub_menu\s*$/) { 15605f9b6cedSSteven Rostedt $grub_number++; 1561eaa1fe25SSteven Rostedt $found = 1; 15625f9b6cedSSteven Rostedt last; 15635f9b6cedSSteven Rostedt } elsif (/^\s*title\s/) { 15645f9b6cedSSteven Rostedt $grub_number++; 15655f9b6cedSSteven Rostedt } 15665f9b6cedSSteven Rostedt } 15675f9b6cedSSteven Rostedt close(IN); 15685f9b6cedSSteven Rostedt 1569a75fececSSteven Rostedt die "Could not find '$grub_menu' in /boot/grub/menu on $machine" 1570eaa1fe25SSteven Rostedt if (!$found); 15715f9b6cedSSteven Rostedt doprint "$grub_number\n"; 15722545eb61SSteven Rostedt} 15732545eb61SSteven Rostedt 15742545eb61SSteven Rostedtsub wait_for_input 15752545eb61SSteven Rostedt{ 15762545eb61SSteven Rostedt my ($fp, $time) = @_; 15772545eb61SSteven Rostedt my $rin; 15782545eb61SSteven Rostedt my $ready; 15792545eb61SSteven Rostedt my $line; 15802545eb61SSteven Rostedt my $ch; 15812545eb61SSteven Rostedt 15822545eb61SSteven Rostedt if (!defined($time)) { 15832545eb61SSteven Rostedt $time = $timeout; 15842545eb61SSteven Rostedt } 15852545eb61SSteven Rostedt 15862545eb61SSteven Rostedt $rin = ''; 15872545eb61SSteven Rostedt vec($rin, fileno($fp), 1) = 1; 15882545eb61SSteven Rostedt $ready = select($rin, undef, undef, $time); 15892545eb61SSteven Rostedt 15902545eb61SSteven Rostedt $line = ""; 15912545eb61SSteven Rostedt 15922545eb61SSteven Rostedt # try to read one char at a time 15932545eb61SSteven Rostedt while (sysread $fp, $ch, 1) { 15942545eb61SSteven Rostedt $line .= $ch; 15952545eb61SSteven Rostedt last if ($ch eq "\n"); 15962545eb61SSteven Rostedt } 15972545eb61SSteven Rostedt 15982545eb61SSteven Rostedt if (!length($line)) { 15992545eb61SSteven Rostedt return undef; 16002545eb61SSteven Rostedt } 16012545eb61SSteven Rostedt 16022545eb61SSteven Rostedt return $line; 16032545eb61SSteven Rostedt} 16042545eb61SSteven Rostedt 160575c3fda7SSteven Rostedtsub reboot_to { 1606bc7c5803SSteven Rostedt if (defined($switch_to_test)) { 1607bc7c5803SSteven Rostedt run_command $switch_to_test; 1608bc7c5803SSteven Rostedt } 1609bc7c5803SSteven Rostedt 1610a75fececSSteven Rostedt if ($reboot_type eq "grub") { 1611c54367f9SSteven Rostedt run_ssh "'(echo \"savedefault --default=$grub_number --once\" | grub --batch)'"; 1612a15ba913SSteven Rostedt } elsif ($reboot_type eq "grub2") { 1613a15ba913SSteven Rostedt run_ssh "$grub_reboot $grub_number"; 16147786954cSSteven Rostedt } elsif ($reboot_type eq "syslinux") { 16157786954cSSteven Rostedt run_ssh "$syslinux --once \\\"$syslinux_label\\\" $syslinux_path"; 161696f6a0dfSSteven Rostedt } elsif (defined $reboot_script) { 1617a75fececSSteven Rostedt run_command "$reboot_script"; 16182545eb61SSteven Rostedt } 161996f6a0dfSSteven Rostedt reboot; 162096f6a0dfSSteven Rostedt} 16212545eb61SSteven Rostedt 1622a57419b3SSteven Rostedtsub get_sha1 { 1623a57419b3SSteven Rostedt my ($commit) = @_; 1624a57419b3SSteven Rostedt 1625a57419b3SSteven Rostedt doprint "git rev-list --max-count=1 $commit ... "; 1626a57419b3SSteven Rostedt my $sha1 = `git rev-list --max-count=1 $commit`; 1627a57419b3SSteven Rostedt my $ret = $?; 1628a57419b3SSteven Rostedt 1629a57419b3SSteven Rostedt logit $sha1; 1630a57419b3SSteven Rostedt 1631a57419b3SSteven Rostedt if ($ret) { 1632a57419b3SSteven Rostedt doprint "FAILED\n"; 1633a57419b3SSteven Rostedt dodie "Failed to get git $commit"; 1634a57419b3SSteven Rostedt } 1635a57419b3SSteven Rostedt 1636a57419b3SSteven Rostedt print "SUCCESS\n"; 1637a57419b3SSteven Rostedt 1638a57419b3SSteven Rostedt chomp $sha1; 1639a57419b3SSteven Rostedt 1640a57419b3SSteven Rostedt return $sha1; 1641a57419b3SSteven Rostedt} 1642a57419b3SSteven Rostedt 16435a391fbfSSteven Rostedtsub monitor { 16442545eb61SSteven Rostedt my $booted = 0; 16452545eb61SSteven Rostedt my $bug = 0; 16466ca996ccSSteven Rostedt my $bug_ignored = 0; 16475c42fc5bSSteven Rostedt my $skip_call_trace = 0; 16482b7d9b21SSteven Rostedt my $loops; 16492545eb61SSteven Rostedt 16507faafbd6SSteven Rostedt wait_for_monitor 5; 16512545eb61SSteven Rostedt 16522545eb61SSteven Rostedt my $line; 16532545eb61SSteven Rostedt my $full_line = ""; 16542545eb61SSteven Rostedt 16557faafbd6SSteven Rostedt open(DMESG, "> $dmesg") or 16567faafbd6SSteven Rostedt die "unable to write to $dmesg"; 16572545eb61SSteven Rostedt 165875c3fda7SSteven Rostedt reboot_to; 16592545eb61SSteven Rostedt 16601c8a617aSSteven Rostedt my $success_start; 16611c8a617aSSteven Rostedt my $failure_start; 16622d01b26aSSteven Rostedt my $monitor_start = time; 16632d01b26aSSteven Rostedt my $done = 0; 1664f1a5b962SSteven Rostedt my $version_found = 0; 16651c8a617aSSteven Rostedt 16662d01b26aSSteven Rostedt while (!$done) { 16672545eb61SSteven Rostedt 1668ecaf8e52SSteven Rostedt if ($bug && defined($stop_after_failure) && 1669ecaf8e52SSteven Rostedt $stop_after_failure >= 0) { 1670ecaf8e52SSteven Rostedt my $time = $stop_after_failure - (time - $failure_start); 1671ecaf8e52SSteven Rostedt $line = wait_for_input($monitor_fp, $time); 1672ecaf8e52SSteven Rostedt if (!defined($line)) { 1673ecaf8e52SSteven Rostedt doprint "bug timed out after $booted_timeout seconds\n"; 1674ecaf8e52SSteven Rostedt doprint "Test forced to stop after $stop_after_failure seconds after failure\n"; 1675ecaf8e52SSteven Rostedt last; 1676ecaf8e52SSteven Rostedt } 1677ecaf8e52SSteven Rostedt } elsif ($booted) { 1678a75fececSSteven Rostedt $line = wait_for_input($monitor_fp, $booted_timeout); 1679cd4f1d53SSteven Rostedt if (!defined($line)) { 1680cd4f1d53SSteven Rostedt my $s = $booted_timeout == 1 ? "" : "s"; 1681cd4f1d53SSteven Rostedt doprint "Successful boot found: break after $booted_timeout second$s\n"; 1682cd4f1d53SSteven Rostedt last; 1683cd4f1d53SSteven Rostedt } 16842b7d9b21SSteven Rostedt } else { 16857faafbd6SSteven Rostedt $line = wait_for_input($monitor_fp); 1686cd4f1d53SSteven Rostedt if (!defined($line)) { 1687cd4f1d53SSteven Rostedt my $s = $timeout == 1 ? "" : "s"; 1688cd4f1d53SSteven Rostedt doprint "Timed out after $timeout second$s\n"; 1689cd4f1d53SSteven Rostedt last; 16902b7d9b21SSteven Rostedt } 1691cd4f1d53SSteven Rostedt } 16922545eb61SSteven Rostedt 16932545eb61SSteven Rostedt doprint $line; 16947faafbd6SSteven Rostedt print DMESG $line; 16952545eb61SSteven Rostedt 16962545eb61SSteven Rostedt # we are not guaranteed to get a full line 16972545eb61SSteven Rostedt $full_line .= $line; 16982545eb61SSteven Rostedt 1699a75fececSSteven Rostedt if ($full_line =~ /$success_line/) { 17002545eb61SSteven Rostedt $booted = 1; 17011c8a617aSSteven Rostedt $success_start = time; 17021c8a617aSSteven Rostedt } 17031c8a617aSSteven Rostedt 17041c8a617aSSteven Rostedt if ($booted && defined($stop_after_success) && 17051c8a617aSSteven Rostedt $stop_after_success >= 0) { 17061c8a617aSSteven Rostedt my $now = time; 17071c8a617aSSteven Rostedt if ($now - $success_start >= $stop_after_success) { 17081c8a617aSSteven Rostedt doprint "Test forced to stop after $stop_after_success seconds after success\n"; 17091c8a617aSSteven Rostedt last; 17101c8a617aSSteven Rostedt } 17112545eb61SSteven Rostedt } 17122545eb61SSteven Rostedt 17135c42fc5bSSteven Rostedt if ($full_line =~ /\[ backtrace testing \]/) { 17145c42fc5bSSteven Rostedt $skip_call_trace = 1; 17155c42fc5bSSteven Rostedt } 17165c42fc5bSSteven Rostedt 17172545eb61SSteven Rostedt if ($full_line =~ /call trace:/i) { 17186ca996ccSSteven Rostedt if (!$bug && !$skip_call_trace) { 17196ca996ccSSteven Rostedt if ($ignore_errors) { 17206ca996ccSSteven Rostedt $bug_ignored = 1; 17216ca996ccSSteven Rostedt } else { 17221c8a617aSSteven Rostedt $bug = 1; 17231c8a617aSSteven Rostedt $failure_start = time; 17241c8a617aSSteven Rostedt } 17251c8a617aSSteven Rostedt } 17266ca996ccSSteven Rostedt } 17271c8a617aSSteven Rostedt 17281c8a617aSSteven Rostedt if ($bug && defined($stop_after_failure) && 17291c8a617aSSteven Rostedt $stop_after_failure >= 0) { 17301c8a617aSSteven Rostedt my $now = time; 17311c8a617aSSteven Rostedt if ($now - $failure_start >= $stop_after_failure) { 17321c8a617aSSteven Rostedt doprint "Test forced to stop after $stop_after_failure seconds after failure\n"; 17331c8a617aSSteven Rostedt last; 17341c8a617aSSteven Rostedt } 17355c42fc5bSSteven Rostedt } 17365c42fc5bSSteven Rostedt 17375c42fc5bSSteven Rostedt if ($full_line =~ /\[ end of backtrace testing \]/) { 17385c42fc5bSSteven Rostedt $skip_call_trace = 0; 17395c42fc5bSSteven Rostedt } 17405c42fc5bSSteven Rostedt 17415c42fc5bSSteven Rostedt if ($full_line =~ /Kernel panic -/) { 174210abf118SSteven Rostedt $failure_start = time; 17432545eb61SSteven Rostedt $bug = 1; 17442545eb61SSteven Rostedt } 17452545eb61SSteven Rostedt 1746f1a5b962SSteven Rostedt # Detect triple faults by testing the banner 1747f1a5b962SSteven Rostedt if ($full_line =~ /\bLinux version (\S+).*\n/) { 1748f1a5b962SSteven Rostedt if ($1 eq $version) { 1749f1a5b962SSteven Rostedt $version_found = 1; 1750f1a5b962SSteven Rostedt } elsif ($version_found && $detect_triplefault) { 1751f1a5b962SSteven Rostedt # We already booted into the kernel we are testing, 1752f1a5b962SSteven Rostedt # but now we booted into another kernel? 1753f1a5b962SSteven Rostedt # Consider this a triple fault. 1754f1a5b962SSteven Rostedt doprint "Aleady booted in Linux kernel $version, but now\n"; 1755f1a5b962SSteven Rostedt doprint "we booted into Linux kernel $1.\n"; 1756f1a5b962SSteven Rostedt doprint "Assuming that this is a triple fault.\n"; 1757f1a5b962SSteven Rostedt doprint "To disable this: set DETECT_TRIPLE_FAULT to 0\n"; 1758f1a5b962SSteven Rostedt last; 1759f1a5b962SSteven Rostedt } 1760f1a5b962SSteven Rostedt } 1761f1a5b962SSteven Rostedt 17622545eb61SSteven Rostedt if ($line =~ /\n/) { 17632545eb61SSteven Rostedt $full_line = ""; 17642545eb61SSteven Rostedt } 17652d01b26aSSteven Rostedt 17662d01b26aSSteven Rostedt if ($stop_test_after > 0 && !$booted && !$bug) { 17672d01b26aSSteven Rostedt if (time - $monitor_start > $stop_test_after) { 17684d62bf51SSteven Rostedt doprint "STOP_TEST_AFTER ($stop_test_after seconds) timed out\n"; 17692d01b26aSSteven Rostedt $done = 1; 17702d01b26aSSteven Rostedt } 17712d01b26aSSteven Rostedt } 17722545eb61SSteven Rostedt } 17732545eb61SSteven Rostedt 17747faafbd6SSteven Rostedt close(DMESG); 17752545eb61SSteven Rostedt 17762545eb61SSteven Rostedt if ($bug) { 17772b7d9b21SSteven Rostedt return 0 if ($in_bisect); 1778576f627cSSteven Rostedt fail "failed - got a bug report" and return 0; 17792545eb61SSteven Rostedt } 17805f9b6cedSSteven Rostedt 1781a75fececSSteven Rostedt if (!$booted) { 1782a75fececSSteven Rostedt return 0 if ($in_bisect); 1783576f627cSSteven Rostedt fail "failed - never got a boot prompt." and return 0; 1784a75fececSSteven Rostedt } 1785a75fececSSteven Rostedt 17866ca996ccSSteven Rostedt if ($bug_ignored) { 17876ca996ccSSteven Rostedt doprint "WARNING: Call Trace detected but ignored due to IGNORE_ERRORS=1\n"; 17886ca996ccSSteven Rostedt } 17896ca996ccSSteven Rostedt 17902b7d9b21SSteven Rostedt return 1; 17912545eb61SSteven Rostedt} 17922545eb61SSteven Rostedt 17932b29b2f8SSteven Rostedtsub eval_kernel_version { 17942b29b2f8SSteven Rostedt my ($option) = @_; 17952b29b2f8SSteven Rostedt 17962b29b2f8SSteven Rostedt $option =~ s/\$KERNEL_VERSION/$version/g; 17972b29b2f8SSteven Rostedt 17982b29b2f8SSteven Rostedt return $option; 17992b29b2f8SSteven Rostedt} 18002b29b2f8SSteven Rostedt 1801db05cfefSSteven Rostedtsub do_post_install { 1802db05cfefSSteven Rostedt 1803db05cfefSSteven Rostedt return if (!defined($post_install)); 1804db05cfefSSteven Rostedt 18052b29b2f8SSteven Rostedt my $cp_post_install = eval_kernel_version $post_install; 1806db05cfefSSteven Rostedt run_command "$cp_post_install" or 1807db05cfefSSteven Rostedt dodie "Failed to run post install"; 1808db05cfefSSteven Rostedt} 1809db05cfefSSteven Rostedt 18102545eb61SSteven Rostedtsub install { 18112545eb61SSteven Rostedt 1812e0a8742eSSteven Rostedt return if ($no_install); 1813e0a8742eSSteven Rostedt 1814e5c2ec11SSteven Rostedt if (defined($pre_install)) { 1815e5c2ec11SSteven Rostedt my $cp_pre_install = eval_kernel_version $pre_install; 1816e5c2ec11SSteven Rostedt run_command "$cp_pre_install" or 1817e5c2ec11SSteven Rostedt dodie "Failed to run pre install"; 1818e5c2ec11SSteven Rostedt } 1819e5c2ec11SSteven Rostedt 18202b29b2f8SSteven Rostedt my $cp_target = eval_kernel_version $target_image; 18212b29b2f8SSteven Rostedt 182202ad2617SSteven Rostedt run_scp_install "$outputdir/$build_target", "$cp_target" or 18235c42fc5bSSteven Rostedt dodie "failed to copy image"; 18245f9b6cedSSteven Rostedt 18255f9b6cedSSteven Rostedt my $install_mods = 0; 18265f9b6cedSSteven Rostedt 18275f9b6cedSSteven Rostedt # should we process modules? 18285f9b6cedSSteven Rostedt $install_mods = 0; 182951ad1dd1SSteven Rostedt open(IN, "$output_config") or dodie("Can't read config file"); 18305f9b6cedSSteven Rostedt while (<IN>) { 18315f9b6cedSSteven Rostedt if (/CONFIG_MODULES(=y)?/) { 18328bc5e4eaSSteven Rostedt if (defined($1)) { 18338bc5e4eaSSteven Rostedt $install_mods = 1; 18345f9b6cedSSteven Rostedt last; 18355f9b6cedSSteven Rostedt } 18365f9b6cedSSteven Rostedt } 18378bc5e4eaSSteven Rostedt } 18385f9b6cedSSteven Rostedt close(IN); 18395f9b6cedSSteven Rostedt 18405f9b6cedSSteven Rostedt if (!$install_mods) { 1841db05cfefSSteven Rostedt do_post_install; 18425f9b6cedSSteven Rostedt doprint "No modules needed\n"; 18435f9b6cedSSteven Rostedt return; 18442545eb61SSteven Rostedt } 18452545eb61SSteven Rostedt 1846627977d8SSteven Rostedt run_command "$make INSTALL_MOD_STRIP=1 INSTALL_MOD_PATH=$tmpdir modules_install" or 18475f9b6cedSSteven Rostedt dodie "Failed to install modules"; 18485f9b6cedSSteven Rostedt 18492545eb61SSteven Rostedt my $modlib = "/lib/modules/$version"; 1850a57419b3SSteven Rostedt my $modtar = "ktest-mods.tar.bz2"; 18512545eb61SSteven Rostedt 1852e48c5293SSteven Rostedt run_ssh "rm -rf $modlib" or 18535c42fc5bSSteven Rostedt dodie "failed to remove old mods: $modlib"; 18542545eb61SSteven Rostedt 18555c42fc5bSSteven Rostedt # would be nice if scp -r did not follow symbolic links 1856a75fececSSteven Rostedt run_command "cd $tmpdir && tar -cjf $modtar lib/modules/$version" or 18575c42fc5bSSteven Rostedt dodie "making tarball"; 18585c42fc5bSSteven Rostedt 185902ad2617SSteven Rostedt run_scp_mod "$tmpdir/$modtar", "/tmp" or 18605c42fc5bSSteven Rostedt dodie "failed to copy modules"; 18615c42fc5bSSteven Rostedt 1862a75fececSSteven Rostedt unlink "$tmpdir/$modtar"; 18635c42fc5bSSteven Rostedt 1864e7b13441SSteven Rostedt run_ssh "'(cd / && tar xjf /tmp/$modtar)'" or 18655c42fc5bSSteven Rostedt dodie "failed to tar modules"; 18665c42fc5bSSteven Rostedt 1867e48c5293SSteven Rostedt run_ssh "rm -f /tmp/$modtar"; 18688b37ca8cSSteven Rostedt 1869db05cfefSSteven Rostedt do_post_install; 18702545eb61SSteven Rostedt} 18712545eb61SSteven Rostedt 1872ddf607e5SSteven Rostedtsub get_version { 1873ddf607e5SSteven Rostedt # get the release name 1874683a3e64SSteven Rostedt return if ($have_version); 1875ddf607e5SSteven Rostedt doprint "$make kernelrelease ... "; 1876ddf607e5SSteven Rostedt $version = `$make kernelrelease | tail -1`; 1877ddf607e5SSteven Rostedt chomp($version); 1878ddf607e5SSteven Rostedt doprint "$version\n"; 1879683a3e64SSteven Rostedt $have_version = 1; 1880ddf607e5SSteven Rostedt} 1881ddf607e5SSteven Rostedt 1882ddf607e5SSteven Rostedtsub start_monitor_and_boot { 18839f7424ccSSteven Rostedt # Make sure the stable kernel has finished booting 18849f7424ccSSteven Rostedt start_monitor; 18859f7424ccSSteven Rostedt wait_for_monitor 5; 18869f7424ccSSteven Rostedt end_monitor; 18879f7424ccSSteven Rostedt 1888ddf607e5SSteven Rostedt get_grub_index; 1889ddf607e5SSteven Rostedt get_version; 1890ddf607e5SSteven Rostedt install; 1891ddf607e5SSteven Rostedt 1892ddf607e5SSteven Rostedt start_monitor; 1893ddf607e5SSteven Rostedt return monitor; 1894ddf607e5SSteven Rostedt} 1895ddf607e5SSteven Rostedt 18966c5ee0beSSteven Rostedtsub check_buildlog { 18976c5ee0beSSteven Rostedt my ($patch) = @_; 18986c5ee0beSSteven Rostedt 18996c5ee0beSSteven Rostedt my @files = `git show $patch | diffstat -l`; 19006c5ee0beSSteven Rostedt 19016c5ee0beSSteven Rostedt open(IN, "git show $patch |") or 19026c5ee0beSSteven Rostedt dodie "failed to show $patch"; 19036c5ee0beSSteven Rostedt while (<IN>) { 19046c5ee0beSSteven Rostedt if (m,^--- a/(.*),) { 19056c5ee0beSSteven Rostedt chomp $1; 19066c5ee0beSSteven Rostedt $files[$#files] = $1; 19076c5ee0beSSteven Rostedt } 19086c5ee0beSSteven Rostedt } 19096c5ee0beSSteven Rostedt close(IN); 19106c5ee0beSSteven Rostedt 19116c5ee0beSSteven Rostedt open(IN, $buildlog) or dodie "Can't open $buildlog"; 19126c5ee0beSSteven Rostedt while (<IN>) { 19136c5ee0beSSteven Rostedt if (/^\s*(.*?):.*(warning|error)/) { 19146c5ee0beSSteven Rostedt my $err = $1; 19156c5ee0beSSteven Rostedt foreach my $file (@files) { 1916a75fececSSteven Rostedt my $fullpath = "$builddir/$file"; 19176c5ee0beSSteven Rostedt if ($file eq $err || $fullpath eq $err) { 19182b7d9b21SSteven Rostedt fail "$file built with warnings" and return 0; 19196c5ee0beSSteven Rostedt } 19206c5ee0beSSteven Rostedt } 19216c5ee0beSSteven Rostedt } 19226c5ee0beSSteven Rostedt } 19236c5ee0beSSteven Rostedt close(IN); 19242b7d9b21SSteven Rostedt 19252b7d9b21SSteven Rostedt return 1; 19266c5ee0beSSteven Rostedt} 19276c5ee0beSSteven Rostedt 1928fcb3f16aSSteven Rostedtsub apply_min_config { 1929fcb3f16aSSteven Rostedt my $outconfig = "$output_config.new"; 1930612b9e9bSSteven Rostedt 1931fcb3f16aSSteven Rostedt # Read the config file and remove anything that 1932fcb3f16aSSteven Rostedt # is in the force_config hash (from minconfig and others) 1933fcb3f16aSSteven Rostedt # then add the force config back. 1934fcb3f16aSSteven Rostedt 1935fcb3f16aSSteven Rostedt doprint "Applying minimum configurations into $output_config.new\n"; 1936fcb3f16aSSteven Rostedt 1937fcb3f16aSSteven Rostedt open (OUT, ">$outconfig") or 1938fcb3f16aSSteven Rostedt dodie "Can't create $outconfig"; 1939fcb3f16aSSteven Rostedt 1940fcb3f16aSSteven Rostedt if (-f $output_config) { 1941fcb3f16aSSteven Rostedt open (IN, $output_config) or 1942fcb3f16aSSteven Rostedt dodie "Failed to open $output_config"; 1943fcb3f16aSSteven Rostedt while (<IN>) { 1944fcb3f16aSSteven Rostedt if (/^(# )?(CONFIG_[^\s=]*)/) { 1945fcb3f16aSSteven Rostedt next if (defined($force_config{$2})); 1946fcb3f16aSSteven Rostedt } 1947fcb3f16aSSteven Rostedt print OUT; 1948fcb3f16aSSteven Rostedt } 1949fcb3f16aSSteven Rostedt close IN; 1950fcb3f16aSSteven Rostedt } 1951fcb3f16aSSteven Rostedt foreach my $config (keys %force_config) { 1952fcb3f16aSSteven Rostedt print OUT "$force_config{$config}\n"; 1953fcb3f16aSSteven Rostedt } 1954fcb3f16aSSteven Rostedt close OUT; 1955fcb3f16aSSteven Rostedt 1956fcb3f16aSSteven Rostedt run_command "mv $outconfig $output_config"; 1957fcb3f16aSSteven Rostedt} 1958fcb3f16aSSteven Rostedt 1959fcb3f16aSSteven Rostedtsub make_oldconfig { 1960fcb3f16aSSteven Rostedt 19614c4ab120SSteven Rostedt my @force_list = keys %force_config; 19624c4ab120SSteven Rostedt 19634c4ab120SSteven Rostedt if ($#force_list >= 0) { 1964fcb3f16aSSteven Rostedt apply_min_config; 19654c4ab120SSteven Rostedt } 1966fcb3f16aSSteven Rostedt 1967fb16d891SAdam Lee if (!run_command "$make olddefconfig") { 1968fb16d891SAdam Lee # Perhaps olddefconfig doesn't exist in this version of the kernel 1969*18925170SSteven Rostedt # try oldnoconfig 1970*18925170SSteven Rostedt doprint "olddefconfig failed, trying make oldnoconfig\n"; 1971*18925170SSteven Rostedt if (!run_command "$make oldnoconfig") { 1972*18925170SSteven Rostedt doprint "oldnoconfig failed, trying yes '' | make oldconfig\n"; 1973612b9e9bSSteven Rostedt # try a yes '' | oldconfig 1974fcb3f16aSSteven Rostedt run_command "yes '' | $make oldconfig" or 1975612b9e9bSSteven Rostedt dodie "failed make config oldconfig"; 1976612b9e9bSSteven Rostedt } 1977612b9e9bSSteven Rostedt } 1978*18925170SSteven Rostedt} 1979612b9e9bSSteven Rostedt 1980fcb3f16aSSteven Rostedt# read a config file and use this to force new configs. 1981fcb3f16aSSteven Rostedtsub load_force_config { 1982fcb3f16aSSteven Rostedt my ($config) = @_; 1983fcb3f16aSSteven Rostedt 1984cf79fab6SSteven Rostedt doprint "Loading force configs from $config\n"; 1985fcb3f16aSSteven Rostedt open(IN, $config) or 1986fcb3f16aSSteven Rostedt dodie "failed to read $config"; 1987fcb3f16aSSteven Rostedt while (<IN>) { 1988fcb3f16aSSteven Rostedt chomp; 1989fcb3f16aSSteven Rostedt if (/^(CONFIG[^\s=]*)(\s*=.*)/) { 1990fcb3f16aSSteven Rostedt $force_config{$1} = $_; 1991fcb3f16aSSteven Rostedt } elsif (/^# (CONFIG_\S*) is not set/) { 1992fcb3f16aSSteven Rostedt $force_config{$1} = $_; 1993fcb3f16aSSteven Rostedt } 1994fcb3f16aSSteven Rostedt } 1995fcb3f16aSSteven Rostedt close IN; 1996fcb3f16aSSteven Rostedt} 1997fcb3f16aSSteven Rostedt 19982545eb61SSteven Rostedtsub build { 19992545eb61SSteven Rostedt my ($type) = @_; 20002545eb61SSteven Rostedt 20017faafbd6SSteven Rostedt unlink $buildlog; 20027faafbd6SSteven Rostedt 20034ab1cce5SSteven Rostedt # Failed builds should not reboot the target 20044ab1cce5SSteven Rostedt my $save_no_reboot = $no_reboot; 20054ab1cce5SSteven Rostedt $no_reboot = 1; 20064ab1cce5SSteven Rostedt 2007683a3e64SSteven Rostedt # Calculate a new version from here. 2008683a3e64SSteven Rostedt $have_version = 0; 2009683a3e64SSteven Rostedt 20100bd6c1a3SSteven Rostedt if (defined($pre_build)) { 20110bd6c1a3SSteven Rostedt my $ret = run_command $pre_build; 20120bd6c1a3SSteven Rostedt if (!$ret && defined($pre_build_die) && 20130bd6c1a3SSteven Rostedt $pre_build_die) { 20140bd6c1a3SSteven Rostedt dodie "failed to pre_build\n"; 20150bd6c1a3SSteven Rostedt } 20160bd6c1a3SSteven Rostedt } 20170bd6c1a3SSteven Rostedt 201875c3fda7SSteven Rostedt if ($type =~ /^useconfig:(.*)/) { 201951ad1dd1SSteven Rostedt run_command "cp $1 $output_config" or 202075c3fda7SSteven Rostedt dodie "could not copy $1 to .config"; 20215f9b6cedSSteven Rostedt 202275c3fda7SSteven Rostedt $type = "oldconfig"; 202375c3fda7SSteven Rostedt } 202475c3fda7SSteven Rostedt 20255c42fc5bSSteven Rostedt # old config can ask questions 20265c42fc5bSSteven Rostedt if ($type eq "oldconfig") { 2027fb16d891SAdam Lee $type = "olddefconfig"; 202875c3fda7SSteven Rostedt 202975c3fda7SSteven Rostedt # allow for empty configs 203051ad1dd1SSteven Rostedt run_command "touch $output_config"; 203175c3fda7SSteven Rostedt 203213488231SAndrew Jones if (!$noclean) { 203351ad1dd1SSteven Rostedt run_command "mv $output_config $outputdir/config_temp" or 20345c42fc5bSSteven Rostedt dodie "moving .config"; 20355c42fc5bSSteven Rostedt 203613488231SAndrew Jones run_command "$make mrproper" or dodie "make mrproper"; 20375c42fc5bSSteven Rostedt 203851ad1dd1SSteven Rostedt run_command "mv $outputdir/config_temp $output_config" or 20395c42fc5bSSteven Rostedt dodie "moving config_temp"; 204013488231SAndrew Jones } 20415c42fc5bSSteven Rostedt 20425c42fc5bSSteven Rostedt } elsif (!$noclean) { 204351ad1dd1SSteven Rostedt unlink "$output_config"; 20445f9b6cedSSteven Rostedt run_command "$make mrproper" or 20455c42fc5bSSteven Rostedt dodie "make mrproper"; 20465c42fc5bSSteven Rostedt } 20472545eb61SSteven Rostedt 20482545eb61SSteven Rostedt # add something to distinguish this build 2049a75fececSSteven Rostedt open(OUT, "> $outputdir/localversion") or dodie("Can't make localversion file"); 2050a75fececSSteven Rostedt print OUT "$localversion\n"; 20512545eb61SSteven Rostedt close(OUT); 20522545eb61SSteven Rostedt 20535f9b6cedSSteven Rostedt if (defined($minconfig)) { 2054fcb3f16aSSteven Rostedt load_force_config($minconfig); 20552545eb61SSteven Rostedt } 20562545eb61SSteven Rostedt 2057fb16d891SAdam Lee if ($type ne "olddefconfig") { 2058fcb3f16aSSteven Rostedt run_command "$make $type" or 20595c42fc5bSSteven Rostedt dodie "failed make config"; 2060612b9e9bSSteven Rostedt } 2061fcb3f16aSSteven Rostedt # Run old config regardless, to enforce min configurations 2062fcb3f16aSSteven Rostedt make_oldconfig; 20632545eb61SSteven Rostedt 2064a75fececSSteven Rostedt $redirect = "$buildlog"; 20650bd6c1a3SSteven Rostedt my $build_ret = run_command "$make $build_options"; 20666c5ee0beSSteven Rostedt undef $redirect; 20670bd6c1a3SSteven Rostedt 20680bd6c1a3SSteven Rostedt if (defined($post_build)) { 2069683a3e64SSteven Rostedt # Because a post build may change the kernel version 2070683a3e64SSteven Rostedt # do it now. 2071683a3e64SSteven Rostedt get_version; 20720bd6c1a3SSteven Rostedt my $ret = run_command $post_build; 20730bd6c1a3SSteven Rostedt if (!$ret && defined($post_build_die) && 20740bd6c1a3SSteven Rostedt $post_build_die) { 20750bd6c1a3SSteven Rostedt dodie "failed to post_build\n"; 20760bd6c1a3SSteven Rostedt } 20770bd6c1a3SSteven Rostedt } 20780bd6c1a3SSteven Rostedt 20790bd6c1a3SSteven Rostedt if (!$build_ret) { 20805f9b6cedSSteven Rostedt # bisect may need this to pass 20814ab1cce5SSteven Rostedt if ($in_bisect) { 20824ab1cce5SSteven Rostedt $no_reboot = $save_no_reboot; 20834ab1cce5SSteven Rostedt return 0; 20844ab1cce5SSteven Rostedt } 20852b7d9b21SSteven Rostedt fail "failed build" and return 0; 20862545eb61SSteven Rostedt } 20875f9b6cedSSteven Rostedt 20884ab1cce5SSteven Rostedt $no_reboot = $save_no_reboot; 20894ab1cce5SSteven Rostedt 20902b7d9b21SSteven Rostedt return 1; 20912545eb61SSteven Rostedt} 20922545eb61SSteven Rostedt 209375c3fda7SSteven Rostedtsub halt { 2094e48c5293SSteven Rostedt if (!run_ssh "halt" or defined($power_off)) { 2095576f627cSSteven Rostedt if (defined($poweroff_after_halt)) { 2096576f627cSSteven Rostedt sleep $poweroff_after_halt; 2097576f627cSSteven Rostedt run_command "$power_off"; 2098576f627cSSteven Rostedt } 2099576f627cSSteven Rostedt } else { 210075c3fda7SSteven Rostedt # nope? the zap it! 2101a75fececSSteven Rostedt run_command "$power_off"; 210275c3fda7SSteven Rostedt } 210375c3fda7SSteven Rostedt} 210475c3fda7SSteven Rostedt 21055f9b6cedSSteven Rostedtsub success { 21065f9b6cedSSteven Rostedt my ($i) = @_; 21075f9b6cedSSteven Rostedt 2108921ed4c7SSteven Rostedt if (defined($post_test)) { 2109921ed4c7SSteven Rostedt run_command $post_test; 2110921ed4c7SSteven Rostedt } 2111921ed4c7SSteven Rostedt 2112e48c5293SSteven Rostedt $successes++; 2113e48c5293SSteven Rostedt 21149064af52SSteven Rostedt my $name = ""; 21159064af52SSteven Rostedt 21169064af52SSteven Rostedt if (defined($test_name)) { 21179064af52SSteven Rostedt $name = " ($test_name)"; 21189064af52SSteven Rostedt } 21199064af52SSteven Rostedt 21205f9b6cedSSteven Rostedt doprint "\n\n*******************************************\n"; 21215f9b6cedSSteven Rostedt doprint "*******************************************\n"; 21229064af52SSteven Rostedt doprint "KTEST RESULT: TEST $i$name SUCCESS!!!! **\n"; 21235f9b6cedSSteven Rostedt doprint "*******************************************\n"; 21245f9b6cedSSteven Rostedt doprint "*******************************************\n"; 21255f9b6cedSSteven Rostedt 2126de5b6e3bSRabin Vincent if (defined($store_successes)) { 2127de5b6e3bSRabin Vincent save_logs "success", $store_successes; 2128de5b6e3bSRabin Vincent } 2129de5b6e3bSRabin Vincent 2130576f627cSSteven Rostedt if ($i != $opt{"NUM_TESTS"} && !do_not_reboot) { 2131a75fececSSteven Rostedt doprint "Reboot and wait $sleep_time seconds\n"; 2132bc7c5803SSteven Rostedt reboot_to_good $sleep_time; 21335f9b6cedSSteven Rostedt } 21345f9b6cedSSteven Rostedt} 21355f9b6cedSSteven Rostedt 2136c960bb9fSSteven Rostedtsub answer_bisect { 2137c960bb9fSSteven Rostedt for (;;) { 2138c960bb9fSSteven Rostedt doprint "Pass or fail? [p/f]"; 2139c960bb9fSSteven Rostedt my $ans = <STDIN>; 2140c960bb9fSSteven Rostedt chomp $ans; 2141c960bb9fSSteven Rostedt if ($ans eq "p" || $ans eq "P") { 2142c960bb9fSSteven Rostedt return 1; 2143c960bb9fSSteven Rostedt } elsif ($ans eq "f" || $ans eq "F") { 2144c960bb9fSSteven Rostedt return 0; 2145c960bb9fSSteven Rostedt } else { 2146c960bb9fSSteven Rostedt print "Please answer 'P' or 'F'\n"; 2147c960bb9fSSteven Rostedt } 2148c960bb9fSSteven Rostedt } 2149c960bb9fSSteven Rostedt} 2150c960bb9fSSteven Rostedt 21515a391fbfSSteven Rostedtsub child_run_test { 21527faafbd6SSteven Rostedt my $failed = 0; 21535a391fbfSSteven Rostedt 21547faafbd6SSteven Rostedt # child should have no power 2155a75fececSSteven Rostedt $reboot_on_error = 0; 2156a75fececSSteven Rostedt $poweroff_on_error = 0; 2157a75fececSSteven Rostedt $die_on_failure = 1; 21587faafbd6SSteven Rostedt 2159a9dd5d63SRabin Vincent $redirect = "$testlog"; 21607faafbd6SSteven Rostedt run_command $run_test or $failed = 1; 2161a9dd5d63SRabin Vincent undef $redirect; 2162a9dd5d63SRabin Vincent 21635a391fbfSSteven Rostedt exit $failed; 21645a391fbfSSteven Rostedt} 21655a391fbfSSteven Rostedt 21665a391fbfSSteven Rostedtmy $child_done; 21675a391fbfSSteven Rostedt 21685a391fbfSSteven Rostedtsub child_finished { 21695a391fbfSSteven Rostedt $child_done = 1; 21705a391fbfSSteven Rostedt} 21715a391fbfSSteven Rostedt 21725a391fbfSSteven Rostedtsub do_run_test { 21735a391fbfSSteven Rostedt my $child_pid; 21745a391fbfSSteven Rostedt my $child_exit; 21755a391fbfSSteven Rostedt my $line; 21765a391fbfSSteven Rostedt my $full_line; 21775a391fbfSSteven Rostedt my $bug = 0; 21789b1d367dSSteven Rostedt my $bug_ignored = 0; 21795a391fbfSSteven Rostedt 21807faafbd6SSteven Rostedt wait_for_monitor 1; 21815a391fbfSSteven Rostedt 21827faafbd6SSteven Rostedt doprint "run test $run_test\n"; 21835a391fbfSSteven Rostedt 21845a391fbfSSteven Rostedt $child_done = 0; 21855a391fbfSSteven Rostedt 21865a391fbfSSteven Rostedt $SIG{CHLD} = qw(child_finished); 21875a391fbfSSteven Rostedt 21885a391fbfSSteven Rostedt $child_pid = fork; 21895a391fbfSSteven Rostedt 21905a391fbfSSteven Rostedt child_run_test if (!$child_pid); 21915a391fbfSSteven Rostedt 21925a391fbfSSteven Rostedt $full_line = ""; 21935a391fbfSSteven Rostedt 21945a391fbfSSteven Rostedt do { 21957faafbd6SSteven Rostedt $line = wait_for_input($monitor_fp, 1); 21965a391fbfSSteven Rostedt if (defined($line)) { 21975a391fbfSSteven Rostedt 21985a391fbfSSteven Rostedt # we are not guaranteed to get a full line 21995a391fbfSSteven Rostedt $full_line .= $line; 22008ea0e063SSteven Rostedt doprint $line; 22015a391fbfSSteven Rostedt 22025a391fbfSSteven Rostedt if ($full_line =~ /call trace:/i) { 22039b1d367dSSteven Rostedt if ($ignore_errors) { 22049b1d367dSSteven Rostedt $bug_ignored = 1; 22059b1d367dSSteven Rostedt } else { 22065a391fbfSSteven Rostedt $bug = 1; 22075a391fbfSSteven Rostedt } 22089b1d367dSSteven Rostedt } 22095a391fbfSSteven Rostedt 22105a391fbfSSteven Rostedt if ($full_line =~ /Kernel panic -/) { 22115a391fbfSSteven Rostedt $bug = 1; 22125a391fbfSSteven Rostedt } 22135a391fbfSSteven Rostedt 22145a391fbfSSteven Rostedt if ($line =~ /\n/) { 22155a391fbfSSteven Rostedt $full_line = ""; 22165a391fbfSSteven Rostedt } 22175a391fbfSSteven Rostedt } 22185a391fbfSSteven Rostedt } while (!$child_done && !$bug); 22195a391fbfSSteven Rostedt 22209b1d367dSSteven Rostedt if (!$bug && $bug_ignored) { 22219b1d367dSSteven Rostedt doprint "WARNING: Call Trace detected but ignored due to IGNORE_ERRORS=1\n"; 22229b1d367dSSteven Rostedt } 22239b1d367dSSteven Rostedt 22245a391fbfSSteven Rostedt if ($bug) { 22258ea0e063SSteven Rostedt my $failure_start = time; 22268ea0e063SSteven Rostedt my $now; 22278ea0e063SSteven Rostedt do { 22288ea0e063SSteven Rostedt $line = wait_for_input($monitor_fp, 1); 22298ea0e063SSteven Rostedt if (defined($line)) { 22308ea0e063SSteven Rostedt doprint $line; 22318ea0e063SSteven Rostedt } 22328ea0e063SSteven Rostedt $now = time; 22338ea0e063SSteven Rostedt if ($now - $failure_start >= $stop_after_failure) { 22348ea0e063SSteven Rostedt last; 22358ea0e063SSteven Rostedt } 22368ea0e063SSteven Rostedt } while (defined($line)); 22378ea0e063SSteven Rostedt 22385a391fbfSSteven Rostedt doprint "Detected kernel crash!\n"; 22395a391fbfSSteven Rostedt # kill the child with extreme prejudice 22405a391fbfSSteven Rostedt kill 9, $child_pid; 22415a391fbfSSteven Rostedt } 22425a391fbfSSteven Rostedt 22435a391fbfSSteven Rostedt waitpid $child_pid, 0; 22445a391fbfSSteven Rostedt $child_exit = $?; 22455a391fbfSSteven Rostedt 2246c5dacb88SSteven Rostedt if (!$bug && $in_bisect) { 2247c5dacb88SSteven Rostedt if (defined($bisect_ret_good)) { 2248c5dacb88SSteven Rostedt if ($child_exit == $bisect_ret_good) { 2249c5dacb88SSteven Rostedt return 1; 2250c5dacb88SSteven Rostedt } 2251c5dacb88SSteven Rostedt } 2252c5dacb88SSteven Rostedt if (defined($bisect_ret_skip)) { 2253c5dacb88SSteven Rostedt if ($child_exit == $bisect_ret_skip) { 2254c5dacb88SSteven Rostedt return -1; 2255c5dacb88SSteven Rostedt } 2256c5dacb88SSteven Rostedt } 2257c5dacb88SSteven Rostedt if (defined($bisect_ret_abort)) { 2258c5dacb88SSteven Rostedt if ($child_exit == $bisect_ret_abort) { 2259c5dacb88SSteven Rostedt fail "test abort" and return -2; 2260c5dacb88SSteven Rostedt } 2261c5dacb88SSteven Rostedt } 2262c5dacb88SSteven Rostedt if (defined($bisect_ret_bad)) { 2263c5dacb88SSteven Rostedt if ($child_exit == $bisect_ret_skip) { 2264c5dacb88SSteven Rostedt return 0; 2265c5dacb88SSteven Rostedt } 2266c5dacb88SSteven Rostedt } 2267c5dacb88SSteven Rostedt if (defined($bisect_ret_default)) { 2268c5dacb88SSteven Rostedt if ($bisect_ret_default eq "good") { 2269c5dacb88SSteven Rostedt return 1; 2270c5dacb88SSteven Rostedt } elsif ($bisect_ret_default eq "bad") { 2271c5dacb88SSteven Rostedt return 0; 2272c5dacb88SSteven Rostedt } elsif ($bisect_ret_default eq "skip") { 2273c5dacb88SSteven Rostedt return -1; 2274c5dacb88SSteven Rostedt } elsif ($bisect_ret_default eq "abort") { 2275c5dacb88SSteven Rostedt return -2; 2276c5dacb88SSteven Rostedt } else { 2277c5dacb88SSteven Rostedt fail "unknown default action: $bisect_ret_default" 2278c5dacb88SSteven Rostedt and return -2; 2279c5dacb88SSteven Rostedt } 2280c5dacb88SSteven Rostedt } 2281c5dacb88SSteven Rostedt } 2282c5dacb88SSteven Rostedt 22835a391fbfSSteven Rostedt if ($bug || $child_exit) { 22842b7d9b21SSteven Rostedt return 0 if $in_bisect; 22852b7d9b21SSteven Rostedt fail "test failed" and return 0; 22865a391fbfSSteven Rostedt } 22872b7d9b21SSteven Rostedt return 1; 22885a391fbfSSteven Rostedt} 22895a391fbfSSteven Rostedt 2290a75fececSSteven Rostedtsub run_git_bisect { 2291a75fececSSteven Rostedt my ($command) = @_; 2292a75fececSSteven Rostedt 2293a75fececSSteven Rostedt doprint "$command ... "; 2294a75fececSSteven Rostedt 2295a75fececSSteven Rostedt my $output = `$command 2>&1`; 2296a75fececSSteven Rostedt my $ret = $?; 2297a75fececSSteven Rostedt 2298a75fececSSteven Rostedt logit $output; 2299a75fececSSteven Rostedt 2300a75fececSSteven Rostedt if ($ret) { 2301a75fececSSteven Rostedt doprint "FAILED\n"; 2302a75fececSSteven Rostedt dodie "Failed to git bisect"; 2303a75fececSSteven Rostedt } 2304a75fececSSteven Rostedt 2305a75fececSSteven Rostedt doprint "SUCCESS\n"; 2306a75fececSSteven Rostedt if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\))\s+\[([[:xdigit:]]+)\]/) { 2307a75fececSSteven Rostedt doprint "$1 [$2]\n"; 2308a75fececSSteven Rostedt } elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) { 2309b5f4aea6SSteven Rostedt $bisect_bad_commit = $1; 2310a75fececSSteven Rostedt doprint "Found bad commit... $1\n"; 2311a75fececSSteven Rostedt return 0; 2312a75fececSSteven Rostedt } else { 2313a75fececSSteven Rostedt # we already logged it, just print it now. 2314a75fececSSteven Rostedt print $output; 2315a75fececSSteven Rostedt } 2316a75fececSSteven Rostedt 2317a75fececSSteven Rostedt return 1; 2318a75fececSSteven Rostedt} 2319a75fececSSteven Rostedt 2320c23dca7cSSteven Rostedtsub bisect_reboot { 2321c23dca7cSSteven Rostedt doprint "Reboot and sleep $bisect_sleep_time seconds\n"; 2322bc7c5803SSteven Rostedt reboot_to_good $bisect_sleep_time; 2323c23dca7cSSteven Rostedt} 2324c23dca7cSSteven Rostedt 2325c23dca7cSSteven Rostedt# returns 1 on success, 0 on failure, -1 on skip 23260a05c769SSteven Rostedtsub run_bisect_test { 23270a05c769SSteven Rostedt my ($type, $buildtype) = @_; 23285f9b6cedSSteven Rostedt 23292b7d9b21SSteven Rostedt my $failed = 0; 23305f9b6cedSSteven Rostedt my $result; 23315f9b6cedSSteven Rostedt my $output; 23325f9b6cedSSteven Rostedt my $ret; 23335f9b6cedSSteven Rostedt 23340a05c769SSteven Rostedt $in_bisect = 1; 23350a05c769SSteven Rostedt 23360a05c769SSteven Rostedt build $buildtype or $failed = 1; 23375f9b6cedSSteven Rostedt 23385f9b6cedSSteven Rostedt if ($type ne "build") { 2339c23dca7cSSteven Rostedt if ($failed && $bisect_skip) { 2340c23dca7cSSteven Rostedt $in_bisect = 0; 2341c23dca7cSSteven Rostedt return -1; 2342c23dca7cSSteven Rostedt } 23437faafbd6SSteven Rostedt dodie "Failed on build" if $failed; 23445f9b6cedSSteven Rostedt 23455f9b6cedSSteven Rostedt # Now boot the box 2346ddf607e5SSteven Rostedt start_monitor_and_boot or $failed = 1; 23475f9b6cedSSteven Rostedt 23485f9b6cedSSteven Rostedt if ($type ne "boot") { 2349c23dca7cSSteven Rostedt if ($failed && $bisect_skip) { 2350c23dca7cSSteven Rostedt end_monitor; 2351c23dca7cSSteven Rostedt bisect_reboot; 2352c23dca7cSSteven Rostedt $in_bisect = 0; 2353c23dca7cSSteven Rostedt return -1; 2354c23dca7cSSteven Rostedt } 23557faafbd6SSteven Rostedt dodie "Failed on boot" if $failed; 23565a391fbfSSteven Rostedt 23572b7d9b21SSteven Rostedt do_run_test or $failed = 1; 23585f9b6cedSSteven Rostedt } 23597faafbd6SSteven Rostedt end_monitor; 23605f9b6cedSSteven Rostedt } 23615f9b6cedSSteven Rostedt 23625f9b6cedSSteven Rostedt if ($failed) { 23630a05c769SSteven Rostedt $result = 0; 23645f9b6cedSSteven Rostedt } else { 23650a05c769SSteven Rostedt $result = 1; 23665f9b6cedSSteven Rostedt } 23674025bc62SSteven Rostedt 23684025bc62SSteven Rostedt # reboot the box to a kernel we can ssh to 23694025bc62SSteven Rostedt if ($type ne "build") { 23704025bc62SSteven Rostedt bisect_reboot; 23714025bc62SSteven Rostedt } 23720a05c769SSteven Rostedt $in_bisect = 0; 23730a05c769SSteven Rostedt 23740a05c769SSteven Rostedt return $result; 23750a05c769SSteven Rostedt} 23760a05c769SSteven Rostedt 23770a05c769SSteven Rostedtsub run_bisect { 23780a05c769SSteven Rostedt my ($type) = @_; 23790a05c769SSteven Rostedt my $buildtype = "oldconfig"; 23800a05c769SSteven Rostedt 23810a05c769SSteven Rostedt # We should have a minconfig to use? 23820a05c769SSteven Rostedt if (defined($minconfig)) { 23830a05c769SSteven Rostedt $buildtype = "useconfig:$minconfig"; 23840a05c769SSteven Rostedt } 23850a05c769SSteven Rostedt 23860a05c769SSteven Rostedt my $ret = run_bisect_test $type, $buildtype; 23870a05c769SSteven Rostedt 2388c960bb9fSSteven Rostedt if ($bisect_manual) { 2389c960bb9fSSteven Rostedt $ret = answer_bisect; 2390c960bb9fSSteven Rostedt } 23915f9b6cedSSteven Rostedt 2392d6ce2a0bSSteven Rostedt # Are we looking for where it worked, not failed? 23935158ba3eSRuss Dill if ($reverse_bisect && $ret >= 0) { 23940a05c769SSteven Rostedt $ret = !$ret; 2395d6ce2a0bSSteven Rostedt } 2396d6ce2a0bSSteven Rostedt 2397c23dca7cSSteven Rostedt if ($ret > 0) { 23980a05c769SSteven Rostedt return "good"; 2399c23dca7cSSteven Rostedt } elsif ($ret == 0) { 24000a05c769SSteven Rostedt return "bad"; 2401c23dca7cSSteven Rostedt } elsif ($bisect_skip) { 2402c23dca7cSSteven Rostedt doprint "HIT A BAD COMMIT ... SKIPPING\n"; 2403c23dca7cSSteven Rostedt return "skip"; 24040a05c769SSteven Rostedt } 24055f9b6cedSSteven Rostedt} 24065f9b6cedSSteven Rostedt 2407dad98754SSteven Rostedtsub update_bisect_replay { 2408dad98754SSteven Rostedt my $tmp_log = "$tmpdir/ktest_bisect_log"; 2409dad98754SSteven Rostedt run_command "git bisect log > $tmp_log" or 2410dad98754SSteven Rostedt die "can't create bisect log"; 2411dad98754SSteven Rostedt return $tmp_log; 2412dad98754SSteven Rostedt} 2413dad98754SSteven Rostedt 24145f9b6cedSSteven Rostedtsub bisect { 24155f9b6cedSSteven Rostedt my ($i) = @_; 24165f9b6cedSSteven Rostedt 24175f9b6cedSSteven Rostedt my $result; 24185f9b6cedSSteven Rostedt 2419b5f4aea6SSteven Rostedt die "BISECT_GOOD[$i] not defined\n" if (!defined($bisect_good)); 2420b5f4aea6SSteven Rostedt die "BISECT_BAD[$i] not defined\n" if (!defined($bisect_bad)); 2421b5f4aea6SSteven Rostedt die "BISECT_TYPE[$i] not defined\n" if (!defined($bisect_type)); 24225f9b6cedSSteven Rostedt 2423b5f4aea6SSteven Rostedt my $good = $bisect_good; 2424b5f4aea6SSteven Rostedt my $bad = $bisect_bad; 2425b5f4aea6SSteven Rostedt my $type = $bisect_type; 2426b5f4aea6SSteven Rostedt my $start = $bisect_start; 2427b5f4aea6SSteven Rostedt my $replay = $bisect_replay; 2428b5f4aea6SSteven Rostedt my $start_files = $bisect_files; 24293410f6fdSSteven Rostedt 24303410f6fdSSteven Rostedt if (defined($start_files)) { 24313410f6fdSSteven Rostedt $start_files = " -- " . $start_files; 24323410f6fdSSteven Rostedt } else { 24333410f6fdSSteven Rostedt $start_files = ""; 24343410f6fdSSteven Rostedt } 24355f9b6cedSSteven Rostedt 2436a57419b3SSteven Rostedt # convert to true sha1's 2437a57419b3SSteven Rostedt $good = get_sha1($good); 2438a57419b3SSteven Rostedt $bad = get_sha1($bad); 2439a57419b3SSteven Rostedt 2440b5f4aea6SSteven Rostedt if (defined($bisect_reverse) && $bisect_reverse == 1) { 2441d6ce2a0bSSteven Rostedt doprint "Performing a reverse bisect (bad is good, good is bad!)\n"; 2442d6ce2a0bSSteven Rostedt $reverse_bisect = 1; 2443d6ce2a0bSSteven Rostedt } else { 2444d6ce2a0bSSteven Rostedt $reverse_bisect = 0; 2445d6ce2a0bSSteven Rostedt } 2446d6ce2a0bSSteven Rostedt 24475a391fbfSSteven Rostedt # Can't have a test without having a test to run 24485a391fbfSSteven Rostedt if ($type eq "test" && !defined($run_test)) { 24495a391fbfSSteven Rostedt $type = "boot"; 24505a391fbfSSteven Rostedt } 24515a391fbfSSteven Rostedt 2452dad98754SSteven Rostedt # Check if a bisect was running 2453dad98754SSteven Rostedt my $bisect_start_file = "$builddir/.git/BISECT_START"; 2454dad98754SSteven Rostedt 2455b5f4aea6SSteven Rostedt my $check = $bisect_check; 2456dad98754SSteven Rostedt my $do_check = defined($check) && $check ne "0"; 2457dad98754SSteven Rostedt 2458dad98754SSteven Rostedt if ( -f $bisect_start_file ) { 2459dad98754SSteven Rostedt print "Bisect in progress found\n"; 2460dad98754SSteven Rostedt if ($do_check) { 2461dad98754SSteven Rostedt print " If you say yes, then no checks of good or bad will be done\n"; 2462dad98754SSteven Rostedt } 2463dad98754SSteven Rostedt if (defined($replay)) { 2464dad98754SSteven Rostedt print "** BISECT_REPLAY is defined in config file **"; 2465dad98754SSteven Rostedt print " Ignore config option and perform new git bisect log?\n"; 2466dad98754SSteven Rostedt if (read_ync " (yes, no, or cancel) ") { 2467dad98754SSteven Rostedt $replay = update_bisect_replay; 2468dad98754SSteven Rostedt $do_check = 0; 2469dad98754SSteven Rostedt } 2470dad98754SSteven Rostedt } elsif (read_yn "read git log and continue?") { 2471dad98754SSteven Rostedt $replay = update_bisect_replay; 2472dad98754SSteven Rostedt $do_check = 0; 2473dad98754SSteven Rostedt } 2474dad98754SSteven Rostedt } 2475dad98754SSteven Rostedt 2476dad98754SSteven Rostedt if ($do_check) { 2477a75fececSSteven Rostedt 2478a75fececSSteven Rostedt # get current HEAD 2479a57419b3SSteven Rostedt my $head = get_sha1("HEAD"); 2480a75fececSSteven Rostedt 2481a75fececSSteven Rostedt if ($check ne "good") { 2482a75fececSSteven Rostedt doprint "TESTING BISECT BAD [$bad]\n"; 2483a75fececSSteven Rostedt run_command "git checkout $bad" or 2484a75fececSSteven Rostedt die "Failed to checkout $bad"; 2485a75fececSSteven Rostedt 2486a75fececSSteven Rostedt $result = run_bisect $type; 2487a75fececSSteven Rostedt 2488a75fececSSteven Rostedt if ($result ne "bad") { 2489a75fececSSteven Rostedt fail "Tested BISECT_BAD [$bad] and it succeeded" and return 0; 2490a75fececSSteven Rostedt } 2491a75fececSSteven Rostedt } 2492a75fececSSteven Rostedt 2493a75fececSSteven Rostedt if ($check ne "bad") { 2494a75fececSSteven Rostedt doprint "TESTING BISECT GOOD [$good]\n"; 2495a75fececSSteven Rostedt run_command "git checkout $good" or 2496a75fececSSteven Rostedt die "Failed to checkout $good"; 2497a75fececSSteven Rostedt 2498a75fececSSteven Rostedt $result = run_bisect $type; 2499a75fececSSteven Rostedt 2500a75fececSSteven Rostedt if ($result ne "good") { 2501a75fececSSteven Rostedt fail "Tested BISECT_GOOD [$good] and it failed" and return 0; 2502a75fececSSteven Rostedt } 2503a75fececSSteven Rostedt } 2504a75fececSSteven Rostedt 2505a75fececSSteven Rostedt # checkout where we started 2506a75fececSSteven Rostedt run_command "git checkout $head" or 2507a75fececSSteven Rostedt die "Failed to checkout $head"; 2508a75fececSSteven Rostedt } 2509a75fececSSteven Rostedt 25103410f6fdSSteven Rostedt run_command "git bisect start$start_files" or 2511a75fececSSteven Rostedt dodie "could not start bisect"; 2512a75fececSSteven Rostedt 2513a75fececSSteven Rostedt run_command "git bisect good $good" or 2514a75fececSSteven Rostedt dodie "could not set bisect good to $good"; 2515a75fececSSteven Rostedt 2516a75fececSSteven Rostedt run_git_bisect "git bisect bad $bad" or 2517a75fececSSteven Rostedt dodie "could not set bisect bad to $bad"; 2518a75fececSSteven Rostedt 2519a75fececSSteven Rostedt if (defined($replay)) { 2520a75fececSSteven Rostedt run_command "git bisect replay $replay" or 2521a75fececSSteven Rostedt dodie "failed to run replay"; 2522a75fececSSteven Rostedt } 2523a75fececSSteven Rostedt 2524a75fececSSteven Rostedt if (defined($start)) { 2525a75fececSSteven Rostedt run_command "git checkout $start" or 2526a75fececSSteven Rostedt dodie "failed to checkout $start"; 2527a75fececSSteven Rostedt } 2528a75fececSSteven Rostedt 2529a75fececSSteven Rostedt my $test; 25305f9b6cedSSteven Rostedt do { 25315f9b6cedSSteven Rostedt $result = run_bisect $type; 2532a75fececSSteven Rostedt $test = run_git_bisect "git bisect $result"; 2533a75fececSSteven Rostedt } while ($test); 25345f9b6cedSSteven Rostedt 25355f9b6cedSSteven Rostedt run_command "git bisect log" or 25365f9b6cedSSteven Rostedt dodie "could not capture git bisect log"; 25375f9b6cedSSteven Rostedt 25385f9b6cedSSteven Rostedt run_command "git bisect reset" or 25395f9b6cedSSteven Rostedt dodie "could not reset git bisect"; 25405f9b6cedSSteven Rostedt 2541b5f4aea6SSteven Rostedt doprint "Bad commit was [$bisect_bad_commit]\n"; 25425f9b6cedSSteven Rostedt 25430a05c769SSteven Rostedt success $i; 25440a05c769SSteven Rostedt} 25450a05c769SSteven Rostedt 2546cf79fab6SSteven Rostedt# config_ignore holds the configs that were set (or unset) for 2547cf79fab6SSteven Rostedt# a good config and we will ignore these configs for the rest 2548cf79fab6SSteven Rostedt# of a config bisect. These configs stay as they were. 25490a05c769SSteven Rostedtmy %config_ignore; 2550cf79fab6SSteven Rostedt 2551cf79fab6SSteven Rostedt# config_set holds what all configs were set as. 25520a05c769SSteven Rostedtmy %config_set; 25530a05c769SSteven Rostedt 2554cf79fab6SSteven Rostedt# config_off holds the set of configs that the bad config had disabled. 2555cf79fab6SSteven Rostedt# We need to record them and set them in the .config when running 2556fb16d891SAdam Lee# olddefconfig, because olddefconfig keeps the defaults. 2557cf79fab6SSteven Rostedtmy %config_off; 2558cf79fab6SSteven Rostedt 2559cf79fab6SSteven Rostedt# config_off_tmp holds a set of configs to turn off for now 2560cf79fab6SSteven Rostedtmy @config_off_tmp; 2561cf79fab6SSteven Rostedt 2562cf79fab6SSteven Rostedt# config_list is the set of configs that are being tested 25630a05c769SSteven Rostedtmy %config_list; 25640a05c769SSteven Rostedtmy %null_config; 25650a05c769SSteven Rostedt 25660a05c769SSteven Rostedtmy %dependency; 25670a05c769SSteven Rostedt 25684c4ab120SSteven Rostedtsub assign_configs { 25694c4ab120SSteven Rostedt my ($hash, $config) = @_; 25700a05c769SSteven Rostedt 25710a05c769SSteven Rostedt open (IN, $config) 25720a05c769SSteven Rostedt or dodie "Failed to read $config"; 25730a05c769SSteven Rostedt 25740a05c769SSteven Rostedt while (<IN>) { 25759bf71749SSteven Rostedt if (/^((CONFIG\S*)=.*)/) { 25764c4ab120SSteven Rostedt ${$hash}{$2} = $1; 25770a05c769SSteven Rostedt } 25780a05c769SSteven Rostedt } 25790a05c769SSteven Rostedt 25800a05c769SSteven Rostedt close(IN); 25810a05c769SSteven Rostedt} 25820a05c769SSteven Rostedt 25834c4ab120SSteven Rostedtsub process_config_ignore { 25844c4ab120SSteven Rostedt my ($config) = @_; 25854c4ab120SSteven Rostedt 25864c4ab120SSteven Rostedt assign_configs \%config_ignore, $config; 25874c4ab120SSteven Rostedt} 25884c4ab120SSteven Rostedt 25890a05c769SSteven Rostedtsub read_current_config { 25900a05c769SSteven Rostedt my ($config_ref) = @_; 25910a05c769SSteven Rostedt 25920a05c769SSteven Rostedt %{$config_ref} = (); 25930a05c769SSteven Rostedt undef %{$config_ref}; 25940a05c769SSteven Rostedt 25950a05c769SSteven Rostedt my @key = keys %{$config_ref}; 25960a05c769SSteven Rostedt if ($#key >= 0) { 25970a05c769SSteven Rostedt print "did not delete!\n"; 25980a05c769SSteven Rostedt exit; 25990a05c769SSteven Rostedt } 26000a05c769SSteven Rostedt open (IN, "$output_config"); 26010a05c769SSteven Rostedt 26020a05c769SSteven Rostedt while (<IN>) { 26030a05c769SSteven Rostedt if (/^(CONFIG\S+)=(.*)/) { 26040a05c769SSteven Rostedt ${$config_ref}{$1} = $2; 26050a05c769SSteven Rostedt } 26060a05c769SSteven Rostedt } 26070a05c769SSteven Rostedt close(IN); 26080a05c769SSteven Rostedt} 26090a05c769SSteven Rostedt 26100a05c769SSteven Rostedtsub get_dependencies { 26110a05c769SSteven Rostedt my ($config) = @_; 26120a05c769SSteven Rostedt 26130a05c769SSteven Rostedt my $arr = $dependency{$config}; 26140a05c769SSteven Rostedt if (!defined($arr)) { 26150a05c769SSteven Rostedt return (); 26160a05c769SSteven Rostedt } 26170a05c769SSteven Rostedt 26180a05c769SSteven Rostedt my @deps = @{$arr}; 26190a05c769SSteven Rostedt 26200a05c769SSteven Rostedt foreach my $dep (@{$arr}) { 26210a05c769SSteven Rostedt print "ADD DEP $dep\n"; 26220a05c769SSteven Rostedt @deps = (@deps, get_dependencies $dep); 26230a05c769SSteven Rostedt } 26240a05c769SSteven Rostedt 26250a05c769SSteven Rostedt return @deps; 26260a05c769SSteven Rostedt} 26270a05c769SSteven Rostedt 26280a05c769SSteven Rostedtsub create_config { 26290a05c769SSteven Rostedt my @configs = @_; 26300a05c769SSteven Rostedt 26310a05c769SSteven Rostedt open(OUT, ">$output_config") or dodie "Can not write to $output_config"; 26320a05c769SSteven Rostedt 26330a05c769SSteven Rostedt foreach my $config (@configs) { 26340a05c769SSteven Rostedt print OUT "$config_set{$config}\n"; 26350a05c769SSteven Rostedt my @deps = get_dependencies $config; 26360a05c769SSteven Rostedt foreach my $dep (@deps) { 26370a05c769SSteven Rostedt print OUT "$config_set{$dep}\n"; 26380a05c769SSteven Rostedt } 26390a05c769SSteven Rostedt } 26400a05c769SSteven Rostedt 2641cf79fab6SSteven Rostedt # turn off configs to keep off 2642cf79fab6SSteven Rostedt foreach my $config (keys %config_off) { 2643cf79fab6SSteven Rostedt print OUT "# $config is not set\n"; 2644cf79fab6SSteven Rostedt } 2645cf79fab6SSteven Rostedt 2646cf79fab6SSteven Rostedt # turn off configs that should be off for now 2647cf79fab6SSteven Rostedt foreach my $config (@config_off_tmp) { 2648cf79fab6SSteven Rostedt print OUT "# $config is not set\n"; 2649cf79fab6SSteven Rostedt } 2650cf79fab6SSteven Rostedt 26510a05c769SSteven Rostedt foreach my $config (keys %config_ignore) { 26520a05c769SSteven Rostedt print OUT "$config_ignore{$config}\n"; 26530a05c769SSteven Rostedt } 26540a05c769SSteven Rostedt close(OUT); 26550a05c769SSteven Rostedt 2656fcb3f16aSSteven Rostedt make_oldconfig; 26570a05c769SSteven Rostedt} 26580a05c769SSteven Rostedt 26590a05c769SSteven Rostedtsub compare_configs { 26600a05c769SSteven Rostedt my (%a, %b) = @_; 26610a05c769SSteven Rostedt 26620a05c769SSteven Rostedt foreach my $item (keys %a) { 26630a05c769SSteven Rostedt if (!defined($b{$item})) { 26640a05c769SSteven Rostedt print "diff $item\n"; 26650a05c769SSteven Rostedt return 1; 26660a05c769SSteven Rostedt } 26670a05c769SSteven Rostedt delete $b{$item}; 26680a05c769SSteven Rostedt } 26690a05c769SSteven Rostedt 26700a05c769SSteven Rostedt my @keys = keys %b; 26710a05c769SSteven Rostedt if ($#keys) { 26720a05c769SSteven Rostedt print "diff2 $keys[0]\n"; 26730a05c769SSteven Rostedt } 26740a05c769SSteven Rostedt return -1 if ($#keys >= 0); 26750a05c769SSteven Rostedt 26760a05c769SSteven Rostedt return 0; 26770a05c769SSteven Rostedt} 26780a05c769SSteven Rostedt 26790a05c769SSteven Rostedtsub run_config_bisect_test { 26800a05c769SSteven Rostedt my ($type) = @_; 26810a05c769SSteven Rostedt 26820a05c769SSteven Rostedt return run_bisect_test $type, "oldconfig"; 26830a05c769SSteven Rostedt} 26840a05c769SSteven Rostedt 26850a05c769SSteven Rostedtsub process_passed { 26860a05c769SSteven Rostedt my (%configs) = @_; 26870a05c769SSteven Rostedt 26880a05c769SSteven Rostedt doprint "These configs had no failure: (Enabling them for further compiles)\n"; 26890a05c769SSteven Rostedt # Passed! All these configs are part of a good compile. 26900a05c769SSteven Rostedt # Add them to the min options. 26910a05c769SSteven Rostedt foreach my $config (keys %configs) { 26920a05c769SSteven Rostedt if (defined($config_list{$config})) { 26930a05c769SSteven Rostedt doprint " removing $config\n"; 26940a05c769SSteven Rostedt $config_ignore{$config} = $config_list{$config}; 26950a05c769SSteven Rostedt delete $config_list{$config}; 26960a05c769SSteven Rostedt } 26970a05c769SSteven Rostedt } 2698f1a27850SSteven Rostedt doprint "config copied to $outputdir/config_good\n"; 2699f1a27850SSteven Rostedt run_command "cp -f $output_config $outputdir/config_good"; 27000a05c769SSteven Rostedt} 27010a05c769SSteven Rostedt 27020a05c769SSteven Rostedtsub process_failed { 27030a05c769SSteven Rostedt my ($config) = @_; 27040a05c769SSteven Rostedt 27050a05c769SSteven Rostedt doprint "\n\n***************************************\n"; 27060a05c769SSteven Rostedt doprint "Found bad config: $config\n"; 27070a05c769SSteven Rostedt doprint "***************************************\n\n"; 27080a05c769SSteven Rostedt} 27090a05c769SSteven Rostedt 27100a05c769SSteven Rostedtsub run_config_bisect { 27110a05c769SSteven Rostedt 27120a05c769SSteven Rostedt my @start_list = keys %config_list; 27130a05c769SSteven Rostedt 27140a05c769SSteven Rostedt if ($#start_list < 0) { 27150a05c769SSteven Rostedt doprint "No more configs to test!!!\n"; 27160a05c769SSteven Rostedt return -1; 27170a05c769SSteven Rostedt } 27180a05c769SSteven Rostedt 27190a05c769SSteven Rostedt doprint "***** RUN TEST ***\n"; 2720b5f4aea6SSteven Rostedt my $type = $config_bisect_type; 27210a05c769SSteven Rostedt my $ret; 27220a05c769SSteven Rostedt my %current_config; 27230a05c769SSteven Rostedt 27240a05c769SSteven Rostedt my $count = $#start_list + 1; 27250a05c769SSteven Rostedt doprint " $count configs to test\n"; 27260a05c769SSteven Rostedt 27270a05c769SSteven Rostedt my $half = int($#start_list / 2); 27280a05c769SSteven Rostedt 27290a05c769SSteven Rostedt do { 27300a05c769SSteven Rostedt my @tophalf = @start_list[0 .. $half]; 27310a05c769SSteven Rostedt 2732cf79fab6SSteven Rostedt # keep the bottom half off 2733cf79fab6SSteven Rostedt if ($half < $#start_list) { 2734cf79fab6SSteven Rostedt @config_off_tmp = @start_list[$half + 1 .. $#start_list]; 2735cf79fab6SSteven Rostedt } else { 2736cf79fab6SSteven Rostedt @config_off_tmp = (); 2737cf79fab6SSteven Rostedt } 2738cf79fab6SSteven Rostedt 27390a05c769SSteven Rostedt create_config @tophalf; 27400a05c769SSteven Rostedt read_current_config \%current_config; 27410a05c769SSteven Rostedt 27420a05c769SSteven Rostedt $count = $#tophalf + 1; 27430a05c769SSteven Rostedt doprint "Testing $count configs\n"; 27440a05c769SSteven Rostedt my $found = 0; 27450a05c769SSteven Rostedt # make sure we test something 27460a05c769SSteven Rostedt foreach my $config (@tophalf) { 27470a05c769SSteven Rostedt if (defined($current_config{$config})) { 27480a05c769SSteven Rostedt logit " $config\n"; 27490a05c769SSteven Rostedt $found = 1; 27500a05c769SSteven Rostedt } 27510a05c769SSteven Rostedt } 27520a05c769SSteven Rostedt if (!$found) { 27530a05c769SSteven Rostedt # try the other half 27540a05c769SSteven Rostedt doprint "Top half produced no set configs, trying bottom half\n"; 2755cf79fab6SSteven Rostedt 2756cf79fab6SSteven Rostedt # keep the top half off 2757cf79fab6SSteven Rostedt @config_off_tmp = @tophalf; 27584c8cc55bSSteven Rostedt @tophalf = @start_list[$half + 1 .. $#start_list]; 2759cf79fab6SSteven Rostedt 27600a05c769SSteven Rostedt create_config @tophalf; 27610a05c769SSteven Rostedt read_current_config \%current_config; 27620a05c769SSteven Rostedt foreach my $config (@tophalf) { 27630a05c769SSteven Rostedt if (defined($current_config{$config})) { 27640a05c769SSteven Rostedt logit " $config\n"; 27650a05c769SSteven Rostedt $found = 1; 27660a05c769SSteven Rostedt } 27670a05c769SSteven Rostedt } 27680a05c769SSteven Rostedt if (!$found) { 27690a05c769SSteven Rostedt doprint "Failed: Can't make new config with current configs\n"; 27700a05c769SSteven Rostedt foreach my $config (@start_list) { 27710a05c769SSteven Rostedt doprint " CONFIG: $config\n"; 27720a05c769SSteven Rostedt } 27730a05c769SSteven Rostedt return -1; 27740a05c769SSteven Rostedt } 27750a05c769SSteven Rostedt $count = $#tophalf + 1; 27760a05c769SSteven Rostedt doprint "Testing $count configs\n"; 27770a05c769SSteven Rostedt } 27780a05c769SSteven Rostedt 27790a05c769SSteven Rostedt $ret = run_config_bisect_test $type; 2780c960bb9fSSteven Rostedt if ($bisect_manual) { 2781c960bb9fSSteven Rostedt $ret = answer_bisect; 2782c960bb9fSSteven Rostedt } 27830a05c769SSteven Rostedt if ($ret) { 27840a05c769SSteven Rostedt process_passed %current_config; 27850a05c769SSteven Rostedt return 0; 27860a05c769SSteven Rostedt } 27870a05c769SSteven Rostedt 27880a05c769SSteven Rostedt doprint "This config had a failure.\n"; 27890a05c769SSteven Rostedt doprint "Removing these configs that were not set in this config:\n"; 2790f1a27850SSteven Rostedt doprint "config copied to $outputdir/config_bad\n"; 2791f1a27850SSteven Rostedt run_command "cp -f $output_config $outputdir/config_bad"; 27920a05c769SSteven Rostedt 27930a05c769SSteven Rostedt # A config exists in this group that was bad. 27940a05c769SSteven Rostedt foreach my $config (keys %config_list) { 27950a05c769SSteven Rostedt if (!defined($current_config{$config})) { 27960a05c769SSteven Rostedt doprint " removing $config\n"; 27970a05c769SSteven Rostedt delete $config_list{$config}; 27980a05c769SSteven Rostedt } 27990a05c769SSteven Rostedt } 28000a05c769SSteven Rostedt 28010a05c769SSteven Rostedt @start_list = @tophalf; 28020a05c769SSteven Rostedt 28030a05c769SSteven Rostedt if ($#start_list == 0) { 28040a05c769SSteven Rostedt process_failed $start_list[0]; 28050a05c769SSteven Rostedt return 1; 28060a05c769SSteven Rostedt } 28070a05c769SSteven Rostedt 28080a05c769SSteven Rostedt # remove half the configs we are looking at and see if 28090a05c769SSteven Rostedt # they are good. 28100a05c769SSteven Rostedt $half = int($#start_list / 2); 28114c8cc55bSSteven Rostedt } while ($#start_list > 0); 28120a05c769SSteven Rostedt 2813c960bb9fSSteven Rostedt # we found a single config, try it again unless we are running manually 2814c960bb9fSSteven Rostedt 2815c960bb9fSSteven Rostedt if ($bisect_manual) { 2816c960bb9fSSteven Rostedt process_failed $start_list[0]; 2817c960bb9fSSteven Rostedt return 1; 2818c960bb9fSSteven Rostedt } 2819c960bb9fSSteven Rostedt 28200a05c769SSteven Rostedt my @tophalf = @start_list[0 .. 0]; 28210a05c769SSteven Rostedt 28220a05c769SSteven Rostedt $ret = run_config_bisect_test $type; 28230a05c769SSteven Rostedt if ($ret) { 28240a05c769SSteven Rostedt process_passed %current_config; 28250a05c769SSteven Rostedt return 0; 28260a05c769SSteven Rostedt } 28270a05c769SSteven Rostedt 28280a05c769SSteven Rostedt process_failed $start_list[0]; 28290a05c769SSteven Rostedt return 1; 28300a05c769SSteven Rostedt} 28310a05c769SSteven Rostedt 28320a05c769SSteven Rostedtsub config_bisect { 28330a05c769SSteven Rostedt my ($i) = @_; 28340a05c769SSteven Rostedt 2835b5f4aea6SSteven Rostedt my $start_config = $config_bisect; 28360a05c769SSteven Rostedt 28370a05c769SSteven Rostedt my $tmpconfig = "$tmpdir/use_config"; 28380a05c769SSteven Rostedt 283930f75da5SSteven Rostedt if (defined($config_bisect_good)) { 284030f75da5SSteven Rostedt process_config_ignore $config_bisect_good; 284130f75da5SSteven Rostedt } 284230f75da5SSteven Rostedt 28430a05c769SSteven Rostedt # Make the file with the bad config and the min config 28440a05c769SSteven Rostedt if (defined($minconfig)) { 28450a05c769SSteven Rostedt # read the min config for things to ignore 28460a05c769SSteven Rostedt run_command "cp $minconfig $tmpconfig" or 28470a05c769SSteven Rostedt dodie "failed to copy $minconfig to $tmpconfig"; 28480a05c769SSteven Rostedt } else { 28490a05c769SSteven Rostedt unlink $tmpconfig; 28500a05c769SSteven Rostedt } 28510a05c769SSteven Rostedt 28520a05c769SSteven Rostedt if (-f $tmpconfig) { 2853fcb3f16aSSteven Rostedt load_force_config($tmpconfig); 28540a05c769SSteven Rostedt process_config_ignore $tmpconfig; 28550a05c769SSteven Rostedt } 28560a05c769SSteven Rostedt 28570a05c769SSteven Rostedt # now process the start config 28580a05c769SSteven Rostedt run_command "cp $start_config $output_config" or 28590a05c769SSteven Rostedt dodie "failed to copy $start_config to $output_config"; 28600a05c769SSteven Rostedt 28610a05c769SSteven Rostedt # read directly what we want to check 28620a05c769SSteven Rostedt my %config_check; 28630a05c769SSteven Rostedt open (IN, $output_config) 2864f9dee311SMasanari Iida or dodie "failed to open $output_config"; 28650a05c769SSteven Rostedt 28660a05c769SSteven Rostedt while (<IN>) { 28670a05c769SSteven Rostedt if (/^((CONFIG\S*)=.*)/) { 28680a05c769SSteven Rostedt $config_check{$2} = $1; 28690a05c769SSteven Rostedt } 28700a05c769SSteven Rostedt } 28710a05c769SSteven Rostedt close(IN); 28720a05c769SSteven Rostedt 2873250bae8bSSteven Rostedt # Now run oldconfig with the minconfig 2874fcb3f16aSSteven Rostedt make_oldconfig; 28750a05c769SSteven Rostedt 28760a05c769SSteven Rostedt # check to see what we lost (or gained) 28770a05c769SSteven Rostedt open (IN, $output_config) 28780a05c769SSteven Rostedt or dodie "Failed to read $start_config"; 28790a05c769SSteven Rostedt 28800a05c769SSteven Rostedt my %removed_configs; 28810a05c769SSteven Rostedt my %added_configs; 28820a05c769SSteven Rostedt 28830a05c769SSteven Rostedt while (<IN>) { 28840a05c769SSteven Rostedt if (/^((CONFIG\S*)=.*)/) { 28850a05c769SSteven Rostedt # save off all options 28860a05c769SSteven Rostedt $config_set{$2} = $1; 28870a05c769SSteven Rostedt if (defined($config_check{$2})) { 28880a05c769SSteven Rostedt if (defined($config_ignore{$2})) { 28890a05c769SSteven Rostedt $removed_configs{$2} = $1; 28900a05c769SSteven Rostedt } else { 28910a05c769SSteven Rostedt $config_list{$2} = $1; 28920a05c769SSteven Rostedt } 28930a05c769SSteven Rostedt } elsif (!defined($config_ignore{$2})) { 28940a05c769SSteven Rostedt $added_configs{$2} = $1; 28950a05c769SSteven Rostedt $config_list{$2} = $1; 28960a05c769SSteven Rostedt } 2897cf79fab6SSteven Rostedt } elsif (/^# ((CONFIG\S*).*)/) { 2898cf79fab6SSteven Rostedt # Keep these configs disabled 2899cf79fab6SSteven Rostedt $config_set{$2} = $1; 2900cf79fab6SSteven Rostedt $config_off{$2} = $1; 29010a05c769SSteven Rostedt } 29020a05c769SSteven Rostedt } 29030a05c769SSteven Rostedt close(IN); 29040a05c769SSteven Rostedt 29050a05c769SSteven Rostedt my @confs = keys %removed_configs; 29060a05c769SSteven Rostedt if ($#confs >= 0) { 29070a05c769SSteven Rostedt doprint "Configs overridden by default configs and removed from check:\n"; 29080a05c769SSteven Rostedt foreach my $config (@confs) { 29090a05c769SSteven Rostedt doprint " $config\n"; 29100a05c769SSteven Rostedt } 29110a05c769SSteven Rostedt } 29120a05c769SSteven Rostedt @confs = keys %added_configs; 29130a05c769SSteven Rostedt if ($#confs >= 0) { 29140a05c769SSteven Rostedt doprint "Configs appearing in make oldconfig and added:\n"; 29150a05c769SSteven Rostedt foreach my $config (@confs) { 29160a05c769SSteven Rostedt doprint " $config\n"; 29170a05c769SSteven Rostedt } 29180a05c769SSteven Rostedt } 29190a05c769SSteven Rostedt 29200a05c769SSteven Rostedt my %config_test; 29210a05c769SSteven Rostedt my $once = 0; 29220a05c769SSteven Rostedt 2923cf79fab6SSteven Rostedt @config_off_tmp = (); 2924cf79fab6SSteven Rostedt 29250a05c769SSteven Rostedt # Sometimes kconfig does weird things. We must make sure 29260a05c769SSteven Rostedt # that the config we autocreate has everything we need 29270a05c769SSteven Rostedt # to test, otherwise we may miss testing configs, or 29280a05c769SSteven Rostedt # may not be able to create a new config. 29290a05c769SSteven Rostedt # Here we create a config with everything set. 29300a05c769SSteven Rostedt create_config (keys %config_list); 29310a05c769SSteven Rostedt read_current_config \%config_test; 29320a05c769SSteven Rostedt foreach my $config (keys %config_list) { 29330a05c769SSteven Rostedt if (!defined($config_test{$config})) { 29340a05c769SSteven Rostedt if (!$once) { 29350a05c769SSteven Rostedt $once = 1; 29360a05c769SSteven Rostedt doprint "Configs not produced by kconfig (will not be checked):\n"; 29370a05c769SSteven Rostedt } 29380a05c769SSteven Rostedt doprint " $config\n"; 29390a05c769SSteven Rostedt delete $config_list{$config}; 29400a05c769SSteven Rostedt } 29410a05c769SSteven Rostedt } 29420a05c769SSteven Rostedt my $ret; 2943b0918612SSteven Rostedt 2944b0918612SSteven Rostedt if (defined($config_bisect_check) && $config_bisect_check) { 2945b0918612SSteven Rostedt doprint " Checking to make sure bad config with min config fails\n"; 2946b0918612SSteven Rostedt create_config keys %config_list; 2947b0918612SSteven Rostedt $ret = run_config_bisect_test $config_bisect_type; 2948b0918612SSteven Rostedt if ($ret) { 2949b0918612SSteven Rostedt doprint " FAILED! Bad config with min config boots fine\n"; 2950b0918612SSteven Rostedt return -1; 2951b0918612SSteven Rostedt } 2952b0918612SSteven Rostedt doprint " Bad config with min config fails as expected\n"; 2953b0918612SSteven Rostedt } 2954b0918612SSteven Rostedt 29550a05c769SSteven Rostedt do { 29560a05c769SSteven Rostedt $ret = run_config_bisect; 29570a05c769SSteven Rostedt } while (!$ret); 29580a05c769SSteven Rostedt 29590a05c769SSteven Rostedt return $ret if ($ret < 0); 29605f9b6cedSSteven Rostedt 29615f9b6cedSSteven Rostedt success $i; 29625f9b6cedSSteven Rostedt} 29635f9b6cedSSteven Rostedt 296427d934b2SSteven Rostedtsub patchcheck_reboot { 296527d934b2SSteven Rostedt doprint "Reboot and sleep $patchcheck_sleep_time seconds\n"; 2966bc7c5803SSteven Rostedt reboot_to_good $patchcheck_sleep_time; 296727d934b2SSteven Rostedt} 296827d934b2SSteven Rostedt 29696c5ee0beSSteven Rostedtsub patchcheck { 29706c5ee0beSSteven Rostedt my ($i) = @_; 29716c5ee0beSSteven Rostedt 29726c5ee0beSSteven Rostedt die "PATCHCHECK_START[$i] not defined\n" 2973b5f4aea6SSteven Rostedt if (!defined($patchcheck_start)); 29746c5ee0beSSteven Rostedt die "PATCHCHECK_TYPE[$i] not defined\n" 2975b5f4aea6SSteven Rostedt if (!defined($patchcheck_type)); 29766c5ee0beSSteven Rostedt 2977b5f4aea6SSteven Rostedt my $start = $patchcheck_start; 29786c5ee0beSSteven Rostedt 29796c5ee0beSSteven Rostedt my $end = "HEAD"; 2980b5f4aea6SSteven Rostedt if (defined($patchcheck_end)) { 2981b5f4aea6SSteven Rostedt $end = $patchcheck_end; 29826c5ee0beSSteven Rostedt } 29836c5ee0beSSteven Rostedt 2984a57419b3SSteven Rostedt # Get the true sha1's since we can use things like HEAD~3 2985a57419b3SSteven Rostedt $start = get_sha1($start); 2986a57419b3SSteven Rostedt $end = get_sha1($end); 2987a57419b3SSteven Rostedt 2988b5f4aea6SSteven Rostedt my $type = $patchcheck_type; 29896c5ee0beSSteven Rostedt 29906c5ee0beSSteven Rostedt # Can't have a test without having a test to run 29916c5ee0beSSteven Rostedt if ($type eq "test" && !defined($run_test)) { 29926c5ee0beSSteven Rostedt $type = "boot"; 29936c5ee0beSSteven Rostedt } 29946c5ee0beSSteven Rostedt 29956c5ee0beSSteven Rostedt open (IN, "git log --pretty=oneline $end|") or 29966c5ee0beSSteven Rostedt dodie "could not get git list"; 29976c5ee0beSSteven Rostedt 29986c5ee0beSSteven Rostedt my @list; 29996c5ee0beSSteven Rostedt 30006c5ee0beSSteven Rostedt while (<IN>) { 30016c5ee0beSSteven Rostedt chomp; 30026c5ee0beSSteven Rostedt $list[$#list+1] = $_; 30036c5ee0beSSteven Rostedt last if (/^$start/); 30046c5ee0beSSteven Rostedt } 30056c5ee0beSSteven Rostedt close(IN); 30066c5ee0beSSteven Rostedt 30076c5ee0beSSteven Rostedt if ($list[$#list] !~ /^$start/) { 30082b7d9b21SSteven Rostedt fail "SHA1 $start not found"; 30096c5ee0beSSteven Rostedt } 30106c5ee0beSSteven Rostedt 30116c5ee0beSSteven Rostedt # go backwards in the list 30126c5ee0beSSteven Rostedt @list = reverse @list; 30136c5ee0beSSteven Rostedt 30146c5ee0beSSteven Rostedt my $save_clean = $noclean; 30151990207dSSteven Rostedt my %ignored_warnings; 30161990207dSSteven Rostedt 30171990207dSSteven Rostedt if (defined($ignore_warnings)) { 30181990207dSSteven Rostedt foreach my $sha1 (split /\s+/, $ignore_warnings) { 30191990207dSSteven Rostedt $ignored_warnings{$sha1} = 1; 30201990207dSSteven Rostedt } 30211990207dSSteven Rostedt } 30226c5ee0beSSteven Rostedt 30236c5ee0beSSteven Rostedt $in_patchcheck = 1; 30246c5ee0beSSteven Rostedt foreach my $item (@list) { 30256c5ee0beSSteven Rostedt my $sha1 = $item; 30266c5ee0beSSteven Rostedt $sha1 =~ s/^([[:xdigit:]]+).*/$1/; 30276c5ee0beSSteven Rostedt 30286c5ee0beSSteven Rostedt doprint "\nProcessing commit $item\n\n"; 30296c5ee0beSSteven Rostedt 30306c5ee0beSSteven Rostedt run_command "git checkout $sha1" or 30316c5ee0beSSteven Rostedt die "Failed to checkout $sha1"; 30326c5ee0beSSteven Rostedt 30336c5ee0beSSteven Rostedt # only clean on the first and last patch 30346c5ee0beSSteven Rostedt if ($item eq $list[0] || 30356c5ee0beSSteven Rostedt $item eq $list[$#list]) { 30366c5ee0beSSteven Rostedt $noclean = $save_clean; 30376c5ee0beSSteven Rostedt } else { 30386c5ee0beSSteven Rostedt $noclean = 1; 30396c5ee0beSSteven Rostedt } 30406c5ee0beSSteven Rostedt 30416c5ee0beSSteven Rostedt if (defined($minconfig)) { 30422b7d9b21SSteven Rostedt build "useconfig:$minconfig" or return 0; 30436c5ee0beSSteven Rostedt } else { 30446c5ee0beSSteven Rostedt # ?? no config to use? 30452b7d9b21SSteven Rostedt build "oldconfig" or return 0; 30466c5ee0beSSteven Rostedt } 30476c5ee0beSSteven Rostedt 30481990207dSSteven Rostedt 30491990207dSSteven Rostedt if (!defined($ignored_warnings{$sha1})) { 30502b7d9b21SSteven Rostedt check_buildlog $sha1 or return 0; 30511990207dSSteven Rostedt } 30526c5ee0beSSteven Rostedt 30536c5ee0beSSteven Rostedt next if ($type eq "build"); 30546c5ee0beSSteven Rostedt 30557faafbd6SSteven Rostedt my $failed = 0; 30567faafbd6SSteven Rostedt 3057ddf607e5SSteven Rostedt start_monitor_and_boot or $failed = 1; 30587faafbd6SSteven Rostedt 30597faafbd6SSteven Rostedt if (!$failed && $type ne "boot"){ 30607faafbd6SSteven Rostedt do_run_test or $failed = 1; 30617faafbd6SSteven Rostedt } 30627faafbd6SSteven Rostedt end_monitor; 30637faafbd6SSteven Rostedt return 0 if ($failed); 30647faafbd6SSteven Rostedt 306527d934b2SSteven Rostedt patchcheck_reboot; 306627d934b2SSteven Rostedt 30676c5ee0beSSteven Rostedt } 30686c5ee0beSSteven Rostedt $in_patchcheck = 0; 30696c5ee0beSSteven Rostedt success $i; 30702b7d9b21SSteven Rostedt 30712b7d9b21SSteven Rostedt return 1; 30726c5ee0beSSteven Rostedt} 30736c5ee0beSSteven Rostedt 3074b9066f6cSSteven Rostedtmy %depends; 3075ac6974c7SSteven Rostedtmy %depcount; 3076b9066f6cSSteven Rostedtmy $iflevel = 0; 3077b9066f6cSSteven Rostedtmy @ifdeps; 3078b9066f6cSSteven Rostedt 3079b9066f6cSSteven Rostedt# prevent recursion 3080b9066f6cSSteven Rostedtmy %read_kconfigs; 3081b9066f6cSSteven Rostedt 3082ac6974c7SSteven Rostedtsub add_dep { 3083ac6974c7SSteven Rostedt # $config depends on $dep 3084ac6974c7SSteven Rostedt my ($config, $dep) = @_; 3085ac6974c7SSteven Rostedt 3086ac6974c7SSteven Rostedt if (defined($depends{$config})) { 3087ac6974c7SSteven Rostedt $depends{$config} .= " " . $dep; 3088ac6974c7SSteven Rostedt } else { 3089ac6974c7SSteven Rostedt $depends{$config} = $dep; 3090ac6974c7SSteven Rostedt } 3091ac6974c7SSteven Rostedt 3092ac6974c7SSteven Rostedt # record the number of configs depending on $dep 3093ac6974c7SSteven Rostedt if (defined $depcount{$dep}) { 3094ac6974c7SSteven Rostedt $depcount{$dep}++; 3095ac6974c7SSteven Rostedt } else { 3096ac6974c7SSteven Rostedt $depcount{$dep} = 1; 3097ac6974c7SSteven Rostedt } 3098ac6974c7SSteven Rostedt} 3099ac6974c7SSteven Rostedt 3100b9066f6cSSteven Rostedt# taken from streamline_config.pl 3101b9066f6cSSteven Rostedtsub read_kconfig { 3102b9066f6cSSteven Rostedt my ($kconfig) = @_; 3103b9066f6cSSteven Rostedt 3104b9066f6cSSteven Rostedt my $state = "NONE"; 3105b9066f6cSSteven Rostedt my $config; 3106b9066f6cSSteven Rostedt my @kconfigs; 3107b9066f6cSSteven Rostedt 3108b9066f6cSSteven Rostedt my $cont = 0; 3109b9066f6cSSteven Rostedt my $line; 3110b9066f6cSSteven Rostedt 3111b9066f6cSSteven Rostedt 3112b9066f6cSSteven Rostedt if (! -f $kconfig) { 3113b9066f6cSSteven Rostedt doprint "file $kconfig does not exist, skipping\n"; 3114b9066f6cSSteven Rostedt return; 3115b9066f6cSSteven Rostedt } 3116b9066f6cSSteven Rostedt 3117b9066f6cSSteven Rostedt open(KIN, "$kconfig") 3118b9066f6cSSteven Rostedt or die "Can't open $kconfig"; 3119b9066f6cSSteven Rostedt while (<KIN>) { 3120b9066f6cSSteven Rostedt chomp; 3121b9066f6cSSteven Rostedt 3122b9066f6cSSteven Rostedt # Make sure that lines ending with \ continue 3123b9066f6cSSteven Rostedt if ($cont) { 3124b9066f6cSSteven Rostedt $_ = $line . " " . $_; 3125b9066f6cSSteven Rostedt } 3126b9066f6cSSteven Rostedt 3127b9066f6cSSteven Rostedt if (s/\\$//) { 3128b9066f6cSSteven Rostedt $cont = 1; 3129b9066f6cSSteven Rostedt $line = $_; 3130b9066f6cSSteven Rostedt next; 3131b9066f6cSSteven Rostedt } 3132b9066f6cSSteven Rostedt 3133b9066f6cSSteven Rostedt $cont = 0; 3134b9066f6cSSteven Rostedt 3135b9066f6cSSteven Rostedt # collect any Kconfig sources 3136b9066f6cSSteven Rostedt if (/^source\s*"(.*)"/) { 3137b9066f6cSSteven Rostedt $kconfigs[$#kconfigs+1] = $1; 3138b9066f6cSSteven Rostedt } 3139b9066f6cSSteven Rostedt 3140b9066f6cSSteven Rostedt # configs found 3141b9066f6cSSteven Rostedt if (/^\s*(menu)?config\s+(\S+)\s*$/) { 3142b9066f6cSSteven Rostedt $state = "NEW"; 3143b9066f6cSSteven Rostedt $config = $2; 3144b9066f6cSSteven Rostedt 3145b9066f6cSSteven Rostedt for (my $i = 0; $i < $iflevel; $i++) { 3146ac6974c7SSteven Rostedt add_dep $config, $ifdeps[$i]; 3147b9066f6cSSteven Rostedt } 3148b9066f6cSSteven Rostedt 3149b9066f6cSSteven Rostedt # collect the depends for the config 3150b9066f6cSSteven Rostedt } elsif ($state eq "NEW" && /^\s*depends\s+on\s+(.*)$/) { 3151b9066f6cSSteven Rostedt 3152ac6974c7SSteven Rostedt add_dep $config, $1; 3153b9066f6cSSteven Rostedt 3154b9066f6cSSteven Rostedt # Get the configs that select this config 3155ac6974c7SSteven Rostedt } elsif ($state eq "NEW" && /^\s*select\s+(\S+)/) { 3156ac6974c7SSteven Rostedt 3157ac6974c7SSteven Rostedt # selected by depends on config 3158ac6974c7SSteven Rostedt add_dep $1, $config; 3159b9066f6cSSteven Rostedt 3160b9066f6cSSteven Rostedt # Check for if statements 3161b9066f6cSSteven Rostedt } elsif (/^if\s+(.*\S)\s*$/) { 3162b9066f6cSSteven Rostedt my $deps = $1; 3163b9066f6cSSteven Rostedt # remove beginning and ending non text 3164b9066f6cSSteven Rostedt $deps =~ s/^[^a-zA-Z0-9_]*//; 3165b9066f6cSSteven Rostedt $deps =~ s/[^a-zA-Z0-9_]*$//; 3166b9066f6cSSteven Rostedt 3167b9066f6cSSteven Rostedt my @deps = split /[^a-zA-Z0-9_]+/, $deps; 3168b9066f6cSSteven Rostedt 3169b9066f6cSSteven Rostedt $ifdeps[$iflevel++] = join ':', @deps; 3170b9066f6cSSteven Rostedt 3171b9066f6cSSteven Rostedt } elsif (/^endif/) { 3172b9066f6cSSteven Rostedt 3173b9066f6cSSteven Rostedt $iflevel-- if ($iflevel); 3174b9066f6cSSteven Rostedt 3175b9066f6cSSteven Rostedt # stop on "help" 3176b9066f6cSSteven Rostedt } elsif (/^\s*help\s*$/) { 3177b9066f6cSSteven Rostedt $state = "NONE"; 3178b9066f6cSSteven Rostedt } 3179b9066f6cSSteven Rostedt } 3180b9066f6cSSteven Rostedt close(KIN); 3181b9066f6cSSteven Rostedt 3182b9066f6cSSteven Rostedt # read in any configs that were found. 3183b9066f6cSSteven Rostedt foreach $kconfig (@kconfigs) { 3184b9066f6cSSteven Rostedt if (!defined($read_kconfigs{$kconfig})) { 3185b9066f6cSSteven Rostedt $read_kconfigs{$kconfig} = 1; 3186b9066f6cSSteven Rostedt read_kconfig("$builddir/$kconfig"); 3187b9066f6cSSteven Rostedt } 3188b9066f6cSSteven Rostedt } 3189b9066f6cSSteven Rostedt} 3190b9066f6cSSteven Rostedt 3191b9066f6cSSteven Rostedtsub read_depends { 3192b9066f6cSSteven Rostedt # find out which arch this is by the kconfig file 3193b9066f6cSSteven Rostedt open (IN, $output_config) 3194b9066f6cSSteven Rostedt or dodie "Failed to read $output_config"; 3195b9066f6cSSteven Rostedt my $arch; 3196b9066f6cSSteven Rostedt while (<IN>) { 3197b9066f6cSSteven Rostedt if (m,Linux/(\S+)\s+\S+\s+Kernel Configuration,) { 3198b9066f6cSSteven Rostedt $arch = $1; 3199b9066f6cSSteven Rostedt last; 3200b9066f6cSSteven Rostedt } 3201b9066f6cSSteven Rostedt } 3202b9066f6cSSteven Rostedt close IN; 3203b9066f6cSSteven Rostedt 3204b9066f6cSSteven Rostedt if (!defined($arch)) { 3205b9066f6cSSteven Rostedt doprint "Could not find arch from config file\n"; 3206b9066f6cSSteven Rostedt doprint "no dependencies used\n"; 3207b9066f6cSSteven Rostedt return; 3208b9066f6cSSteven Rostedt } 3209b9066f6cSSteven Rostedt 3210b9066f6cSSteven Rostedt # arch is really the subarch, we need to know 3211b9066f6cSSteven Rostedt # what directory to look at. 3212b9066f6cSSteven Rostedt if ($arch eq "i386" || $arch eq "x86_64") { 3213b9066f6cSSteven Rostedt $arch = "x86"; 3214b9066f6cSSteven Rostedt } elsif ($arch =~ /^tile/) { 3215b9066f6cSSteven Rostedt $arch = "tile"; 3216b9066f6cSSteven Rostedt } 3217b9066f6cSSteven Rostedt 3218b9066f6cSSteven Rostedt my $kconfig = "$builddir/arch/$arch/Kconfig"; 3219b9066f6cSSteven Rostedt 3220b9066f6cSSteven Rostedt if (! -f $kconfig && $arch =~ /\d$/) { 3221b9066f6cSSteven Rostedt my $orig = $arch; 3222b9066f6cSSteven Rostedt # some subarchs have numbers, truncate them 3223b9066f6cSSteven Rostedt $arch =~ s/\d*$//; 3224b9066f6cSSteven Rostedt $kconfig = "$builddir/arch/$arch/Kconfig"; 3225b9066f6cSSteven Rostedt if (! -f $kconfig) { 3226b9066f6cSSteven Rostedt doprint "No idea what arch dir $orig is for\n"; 3227b9066f6cSSteven Rostedt doprint "no dependencies used\n"; 3228b9066f6cSSteven Rostedt return; 3229b9066f6cSSteven Rostedt } 3230b9066f6cSSteven Rostedt } 3231b9066f6cSSteven Rostedt 3232b9066f6cSSteven Rostedt read_kconfig($kconfig); 3233b9066f6cSSteven Rostedt} 3234b9066f6cSSteven Rostedt 32354c4ab120SSteven Rostedtsub read_config_list { 32364c4ab120SSteven Rostedt my ($config) = @_; 32374c4ab120SSteven Rostedt 32384c4ab120SSteven Rostedt open (IN, $config) 32394c4ab120SSteven Rostedt or dodie "Failed to read $config"; 32404c4ab120SSteven Rostedt 32414c4ab120SSteven Rostedt while (<IN>) { 32424c4ab120SSteven Rostedt if (/^((CONFIG\S*)=.*)/) { 32434c4ab120SSteven Rostedt if (!defined($config_ignore{$2})) { 32444c4ab120SSteven Rostedt $config_list{$2} = $1; 32454c4ab120SSteven Rostedt } 32464c4ab120SSteven Rostedt } 32474c4ab120SSteven Rostedt } 32484c4ab120SSteven Rostedt 32494c4ab120SSteven Rostedt close(IN); 32504c4ab120SSteven Rostedt} 32514c4ab120SSteven Rostedt 32524c4ab120SSteven Rostedtsub read_output_config { 32534c4ab120SSteven Rostedt my ($config) = @_; 32544c4ab120SSteven Rostedt 32554c4ab120SSteven Rostedt assign_configs \%config_ignore, $config; 32564c4ab120SSteven Rostedt} 32574c4ab120SSteven Rostedt 32584c4ab120SSteven Rostedtsub make_new_config { 32594c4ab120SSteven Rostedt my @configs = @_; 32604c4ab120SSteven Rostedt 32614c4ab120SSteven Rostedt open (OUT, ">$output_config") 32624c4ab120SSteven Rostedt or dodie "Failed to write $output_config"; 32634c4ab120SSteven Rostedt 32644c4ab120SSteven Rostedt foreach my $config (@configs) { 32654c4ab120SSteven Rostedt print OUT "$config\n"; 32664c4ab120SSteven Rostedt } 32674c4ab120SSteven Rostedt close OUT; 32684c4ab120SSteven Rostedt} 32694c4ab120SSteven Rostedt 3270ac6974c7SSteven Rostedtsub chomp_config { 3271ac6974c7SSteven Rostedt my ($config) = @_; 3272ac6974c7SSteven Rostedt 3273ac6974c7SSteven Rostedt $config =~ s/CONFIG_//; 3274ac6974c7SSteven Rostedt 3275ac6974c7SSteven Rostedt return $config; 3276ac6974c7SSteven Rostedt} 3277ac6974c7SSteven Rostedt 3278b9066f6cSSteven Rostedtsub get_depends { 3279b9066f6cSSteven Rostedt my ($dep) = @_; 3280b9066f6cSSteven Rostedt 3281ac6974c7SSteven Rostedt my $kconfig = chomp_config $dep; 3282b9066f6cSSteven Rostedt 3283b9066f6cSSteven Rostedt $dep = $depends{"$kconfig"}; 3284b9066f6cSSteven Rostedt 3285b9066f6cSSteven Rostedt # the dep string we have saves the dependencies as they 3286b9066f6cSSteven Rostedt # were found, including expressions like ! && ||. We 3287b9066f6cSSteven Rostedt # want to split this out into just an array of configs. 3288b9066f6cSSteven Rostedt 3289b9066f6cSSteven Rostedt my $valid = "A-Za-z_0-9"; 3290b9066f6cSSteven Rostedt 3291b9066f6cSSteven Rostedt my @configs; 3292b9066f6cSSteven Rostedt 3293b9066f6cSSteven Rostedt while ($dep =~ /[$valid]/) { 3294b9066f6cSSteven Rostedt 3295b9066f6cSSteven Rostedt if ($dep =~ /^[^$valid]*([$valid]+)/) { 3296b9066f6cSSteven Rostedt my $conf = "CONFIG_" . $1; 3297b9066f6cSSteven Rostedt 3298b9066f6cSSteven Rostedt $configs[$#configs + 1] = $conf; 3299b9066f6cSSteven Rostedt 3300b9066f6cSSteven Rostedt $dep =~ s/^[^$valid]*[$valid]+//; 3301b9066f6cSSteven Rostedt } else { 3302b9066f6cSSteven Rostedt die "this should never happen"; 3303b9066f6cSSteven Rostedt } 3304b9066f6cSSteven Rostedt } 3305b9066f6cSSteven Rostedt 3306b9066f6cSSteven Rostedt return @configs; 3307b9066f6cSSteven Rostedt} 3308b9066f6cSSteven Rostedt 3309b9066f6cSSteven Rostedtmy %min_configs; 3310b9066f6cSSteven Rostedtmy %keep_configs; 331143d1b651SSteven Rostedtmy %save_configs; 3312b9066f6cSSteven Rostedtmy %processed_configs; 3313b9066f6cSSteven Rostedtmy %nochange_config; 3314b9066f6cSSteven Rostedt 3315b9066f6cSSteven Rostedtsub test_this_config { 3316b9066f6cSSteven Rostedt my ($config) = @_; 3317b9066f6cSSteven Rostedt 3318b9066f6cSSteven Rostedt my $found; 3319b9066f6cSSteven Rostedt 3320b9066f6cSSteven Rostedt # if we already processed this config, skip it 3321b9066f6cSSteven Rostedt if (defined($processed_configs{$config})) { 3322b9066f6cSSteven Rostedt return undef; 3323b9066f6cSSteven Rostedt } 3324b9066f6cSSteven Rostedt $processed_configs{$config} = 1; 3325b9066f6cSSteven Rostedt 3326b9066f6cSSteven Rostedt # if this config failed during this round, skip it 3327b9066f6cSSteven Rostedt if (defined($nochange_config{$config})) { 3328b9066f6cSSteven Rostedt return undef; 3329b9066f6cSSteven Rostedt } 3330b9066f6cSSteven Rostedt 3331ac6974c7SSteven Rostedt my $kconfig = chomp_config $config; 3332b9066f6cSSteven Rostedt 3333b9066f6cSSteven Rostedt # Test dependencies first 3334b9066f6cSSteven Rostedt if (defined($depends{"$kconfig"})) { 3335b9066f6cSSteven Rostedt my @parents = get_depends $config; 3336b9066f6cSSteven Rostedt foreach my $parent (@parents) { 3337b9066f6cSSteven Rostedt # if the parent is in the min config, check it first 3338b9066f6cSSteven Rostedt next if (!defined($min_configs{$parent})); 3339b9066f6cSSteven Rostedt $found = test_this_config($parent); 3340b9066f6cSSteven Rostedt if (defined($found)) { 3341b9066f6cSSteven Rostedt return $found; 3342b9066f6cSSteven Rostedt } 3343b9066f6cSSteven Rostedt } 3344b9066f6cSSteven Rostedt } 3345b9066f6cSSteven Rostedt 3346b9066f6cSSteven Rostedt # Remove this config from the list of configs 3347fb16d891SAdam Lee # do a make olddefconfig and then read the resulting 3348b9066f6cSSteven Rostedt # .config to make sure it is missing the config that 3349b9066f6cSSteven Rostedt # we had before 3350b9066f6cSSteven Rostedt my %configs = %min_configs; 3351b9066f6cSSteven Rostedt delete $configs{$config}; 3352b9066f6cSSteven Rostedt make_new_config ((values %configs), (values %keep_configs)); 3353b9066f6cSSteven Rostedt make_oldconfig; 3354b9066f6cSSteven Rostedt undef %configs; 3355b9066f6cSSteven Rostedt assign_configs \%configs, $output_config; 3356b9066f6cSSteven Rostedt 3357b9066f6cSSteven Rostedt return $config if (!defined($configs{$config})); 3358b9066f6cSSteven Rostedt 3359b9066f6cSSteven Rostedt doprint "disabling config $config did not change .config\n"; 3360b9066f6cSSteven Rostedt 3361b9066f6cSSteven Rostedt $nochange_config{$config} = 1; 3362b9066f6cSSteven Rostedt 3363b9066f6cSSteven Rostedt return undef; 3364b9066f6cSSteven Rostedt} 3365b9066f6cSSteven Rostedt 33664c4ab120SSteven Rostedtsub make_min_config { 33674c4ab120SSteven Rostedt my ($i) = @_; 33684c4ab120SSteven Rostedt 3369ccc513b6SSteven Rostedt my $type = $minconfig_type; 3370ccc513b6SSteven Rostedt if ($type ne "boot" && $type ne "test") { 3371ccc513b6SSteven Rostedt fail "Invalid MIN_CONFIG_TYPE '$minconfig_type'\n" . 3372ccc513b6SSteven Rostedt " make_min_config works only with 'boot' and 'test'\n" and return; 3373ccc513b6SSteven Rostedt } 3374ccc513b6SSteven Rostedt 33754c4ab120SSteven Rostedt if (!defined($output_minconfig)) { 33764c4ab120SSteven Rostedt fail "OUTPUT_MIN_CONFIG not defined" and return; 33774c4ab120SSteven Rostedt } 337835ce5952SSteven Rostedt 337935ce5952SSteven Rostedt # If output_minconfig exists, and the start_minconfig 338035ce5952SSteven Rostedt # came from min_config, than ask if we should use 338135ce5952SSteven Rostedt # that instead. 338235ce5952SSteven Rostedt if (-f $output_minconfig && !$start_minconfig_defined) { 338335ce5952SSteven Rostedt print "$output_minconfig exists\n"; 338443de3316SSteven Rostedt if (!defined($use_output_minconfig)) { 338535ce5952SSteven Rostedt if (read_yn " Use it as minconfig?") { 338635ce5952SSteven Rostedt $start_minconfig = $output_minconfig; 338735ce5952SSteven Rostedt } 338843de3316SSteven Rostedt } elsif ($use_output_minconfig > 0) { 338943de3316SSteven Rostedt doprint "Using $output_minconfig as MIN_CONFIG\n"; 339043de3316SSteven Rostedt $start_minconfig = $output_minconfig; 339143de3316SSteven Rostedt } else { 339243de3316SSteven Rostedt doprint "Set to still use MIN_CONFIG as starting point\n"; 339343de3316SSteven Rostedt } 339435ce5952SSteven Rostedt } 339535ce5952SSteven Rostedt 33964c4ab120SSteven Rostedt if (!defined($start_minconfig)) { 33974c4ab120SSteven Rostedt fail "START_MIN_CONFIG or MIN_CONFIG not defined" and return; 33984c4ab120SSteven Rostedt } 33994c4ab120SSteven Rostedt 340035ce5952SSteven Rostedt my $temp_config = "$tmpdir/temp_config"; 340135ce5952SSteven Rostedt 34024c4ab120SSteven Rostedt # First things first. We build an allnoconfig to find 34034c4ab120SSteven Rostedt # out what the defaults are that we can't touch. 34044c4ab120SSteven Rostedt # Some are selections, but we really can't handle selections. 34054c4ab120SSteven Rostedt 34064c4ab120SSteven Rostedt my $save_minconfig = $minconfig; 34074c4ab120SSteven Rostedt undef $minconfig; 34084c4ab120SSteven Rostedt 34094c4ab120SSteven Rostedt run_command "$make allnoconfig" or return 0; 34104c4ab120SSteven Rostedt 3411b9066f6cSSteven Rostedt read_depends; 3412b9066f6cSSteven Rostedt 34134c4ab120SSteven Rostedt process_config_ignore $output_config; 3414b9066f6cSSteven Rostedt 341543d1b651SSteven Rostedt undef %save_configs; 3416b9066f6cSSteven Rostedt undef %min_configs; 34174c4ab120SSteven Rostedt 34184c4ab120SSteven Rostedt if (defined($ignore_config)) { 34194c4ab120SSteven Rostedt # make sure the file exists 34204c4ab120SSteven Rostedt `touch $ignore_config`; 342143d1b651SSteven Rostedt assign_configs \%save_configs, $ignore_config; 34224c4ab120SSteven Rostedt } 34234c4ab120SSteven Rostedt 342443d1b651SSteven Rostedt %keep_configs = %save_configs; 342543d1b651SSteven Rostedt 34264c4ab120SSteven Rostedt doprint "Load initial configs from $start_minconfig\n"; 34274c4ab120SSteven Rostedt 34284c4ab120SSteven Rostedt # Look at the current min configs, and save off all the 34294c4ab120SSteven Rostedt # ones that were set via the allnoconfig 34304c4ab120SSteven Rostedt assign_configs \%min_configs, $start_minconfig; 34314c4ab120SSteven Rostedt 34324c4ab120SSteven Rostedt my @config_keys = keys %min_configs; 34334c4ab120SSteven Rostedt 3434ac6974c7SSteven Rostedt # All configs need a depcount 3435ac6974c7SSteven Rostedt foreach my $config (@config_keys) { 3436ac6974c7SSteven Rostedt my $kconfig = chomp_config $config; 3437ac6974c7SSteven Rostedt if (!defined $depcount{$kconfig}) { 3438ac6974c7SSteven Rostedt $depcount{$kconfig} = 0; 3439ac6974c7SSteven Rostedt } 3440ac6974c7SSteven Rostedt } 3441ac6974c7SSteven Rostedt 34424c4ab120SSteven Rostedt # Remove anything that was set by the make allnoconfig 34434c4ab120SSteven Rostedt # we shouldn't need them as they get set for us anyway. 34444c4ab120SSteven Rostedt foreach my $config (@config_keys) { 34454c4ab120SSteven Rostedt # Remove anything in the ignore_config 34464c4ab120SSteven Rostedt if (defined($keep_configs{$config})) { 34474c4ab120SSteven Rostedt my $file = $ignore_config; 34484c4ab120SSteven Rostedt $file =~ s,.*/(.*?)$,$1,; 34494c4ab120SSteven Rostedt doprint "$config set by $file ... ignored\n"; 34504c4ab120SSteven Rostedt delete $min_configs{$config}; 34514c4ab120SSteven Rostedt next; 34524c4ab120SSteven Rostedt } 34534c4ab120SSteven Rostedt # But make sure the settings are the same. If a min config 34544c4ab120SSteven Rostedt # sets a selection, we do not want to get rid of it if 34554c4ab120SSteven Rostedt # it is not the same as what we have. Just move it into 34564c4ab120SSteven Rostedt # the keep configs. 34574c4ab120SSteven Rostedt if (defined($config_ignore{$config})) { 34584c4ab120SSteven Rostedt if ($config_ignore{$config} ne $min_configs{$config}) { 34594c4ab120SSteven Rostedt doprint "$config is in allnoconfig as '$config_ignore{$config}'"; 34604c4ab120SSteven Rostedt doprint " but it is '$min_configs{$config}' in minconfig .. keeping\n"; 34614c4ab120SSteven Rostedt $keep_configs{$config} = $min_configs{$config}; 34624c4ab120SSteven Rostedt } else { 34634c4ab120SSteven Rostedt doprint "$config set by allnoconfig ... ignored\n"; 34644c4ab120SSteven Rostedt } 34654c4ab120SSteven Rostedt delete $min_configs{$config}; 34664c4ab120SSteven Rostedt } 34674c4ab120SSteven Rostedt } 34684c4ab120SSteven Rostedt 34694c4ab120SSteven Rostedt my $done = 0; 3470b9066f6cSSteven Rostedt my $take_two = 0; 34714c4ab120SSteven Rostedt 34724c4ab120SSteven Rostedt while (!$done) { 34734c4ab120SSteven Rostedt 34744c4ab120SSteven Rostedt my $config; 34754c4ab120SSteven Rostedt my $found; 34764c4ab120SSteven Rostedt 34774c4ab120SSteven Rostedt # Now disable each config one by one and do a make oldconfig 34784c4ab120SSteven Rostedt # till we find a config that changes our list. 34794c4ab120SSteven Rostedt 34804c4ab120SSteven Rostedt my @test_configs = keys %min_configs; 3481ac6974c7SSteven Rostedt 3482ac6974c7SSteven Rostedt # Sort keys by who is most dependent on 3483ac6974c7SSteven Rostedt @test_configs = sort { $depcount{chomp_config($b)} <=> $depcount{chomp_config($a)} } 3484ac6974c7SSteven Rostedt @test_configs ; 3485ac6974c7SSteven Rostedt 3486ac6974c7SSteven Rostedt # Put configs that did not modify the config at the end. 34874c4ab120SSteven Rostedt my $reset = 1; 34884c4ab120SSteven Rostedt for (my $i = 0; $i < $#test_configs; $i++) { 34894c4ab120SSteven Rostedt if (!defined($nochange_config{$test_configs[0]})) { 34904c4ab120SSteven Rostedt $reset = 0; 34914c4ab120SSteven Rostedt last; 34924c4ab120SSteven Rostedt } 34934c4ab120SSteven Rostedt # This config didn't change the .config last time. 34944c4ab120SSteven Rostedt # Place it at the end 34954c4ab120SSteven Rostedt my $config = shift @test_configs; 34964c4ab120SSteven Rostedt push @test_configs, $config; 34974c4ab120SSteven Rostedt } 34984c4ab120SSteven Rostedt 34994c4ab120SSteven Rostedt # if every test config has failed to modify the .config file 35004c4ab120SSteven Rostedt # in the past, then reset and start over. 35014c4ab120SSteven Rostedt if ($reset) { 35024c4ab120SSteven Rostedt undef %nochange_config; 35034c4ab120SSteven Rostedt } 35044c4ab120SSteven Rostedt 3505b9066f6cSSteven Rostedt undef %processed_configs; 3506b9066f6cSSteven Rostedt 35074c4ab120SSteven Rostedt foreach my $config (@test_configs) { 35084c4ab120SSteven Rostedt 3509b9066f6cSSteven Rostedt $found = test_this_config $config; 35104c4ab120SSteven Rostedt 3511b9066f6cSSteven Rostedt last if (defined($found)); 35124c4ab120SSteven Rostedt 35134c4ab120SSteven Rostedt # oh well, try another config 35144c4ab120SSteven Rostedt } 35154c4ab120SSteven Rostedt 35164c4ab120SSteven Rostedt if (!defined($found)) { 3517b9066f6cSSteven Rostedt # we could have failed due to the nochange_config hash 3518b9066f6cSSteven Rostedt # reset and try again 3519b9066f6cSSteven Rostedt if (!$take_two) { 3520b9066f6cSSteven Rostedt undef %nochange_config; 3521b9066f6cSSteven Rostedt $take_two = 1; 3522b9066f6cSSteven Rostedt next; 3523b9066f6cSSteven Rostedt } 35244c4ab120SSteven Rostedt doprint "No more configs found that we can disable\n"; 35254c4ab120SSteven Rostedt $done = 1; 35264c4ab120SSteven Rostedt last; 35274c4ab120SSteven Rostedt } 3528b9066f6cSSteven Rostedt $take_two = 0; 35294c4ab120SSteven Rostedt 35304c4ab120SSteven Rostedt $config = $found; 35314c4ab120SSteven Rostedt 35324c4ab120SSteven Rostedt doprint "Test with $config disabled\n"; 35334c4ab120SSteven Rostedt 35344c4ab120SSteven Rostedt # set in_bisect to keep build and monitor from dieing 35354c4ab120SSteven Rostedt $in_bisect = 1; 35364c4ab120SSteven Rostedt 35374c4ab120SSteven Rostedt my $failed = 0; 3538bf1c95abSSteven Rostedt build "oldconfig" or $failed = 1; 3539bf1c95abSSteven Rostedt if (!$failed) { 35404c4ab120SSteven Rostedt start_monitor_and_boot or $failed = 1; 3541ccc513b6SSteven Rostedt 3542ccc513b6SSteven Rostedt if ($type eq "test" && !$failed) { 3543ccc513b6SSteven Rostedt do_run_test or $failed = 1; 3544ccc513b6SSteven Rostedt } 3545ccc513b6SSteven Rostedt 35464c4ab120SSteven Rostedt end_monitor; 3547bf1c95abSSteven Rostedt } 35484c4ab120SSteven Rostedt 35494c4ab120SSteven Rostedt $in_bisect = 0; 35504c4ab120SSteven Rostedt 35514c4ab120SSteven Rostedt if ($failed) { 3552b9066f6cSSteven Rostedt doprint "$min_configs{$config} is needed to boot the box... keeping\n"; 35534c4ab120SSteven Rostedt # this config is needed, add it to the ignore list. 35544c4ab120SSteven Rostedt $keep_configs{$config} = $min_configs{$config}; 355543d1b651SSteven Rostedt $save_configs{$config} = $min_configs{$config}; 35564c4ab120SSteven Rostedt delete $min_configs{$config}; 355735ce5952SSteven Rostedt 355835ce5952SSteven Rostedt # update new ignore configs 355935ce5952SSteven Rostedt if (defined($ignore_config)) { 356035ce5952SSteven Rostedt open (OUT, ">$temp_config") 356135ce5952SSteven Rostedt or die "Can't write to $temp_config"; 356243d1b651SSteven Rostedt foreach my $config (keys %save_configs) { 356343d1b651SSteven Rostedt print OUT "$save_configs{$config}\n"; 356435ce5952SSteven Rostedt } 356535ce5952SSteven Rostedt close OUT; 356635ce5952SSteven Rostedt run_command "mv $temp_config $ignore_config" or 356735ce5952SSteven Rostedt dodie "failed to copy update to $ignore_config"; 356835ce5952SSteven Rostedt } 356935ce5952SSteven Rostedt 35704c4ab120SSteven Rostedt } else { 35714c4ab120SSteven Rostedt # We booted without this config, remove it from the minconfigs. 35724c4ab120SSteven Rostedt doprint "$config is not needed, disabling\n"; 35734c4ab120SSteven Rostedt 35744c4ab120SSteven Rostedt delete $min_configs{$config}; 35754c4ab120SSteven Rostedt 35764c4ab120SSteven Rostedt # Also disable anything that is not enabled in this config 35774c4ab120SSteven Rostedt my %configs; 35784c4ab120SSteven Rostedt assign_configs \%configs, $output_config; 35794c4ab120SSteven Rostedt my @config_keys = keys %min_configs; 35804c4ab120SSteven Rostedt foreach my $config (@config_keys) { 35814c4ab120SSteven Rostedt if (!defined($configs{$config})) { 35824c4ab120SSteven Rostedt doprint "$config is not set, disabling\n"; 35834c4ab120SSteven Rostedt delete $min_configs{$config}; 35844c4ab120SSteven Rostedt } 35854c4ab120SSteven Rostedt } 35864c4ab120SSteven Rostedt 35874c4ab120SSteven Rostedt # Save off all the current mandidory configs 358835ce5952SSteven Rostedt open (OUT, ">$temp_config") 358935ce5952SSteven Rostedt or die "Can't write to $temp_config"; 35904c4ab120SSteven Rostedt foreach my $config (keys %keep_configs) { 35914c4ab120SSteven Rostedt print OUT "$keep_configs{$config}\n"; 35924c4ab120SSteven Rostedt } 35934c4ab120SSteven Rostedt foreach my $config (keys %min_configs) { 35944c4ab120SSteven Rostedt print OUT "$min_configs{$config}\n"; 35954c4ab120SSteven Rostedt } 35964c4ab120SSteven Rostedt close OUT; 359735ce5952SSteven Rostedt 359835ce5952SSteven Rostedt run_command "mv $temp_config $output_minconfig" or 359935ce5952SSteven Rostedt dodie "failed to copy update to $output_minconfig"; 36004c4ab120SSteven Rostedt } 36014c4ab120SSteven Rostedt 36024c4ab120SSteven Rostedt doprint "Reboot and wait $sleep_time seconds\n"; 3603bc7c5803SSteven Rostedt reboot_to_good $sleep_time; 36044c4ab120SSteven Rostedt } 36054c4ab120SSteven Rostedt 36064c4ab120SSteven Rostedt success $i; 36074c4ab120SSteven Rostedt return 1; 36084c4ab120SSteven Rostedt} 36094c4ab120SSteven Rostedt 36108d1491baSSteven Rostedt$#ARGV < 1 or die "ktest.pl version: $VERSION\n usage: ktest.pl config-file\n"; 36112545eb61SSteven Rostedt 36128d1491baSSteven Rostedtif ($#ARGV == 0) { 36138d1491baSSteven Rostedt $ktest_config = $ARGV[0]; 36148d1491baSSteven Rostedt if (! -f $ktest_config) { 36158d1491baSSteven Rostedt print "$ktest_config does not exist.\n"; 361635ce5952SSteven Rostedt if (!read_yn "Create it?") { 36178d1491baSSteven Rostedt exit 0; 36188d1491baSSteven Rostedt } 36198d1491baSSteven Rostedt } 36208d1491baSSteven Rostedt} else { 36218d1491baSSteven Rostedt $ktest_config = "ktest.conf"; 36228d1491baSSteven Rostedt} 36238d1491baSSteven Rostedt 36248d1491baSSteven Rostedtif (! -f $ktest_config) { 3625dbd3783bSSteven Rostedt $newconfig = 1; 3626c4261d0fSSteven Rostedt get_test_case; 36278d1491baSSteven Rostedt open(OUT, ">$ktest_config") or die "Can not create $ktest_config"; 36288d1491baSSteven Rostedt print OUT << "EOF" 36298d1491baSSteven Rostedt# Generated by ktest.pl 36308d1491baSSteven Rostedt# 36310e7a22deSSteven Rostedt 36320e7a22deSSteven Rostedt# PWD is a ktest.pl variable that will result in the process working 36330e7a22deSSteven Rostedt# directory that ktest.pl is executed in. 36340e7a22deSSteven Rostedt 36350e7a22deSSteven Rostedt# THIS_DIR is automatically assigned the PWD of the path that generated 36360e7a22deSSteven Rostedt# the config file. It is best to use this variable when assigning other 36370e7a22deSSteven Rostedt# directory paths within this directory. This allows you to easily 36380e7a22deSSteven Rostedt# move the test cases to other locations or to other machines. 36390e7a22deSSteven Rostedt# 36400e7a22deSSteven RostedtTHIS_DIR := $variable{"PWD"} 36410e7a22deSSteven Rostedt 36428d1491baSSteven Rostedt# Define each test with TEST_START 36438d1491baSSteven Rostedt# The config options below it will override the defaults 36448d1491baSSteven RostedtTEST_START 3645c4261d0fSSteven RostedtTEST_TYPE = $default{"TEST_TYPE"} 36468d1491baSSteven Rostedt 36478d1491baSSteven RostedtDEFAULTS 36488d1491baSSteven RostedtEOF 36498d1491baSSteven Rostedt; 36508d1491baSSteven Rostedt close(OUT); 36518d1491baSSteven Rostedt} 36528d1491baSSteven Rostedtread_config $ktest_config; 36538d1491baSSteven Rostedt 365423715c3cSSteven Rostedtif (defined($opt{"LOG_FILE"})) { 365523715c3cSSteven Rostedt $opt{"LOG_FILE"} = eval_option($opt{"LOG_FILE"}, -1); 365623715c3cSSteven Rostedt} 365723715c3cSSteven Rostedt 36588d1491baSSteven Rostedt# Append any configs entered in manually to the config file. 36598d1491baSSteven Rostedtmy @new_configs = keys %entered_configs; 36608d1491baSSteven Rostedtif ($#new_configs >= 0) { 36618d1491baSSteven Rostedt print "\nAppending entered in configs to $ktest_config\n"; 36628d1491baSSteven Rostedt open(OUT, ">>$ktest_config") or die "Can not append to $ktest_config"; 36638d1491baSSteven Rostedt foreach my $config (@new_configs) { 36648d1491baSSteven Rostedt print OUT "$config = $entered_configs{$config}\n"; 36650e7a22deSSteven Rostedt $opt{$config} = process_variables($entered_configs{$config}); 36668d1491baSSteven Rostedt } 36678d1491baSSteven Rostedt} 36682545eb61SSteven Rostedt 36692b7d9b21SSteven Rostedtif ($opt{"CLEAR_LOG"} && defined($opt{"LOG_FILE"})) { 36702b7d9b21SSteven Rostedt unlink $opt{"LOG_FILE"}; 36712b7d9b21SSteven Rostedt} 36722545eb61SSteven Rostedt 36732b7d9b21SSteven Rostedtdoprint "\n\nSTARTING AUTOMATED TESTS\n\n"; 36742b7d9b21SSteven Rostedt 3675a57419b3SSteven Rostedtfor (my $i = 0, my $repeat = 1; $i <= $opt{"NUM_TESTS"}; $i += $repeat) { 3676a57419b3SSteven Rostedt 3677a57419b3SSteven Rostedt if (!$i) { 3678a57419b3SSteven Rostedt doprint "DEFAULT OPTIONS:\n"; 3679a57419b3SSteven Rostedt } else { 3680a57419b3SSteven Rostedt doprint "\nTEST $i OPTIONS"; 3681a57419b3SSteven Rostedt if (defined($repeat_tests{$i})) { 3682a57419b3SSteven Rostedt $repeat = $repeat_tests{$i}; 3683a57419b3SSteven Rostedt doprint " ITERATE $repeat"; 3684a57419b3SSteven Rostedt } 3685a57419b3SSteven Rostedt doprint "\n"; 3686a57419b3SSteven Rostedt } 3687a57419b3SSteven Rostedt 36882b7d9b21SSteven Rostedt foreach my $option (sort keys %opt) { 3689a57419b3SSteven Rostedt 3690a57419b3SSteven Rostedt if ($option =~ /\[(\d+)\]$/) { 3691a57419b3SSteven Rostedt next if ($i != $1); 3692a57419b3SSteven Rostedt } else { 3693a57419b3SSteven Rostedt next if ($i); 3694a57419b3SSteven Rostedt } 3695a57419b3SSteven Rostedt 36962b7d9b21SSteven Rostedt doprint "$option = $opt{$option}\n"; 36972b7d9b21SSteven Rostedt } 3698a57419b3SSteven Rostedt} 36992545eb61SSteven Rostedt 37002a62512bSSteven Rostedtsub __set_test_option { 37015a391fbfSSteven Rostedt my ($name, $i) = @_; 37025a391fbfSSteven Rostedt 37035a391fbfSSteven Rostedt my $option = "$name\[$i\]"; 37045a391fbfSSteven Rostedt 37055a391fbfSSteven Rostedt if (defined($opt{$option})) { 37065a391fbfSSteven Rostedt return $opt{$option}; 37075a391fbfSSteven Rostedt } 37085a391fbfSSteven Rostedt 3709a57419b3SSteven Rostedt foreach my $test (keys %repeat_tests) { 3710a57419b3SSteven Rostedt if ($i >= $test && 3711a57419b3SSteven Rostedt $i < $test + $repeat_tests{$test}) { 3712a57419b3SSteven Rostedt $option = "$name\[$test\]"; 3713a57419b3SSteven Rostedt if (defined($opt{$option})) { 3714a57419b3SSteven Rostedt return $opt{$option}; 3715a57419b3SSteven Rostedt } 3716a57419b3SSteven Rostedt } 3717a57419b3SSteven Rostedt } 3718a57419b3SSteven Rostedt 37195a391fbfSSteven Rostedt if (defined($opt{$name})) { 37205a391fbfSSteven Rostedt return $opt{$name}; 37215a391fbfSSteven Rostedt } 37225a391fbfSSteven Rostedt 37235a391fbfSSteven Rostedt return undef; 37245a391fbfSSteven Rostedt} 37255a391fbfSSteven Rostedt 37262a62512bSSteven Rostedtsub set_test_option { 37272a62512bSSteven Rostedt my ($name, $i) = @_; 37282a62512bSSteven Rostedt 37292a62512bSSteven Rostedt my $option = __set_test_option($name, $i); 37302a62512bSSteven Rostedt return $option if (!defined($option)); 37312a62512bSSteven Rostedt 373223715c3cSSteven Rostedt return eval_option($option, $i); 37332a62512bSSteven Rostedt} 37342a62512bSSteven Rostedt 37352545eb61SSteven Rostedt# First we need to do is the builds 3736a75fececSSteven Rostedtfor (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) { 37372545eb61SSteven Rostedt 37384ab1cce5SSteven Rostedt # Do not reboot on failing test options 37394ab1cce5SSteven Rostedt $no_reboot = 1; 3740759a3cc6SSteven Rostedt $reboot_success = 0; 37414ab1cce5SSteven Rostedt 3742683a3e64SSteven Rostedt $have_version = 0; 3743683a3e64SSteven Rostedt 3744576f627cSSteven Rostedt $iteration = $i; 3745576f627cSSteven Rostedt 3746c1434dccSSteven Rostedt undef %force_config; 3747c1434dccSSteven Rostedt 3748a75fececSSteven Rostedt my $makecmd = set_test_option("MAKE_CMD", $i); 3749a75fececSSteven Rostedt 37509cc9e091SSteven Rostedt # Load all the options into their mapped variable names 37519cc9e091SSteven Rostedt foreach my $opt (keys %option_map) { 37529cc9e091SSteven Rostedt ${$option_map{$opt}} = set_test_option($opt, $i); 37539cc9e091SSteven Rostedt } 3754b5f4aea6SSteven Rostedt 375535ce5952SSteven Rostedt $start_minconfig_defined = 1; 375635ce5952SSteven Rostedt 3757921ed4c7SSteven Rostedt # The first test may override the PRE_KTEST option 3758921ed4c7SSteven Rostedt if (defined($pre_ktest) && $i == 1) { 3759921ed4c7SSteven Rostedt doprint "\n"; 3760921ed4c7SSteven Rostedt run_command $pre_ktest; 3761921ed4c7SSteven Rostedt } 3762921ed4c7SSteven Rostedt 3763921ed4c7SSteven Rostedt # Any test can override the POST_KTEST option 3764921ed4c7SSteven Rostedt # The last test takes precedence. 3765921ed4c7SSteven Rostedt if (defined($post_ktest)) { 3766921ed4c7SSteven Rostedt $final_post_ktest = $post_ktest; 3767921ed4c7SSteven Rostedt } 3768921ed4c7SSteven Rostedt 37694c4ab120SSteven Rostedt if (!defined($start_minconfig)) { 377035ce5952SSteven Rostedt $start_minconfig_defined = 0; 37714c4ab120SSteven Rostedt $start_minconfig = $minconfig; 37724c4ab120SSteven Rostedt } 37734c4ab120SSteven Rostedt 3774a75fececSSteven Rostedt chdir $builddir || die "can't change directory to $builddir"; 3775a75fececSSteven Rostedt 3776a908a665SAndrew Jones foreach my $dir ($tmpdir, $outputdir) { 3777a908a665SAndrew Jones if (!-d $dir) { 3778a908a665SAndrew Jones mkpath($dir) or 3779a908a665SAndrew Jones die "can't create $dir"; 3780a908a665SAndrew Jones } 3781a75fececSSteven Rostedt } 3782a75fececSSteven Rostedt 3783e48c5293SSteven Rostedt $ENV{"SSH_USER"} = $ssh_user; 3784e48c5293SSteven Rostedt $ENV{"MACHINE"} = $machine; 3785e48c5293SSteven Rostedt 3786a75fececSSteven Rostedt $buildlog = "$tmpdir/buildlog-$machine"; 3787a9dd5d63SRabin Vincent $testlog = "$tmpdir/testlog-$machine"; 3788a75fececSSteven Rostedt $dmesg = "$tmpdir/dmesg-$machine"; 3789a75fececSSteven Rostedt $make = "$makecmd O=$outputdir"; 379051ad1dd1SSteven Rostedt $output_config = "$outputdir/.config"; 3791a75fececSSteven Rostedt 3792bb8474b1SSteven Rostedt if (!$buildonly) { 3793bb8474b1SSteven Rostedt $target = "$ssh_user\@$machine"; 3794a75fececSSteven Rostedt if ($reboot_type eq "grub") { 3795576f627cSSteven Rostedt dodie "GRUB_MENU not defined" if (!defined($grub_menu)); 3796a15ba913SSteven Rostedt } elsif ($reboot_type eq "grub2") { 3797a15ba913SSteven Rostedt dodie "GRUB_MENU not defined" if (!defined($grub_menu)); 3798a15ba913SSteven Rostedt dodie "GRUB_FILE not defined" if (!defined($grub_file)); 37997786954cSSteven Rostedt } elsif ($reboot_type eq "syslinux") { 38007786954cSSteven Rostedt dodie "SYSLINUX_LABEL not defined" if (!defined($syslinux_label)); 3801a75fececSSteven Rostedt } 3802bb8474b1SSteven Rostedt } 3803a75fececSSteven Rostedt 3804a75fececSSteven Rostedt my $run_type = $build_type; 3805a75fececSSteven Rostedt if ($test_type eq "patchcheck") { 3806b5f4aea6SSteven Rostedt $run_type = $patchcheck_type; 3807a75fececSSteven Rostedt } elsif ($test_type eq "bisect") { 3808b5f4aea6SSteven Rostedt $run_type = $bisect_type; 38090a05c769SSteven Rostedt } elsif ($test_type eq "config_bisect") { 3810b5f4aea6SSteven Rostedt $run_type = $config_bisect_type; 3811a75fececSSteven Rostedt } 3812a75fececSSteven Rostedt 38134c4ab120SSteven Rostedt if ($test_type eq "make_min_config") { 38144c4ab120SSteven Rostedt $run_type = ""; 38154c4ab120SSteven Rostedt } 38164c4ab120SSteven Rostedt 3817a75fececSSteven Rostedt # mistake in config file? 3818a75fececSSteven Rostedt if (!defined($run_type)) { 3819a75fececSSteven Rostedt $run_type = "ERROR"; 3820a75fececSSteven Rostedt } 38212545eb61SSteven Rostedt 3822e0a8742eSSteven Rostedt my $installme = ""; 3823e0a8742eSSteven Rostedt $installme = " no_install" if ($no_install); 3824e0a8742eSSteven Rostedt 38252545eb61SSteven Rostedt doprint "\n\n"; 3826e0a8742eSSteven Rostedt doprint "RUNNING TEST $i of $opt{NUM_TESTS} with option $test_type $run_type$installme\n\n"; 38277faafbd6SSteven Rostedt 3828921ed4c7SSteven Rostedt if (defined($pre_test)) { 3829921ed4c7SSteven Rostedt run_command $pre_test; 3830921ed4c7SSteven Rostedt } 3831921ed4c7SSteven Rostedt 38327faafbd6SSteven Rostedt unlink $dmesg; 38337faafbd6SSteven Rostedt unlink $buildlog; 3834a9dd5d63SRabin Vincent unlink $testlog; 38352545eb61SSteven Rostedt 3836250bae8bSSteven Rostedt if (defined($addconfig)) { 3837250bae8bSSteven Rostedt my $min = $minconfig; 38382b7d9b21SSteven Rostedt if (!defined($minconfig)) { 3839250bae8bSSteven Rostedt $min = ""; 3840250bae8bSSteven Rostedt } 3841250bae8bSSteven Rostedt run_command "cat $addconfig $min > $tmpdir/add_config" or 38422b7d9b21SSteven Rostedt dodie "Failed to create temp config"; 38439be2e6b5SSteven Rostedt $minconfig = "$tmpdir/add_config"; 38442b7d9b21SSteven Rostedt } 38452b7d9b21SSteven Rostedt 38466c5ee0beSSteven Rostedt if (defined($checkout)) { 38476c5ee0beSSteven Rostedt run_command "git checkout $checkout" or 38486c5ee0beSSteven Rostedt die "failed to checkout $checkout"; 38496c5ee0beSSteven Rostedt } 38506c5ee0beSSteven Rostedt 3851759a3cc6SSteven Rostedt $no_reboot = 0; 3852759a3cc6SSteven Rostedt 3853648a182cSSteven Rostedt # A test may opt to not reboot the box 3854648a182cSSteven Rostedt if ($reboot_on_success) { 3855759a3cc6SSteven Rostedt $reboot_success = 1; 3856648a182cSSteven Rostedt } 38574ab1cce5SSteven Rostedt 3858a75fececSSteven Rostedt if ($test_type eq "bisect") { 38595f9b6cedSSteven Rostedt bisect $i; 38605f9b6cedSSteven Rostedt next; 38610a05c769SSteven Rostedt } elsif ($test_type eq "config_bisect") { 38620a05c769SSteven Rostedt config_bisect $i; 38630a05c769SSteven Rostedt next; 3864a75fececSSteven Rostedt } elsif ($test_type eq "patchcheck") { 38656c5ee0beSSteven Rostedt patchcheck $i; 38666c5ee0beSSteven Rostedt next; 38674c4ab120SSteven Rostedt } elsif ($test_type eq "make_min_config") { 38684c4ab120SSteven Rostedt make_min_config $i; 38694c4ab120SSteven Rostedt next; 38705f9b6cedSSteven Rostedt } 38715f9b6cedSSteven Rostedt 38727faafbd6SSteven Rostedt if ($build_type ne "nobuild") { 38737faafbd6SSteven Rostedt build $build_type or next; 38742545eb61SSteven Rostedt } 38752545eb61SSteven Rostedt 3876cd8e368fSSteven Rostedt if ($test_type eq "install") { 3877cd8e368fSSteven Rostedt get_version; 3878cd8e368fSSteven Rostedt install; 3879cd8e368fSSteven Rostedt success $i; 3880cd8e368fSSteven Rostedt next; 3881cd8e368fSSteven Rostedt } 3882cd8e368fSSteven Rostedt 3883a75fececSSteven Rostedt if ($test_type ne "build") { 38847faafbd6SSteven Rostedt my $failed = 0; 3885ddf607e5SSteven Rostedt start_monitor_and_boot or $failed = 1; 3886a75fececSSteven Rostedt 3887a75fececSSteven Rostedt if (!$failed && $test_type ne "boot" && defined($run_test)) { 38887faafbd6SSteven Rostedt do_run_test or $failed = 1; 38895a391fbfSSteven Rostedt } 38907faafbd6SSteven Rostedt end_monitor; 38917faafbd6SSteven Rostedt next if ($failed); 3892a75fececSSteven Rostedt } 38935a391fbfSSteven Rostedt 38945f9b6cedSSteven Rostedt success $i; 389575c3fda7SSteven Rostedt} 38962545eb61SSteven Rostedt 3897921ed4c7SSteven Rostedtif (defined($final_post_ktest)) { 3898921ed4c7SSteven Rostedt run_command $final_post_ktest; 3899921ed4c7SSteven Rostedt} 3900921ed4c7SSteven Rostedt 39015c42fc5bSSteven Rostedtif ($opt{"POWEROFF_ON_SUCCESS"}) { 390275c3fda7SSteven Rostedt halt; 3903759a3cc6SSteven Rostedt} elsif ($opt{"REBOOT_ON_SUCCESS"} && !do_not_reboot && $reboot_success) { 3904bc7c5803SSteven Rostedt reboot_to_good; 3905648a182cSSteven Rostedt} elsif (defined($switch_to_good)) { 3906648a182cSSteven Rostedt # still need to get to the good kernel 3907648a182cSSteven Rostedt run_command $switch_to_good; 39085c42fc5bSSteven Rostedt} 390975c3fda7SSteven Rostedt 3910648a182cSSteven Rostedt 3911e48c5293SSteven Rostedtdoprint "\n $successes of $opt{NUM_TESTS} tests were successful\n\n"; 3912e48c5293SSteven Rostedt 39132545eb61SSteven Rostedtexit 0; 3914