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, 56600bbf0aSSteven Rostedt 57600bbf0aSSteven Rostedt# required, and we will ask users if they don't have them but we keep the default 58600bbf0aSSteven Rostedt# value something that is common. 594f43e0dcSSteven Rostedt "REBOOT_TYPE" => "grub", 604f43e0dcSSteven Rostedt "LOCALVERSION" => "-test", 614f43e0dcSSteven Rostedt "SSH_USER" => "root", 624f43e0dcSSteven Rostedt "BUILD_TARGET" => "arch/x86/boot/bzImage", 634f43e0dcSSteven Rostedt "TARGET_IMAGE" => "/boot/vmlinuz-test", 649cc9e091SSteven Rostedt 659cc9e091SSteven Rostedt "LOG_FILE" => undef, 669cc9e091SSteven Rostedt "IGNORE_UNUSED" => 0, 674f43e0dcSSteven Rostedt); 682545eb61SSteven Rostedt 698d1491baSSteven Rostedtmy $ktest_config; 702545eb61SSteven Rostedtmy $version; 71683a3e64SSteven Rostedtmy $have_version = 0; 72a75fececSSteven Rostedtmy $machine; 73e48c5293SSteven Rostedtmy $ssh_user; 74a75fececSSteven Rostedtmy $tmpdir; 75a75fececSSteven Rostedtmy $builddir; 76a75fececSSteven Rostedtmy $outputdir; 7751ad1dd1SSteven Rostedtmy $output_config; 78a75fececSSteven Rostedtmy $test_type; 797faafbd6SSteven Rostedtmy $build_type; 80a75fececSSteven Rostedtmy $build_options; 81921ed4c7SSteven Rostedtmy $final_post_ktest; 82921ed4c7SSteven Rostedtmy $pre_ktest; 83921ed4c7SSteven Rostedtmy $post_ktest; 84921ed4c7SSteven Rostedtmy $pre_test; 85921ed4c7SSteven Rostedtmy $post_test; 860bd6c1a3SSteven Rostedtmy $pre_build; 870bd6c1a3SSteven Rostedtmy $post_build; 880bd6c1a3SSteven Rostedtmy $pre_build_die; 890bd6c1a3SSteven Rostedtmy $post_build_die; 90a75fececSSteven Rostedtmy $reboot_type; 91a75fececSSteven Rostedtmy $reboot_script; 92a75fececSSteven Rostedtmy $power_cycle; 93e48c5293SSteven Rostedtmy $reboot; 94a75fececSSteven Rostedtmy $reboot_on_error; 95bc7c5803SSteven Rostedtmy $switch_to_good; 96bc7c5803SSteven Rostedtmy $switch_to_test; 97a75fececSSteven Rostedtmy $poweroff_on_error; 98648a182cSSteven Rostedtmy $reboot_on_success; 99a75fececSSteven Rostedtmy $die_on_failure; 100576f627cSSteven Rostedtmy $powercycle_after_reboot; 101576f627cSSteven Rostedtmy $poweroff_after_halt; 102407b95b7SSteven Rostedtmy $max_monitor_wait; 103e48c5293SSteven Rostedtmy $ssh_exec; 104e48c5293SSteven Rostedtmy $scp_to_target; 10502ad2617SSteven Rostedtmy $scp_to_target_install; 106a75fececSSteven Rostedtmy $power_off; 107a75fececSSteven Rostedtmy $grub_menu; 1082545eb61SSteven Rostedtmy $grub_number; 1092545eb61SSteven Rostedtmy $target; 1102545eb61SSteven Rostedtmy $make; 111e5c2ec11SSteven Rostedtmy $pre_install; 1128b37ca8cSSteven Rostedtmy $post_install; 113e0a8742eSSteven Rostedtmy $no_install; 1145c42fc5bSSteven Rostedtmy $noclean; 1155f9b6cedSSteven Rostedtmy $minconfig; 1164c4ab120SSteven Rostedtmy $start_minconfig; 11735ce5952SSteven Rostedtmy $start_minconfig_defined; 1184c4ab120SSteven Rostedtmy $output_minconfig; 119ccc513b6SSteven Rostedtmy $minconfig_type; 12043de3316SSteven Rostedtmy $use_output_minconfig; 1214c4ab120SSteven Rostedtmy $ignore_config; 122be405f95SSteven Rostedtmy $ignore_errors; 1232b7d9b21SSteven Rostedtmy $addconfig; 1245f9b6cedSSteven Rostedtmy $in_bisect = 0; 125b5f4aea6SSteven Rostedtmy $bisect_bad_commit = ""; 126d6ce2a0bSSteven Rostedtmy $reverse_bisect; 127c960bb9fSSteven Rostedtmy $bisect_manual; 128c23dca7cSSteven Rostedtmy $bisect_skip; 12930f75da5SSteven Rostedtmy $config_bisect_good; 130c5dacb88SSteven Rostedtmy $bisect_ret_good; 131c5dacb88SSteven Rostedtmy $bisect_ret_bad; 132c5dacb88SSteven Rostedtmy $bisect_ret_skip; 133c5dacb88SSteven Rostedtmy $bisect_ret_abort; 134c5dacb88SSteven Rostedtmy $bisect_ret_default; 1356c5ee0beSSteven Rostedtmy $in_patchcheck = 0; 1365a391fbfSSteven Rostedtmy $run_test; 1376c5ee0beSSteven Rostedtmy $redirect; 1387faafbd6SSteven Rostedtmy $buildlog; 139a9dd5d63SRabin Vincentmy $testlog; 1407faafbd6SSteven Rostedtmy $dmesg; 1417faafbd6SSteven Rostedtmy $monitor_fp; 1427faafbd6SSteven Rostedtmy $monitor_pid; 1437faafbd6SSteven Rostedtmy $monitor_cnt = 0; 144a75fececSSteven Rostedtmy $sleep_time; 145a75fececSSteven Rostedtmy $bisect_sleep_time; 14627d934b2SSteven Rostedtmy $patchcheck_sleep_time; 1471990207dSSteven Rostedtmy $ignore_warnings; 148a75fececSSteven Rostedtmy $store_failures; 149de5b6e3bSRabin Vincentmy $store_successes; 1509064af52SSteven Rostedtmy $test_name; 151a75fececSSteven Rostedtmy $timeout; 152a75fececSSteven Rostedtmy $booted_timeout; 153f1a5b962SSteven Rostedtmy $detect_triplefault; 154a75fececSSteven Rostedtmy $console; 1552b803365SSteven Rostedtmy $reboot_success_line; 156a75fececSSteven Rostedtmy $success_line; 1571c8a617aSSteven Rostedtmy $stop_after_success; 1581c8a617aSSteven Rostedtmy $stop_after_failure; 1592d01b26aSSteven Rostedtmy $stop_test_after; 160a75fececSSteven Rostedtmy $build_target; 161a75fececSSteven Rostedtmy $target_image; 162b5f4aea6SSteven Rostedtmy $checkout; 163a75fececSSteven Rostedtmy $localversion; 164576f627cSSteven Rostedtmy $iteration = 0; 165e48c5293SSteven Rostedtmy $successes = 0; 1662545eb61SSteven Rostedt 167b5f4aea6SSteven Rostedtmy $bisect_good; 168b5f4aea6SSteven Rostedtmy $bisect_bad; 169b5f4aea6SSteven Rostedtmy $bisect_type; 170b5f4aea6SSteven Rostedtmy $bisect_start; 171b5f4aea6SSteven Rostedtmy $bisect_replay; 172b5f4aea6SSteven Rostedtmy $bisect_files; 173b5f4aea6SSteven Rostedtmy $bisect_reverse; 174b5f4aea6SSteven Rostedtmy $bisect_check; 175b5f4aea6SSteven Rostedt 176b5f4aea6SSteven Rostedtmy $config_bisect; 177b5f4aea6SSteven Rostedtmy $config_bisect_type; 178b0918612SSteven Rostedtmy $config_bisect_check; 179b5f4aea6SSteven Rostedt 180b5f4aea6SSteven Rostedtmy $patchcheck_type; 181b5f4aea6SSteven Rostedtmy $patchcheck_start; 182b5f4aea6SSteven Rostedtmy $patchcheck_end; 183b5f4aea6SSteven Rostedt 184165708b2SSteven Rostedt# set when a test is something other that just building or install 185bb8474b1SSteven Rostedt# which would require more options. 186bb8474b1SSteven Rostedtmy $buildonly = 1; 187bb8474b1SSteven Rostedt 188dbd3783bSSteven Rostedt# set when creating a new config 189dbd3783bSSteven Rostedtmy $newconfig = 0; 190dbd3783bSSteven Rostedt 1918d1491baSSteven Rostedtmy %entered_configs; 1928d1491baSSteven Rostedtmy %config_help; 19377d942ceSSteven Rostedtmy %variable; 194cf79fab6SSteven Rostedt 195cf79fab6SSteven Rostedt# force_config is the list of configs that we force enabled (or disabled) 196cf79fab6SSteven Rostedt# in a .config file. The MIN_CONFIG and ADD_CONFIG configs. 197fcb3f16aSSteven Rostedtmy %force_config; 1988d1491baSSteven Rostedt 1994ab1cce5SSteven Rostedt# do not force reboots on config problems 2004ab1cce5SSteven Rostedtmy $no_reboot = 1; 2014ab1cce5SSteven Rostedt 202759a3cc6SSteven Rostedt# reboot on success 203759a3cc6SSteven Rostedtmy $reboot_success = 0; 204759a3cc6SSteven Rostedt 2059cc9e091SSteven Rostedtmy %option_map = ( 2069cc9e091SSteven Rostedt "MACHINE" => \$machine, 2079cc9e091SSteven Rostedt "SSH_USER" => \$ssh_user, 2089cc9e091SSteven Rostedt "TMP_DIR" => \$tmpdir, 2099cc9e091SSteven Rostedt "OUTPUT_DIR" => \$outputdir, 2109cc9e091SSteven Rostedt "BUILD_DIR" => \$builddir, 2119cc9e091SSteven Rostedt "TEST_TYPE" => \$test_type, 212921ed4c7SSteven Rostedt "PRE_KTEST" => \$pre_ktest, 213921ed4c7SSteven Rostedt "POST_KTEST" => \$post_ktest, 214921ed4c7SSteven Rostedt "PRE_TEST" => \$pre_test, 215921ed4c7SSteven Rostedt "POST_TEST" => \$post_test, 2169cc9e091SSteven Rostedt "BUILD_TYPE" => \$build_type, 2179cc9e091SSteven Rostedt "BUILD_OPTIONS" => \$build_options, 2189cc9e091SSteven Rostedt "PRE_BUILD" => \$pre_build, 2199cc9e091SSteven Rostedt "POST_BUILD" => \$post_build, 2209cc9e091SSteven Rostedt "PRE_BUILD_DIE" => \$pre_build_die, 2219cc9e091SSteven Rostedt "POST_BUILD_DIE" => \$post_build_die, 2229cc9e091SSteven Rostedt "POWER_CYCLE" => \$power_cycle, 2239cc9e091SSteven Rostedt "REBOOT" => \$reboot, 2249cc9e091SSteven Rostedt "BUILD_NOCLEAN" => \$noclean, 2259cc9e091SSteven Rostedt "MIN_CONFIG" => \$minconfig, 2269cc9e091SSteven Rostedt "OUTPUT_MIN_CONFIG" => \$output_minconfig, 2279cc9e091SSteven Rostedt "START_MIN_CONFIG" => \$start_minconfig, 228ccc513b6SSteven Rostedt "MIN_CONFIG_TYPE" => \$minconfig_type, 22943de3316SSteven Rostedt "USE_OUTPUT_MIN_CONFIG" => \$use_output_minconfig, 2309cc9e091SSteven Rostedt "IGNORE_CONFIG" => \$ignore_config, 2319cc9e091SSteven Rostedt "TEST" => \$run_test, 2329cc9e091SSteven Rostedt "ADD_CONFIG" => \$addconfig, 2339cc9e091SSteven Rostedt "REBOOT_TYPE" => \$reboot_type, 2349cc9e091SSteven Rostedt "GRUB_MENU" => \$grub_menu, 235e5c2ec11SSteven Rostedt "PRE_INSTALL" => \$pre_install, 2369cc9e091SSteven Rostedt "POST_INSTALL" => \$post_install, 2379cc9e091SSteven Rostedt "NO_INSTALL" => \$no_install, 2389cc9e091SSteven Rostedt "REBOOT_SCRIPT" => \$reboot_script, 2399cc9e091SSteven Rostedt "REBOOT_ON_ERROR" => \$reboot_on_error, 2409cc9e091SSteven Rostedt "SWITCH_TO_GOOD" => \$switch_to_good, 2419cc9e091SSteven Rostedt "SWITCH_TO_TEST" => \$switch_to_test, 2429cc9e091SSteven Rostedt "POWEROFF_ON_ERROR" => \$poweroff_on_error, 243648a182cSSteven Rostedt "REBOOT_ON_SUCCESS" => \$reboot_on_success, 2449cc9e091SSteven Rostedt "DIE_ON_FAILURE" => \$die_on_failure, 2459cc9e091SSteven Rostedt "POWER_OFF" => \$power_off, 2469cc9e091SSteven Rostedt "POWERCYCLE_AFTER_REBOOT" => \$powercycle_after_reboot, 2479cc9e091SSteven Rostedt "POWEROFF_AFTER_HALT" => \$poweroff_after_halt, 248407b95b7SSteven Rostedt "MAX_MONITOR_WAIT" => \$max_monitor_wait, 2499cc9e091SSteven Rostedt "SLEEP_TIME" => \$sleep_time, 2509cc9e091SSteven Rostedt "BISECT_SLEEP_TIME" => \$bisect_sleep_time, 2519cc9e091SSteven Rostedt "PATCHCHECK_SLEEP_TIME" => \$patchcheck_sleep_time, 2529cc9e091SSteven Rostedt "IGNORE_WARNINGS" => \$ignore_warnings, 253be405f95SSteven Rostedt "IGNORE_ERRORS" => \$ignore_errors, 2549cc9e091SSteven Rostedt "BISECT_MANUAL" => \$bisect_manual, 2559cc9e091SSteven Rostedt "BISECT_SKIP" => \$bisect_skip, 2569cc9e091SSteven Rostedt "CONFIG_BISECT_GOOD" => \$config_bisect_good, 2579cc9e091SSteven Rostedt "BISECT_RET_GOOD" => \$bisect_ret_good, 2589cc9e091SSteven Rostedt "BISECT_RET_BAD" => \$bisect_ret_bad, 2599cc9e091SSteven Rostedt "BISECT_RET_SKIP" => \$bisect_ret_skip, 2609cc9e091SSteven Rostedt "BISECT_RET_ABORT" => \$bisect_ret_abort, 2619cc9e091SSteven Rostedt "BISECT_RET_DEFAULT" => \$bisect_ret_default, 2629cc9e091SSteven Rostedt "STORE_FAILURES" => \$store_failures, 2639cc9e091SSteven Rostedt "STORE_SUCCESSES" => \$store_successes, 2649cc9e091SSteven Rostedt "TEST_NAME" => \$test_name, 2659cc9e091SSteven Rostedt "TIMEOUT" => \$timeout, 2669cc9e091SSteven Rostedt "BOOTED_TIMEOUT" => \$booted_timeout, 2679cc9e091SSteven Rostedt "CONSOLE" => \$console, 2689cc9e091SSteven Rostedt "DETECT_TRIPLE_FAULT" => \$detect_triplefault, 2699cc9e091SSteven Rostedt "SUCCESS_LINE" => \$success_line, 2709cc9e091SSteven Rostedt "REBOOT_SUCCESS_LINE" => \$reboot_success_line, 2719cc9e091SSteven Rostedt "STOP_AFTER_SUCCESS" => \$stop_after_success, 2729cc9e091SSteven Rostedt "STOP_AFTER_FAILURE" => \$stop_after_failure, 2739cc9e091SSteven Rostedt "STOP_TEST_AFTER" => \$stop_test_after, 2749cc9e091SSteven Rostedt "BUILD_TARGET" => \$build_target, 2759cc9e091SSteven Rostedt "SSH_EXEC" => \$ssh_exec, 2769cc9e091SSteven Rostedt "SCP_TO_TARGET" => \$scp_to_target, 27702ad2617SSteven Rostedt "SCP_TO_TARGET_INSTALL" => \$scp_to_target_install, 2789cc9e091SSteven Rostedt "CHECKOUT" => \$checkout, 2799cc9e091SSteven Rostedt "TARGET_IMAGE" => \$target_image, 2809cc9e091SSteven Rostedt "LOCALVERSION" => \$localversion, 2819cc9e091SSteven Rostedt 2829cc9e091SSteven Rostedt "BISECT_GOOD" => \$bisect_good, 2839cc9e091SSteven Rostedt "BISECT_BAD" => \$bisect_bad, 2849cc9e091SSteven Rostedt "BISECT_TYPE" => \$bisect_type, 2859cc9e091SSteven Rostedt "BISECT_START" => \$bisect_start, 2869cc9e091SSteven Rostedt "BISECT_REPLAY" => \$bisect_replay, 2879cc9e091SSteven Rostedt "BISECT_FILES" => \$bisect_files, 2889cc9e091SSteven Rostedt "BISECT_REVERSE" => \$bisect_reverse, 2899cc9e091SSteven Rostedt "BISECT_CHECK" => \$bisect_check, 2909cc9e091SSteven Rostedt 2919cc9e091SSteven Rostedt "CONFIG_BISECT" => \$config_bisect, 2929cc9e091SSteven Rostedt "CONFIG_BISECT_TYPE" => \$config_bisect_type, 293b0918612SSteven Rostedt "CONFIG_BISECT_CHECK" => \$config_bisect_check, 2949cc9e091SSteven Rostedt 2959cc9e091SSteven Rostedt "PATCHCHECK_TYPE" => \$patchcheck_type, 2969cc9e091SSteven Rostedt "PATCHCHECK_START" => \$patchcheck_start, 2979cc9e091SSteven Rostedt "PATCHCHECK_END" => \$patchcheck_end, 2989cc9e091SSteven Rostedt); 2999cc9e091SSteven Rostedt 3009cc9e091SSteven Rostedt# Options may be used by other options, record them. 3019cc9e091SSteven Rostedtmy %used_options; 3029cc9e091SSteven Rostedt 3037bf51073SSteven Rostedt# default variables that can be used 3047bf51073SSteven Rostedtchomp ($variable{"PWD"} = `pwd`); 3057bf51073SSteven Rostedt 3068d1491baSSteven Rostedt$config_help{"MACHINE"} = << "EOF" 3078d1491baSSteven Rostedt The machine hostname that you will test. 308bb8474b1SSteven Rostedt For build only tests, it is still needed to differentiate log files. 3098d1491baSSteven RostedtEOF 3108d1491baSSteven Rostedt ; 3118d1491baSSteven Rostedt$config_help{"SSH_USER"} = << "EOF" 3128d1491baSSteven Rostedt The box is expected to have ssh on normal bootup, provide the user 3138d1491baSSteven Rostedt (most likely root, since you need privileged operations) 3148d1491baSSteven RostedtEOF 3158d1491baSSteven Rostedt ; 3168d1491baSSteven Rostedt$config_help{"BUILD_DIR"} = << "EOF" 3178d1491baSSteven Rostedt The directory that contains the Linux source code (full path). 3180e7a22deSSteven Rostedt You can use \${PWD} that will be the path where ktest.pl is run, or use 3190e7a22deSSteven Rostedt \${THIS_DIR} which is assigned \${PWD} but may be changed later. 3208d1491baSSteven RostedtEOF 3218d1491baSSteven Rostedt ; 3228d1491baSSteven Rostedt$config_help{"OUTPUT_DIR"} = << "EOF" 3238d1491baSSteven Rostedt The directory that the objects will be built (full path). 3248d1491baSSteven Rostedt (can not be same as BUILD_DIR) 3250e7a22deSSteven Rostedt You can use \${PWD} that will be the path where ktest.pl is run, or use 3260e7a22deSSteven Rostedt \${THIS_DIR} which is assigned \${PWD} but may be changed later. 3278d1491baSSteven RostedtEOF 3288d1491baSSteven Rostedt ; 3298d1491baSSteven Rostedt$config_help{"BUILD_TARGET"} = << "EOF" 3308d1491baSSteven Rostedt The location of the compiled file to copy to the target. 3318d1491baSSteven Rostedt (relative to OUTPUT_DIR) 3328d1491baSSteven RostedtEOF 3338d1491baSSteven Rostedt ; 334dbd3783bSSteven Rostedt$config_help{"BUILD_OPTIONS"} = << "EOF" 335dbd3783bSSteven Rostedt Options to add to \"make\" when building. 336dbd3783bSSteven Rostedt i.e. -j20 337dbd3783bSSteven RostedtEOF 338dbd3783bSSteven Rostedt ; 3398d1491baSSteven Rostedt$config_help{"TARGET_IMAGE"} = << "EOF" 3408d1491baSSteven Rostedt The place to put your image on the test machine. 3418d1491baSSteven RostedtEOF 3428d1491baSSteven Rostedt ; 3438d1491baSSteven Rostedt$config_help{"POWER_CYCLE"} = << "EOF" 3448d1491baSSteven Rostedt A script or command to reboot the box. 3458d1491baSSteven Rostedt 3468d1491baSSteven Rostedt Here is a digital loggers power switch example 3478d1491baSSteven Rostedt POWER_CYCLE = wget --no-proxy -O /dev/null -q --auth-no-challenge 'http://admin:admin\@power/outlet?5=CCL' 3488d1491baSSteven Rostedt 3498d1491baSSteven Rostedt Here is an example to reboot a virtual box on the current host 3508d1491baSSteven Rostedt with the name "Guest". 3518d1491baSSteven Rostedt POWER_CYCLE = virsh destroy Guest; sleep 5; virsh start Guest 3528d1491baSSteven RostedtEOF 3538d1491baSSteven Rostedt ; 3548d1491baSSteven Rostedt$config_help{"CONSOLE"} = << "EOF" 3558d1491baSSteven Rostedt The script or command that reads the console 3568d1491baSSteven Rostedt 3578d1491baSSteven Rostedt If you use ttywatch server, something like the following would work. 3588d1491baSSteven RostedtCONSOLE = nc -d localhost 3001 3598d1491baSSteven Rostedt 3608d1491baSSteven Rostedt For a virtual machine with guest name "Guest". 3618d1491baSSteven RostedtCONSOLE = virsh console Guest 3628d1491baSSteven RostedtEOF 3638d1491baSSteven Rostedt ; 3648d1491baSSteven Rostedt$config_help{"LOCALVERSION"} = << "EOF" 3658d1491baSSteven Rostedt Required version ending to differentiate the test 3668d1491baSSteven Rostedt from other linux builds on the system. 3678d1491baSSteven RostedtEOF 3688d1491baSSteven Rostedt ; 3698d1491baSSteven Rostedt$config_help{"REBOOT_TYPE"} = << "EOF" 3708d1491baSSteven Rostedt Way to reboot the box to the test kernel. 3718d1491baSSteven Rostedt Only valid options so far are "grub" and "script". 3728d1491baSSteven Rostedt 3738d1491baSSteven Rostedt If you specify grub, it will assume grub version 1 3748d1491baSSteven Rostedt and will search in /boot/grub/menu.lst for the title \$GRUB_MENU 3758d1491baSSteven Rostedt and select that target to reboot to the kernel. If this is not 3768d1491baSSteven Rostedt your setup, then specify "script" and have a command or script 3778d1491baSSteven Rostedt specified in REBOOT_SCRIPT to boot to the target. 3788d1491baSSteven Rostedt 3798d1491baSSteven Rostedt The entry in /boot/grub/menu.lst must be entered in manually. 3808d1491baSSteven Rostedt The test will not modify that file. 3818d1491baSSteven RostedtEOF 3828d1491baSSteven Rostedt ; 3838d1491baSSteven Rostedt$config_help{"GRUB_MENU"} = << "EOF" 3848d1491baSSteven Rostedt The grub title name for the test kernel to boot 3858d1491baSSteven Rostedt (Only mandatory if REBOOT_TYPE = grub) 3868d1491baSSteven Rostedt 3878d1491baSSteven Rostedt Note, ktest.pl will not update the grub menu.lst, you need to 3888d1491baSSteven Rostedt manually add an option for the test. ktest.pl will search 3898d1491baSSteven Rostedt the grub menu.lst for this option to find what kernel to 3908d1491baSSteven Rostedt reboot into. 3918d1491baSSteven Rostedt 3928d1491baSSteven Rostedt For example, if in the /boot/grub/menu.lst the test kernel title has: 3938d1491baSSteven Rostedt title Test Kernel 3948d1491baSSteven Rostedt kernel vmlinuz-test 3958d1491baSSteven Rostedt GRUB_MENU = Test Kernel 3968d1491baSSteven RostedtEOF 3978d1491baSSteven Rostedt ; 3988d1491baSSteven Rostedt$config_help{"REBOOT_SCRIPT"} = << "EOF" 3998d1491baSSteven Rostedt A script to reboot the target into the test kernel 4008d1491baSSteven Rostedt (Only mandatory if REBOOT_TYPE = script) 4018d1491baSSteven RostedtEOF 4028d1491baSSteven Rostedt ; 4038d1491baSSteven Rostedt 404dad98754SSteven Rostedtsub read_prompt { 405dad98754SSteven Rostedt my ($cancel, $prompt) = @_; 40635ce5952SSteven Rostedt 40735ce5952SSteven Rostedt my $ans; 40835ce5952SSteven Rostedt 40935ce5952SSteven Rostedt for (;;) { 410dad98754SSteven Rostedt if ($cancel) { 411dad98754SSteven Rostedt print "$prompt [y/n/C] "; 412dad98754SSteven Rostedt } else { 41335ce5952SSteven Rostedt print "$prompt [Y/n] "; 414dad98754SSteven Rostedt } 41535ce5952SSteven Rostedt $ans = <STDIN>; 41635ce5952SSteven Rostedt chomp $ans; 41735ce5952SSteven Rostedt if ($ans =~ /^\s*$/) { 418dad98754SSteven Rostedt if ($cancel) { 419dad98754SSteven Rostedt $ans = "c"; 420dad98754SSteven Rostedt } else { 42135ce5952SSteven Rostedt $ans = "y"; 42235ce5952SSteven Rostedt } 423dad98754SSteven Rostedt } 42435ce5952SSteven Rostedt last if ($ans =~ /^y$/i || $ans =~ /^n$/i); 425dad98754SSteven Rostedt if ($cancel) { 426dad98754SSteven Rostedt last if ($ans =~ /^c$/i); 427dad98754SSteven Rostedt print "Please answer either 'y', 'n' or 'c'.\n"; 428dad98754SSteven Rostedt } else { 42935ce5952SSteven Rostedt print "Please answer either 'y' or 'n'.\n"; 43035ce5952SSteven Rostedt } 431dad98754SSteven Rostedt } 432dad98754SSteven Rostedt if ($ans =~ /^c/i) { 433dad98754SSteven Rostedt exit; 434dad98754SSteven Rostedt } 43535ce5952SSteven Rostedt if ($ans !~ /^y$/i) { 43635ce5952SSteven Rostedt return 0; 43735ce5952SSteven Rostedt } 43835ce5952SSteven Rostedt return 1; 43935ce5952SSteven Rostedt} 4408d1491baSSteven Rostedt 441dad98754SSteven Rostedtsub read_yn { 442dad98754SSteven Rostedt my ($prompt) = @_; 443dad98754SSteven Rostedt 444dad98754SSteven Rostedt return read_prompt 0, $prompt; 445dad98754SSteven Rostedt} 446dad98754SSteven Rostedt 447dad98754SSteven Rostedtsub read_ync { 448dad98754SSteven Rostedt my ($prompt) = @_; 449dad98754SSteven Rostedt 450dad98754SSteven Rostedt return read_prompt 1, $prompt; 451dad98754SSteven Rostedt} 452dad98754SSteven Rostedt 4538d1491baSSteven Rostedtsub get_ktest_config { 4548d1491baSSteven Rostedt my ($config) = @_; 455815e2bd7SSteven Rostedt my $ans; 4568d1491baSSteven Rostedt 4578d1491baSSteven Rostedt return if (defined($opt{$config})); 4588d1491baSSteven Rostedt 4598d1491baSSteven Rostedt if (defined($config_help{$config})) { 4608d1491baSSteven Rostedt print "\n"; 4618d1491baSSteven Rostedt print $config_help{$config}; 4628d1491baSSteven Rostedt } 4638d1491baSSteven Rostedt 4648d1491baSSteven Rostedt for (;;) { 4658d1491baSSteven Rostedt print "$config = "; 466dbd3783bSSteven Rostedt if (defined($default{$config}) && length($default{$config})) { 4678d1491baSSteven Rostedt print "\[$default{$config}\] "; 4688d1491baSSteven Rostedt } 469815e2bd7SSteven Rostedt $ans = <STDIN>; 470815e2bd7SSteven Rostedt $ans =~ s/^\s*(.*\S)\s*$/$1/; 471815e2bd7SSteven Rostedt if ($ans =~ /^\s*$/) { 4728d1491baSSteven Rostedt if ($default{$config}) { 473815e2bd7SSteven Rostedt $ans = $default{$config}; 4748d1491baSSteven Rostedt } else { 4758d1491baSSteven Rostedt print "Your answer can not be blank\n"; 4768d1491baSSteven Rostedt next; 4778d1491baSSteven Rostedt } 4788d1491baSSteven Rostedt } 4790e7a22deSSteven Rostedt $entered_configs{$config} = ${ans}; 4808d1491baSSteven Rostedt last; 4818d1491baSSteven Rostedt } 4828d1491baSSteven Rostedt} 4838d1491baSSteven Rostedt 4848d1491baSSteven Rostedtsub get_ktest_configs { 4858d1491baSSteven Rostedt get_ktest_config("MACHINE"); 4868d1491baSSteven Rostedt get_ktest_config("BUILD_DIR"); 4878d1491baSSteven Rostedt get_ktest_config("OUTPUT_DIR"); 488bb8474b1SSteven Rostedt 489dbd3783bSSteven Rostedt if ($newconfig) { 490dbd3783bSSteven Rostedt get_ktest_config("BUILD_OPTIONS"); 491dbd3783bSSteven Rostedt } 492dbd3783bSSteven Rostedt 493bb8474b1SSteven Rostedt # options required for other than just building a kernel 494bb8474b1SSteven Rostedt if (!$buildonly) { 495165708b2SSteven Rostedt get_ktest_config("POWER_CYCLE"); 496165708b2SSteven Rostedt get_ktest_config("CONSOLE"); 497165708b2SSteven Rostedt } 498165708b2SSteven Rostedt 499165708b2SSteven Rostedt # options required for install and more 500165708b2SSteven Rostedt if ($buildonly != 1) { 501bb8474b1SSteven Rostedt get_ktest_config("SSH_USER"); 5028d1491baSSteven Rostedt get_ktest_config("BUILD_TARGET"); 5038d1491baSSteven Rostedt get_ktest_config("TARGET_IMAGE"); 504bb8474b1SSteven Rostedt } 505bb8474b1SSteven Rostedt 5068d1491baSSteven Rostedt get_ktest_config("LOCALVERSION"); 5078d1491baSSteven Rostedt 508bb8474b1SSteven Rostedt return if ($buildonly); 509bb8474b1SSteven Rostedt 5108d1491baSSteven Rostedt my $rtype = $opt{"REBOOT_TYPE"}; 5118d1491baSSteven Rostedt 5128d1491baSSteven Rostedt if (!defined($rtype)) { 5138d1491baSSteven Rostedt if (!defined($opt{"GRUB_MENU"})) { 5148d1491baSSteven Rostedt get_ktest_config("REBOOT_TYPE"); 5158d1491baSSteven Rostedt $rtype = $entered_configs{"REBOOT_TYPE"}; 5168d1491baSSteven Rostedt } else { 5178d1491baSSteven Rostedt $rtype = "grub"; 5188d1491baSSteven Rostedt } 5198d1491baSSteven Rostedt } 5208d1491baSSteven Rostedt 5218d1491baSSteven Rostedt if ($rtype eq "grub") { 5228d1491baSSteven Rostedt get_ktest_config("GRUB_MENU"); 5238d1491baSSteven Rostedt } 5248d1491baSSteven Rostedt} 5258d1491baSSteven Rostedt 52677d942ceSSteven Rostedtsub process_variables { 5278d735212SSteven Rostedt my ($value, $remove_undef) = @_; 52877d942ceSSteven Rostedt my $retval = ""; 52977d942ceSSteven Rostedt 53077d942ceSSteven Rostedt # We want to check for '\', and it is just easier 53177d942ceSSteven Rostedt # to check the previous characet of '$' and not need 53277d942ceSSteven Rostedt # to worry if '$' is the first character. By adding 53377d942ceSSteven Rostedt # a space to $value, we can just check [^\\]\$ and 53477d942ceSSteven Rostedt # it will still work. 53577d942ceSSteven Rostedt $value = " $value"; 53677d942ceSSteven Rostedt 53777d942ceSSteven Rostedt while ($value =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) { 53877d942ceSSteven Rostedt my $begin = $1; 53977d942ceSSteven Rostedt my $var = $2; 54077d942ceSSteven Rostedt my $end = $3; 54177d942ceSSteven Rostedt # append beginning of value to retval 54277d942ceSSteven Rostedt $retval = "$retval$begin"; 54377d942ceSSteven Rostedt if (defined($variable{$var})) { 54477d942ceSSteven Rostedt $retval = "$retval$variable{$var}"; 5458d735212SSteven Rostedt } elsif (defined($remove_undef) && $remove_undef) { 5468d735212SSteven Rostedt # for if statements, any variable that is not defined, 5478d735212SSteven Rostedt # we simple convert to 0 5488d735212SSteven Rostedt $retval = "${retval}0"; 54977d942ceSSteven Rostedt } else { 55077d942ceSSteven Rostedt # put back the origin piece. 55177d942ceSSteven Rostedt $retval = "$retval\$\{$var\}"; 5529cc9e091SSteven Rostedt # This could be an option that is used later, save 5539cc9e091SSteven Rostedt # it so we don't warn if this option is not one of 5549cc9e091SSteven Rostedt # ktests options. 5559cc9e091SSteven Rostedt $used_options{$var} = 1; 55677d942ceSSteven Rostedt } 55777d942ceSSteven Rostedt $value = $end; 55877d942ceSSteven Rostedt } 55977d942ceSSteven Rostedt $retval = "$retval$value"; 56077d942ceSSteven Rostedt 56177d942ceSSteven Rostedt # remove the space added in the beginning 56277d942ceSSteven Rostedt $retval =~ s/ //; 56377d942ceSSteven Rostedt 56477d942ceSSteven Rostedt return "$retval" 56577d942ceSSteven Rostedt} 56677d942ceSSteven Rostedt 567a57419b3SSteven Rostedtsub set_value { 5683d1cc414SSteven Rostedt my ($lvalue, $rvalue, $override, $overrides, $name) = @_; 5692545eb61SSteven Rostedt 570cad96669SSteven Rostedt my $prvalue = process_variables($rvalue); 571cad96669SSteven Rostedt 572cad96669SSteven Rostedt if ($buildonly && $lvalue =~ /^TEST_TYPE(\[.*\])?$/ && $prvalue ne "build") { 573bb8474b1SSteven Rostedt # Note if a test is something other than build, then we 574bb8474b1SSteven Rostedt # will need other manditory options. 575cad96669SSteven Rostedt if ($prvalue ne "install") { 576bb8474b1SSteven Rostedt $buildonly = 0; 577165708b2SSteven Rostedt } else { 578165708b2SSteven Rostedt # install still limits some manditory options. 579165708b2SSteven Rostedt $buildonly = 2; 580165708b2SSteven Rostedt } 581bb8474b1SSteven Rostedt } 582bb8474b1SSteven Rostedt 583a75fececSSteven Rostedt if (defined($opt{$lvalue})) { 5843d1cc414SSteven Rostedt if (!$override || defined(${$overrides}{$lvalue})) { 5853d1cc414SSteven Rostedt my $extra = ""; 5863d1cc414SSteven Rostedt if ($override) { 5873d1cc414SSteven Rostedt $extra = "In the same override section!\n"; 5883d1cc414SSteven Rostedt } 5893d1cc414SSteven Rostedt die "$name: $.: Option $lvalue defined more than once!\n$extra"; 5903d1cc414SSteven Rostedt } 591cad96669SSteven Rostedt ${$overrides}{$lvalue} = $prvalue; 592a75fececSSteven Rostedt } 59321a9679fSSteven Rostedt if ($rvalue =~ /^\s*$/) { 59421a9679fSSteven Rostedt delete $opt{$lvalue}; 59521a9679fSSteven Rostedt } else { 596cad96669SSteven Rostedt $opt{$lvalue} = $prvalue; 59721a9679fSSteven Rostedt } 5982545eb61SSteven Rostedt} 599a57419b3SSteven Rostedt 60077d942ceSSteven Rostedtsub set_variable { 60177d942ceSSteven Rostedt my ($lvalue, $rvalue) = @_; 60277d942ceSSteven Rostedt 60377d942ceSSteven Rostedt if ($rvalue =~ /^\s*$/) { 60477d942ceSSteven Rostedt delete $variable{$lvalue}; 60577d942ceSSteven Rostedt } else { 60677d942ceSSteven Rostedt $rvalue = process_variables($rvalue); 60777d942ceSSteven Rostedt $variable{$lvalue} = $rvalue; 60877d942ceSSteven Rostedt } 60977d942ceSSteven Rostedt} 61077d942ceSSteven Rostedt 611ab7a3f52SSteven Rostedtsub process_compare { 612ab7a3f52SSteven Rostedt my ($lval, $cmp, $rval) = @_; 613ab7a3f52SSteven Rostedt 614ab7a3f52SSteven Rostedt # remove whitespace 615ab7a3f52SSteven Rostedt 616ab7a3f52SSteven Rostedt $lval =~ s/^\s*//; 617ab7a3f52SSteven Rostedt $lval =~ s/\s*$//; 618ab7a3f52SSteven Rostedt 619ab7a3f52SSteven Rostedt $rval =~ s/^\s*//; 620ab7a3f52SSteven Rostedt $rval =~ s/\s*$//; 621ab7a3f52SSteven Rostedt 622ab7a3f52SSteven Rostedt if ($cmp eq "==") { 623ab7a3f52SSteven Rostedt return $lval eq $rval; 624ab7a3f52SSteven Rostedt } elsif ($cmp eq "!=") { 625ab7a3f52SSteven Rostedt return $lval ne $rval; 626*8fddbe9bSSteven Rostedt } elsif ($cmp eq "=~") { 627*8fddbe9bSSteven Rostedt return $lval =~ m/$rval/; 628*8fddbe9bSSteven Rostedt } elsif ($cmp eq "!~") { 629*8fddbe9bSSteven Rostedt return $lval !~ m/$rval/; 630ab7a3f52SSteven Rostedt } 631ab7a3f52SSteven Rostedt 632ab7a3f52SSteven Rostedt my $statement = "$lval $cmp $rval"; 633ab7a3f52SSteven Rostedt my $ret = eval $statement; 634ab7a3f52SSteven Rostedt 635ab7a3f52SSteven Rostedt # $@ stores error of eval 636ab7a3f52SSteven Rostedt if ($@) { 637ab7a3f52SSteven Rostedt return -1; 638ab7a3f52SSteven Rostedt } 639ab7a3f52SSteven Rostedt 640ab7a3f52SSteven Rostedt return $ret; 641ab7a3f52SSteven Rostedt} 642ab7a3f52SSteven Rostedt 6439900b5dcSSteven Rostedtsub value_defined { 6449900b5dcSSteven Rostedt my ($val) = @_; 6459900b5dcSSteven Rostedt 6469900b5dcSSteven Rostedt return defined($variable{$2}) || 6479900b5dcSSteven Rostedt defined($opt{$2}); 6489900b5dcSSteven Rostedt} 6499900b5dcSSteven Rostedt 6508d735212SSteven Rostedtmy $d = 0; 6518d735212SSteven Rostedtsub process_expression { 6528d735212SSteven Rostedt my ($name, $val) = @_; 65345d73a5dSSteven Rostedt 6548d735212SSteven Rostedt my $c = $d++; 6558d735212SSteven Rostedt 6568d735212SSteven Rostedt while ($val =~ s/\(([^\(]*?)\)/\&\&\&\&VAL\&\&\&\&/) { 6578d735212SSteven Rostedt my $express = $1; 6588d735212SSteven Rostedt 6598d735212SSteven Rostedt if (process_expression($name, $express)) { 6608d735212SSteven Rostedt $val =~ s/\&\&\&\&VAL\&\&\&\&/ 1 /; 6618d735212SSteven Rostedt } else { 6628d735212SSteven Rostedt $val =~ s/\&\&\&\&VAL\&\&\&\&/ 0 /; 6638d735212SSteven Rostedt } 6648d735212SSteven Rostedt } 6658d735212SSteven Rostedt 6668d735212SSteven Rostedt $d--; 6678d735212SSteven Rostedt my $OR = "\\|\\|"; 6688d735212SSteven Rostedt my $AND = "\\&\\&"; 6698d735212SSteven Rostedt 6708d735212SSteven Rostedt while ($val =~ s/^(.*?)($OR|$AND)//) { 6718d735212SSteven Rostedt my $express = $1; 6728d735212SSteven Rostedt my $op = $2; 6738d735212SSteven Rostedt 6748d735212SSteven Rostedt if (process_expression($name, $express)) { 6758d735212SSteven Rostedt if ($op eq "||") { 6768d735212SSteven Rostedt return 1; 6778d735212SSteven Rostedt } 6788d735212SSteven Rostedt } else { 6798d735212SSteven Rostedt if ($op eq "&&") { 6808d735212SSteven Rostedt return 0; 6818d735212SSteven Rostedt } 6828d735212SSteven Rostedt } 6838d735212SSteven Rostedt } 68445d73a5dSSteven Rostedt 685*8fddbe9bSSteven Rostedt if ($val =~ /(.*)(==|\!=|>=|<=|>|<|=~|\!~)(.*)/) { 686ab7a3f52SSteven Rostedt my $ret = process_compare($1, $2, $3); 687ab7a3f52SSteven Rostedt if ($ret < 0) { 688ab7a3f52SSteven Rostedt die "$name: $.: Unable to process comparison\n"; 689ab7a3f52SSteven Rostedt } 690ab7a3f52SSteven Rostedt return $ret; 691ab7a3f52SSteven Rostedt } 692ab7a3f52SSteven Rostedt 6939900b5dcSSteven Rostedt if ($val =~ /^\s*(NOT\s*)?DEFINED\s+(\S+)\s*$/) { 6949900b5dcSSteven Rostedt if (defined $1) { 6959900b5dcSSteven Rostedt return !value_defined($2); 6969900b5dcSSteven Rostedt } else { 6979900b5dcSSteven Rostedt return value_defined($2); 6989900b5dcSSteven Rostedt } 6999900b5dcSSteven Rostedt } 7009900b5dcSSteven Rostedt 70145d73a5dSSteven Rostedt if ($val =~ /^\s*0\s*$/) { 70245d73a5dSSteven Rostedt return 0; 70345d73a5dSSteven Rostedt } elsif ($val =~ /^\s*\d+\s*$/) { 70445d73a5dSSteven Rostedt return 1; 70545d73a5dSSteven Rostedt } 70645d73a5dSSteven Rostedt 7079900b5dcSSteven Rostedt die ("$name: $.: Undefined content $val in if statement\n"); 7088d735212SSteven Rostedt} 7098d735212SSteven Rostedt 7108d735212SSteven Rostedtsub process_if { 7118d735212SSteven Rostedt my ($name, $value) = @_; 7128d735212SSteven Rostedt 7138d735212SSteven Rostedt # Convert variables and replace undefined ones with 0 7148d735212SSteven Rostedt my $val = process_variables($value, 1); 7158d735212SSteven Rostedt my $ret = process_expression $name, $val; 7168d735212SSteven Rostedt 7178d735212SSteven Rostedt return $ret; 71845d73a5dSSteven Rostedt} 71945d73a5dSSteven Rostedt 7202ed3b161SSteven Rostedtsub __read_config { 7212ed3b161SSteven Rostedt my ($config, $current_test_num) = @_; 722a57419b3SSteven Rostedt 7232ed3b161SSteven Rostedt my $in; 7242ed3b161SSteven Rostedt open($in, $config) || die "can't read file $config"; 725a57419b3SSteven Rostedt 726a57419b3SSteven Rostedt my $name = $config; 727a57419b3SSteven Rostedt $name =~ s,.*/(.*),$1,; 728a57419b3SSteven Rostedt 7292ed3b161SSteven Rostedt my $test_num = $$current_test_num; 730a57419b3SSteven Rostedt my $default = 1; 731a57419b3SSteven Rostedt my $repeat = 1; 732a57419b3SSteven Rostedt my $num_tests_set = 0; 733a57419b3SSteven Rostedt my $skip = 0; 734a57419b3SSteven Rostedt my $rest; 735a9f84424SSteven Rostedt my $line; 7360df213caSSteven Rostedt my $test_case = 0; 73745d73a5dSSteven Rostedt my $if = 0; 73845d73a5dSSteven Rostedt my $if_set = 0; 7393d1cc414SSteven Rostedt my $override = 0; 7403d1cc414SSteven Rostedt 7413d1cc414SSteven Rostedt my %overrides; 742a57419b3SSteven Rostedt 7432ed3b161SSteven Rostedt while (<$in>) { 744a57419b3SSteven Rostedt 745a57419b3SSteven Rostedt # ignore blank lines and comments 746a57419b3SSteven Rostedt next if (/^\s*$/ || /\s*\#/); 747a57419b3SSteven Rostedt 7480050b6bbSSteven Rostedt if (/^\s*(TEST_START|DEFAULTS)\b(.*)/) { 749a57419b3SSteven Rostedt 7500050b6bbSSteven Rostedt my $type = $1; 7510050b6bbSSteven Rostedt $rest = $2; 752a9f84424SSteven Rostedt $line = $2; 7530050b6bbSSteven Rostedt 7540050b6bbSSteven Rostedt my $old_test_num; 7550050b6bbSSteven Rostedt my $old_repeat; 7563d1cc414SSteven Rostedt $override = 0; 7570050b6bbSSteven Rostedt 7580050b6bbSSteven Rostedt if ($type eq "TEST_START") { 759a57419b3SSteven Rostedt 760a57419b3SSteven Rostedt if ($num_tests_set) { 761a57419b3SSteven Rostedt die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n"; 762a57419b3SSteven Rostedt } 763a57419b3SSteven Rostedt 7640050b6bbSSteven Rostedt $old_test_num = $test_num; 7650050b6bbSSteven Rostedt $old_repeat = $repeat; 766a57419b3SSteven Rostedt 767a57419b3SSteven Rostedt $test_num += $repeat; 768a57419b3SSteven Rostedt $default = 0; 769a57419b3SSteven Rostedt $repeat = 1; 7700050b6bbSSteven Rostedt } else { 7710050b6bbSSteven Rostedt $default = 1; 7720050b6bbSSteven Rostedt } 773a57419b3SSteven Rostedt 774a9f84424SSteven Rostedt # If SKIP is anywhere in the line, the command will be skipped 775a9f84424SSteven Rostedt if ($rest =~ s/\s+SKIP\b//) { 776a57419b3SSteven Rostedt $skip = 1; 777a57419b3SSteven Rostedt } else { 7780df213caSSteven Rostedt $test_case = 1; 779a57419b3SSteven Rostedt $skip = 0; 780a57419b3SSteven Rostedt } 781a57419b3SSteven Rostedt 782a9f84424SSteven Rostedt if ($rest =~ s/\sELSE\b//) { 783a9f84424SSteven Rostedt if (!$if) { 784a9f84424SSteven Rostedt die "$name: $.: ELSE found with out matching IF section\n$_"; 785a57419b3SSteven Rostedt } 786a9f84424SSteven Rostedt $if = 0; 787a9f84424SSteven Rostedt 788a9f84424SSteven Rostedt if ($if_set) { 789a9f84424SSteven Rostedt $skip = 1; 790a9f84424SSteven Rostedt } else { 791a9f84424SSteven Rostedt $skip = 0; 7923d1cc414SSteven Rostedt } 7933d1cc414SSteven Rostedt } 794a57419b3SSteven Rostedt 795a9f84424SSteven Rostedt if ($rest =~ s/\sIF\s+(.*)//) { 79645d73a5dSSteven Rostedt if (process_if($name, $1)) { 79745d73a5dSSteven Rostedt $if_set = 1; 79845d73a5dSSteven Rostedt } else { 799a57419b3SSteven Rostedt $skip = 1; 800a57419b3SSteven Rostedt } 80145d73a5dSSteven Rostedt $if = 1; 80245d73a5dSSteven Rostedt } else { 80345d73a5dSSteven Rostedt $if = 0; 804a9f84424SSteven Rostedt $if_set = 0; 80545d73a5dSSteven Rostedt } 806a57419b3SSteven Rostedt 807a9f84424SSteven Rostedt if (!$skip) { 808a9f84424SSteven Rostedt if ($type eq "TEST_START") { 809a9f84424SSteven Rostedt if ($rest =~ s/\s+ITERATE\s+(\d+)//) { 810a9f84424SSteven Rostedt $repeat = $1; 811a9f84424SSteven Rostedt $repeat_tests{"$test_num"} = $repeat; 812a9f84424SSteven Rostedt } 813a9f84424SSteven Rostedt } elsif ($rest =~ s/\sOVERRIDE\b//) { 814a9f84424SSteven Rostedt # DEFAULT only 815a9f84424SSteven Rostedt $override = 1; 816a9f84424SSteven Rostedt # Clear previous overrides 817a9f84424SSteven Rostedt %overrides = (); 818a9f84424SSteven Rostedt } 819a9f84424SSteven Rostedt } 820a9f84424SSteven Rostedt 821a9f84424SSteven Rostedt if (!$skip && $rest !~ /^\s*$/) { 8220050b6bbSSteven Rostedt die "$name: $.: Gargbage found after $type\n$_"; 823a57419b3SSteven Rostedt } 824a57419b3SSteven Rostedt 8250050b6bbSSteven Rostedt if ($skip && $type eq "TEST_START") { 826a57419b3SSteven Rostedt $test_num = $old_test_num; 827e48c5293SSteven Rostedt $repeat = $old_repeat; 828a57419b3SSteven Rostedt } 829a57419b3SSteven Rostedt 830ab7a3f52SSteven Rostedt } elsif (/^\s*ELSE\b(.*)$/) { 83145d73a5dSSteven Rostedt if (!$if) { 83245d73a5dSSteven Rostedt die "$name: $.: ELSE found with out matching IF section\n$_"; 83345d73a5dSSteven Rostedt } 83445d73a5dSSteven Rostedt $rest = $1; 83545d73a5dSSteven Rostedt if ($if_set) { 83645d73a5dSSteven Rostedt $skip = 1; 837ab7a3f52SSteven Rostedt $rest = ""; 83845d73a5dSSteven Rostedt } else { 83945d73a5dSSteven Rostedt $skip = 0; 84045d73a5dSSteven Rostedt 841ab7a3f52SSteven Rostedt if ($rest =~ /\sIF\s+(.*)/) { 84245d73a5dSSteven Rostedt # May be a ELSE IF section. 84345d73a5dSSteven Rostedt if (!process_if($name, $1)) { 84445d73a5dSSteven Rostedt $skip = 1; 84545d73a5dSSteven Rostedt } 846ab7a3f52SSteven Rostedt $rest = ""; 84745d73a5dSSteven Rostedt } else { 84845d73a5dSSteven Rostedt $if = 0; 84945d73a5dSSteven Rostedt } 85045d73a5dSSteven Rostedt } 85145d73a5dSSteven Rostedt 852ab7a3f52SSteven Rostedt if ($rest !~ /^\s*$/) { 853ab7a3f52SSteven Rostedt die "$name: $.: Gargbage found after DEFAULTS\n$_"; 854ab7a3f52SSteven Rostedt } 855ab7a3f52SSteven Rostedt 8562ed3b161SSteven Rostedt } elsif (/^\s*INCLUDE\s+(\S+)/) { 8572ed3b161SSteven Rostedt 8582ed3b161SSteven Rostedt next if ($skip); 8592ed3b161SSteven Rostedt 8602ed3b161SSteven Rostedt if (!$default) { 8612ed3b161SSteven Rostedt die "$name: $.: INCLUDE can only be done in default sections\n$_"; 8622ed3b161SSteven Rostedt } 8632ed3b161SSteven Rostedt 8642ed3b161SSteven Rostedt my $file = process_variables($1); 8652ed3b161SSteven Rostedt 8662ed3b161SSteven Rostedt if ($file !~ m,^/,) { 8672ed3b161SSteven Rostedt # check the path of the config file first 8682ed3b161SSteven Rostedt if ($config =~ m,(.*)/,) { 8692ed3b161SSteven Rostedt if (-f "$1/$file") { 8702ed3b161SSteven Rostedt $file = "$1/$file"; 8712ed3b161SSteven Rostedt } 8722ed3b161SSteven Rostedt } 8732ed3b161SSteven Rostedt } 8742ed3b161SSteven Rostedt 8752ed3b161SSteven Rostedt if ( ! -r $file ) { 8762ed3b161SSteven Rostedt die "$name: $.: Can't read file $file\n$_"; 8772ed3b161SSteven Rostedt } 8782ed3b161SSteven Rostedt 8792ed3b161SSteven Rostedt if (__read_config($file, \$test_num)) { 8802ed3b161SSteven Rostedt $test_case = 1; 8812ed3b161SSteven Rostedt } 8822ed3b161SSteven Rostedt 883a57419b3SSteven Rostedt } elsif (/^\s*([A-Z_\[\]\d]+)\s*=\s*(.*?)\s*$/) { 884a57419b3SSteven Rostedt 885a57419b3SSteven Rostedt next if ($skip); 886a57419b3SSteven Rostedt 887a57419b3SSteven Rostedt my $lvalue = $1; 888a57419b3SSteven Rostedt my $rvalue = $2; 889a57419b3SSteven Rostedt 890a57419b3SSteven Rostedt if (!$default && 891a57419b3SSteven Rostedt ($lvalue eq "NUM_TESTS" || 892a57419b3SSteven Rostedt $lvalue eq "LOG_FILE" || 893a57419b3SSteven Rostedt $lvalue eq "CLEAR_LOG")) { 894a57419b3SSteven Rostedt die "$name: $.: $lvalue must be set in DEFAULTS section\n"; 895a57419b3SSteven Rostedt } 896a57419b3SSteven Rostedt 897a57419b3SSteven Rostedt if ($lvalue eq "NUM_TESTS") { 898a57419b3SSteven Rostedt if ($test_num) { 899a57419b3SSteven Rostedt die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n"; 900a57419b3SSteven Rostedt } 901a57419b3SSteven Rostedt if (!$default) { 902a57419b3SSteven Rostedt die "$name: $.: NUM_TESTS must be set in default section\n"; 903a57419b3SSteven Rostedt } 904a57419b3SSteven Rostedt $num_tests_set = 1; 905a57419b3SSteven Rostedt } 906a57419b3SSteven Rostedt 907a57419b3SSteven Rostedt if ($default || $lvalue =~ /\[\d+\]$/) { 9083d1cc414SSteven Rostedt set_value($lvalue, $rvalue, $override, \%overrides, $name); 909a57419b3SSteven Rostedt } else { 910a57419b3SSteven Rostedt my $val = "$lvalue\[$test_num\]"; 9113d1cc414SSteven Rostedt set_value($val, $rvalue, $override, \%overrides, $name); 912a57419b3SSteven Rostedt 913a57419b3SSteven Rostedt if ($repeat > 1) { 914a57419b3SSteven Rostedt $repeats{$val} = $repeat; 915a57419b3SSteven Rostedt } 916a57419b3SSteven Rostedt } 91777d942ceSSteven Rostedt } elsif (/^\s*([A-Z_\[\]\d]+)\s*:=\s*(.*?)\s*$/) { 91877d942ceSSteven Rostedt next if ($skip); 91977d942ceSSteven Rostedt 92077d942ceSSteven Rostedt my $lvalue = $1; 92177d942ceSSteven Rostedt my $rvalue = $2; 92277d942ceSSteven Rostedt 92377d942ceSSteven Rostedt # process config variables. 92477d942ceSSteven Rostedt # Config variables are only active while reading the 92577d942ceSSteven Rostedt # config and can be defined anywhere. They also ignore 92677d942ceSSteven Rostedt # TEST_START and DEFAULTS, but are skipped if they are in 92777d942ceSSteven Rostedt # on of these sections that have SKIP defined. 92877d942ceSSteven Rostedt # The save variable can be 92977d942ceSSteven Rostedt # defined multiple times and the new one simply overrides 93077d942ceSSteven Rostedt # the prevous one. 93177d942ceSSteven Rostedt set_variable($lvalue, $rvalue); 93277d942ceSSteven Rostedt 933a57419b3SSteven Rostedt } else { 934a57419b3SSteven Rostedt die "$name: $.: Garbage found in config\n$_"; 935a57419b3SSteven Rostedt } 9362545eb61SSteven Rostedt } 9372545eb61SSteven Rostedt 938a57419b3SSteven Rostedt if ($test_num) { 939a57419b3SSteven Rostedt $test_num += $repeat - 1; 940a57419b3SSteven Rostedt $opt{"NUM_TESTS"} = $test_num; 941a57419b3SSteven Rostedt } 942a57419b3SSteven Rostedt 9432ed3b161SSteven Rostedt close($in); 9442ed3b161SSteven Rostedt 9452ed3b161SSteven Rostedt $$current_test_num = $test_num; 9462ed3b161SSteven Rostedt 9472ed3b161SSteven Rostedt return $test_case; 9482ed3b161SSteven Rostedt} 9492ed3b161SSteven Rostedt 950c4261d0fSSteven Rostedtsub get_test_case { 951c4261d0fSSteven Rostedt print "What test case would you like to run?\n"; 952c4261d0fSSteven Rostedt print " (build, install or boot)\n"; 953c4261d0fSSteven Rostedt print " Other tests are available but require editing the config file\n"; 954c4261d0fSSteven Rostedt my $ans = <STDIN>; 955c4261d0fSSteven Rostedt chomp $ans; 956c4261d0fSSteven Rostedt $default{"TEST_TYPE"} = $ans; 957c4261d0fSSteven Rostedt} 958c4261d0fSSteven Rostedt 9592ed3b161SSteven Rostedtsub read_config { 9602ed3b161SSteven Rostedt my ($config) = @_; 9612ed3b161SSteven Rostedt 9622ed3b161SSteven Rostedt my $test_case; 9632ed3b161SSteven Rostedt my $test_num = 0; 9642ed3b161SSteven Rostedt 9652ed3b161SSteven Rostedt $test_case = __read_config $config, \$test_num; 9662ed3b161SSteven Rostedt 9678d1491baSSteven Rostedt # make sure we have all mandatory configs 9688d1491baSSteven Rostedt get_ktest_configs; 9698d1491baSSteven Rostedt 9700df213caSSteven Rostedt # was a test specified? 9710df213caSSteven Rostedt if (!$test_case) { 9720df213caSSteven Rostedt print "No test case specified.\n"; 973c4261d0fSSteven Rostedt get_test_case; 9740df213caSSteven Rostedt } 9750df213caSSteven Rostedt 976a75fececSSteven Rostedt # set any defaults 977a75fececSSteven Rostedt 978a75fececSSteven Rostedt foreach my $default (keys %default) { 979a75fececSSteven Rostedt if (!defined($opt{$default})) { 980a75fececSSteven Rostedt $opt{$default} = $default{$default}; 981a75fececSSteven Rostedt } 982a75fececSSteven Rostedt } 9839cc9e091SSteven Rostedt 9849cc9e091SSteven Rostedt if ($opt{"IGNORE_UNUSED"} == 1) { 9859cc9e091SSteven Rostedt return; 9869cc9e091SSteven Rostedt } 9879cc9e091SSteven Rostedt 9889cc9e091SSteven Rostedt my %not_used; 9899cc9e091SSteven Rostedt 9909cc9e091SSteven Rostedt # check if there are any stragglers (typos?) 9919cc9e091SSteven Rostedt foreach my $option (keys %opt) { 9929cc9e091SSteven Rostedt my $op = $option; 9939cc9e091SSteven Rostedt # remove per test labels. 9949cc9e091SSteven Rostedt $op =~ s/\[.*\]//; 9959cc9e091SSteven Rostedt if (!exists($option_map{$op}) && 9969cc9e091SSteven Rostedt !exists($default{$op}) && 9979cc9e091SSteven Rostedt !exists($used_options{$op})) { 9989cc9e091SSteven Rostedt $not_used{$op} = 1; 9999cc9e091SSteven Rostedt } 10009cc9e091SSteven Rostedt } 10019cc9e091SSteven Rostedt 10029cc9e091SSteven Rostedt if (%not_used) { 10039cc9e091SSteven Rostedt my $s = "s are"; 10049cc9e091SSteven Rostedt $s = " is" if (keys %not_used == 1); 10059cc9e091SSteven Rostedt print "The following option$s not used; could be a typo:\n"; 10069cc9e091SSteven Rostedt foreach my $option (keys %not_used) { 10079cc9e091SSteven Rostedt print "$option\n"; 10089cc9e091SSteven Rostedt } 10099cc9e091SSteven Rostedt print "Set IGRNORE_UNUSED = 1 to have ktest ignore unused variables\n"; 10109cc9e091SSteven Rostedt if (!read_yn "Do you want to continue?") { 10119cc9e091SSteven Rostedt exit -1; 10129cc9e091SSteven Rostedt } 10139cc9e091SSteven Rostedt } 10142545eb61SSteven Rostedt} 10152545eb61SSteven Rostedt 101623715c3cSSteven Rostedtsub __eval_option { 101723715c3cSSteven Rostedt my ($option, $i) = @_; 101823715c3cSSteven Rostedt 101923715c3cSSteven Rostedt # Add space to evaluate the character before $ 102023715c3cSSteven Rostedt $option = " $option"; 102123715c3cSSteven Rostedt my $retval = ""; 1022f9dfb65bSRabin Vincent my $repeated = 0; 1023f9dfb65bSRabin Vincent my $parent = 0; 1024f9dfb65bSRabin Vincent 1025f9dfb65bSRabin Vincent foreach my $test (keys %repeat_tests) { 1026f9dfb65bSRabin Vincent if ($i >= $test && 1027f9dfb65bSRabin Vincent $i < $test + $repeat_tests{$test}) { 1028f9dfb65bSRabin Vincent 1029f9dfb65bSRabin Vincent $repeated = 1; 1030f9dfb65bSRabin Vincent $parent = $test; 1031f9dfb65bSRabin Vincent last; 1032f9dfb65bSRabin Vincent } 1033f9dfb65bSRabin Vincent } 103423715c3cSSteven Rostedt 103523715c3cSSteven Rostedt while ($option =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) { 103623715c3cSSteven Rostedt my $start = $1; 103723715c3cSSteven Rostedt my $var = $2; 103823715c3cSSteven Rostedt my $end = $3; 103923715c3cSSteven Rostedt 104023715c3cSSteven Rostedt # Append beginning of line 104123715c3cSSteven Rostedt $retval = "$retval$start"; 104223715c3cSSteven Rostedt 104323715c3cSSteven Rostedt # If the iteration option OPT[$i] exists, then use that. 104423715c3cSSteven Rostedt # otherwise see if the default OPT (without [$i]) exists. 104523715c3cSSteven Rostedt 104623715c3cSSteven Rostedt my $o = "$var\[$i\]"; 1047f9dfb65bSRabin Vincent my $parento = "$var\[$parent\]"; 104823715c3cSSteven Rostedt 104923715c3cSSteven Rostedt if (defined($opt{$o})) { 105023715c3cSSteven Rostedt $o = $opt{$o}; 105123715c3cSSteven Rostedt $retval = "$retval$o"; 1052f9dfb65bSRabin Vincent } elsif ($repeated && defined($opt{$parento})) { 1053f9dfb65bSRabin Vincent $o = $opt{$parento}; 1054f9dfb65bSRabin Vincent $retval = "$retval$o"; 105523715c3cSSteven Rostedt } elsif (defined($opt{$var})) { 105623715c3cSSteven Rostedt $o = $opt{$var}; 105723715c3cSSteven Rostedt $retval = "$retval$o"; 105823715c3cSSteven Rostedt } else { 105923715c3cSSteven Rostedt $retval = "$retval\$\{$var\}"; 106023715c3cSSteven Rostedt } 106123715c3cSSteven Rostedt 106223715c3cSSteven Rostedt $option = $end; 106323715c3cSSteven Rostedt } 106423715c3cSSteven Rostedt 106523715c3cSSteven Rostedt $retval = "$retval$option"; 106623715c3cSSteven Rostedt 106723715c3cSSteven Rostedt $retval =~ s/^ //; 106823715c3cSSteven Rostedt 106923715c3cSSteven Rostedt return $retval; 107023715c3cSSteven Rostedt} 107123715c3cSSteven Rostedt 107223715c3cSSteven Rostedtsub eval_option { 107323715c3cSSteven Rostedt my ($option, $i) = @_; 107423715c3cSSteven Rostedt 107523715c3cSSteven Rostedt my $prev = ""; 107623715c3cSSteven Rostedt 107723715c3cSSteven Rostedt # Since an option can evaluate to another option, 107823715c3cSSteven Rostedt # keep iterating until we do not evaluate any more 107923715c3cSSteven Rostedt # options. 108023715c3cSSteven Rostedt my $r = 0; 108123715c3cSSteven Rostedt while ($prev ne $option) { 108223715c3cSSteven Rostedt # Check for recursive evaluations. 108323715c3cSSteven Rostedt # 100 deep should be more than enough. 108423715c3cSSteven Rostedt if ($r++ > 100) { 108523715c3cSSteven Rostedt die "Over 100 evaluations accurred with $option\n" . 108623715c3cSSteven Rostedt "Check for recursive variables\n"; 108723715c3cSSteven Rostedt } 108823715c3cSSteven Rostedt $prev = $option; 108923715c3cSSteven Rostedt $option = __eval_option($option, $i); 109023715c3cSSteven Rostedt } 109123715c3cSSteven Rostedt 109223715c3cSSteven Rostedt return $option; 109323715c3cSSteven Rostedt} 109423715c3cSSteven Rostedt 1095d1e2f22aSSteven Rostedtsub _logit { 10962545eb61SSteven Rostedt if (defined($opt{"LOG_FILE"})) { 10972545eb61SSteven Rostedt open(OUT, ">> $opt{LOG_FILE}") or die "Can't write to $opt{LOG_FILE}"; 10982545eb61SSteven Rostedt print OUT @_; 10992545eb61SSteven Rostedt close(OUT); 11002545eb61SSteven Rostedt } 11012545eb61SSteven Rostedt} 11022545eb61SSteven Rostedt 1103d1e2f22aSSteven Rostedtsub logit { 1104d1e2f22aSSteven Rostedt if (defined($opt{"LOG_FILE"})) { 1105d1e2f22aSSteven Rostedt _logit @_; 1106d1e2f22aSSteven Rostedt } else { 1107d1e2f22aSSteven Rostedt print @_; 1108d1e2f22aSSteven Rostedt } 1109d1e2f22aSSteven Rostedt} 1110d1e2f22aSSteven Rostedt 11115f9b6cedSSteven Rostedtsub doprint { 11125f9b6cedSSteven Rostedt print @_; 1113d1e2f22aSSteven Rostedt _logit @_; 11145f9b6cedSSteven Rostedt} 11155f9b6cedSSteven Rostedt 11167faafbd6SSteven Rostedtsub run_command; 11172728be41SAndrew Jonessub start_monitor; 11182728be41SAndrew Jonessub end_monitor; 11192728be41SAndrew Jonessub wait_for_monitor; 11207faafbd6SSteven Rostedt 11217faafbd6SSteven Rostedtsub reboot { 11222728be41SAndrew Jones my ($time) = @_; 11232728be41SAndrew Jones 11242b803365SSteven Rostedt if (defined($time)) { 11252b803365SSteven Rostedt start_monitor; 11262b803365SSteven Rostedt # flush out current monitor 11272b803365SSteven Rostedt # May contain the reboot success line 11282b803365SSteven Rostedt wait_for_monitor 1; 11292b803365SSteven Rostedt } 11302b803365SSteven Rostedt 11317faafbd6SSteven Rostedt # try to reboot normally 1132e48c5293SSteven Rostedt if (run_command $reboot) { 1133576f627cSSteven Rostedt if (defined($powercycle_after_reboot)) { 1134576f627cSSteven Rostedt sleep $powercycle_after_reboot; 1135576f627cSSteven Rostedt run_command "$power_cycle"; 1136576f627cSSteven Rostedt } 1137576f627cSSteven Rostedt } else { 11387faafbd6SSteven Rostedt # nope? power cycle it. 1139a75fececSSteven Rostedt run_command "$power_cycle"; 11407faafbd6SSteven Rostedt } 11412728be41SAndrew Jones 11422728be41SAndrew Jones if (defined($time)) { 1143407b95b7SSteven Rostedt if (wait_for_monitor($time, $reboot_success_line)) { 1144407b95b7SSteven Rostedt # reboot got stuck? 11458a80c727SSteven Rostedt doprint "Reboot did not finish. Forcing power cycle\n"; 1146407b95b7SSteven Rostedt run_command "$power_cycle"; 1147407b95b7SSteven Rostedt } 11482728be41SAndrew Jones end_monitor; 11492728be41SAndrew Jones } 11507faafbd6SSteven Rostedt} 11517faafbd6SSteven Rostedt 1152bc7c5803SSteven Rostedtsub reboot_to_good { 1153bc7c5803SSteven Rostedt my ($time) = @_; 1154bc7c5803SSteven Rostedt 1155bc7c5803SSteven Rostedt if (defined($switch_to_good)) { 1156bc7c5803SSteven Rostedt run_command $switch_to_good; 1157bc7c5803SSteven Rostedt } 1158bc7c5803SSteven Rostedt 1159bc7c5803SSteven Rostedt reboot $time; 1160bc7c5803SSteven Rostedt} 1161bc7c5803SSteven Rostedt 1162576f627cSSteven Rostedtsub do_not_reboot { 1163576f627cSSteven Rostedt my $i = $iteration; 1164576f627cSSteven Rostedt 11654ab1cce5SSteven Rostedt return $test_type eq "build" || $no_reboot || 1166576f627cSSteven Rostedt ($test_type eq "patchcheck" && $opt{"PATCHCHECK_TYPE[$i]"} eq "build") || 1167576f627cSSteven Rostedt ($test_type eq "bisect" && $opt{"BISECT_TYPE[$i]"} eq "build"); 1168576f627cSSteven Rostedt} 1169576f627cSSteven Rostedt 11705c42fc5bSSteven Rostedtsub dodie { 11715a391fbfSSteven Rostedt doprint "CRITICAL FAILURE... ", @_, "\n"; 11725c42fc5bSSteven Rostedt 1173576f627cSSteven Rostedt my $i = $iteration; 1174576f627cSSteven Rostedt 1175576f627cSSteven Rostedt if ($reboot_on_error && !do_not_reboot) { 1176576f627cSSteven Rostedt 117775c3fda7SSteven Rostedt doprint "REBOOTING\n"; 1178bc7c5803SSteven Rostedt reboot_to_good; 117975c3fda7SSteven Rostedt 1180a75fececSSteven Rostedt } elsif ($poweroff_on_error && defined($power_off)) { 11815c42fc5bSSteven Rostedt doprint "POWERING OFF\n"; 1182a75fececSSteven Rostedt `$power_off`; 11835c42fc5bSSteven Rostedt } 118475c3fda7SSteven Rostedt 1185f80802cbSSteven Rostedt if (defined($opt{"LOG_FILE"})) { 1186f80802cbSSteven Rostedt print " See $opt{LOG_FILE} for more info.\n"; 1187f80802cbSSteven Rostedt } 1188f80802cbSSteven Rostedt 1189576f627cSSteven Rostedt die @_, "\n"; 11905c42fc5bSSteven Rostedt} 11915c42fc5bSSteven Rostedt 11927faafbd6SSteven Rostedtsub open_console { 11937faafbd6SSteven Rostedt my ($fp) = @_; 11947faafbd6SSteven Rostedt 11957faafbd6SSteven Rostedt my $flags; 11967faafbd6SSteven Rostedt 1197a75fececSSteven Rostedt my $pid = open($fp, "$console|") or 1198a75fececSSteven Rostedt dodie "Can't open console $console"; 11997faafbd6SSteven Rostedt 12007faafbd6SSteven Rostedt $flags = fcntl($fp, F_GETFL, 0) or 1201576f627cSSteven Rostedt dodie "Can't get flags for the socket: $!"; 12027faafbd6SSteven Rostedt $flags = fcntl($fp, F_SETFL, $flags | O_NONBLOCK) or 1203576f627cSSteven Rostedt dodie "Can't set flags for the socket: $!"; 12047faafbd6SSteven Rostedt 12057faafbd6SSteven Rostedt return $pid; 12067faafbd6SSteven Rostedt} 12077faafbd6SSteven Rostedt 12087faafbd6SSteven Rostedtsub close_console { 12097faafbd6SSteven Rostedt my ($fp, $pid) = @_; 12107faafbd6SSteven Rostedt 12117faafbd6SSteven Rostedt doprint "kill child process $pid\n"; 12127faafbd6SSteven Rostedt kill 2, $pid; 12137faafbd6SSteven Rostedt 12147faafbd6SSteven Rostedt print "closing!\n"; 12157faafbd6SSteven Rostedt close($fp); 12167faafbd6SSteven Rostedt} 12177faafbd6SSteven Rostedt 12187faafbd6SSteven Rostedtsub start_monitor { 12197faafbd6SSteven Rostedt if ($monitor_cnt++) { 12207faafbd6SSteven Rostedt return; 12217faafbd6SSteven Rostedt } 12227faafbd6SSteven Rostedt $monitor_fp = \*MONFD; 12237faafbd6SSteven Rostedt $monitor_pid = open_console $monitor_fp; 1224a75fececSSteven Rostedt 1225a75fececSSteven Rostedt return; 1226a75fececSSteven Rostedt 1227a75fececSSteven Rostedt open(MONFD, "Stop perl from warning about single use of MONFD"); 12287faafbd6SSteven Rostedt} 12297faafbd6SSteven Rostedt 12307faafbd6SSteven Rostedtsub end_monitor { 12317faafbd6SSteven Rostedt if (--$monitor_cnt) { 12327faafbd6SSteven Rostedt return; 12337faafbd6SSteven Rostedt } 12347faafbd6SSteven Rostedt close_console($monitor_fp, $monitor_pid); 12357faafbd6SSteven Rostedt} 12367faafbd6SSteven Rostedt 12377faafbd6SSteven Rostedtsub wait_for_monitor { 12382b803365SSteven Rostedt my ($time, $stop) = @_; 12392b803365SSteven Rostedt my $full_line = ""; 12407faafbd6SSteven Rostedt my $line; 12412b803365SSteven Rostedt my $booted = 0; 1242407b95b7SSteven Rostedt my $start_time = time; 12438a80c727SSteven Rostedt my $skip_call_trace = 0; 12448a80c727SSteven Rostedt my $bug = 0; 12458a80c727SSteven Rostedt my $bug_ignored = 0; 1246407b95b7SSteven Rostedt my $now; 12477faafbd6SSteven Rostedt 1248a75fececSSteven Rostedt doprint "** Wait for monitor to settle down **\n"; 12497faafbd6SSteven Rostedt 12507faafbd6SSteven Rostedt # read the monitor and wait for the system to calm down 12512b803365SSteven Rostedt while (!$booted) { 12527faafbd6SSteven Rostedt $line = wait_for_input($monitor_fp, $time); 12532b803365SSteven Rostedt last if (!defined($line)); 12542b803365SSteven Rostedt print "$line"; 12552b803365SSteven Rostedt $full_line .= $line; 12562b803365SSteven Rostedt 12572b803365SSteven Rostedt if (defined($stop) && $full_line =~ /$stop/) { 12582b803365SSteven Rostedt doprint "wait for monitor detected $stop\n"; 12592b803365SSteven Rostedt $booted = 1; 12602b803365SSteven Rostedt } 12612b803365SSteven Rostedt 12628a80c727SSteven Rostedt if ($full_line =~ /\[ backtrace testing \]/) { 12638a80c727SSteven Rostedt $skip_call_trace = 1; 12648a80c727SSteven Rostedt } 12658a80c727SSteven Rostedt 12668a80c727SSteven Rostedt if ($full_line =~ /call trace:/i) { 12678a80c727SSteven Rostedt if (!$bug && !$skip_call_trace) { 12688a80c727SSteven Rostedt if ($ignore_errors) { 12698a80c727SSteven Rostedt $bug_ignored = 1; 12708a80c727SSteven Rostedt } else { 12718a80c727SSteven Rostedt $bug = 1; 12728a80c727SSteven Rostedt } 12738a80c727SSteven Rostedt } 12748a80c727SSteven Rostedt } 12758a80c727SSteven Rostedt 12768a80c727SSteven Rostedt if ($full_line =~ /\[ end of backtrace testing \]/) { 12778a80c727SSteven Rostedt $skip_call_trace = 0; 12788a80c727SSteven Rostedt } 12798a80c727SSteven Rostedt 12808a80c727SSteven Rostedt if ($full_line =~ /Kernel panic -/) { 12818a80c727SSteven Rostedt $bug = 1; 12828a80c727SSteven Rostedt } 12838a80c727SSteven Rostedt 12842b803365SSteven Rostedt if ($line =~ /\n/) { 12852b803365SSteven Rostedt $full_line = ""; 12862b803365SSteven Rostedt } 1287407b95b7SSteven Rostedt $now = time; 1288407b95b7SSteven Rostedt if ($now - $start_time >= $max_monitor_wait) { 1289407b95b7SSteven Rostedt doprint "Exiting monitor flush due to hitting MAX_MONITOR_WAIT\n"; 1290407b95b7SSteven Rostedt return 1; 1291407b95b7SSteven Rostedt } 12922b803365SSteven Rostedt } 1293a75fececSSteven Rostedt print "** Monitor flushed **\n"; 12948a80c727SSteven Rostedt return $bug; 12957faafbd6SSteven Rostedt} 12967faafbd6SSteven Rostedt 1297de5b6e3bSRabin Vincentsub save_logs { 1298de5b6e3bSRabin Vincent my ($result, $basedir) = @_; 1299de5b6e3bSRabin Vincent my @t = localtime; 1300de5b6e3bSRabin Vincent my $date = sprintf "%04d%02d%02d%02d%02d%02d", 1301de5b6e3bSRabin Vincent 1900+$t[5],$t[4],$t[3],$t[2],$t[1],$t[0]; 1302de5b6e3bSRabin Vincent 1303de5b6e3bSRabin Vincent my $type = $build_type; 1304de5b6e3bSRabin Vincent if ($type =~ /useconfig/) { 1305de5b6e3bSRabin Vincent $type = "useconfig"; 1306de5b6e3bSRabin Vincent } 1307de5b6e3bSRabin Vincent 1308de5b6e3bSRabin Vincent my $dir = "$machine-$test_type-$type-$result-$date"; 1309de5b6e3bSRabin Vincent 1310de5b6e3bSRabin Vincent $dir = "$basedir/$dir"; 1311de5b6e3bSRabin Vincent 1312de5b6e3bSRabin Vincent if (!-d $dir) { 1313de5b6e3bSRabin Vincent mkpath($dir) or 1314de5b6e3bSRabin Vincent die "can't create $dir"; 1315de5b6e3bSRabin Vincent } 1316de5b6e3bSRabin Vincent 1317de5b6e3bSRabin Vincent my %files = ( 1318de5b6e3bSRabin Vincent "config" => $output_config, 1319de5b6e3bSRabin Vincent "buildlog" => $buildlog, 1320de5b6e3bSRabin Vincent "dmesg" => $dmesg, 1321de5b6e3bSRabin Vincent "testlog" => $testlog, 1322de5b6e3bSRabin Vincent ); 1323de5b6e3bSRabin Vincent 1324de5b6e3bSRabin Vincent while (my ($name, $source) = each(%files)) { 1325de5b6e3bSRabin Vincent if (-f "$source") { 1326de5b6e3bSRabin Vincent cp "$source", "$dir/$name" or 1327de5b6e3bSRabin Vincent die "failed to copy $source"; 1328de5b6e3bSRabin Vincent } 1329de5b6e3bSRabin Vincent } 1330de5b6e3bSRabin Vincent 1331de5b6e3bSRabin Vincent doprint "*** Saved info to $dir ***\n"; 1332de5b6e3bSRabin Vincent} 1333de5b6e3bSRabin Vincent 13342b7d9b21SSteven Rostedtsub fail { 13352b7d9b21SSteven Rostedt 1336921ed4c7SSteven Rostedt if (defined($post_test)) { 1337921ed4c7SSteven Rostedt run_command $post_test; 1338921ed4c7SSteven Rostedt } 1339921ed4c7SSteven Rostedt 1340a75fececSSteven Rostedt if ($die_on_failure) { 13412b7d9b21SSteven Rostedt dodie @_; 13422b7d9b21SSteven Rostedt } 13432b7d9b21SSteven Rostedt 1344a75fececSSteven Rostedt doprint "FAILED\n"; 13457faafbd6SSteven Rostedt 1346576f627cSSteven Rostedt my $i = $iteration; 1347576f627cSSteven Rostedt 1348a75fececSSteven Rostedt # no need to reboot for just building. 1349576f627cSSteven Rostedt if (!do_not_reboot) { 13507faafbd6SSteven Rostedt doprint "REBOOTING\n"; 1351bc7c5803SSteven Rostedt reboot_to_good $sleep_time; 1352a75fececSSteven Rostedt } 13537faafbd6SSteven Rostedt 13549064af52SSteven Rostedt my $name = ""; 13559064af52SSteven Rostedt 13569064af52SSteven Rostedt if (defined($test_name)) { 13579064af52SSteven Rostedt $name = " ($test_name)"; 13589064af52SSteven Rostedt } 13599064af52SSteven Rostedt 1360576f627cSSteven Rostedt doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"; 1361576f627cSSteven Rostedt doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"; 13629064af52SSteven Rostedt doprint "KTEST RESULT: TEST $i$name Failed: ", @_, "\n"; 1363576f627cSSteven Rostedt doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"; 1364576f627cSSteven Rostedt doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"; 1365a75fececSSteven Rostedt 1366de5b6e3bSRabin Vincent if (defined($store_failures)) { 1367de5b6e3bSRabin Vincent save_logs "fail", $store_failures; 1368cccae1a6SSteven Rostedt } 1369cccae1a6SSteven Rostedt 13702b7d9b21SSteven Rostedt return 1; 13712b7d9b21SSteven Rostedt} 13722b7d9b21SSteven Rostedt 13732545eb61SSteven Rostedtsub run_command { 13742545eb61SSteven Rostedt my ($command) = @_; 1375d6ce2a0bSSteven Rostedt my $dolog = 0; 1376d6ce2a0bSSteven Rostedt my $dord = 0; 1377d6ce2a0bSSteven Rostedt my $pid; 1378d6ce2a0bSSteven Rostedt 1379e48c5293SSteven Rostedt $command =~ s/\$SSH_USER/$ssh_user/g; 1380e48c5293SSteven Rostedt $command =~ s/\$MACHINE/$machine/g; 1381e48c5293SSteven Rostedt 1382d6ce2a0bSSteven Rostedt doprint("$command ... "); 1383d6ce2a0bSSteven Rostedt 1384d6ce2a0bSSteven Rostedt $pid = open(CMD, "$command 2>&1 |") or 13852b7d9b21SSteven Rostedt (fail "unable to exec $command" and return 0); 13862545eb61SSteven Rostedt 13872545eb61SSteven Rostedt if (defined($opt{"LOG_FILE"})) { 1388d6ce2a0bSSteven Rostedt open(LOG, ">>$opt{LOG_FILE}") or 1389d6ce2a0bSSteven Rostedt dodie "failed to write to log"; 1390d6ce2a0bSSteven Rostedt $dolog = 1; 13916c5ee0beSSteven Rostedt } 13926c5ee0beSSteven Rostedt 13936c5ee0beSSteven Rostedt if (defined($redirect)) { 1394d6ce2a0bSSteven Rostedt open (RD, ">$redirect") or 1395d6ce2a0bSSteven Rostedt dodie "failed to write to redirect $redirect"; 1396d6ce2a0bSSteven Rostedt $dord = 1; 13972545eb61SSteven Rostedt } 13982545eb61SSteven Rostedt 1399d6ce2a0bSSteven Rostedt while (<CMD>) { 1400d6ce2a0bSSteven Rostedt print LOG if ($dolog); 1401d6ce2a0bSSteven Rostedt print RD if ($dord); 1402d6ce2a0bSSteven Rostedt } 14032545eb61SSteven Rostedt 1404d6ce2a0bSSteven Rostedt waitpid($pid, 0); 14052545eb61SSteven Rostedt my $failed = $?; 14062545eb61SSteven Rostedt 1407d6ce2a0bSSteven Rostedt close(CMD); 1408d6ce2a0bSSteven Rostedt close(LOG) if ($dolog); 1409d6ce2a0bSSteven Rostedt close(RD) if ($dord); 1410d6ce2a0bSSteven Rostedt 14112545eb61SSteven Rostedt if ($failed) { 14122545eb61SSteven Rostedt doprint "FAILED!\n"; 14132545eb61SSteven Rostedt } else { 14142545eb61SSteven Rostedt doprint "SUCCESS\n"; 14152545eb61SSteven Rostedt } 14162545eb61SSteven Rostedt 14175f9b6cedSSteven Rostedt return !$failed; 14185f9b6cedSSteven Rostedt} 14195f9b6cedSSteven Rostedt 1420e48c5293SSteven Rostedtsub run_ssh { 1421e48c5293SSteven Rostedt my ($cmd) = @_; 1422e48c5293SSteven Rostedt my $cp_exec = $ssh_exec; 1423e48c5293SSteven Rostedt 1424e48c5293SSteven Rostedt $cp_exec =~ s/\$SSH_COMMAND/$cmd/g; 1425e48c5293SSteven Rostedt return run_command "$cp_exec"; 1426e48c5293SSteven Rostedt} 1427e48c5293SSteven Rostedt 1428e48c5293SSteven Rostedtsub run_scp { 142902ad2617SSteven Rostedt my ($src, $dst, $cp_scp) = @_; 1430e48c5293SSteven Rostedt 1431e48c5293SSteven Rostedt $cp_scp =~ s/\$SRC_FILE/$src/g; 1432e48c5293SSteven Rostedt $cp_scp =~ s/\$DST_FILE/$dst/g; 1433e48c5293SSteven Rostedt 1434e48c5293SSteven Rostedt return run_command "$cp_scp"; 1435e48c5293SSteven Rostedt} 1436e48c5293SSteven Rostedt 143702ad2617SSteven Rostedtsub run_scp_install { 143802ad2617SSteven Rostedt my ($src, $dst) = @_; 143902ad2617SSteven Rostedt 144002ad2617SSteven Rostedt my $cp_scp = $scp_to_target_install; 144102ad2617SSteven Rostedt 144202ad2617SSteven Rostedt return run_scp($src, $dst, $cp_scp); 144302ad2617SSteven Rostedt} 144402ad2617SSteven Rostedt 144502ad2617SSteven Rostedtsub run_scp_mod { 144602ad2617SSteven Rostedt my ($src, $dst) = @_; 144702ad2617SSteven Rostedt 144802ad2617SSteven Rostedt my $cp_scp = $scp_to_target; 144902ad2617SSteven Rostedt 145002ad2617SSteven Rostedt return run_scp($src, $dst, $cp_scp); 145102ad2617SSteven Rostedt} 145202ad2617SSteven Rostedt 14535f9b6cedSSteven Rostedtsub get_grub_index { 14545f9b6cedSSteven Rostedt 1455a75fececSSteven Rostedt if ($reboot_type ne "grub") { 1456a75fececSSteven Rostedt return; 1457a75fececSSteven Rostedt } 14585a391fbfSSteven Rostedt return if (defined($grub_number)); 14595f9b6cedSSteven Rostedt 14605f9b6cedSSteven Rostedt doprint "Find grub menu ... "; 14615f9b6cedSSteven Rostedt $grub_number = -1; 1462e48c5293SSteven Rostedt 1463e48c5293SSteven Rostedt my $ssh_grub = $ssh_exec; 1464e48c5293SSteven Rostedt $ssh_grub =~ s,\$SSH_COMMAND,cat /boot/grub/menu.lst,g; 1465e48c5293SSteven Rostedt 1466e48c5293SSteven Rostedt open(IN, "$ssh_grub |") 14675f9b6cedSSteven Rostedt or die "unable to get menu.lst"; 1468e48c5293SSteven Rostedt 1469eaa1fe25SSteven Rostedt my $found = 0; 1470eaa1fe25SSteven Rostedt 14715f9b6cedSSteven Rostedt while (<IN>) { 1472a75fececSSteven Rostedt if (/^\s*title\s+$grub_menu\s*$/) { 14735f9b6cedSSteven Rostedt $grub_number++; 1474eaa1fe25SSteven Rostedt $found = 1; 14755f9b6cedSSteven Rostedt last; 14765f9b6cedSSteven Rostedt } elsif (/^\s*title\s/) { 14775f9b6cedSSteven Rostedt $grub_number++; 14785f9b6cedSSteven Rostedt } 14795f9b6cedSSteven Rostedt } 14805f9b6cedSSteven Rostedt close(IN); 14815f9b6cedSSteven Rostedt 1482a75fececSSteven Rostedt die "Could not find '$grub_menu' in /boot/grub/menu on $machine" 1483eaa1fe25SSteven Rostedt if (!$found); 14845f9b6cedSSteven Rostedt doprint "$grub_number\n"; 14852545eb61SSteven Rostedt} 14862545eb61SSteven Rostedt 14872545eb61SSteven Rostedtsub wait_for_input 14882545eb61SSteven Rostedt{ 14892545eb61SSteven Rostedt my ($fp, $time) = @_; 14902545eb61SSteven Rostedt my $rin; 14912545eb61SSteven Rostedt my $ready; 14922545eb61SSteven Rostedt my $line; 14932545eb61SSteven Rostedt my $ch; 14942545eb61SSteven Rostedt 14952545eb61SSteven Rostedt if (!defined($time)) { 14962545eb61SSteven Rostedt $time = $timeout; 14972545eb61SSteven Rostedt } 14982545eb61SSteven Rostedt 14992545eb61SSteven Rostedt $rin = ''; 15002545eb61SSteven Rostedt vec($rin, fileno($fp), 1) = 1; 15012545eb61SSteven Rostedt $ready = select($rin, undef, undef, $time); 15022545eb61SSteven Rostedt 15032545eb61SSteven Rostedt $line = ""; 15042545eb61SSteven Rostedt 15052545eb61SSteven Rostedt # try to read one char at a time 15062545eb61SSteven Rostedt while (sysread $fp, $ch, 1) { 15072545eb61SSteven Rostedt $line .= $ch; 15082545eb61SSteven Rostedt last if ($ch eq "\n"); 15092545eb61SSteven Rostedt } 15102545eb61SSteven Rostedt 15112545eb61SSteven Rostedt if (!length($line)) { 15122545eb61SSteven Rostedt return undef; 15132545eb61SSteven Rostedt } 15142545eb61SSteven Rostedt 15152545eb61SSteven Rostedt return $line; 15162545eb61SSteven Rostedt} 15172545eb61SSteven Rostedt 151875c3fda7SSteven Rostedtsub reboot_to { 1519bc7c5803SSteven Rostedt if (defined($switch_to_test)) { 1520bc7c5803SSteven Rostedt run_command $switch_to_test; 1521bc7c5803SSteven Rostedt } 1522bc7c5803SSteven Rostedt 1523a75fececSSteven Rostedt if ($reboot_type eq "grub") { 1524c54367f9SSteven Rostedt run_ssh "'(echo \"savedefault --default=$grub_number --once\" | grub --batch)'"; 152596f6a0dfSSteven Rostedt } elsif (defined $reboot_script) { 1526a75fececSSteven Rostedt run_command "$reboot_script"; 15272545eb61SSteven Rostedt } 152896f6a0dfSSteven Rostedt reboot; 152996f6a0dfSSteven Rostedt} 15302545eb61SSteven Rostedt 1531a57419b3SSteven Rostedtsub get_sha1 { 1532a57419b3SSteven Rostedt my ($commit) = @_; 1533a57419b3SSteven Rostedt 1534a57419b3SSteven Rostedt doprint "git rev-list --max-count=1 $commit ... "; 1535a57419b3SSteven Rostedt my $sha1 = `git rev-list --max-count=1 $commit`; 1536a57419b3SSteven Rostedt my $ret = $?; 1537a57419b3SSteven Rostedt 1538a57419b3SSteven Rostedt logit $sha1; 1539a57419b3SSteven Rostedt 1540a57419b3SSteven Rostedt if ($ret) { 1541a57419b3SSteven Rostedt doprint "FAILED\n"; 1542a57419b3SSteven Rostedt dodie "Failed to get git $commit"; 1543a57419b3SSteven Rostedt } 1544a57419b3SSteven Rostedt 1545a57419b3SSteven Rostedt print "SUCCESS\n"; 1546a57419b3SSteven Rostedt 1547a57419b3SSteven Rostedt chomp $sha1; 1548a57419b3SSteven Rostedt 1549a57419b3SSteven Rostedt return $sha1; 1550a57419b3SSteven Rostedt} 1551a57419b3SSteven Rostedt 15525a391fbfSSteven Rostedtsub monitor { 15532545eb61SSteven Rostedt my $booted = 0; 15542545eb61SSteven Rostedt my $bug = 0; 15556ca996ccSSteven Rostedt my $bug_ignored = 0; 15565c42fc5bSSteven Rostedt my $skip_call_trace = 0; 15572b7d9b21SSteven Rostedt my $loops; 15582545eb61SSteven Rostedt 15597faafbd6SSteven Rostedt wait_for_monitor 5; 15602545eb61SSteven Rostedt 15612545eb61SSteven Rostedt my $line; 15622545eb61SSteven Rostedt my $full_line = ""; 15632545eb61SSteven Rostedt 15647faafbd6SSteven Rostedt open(DMESG, "> $dmesg") or 15657faafbd6SSteven Rostedt die "unable to write to $dmesg"; 15662545eb61SSteven Rostedt 156775c3fda7SSteven Rostedt reboot_to; 15682545eb61SSteven Rostedt 15691c8a617aSSteven Rostedt my $success_start; 15701c8a617aSSteven Rostedt my $failure_start; 15712d01b26aSSteven Rostedt my $monitor_start = time; 15722d01b26aSSteven Rostedt my $done = 0; 1573f1a5b962SSteven Rostedt my $version_found = 0; 15741c8a617aSSteven Rostedt 15752d01b26aSSteven Rostedt while (!$done) { 15762545eb61SSteven Rostedt 1577ecaf8e52SSteven Rostedt if ($bug && defined($stop_after_failure) && 1578ecaf8e52SSteven Rostedt $stop_after_failure >= 0) { 1579ecaf8e52SSteven Rostedt my $time = $stop_after_failure - (time - $failure_start); 1580ecaf8e52SSteven Rostedt $line = wait_for_input($monitor_fp, $time); 1581ecaf8e52SSteven Rostedt if (!defined($line)) { 1582ecaf8e52SSteven Rostedt doprint "bug timed out after $booted_timeout seconds\n"; 1583ecaf8e52SSteven Rostedt doprint "Test forced to stop after $stop_after_failure seconds after failure\n"; 1584ecaf8e52SSteven Rostedt last; 1585ecaf8e52SSteven Rostedt } 1586ecaf8e52SSteven Rostedt } elsif ($booted) { 1587a75fececSSteven Rostedt $line = wait_for_input($monitor_fp, $booted_timeout); 1588cd4f1d53SSteven Rostedt if (!defined($line)) { 1589cd4f1d53SSteven Rostedt my $s = $booted_timeout == 1 ? "" : "s"; 1590cd4f1d53SSteven Rostedt doprint "Successful boot found: break after $booted_timeout second$s\n"; 1591cd4f1d53SSteven Rostedt last; 1592cd4f1d53SSteven Rostedt } 15932b7d9b21SSteven Rostedt } else { 15947faafbd6SSteven Rostedt $line = wait_for_input($monitor_fp); 1595cd4f1d53SSteven Rostedt if (!defined($line)) { 1596cd4f1d53SSteven Rostedt my $s = $timeout == 1 ? "" : "s"; 1597cd4f1d53SSteven Rostedt doprint "Timed out after $timeout second$s\n"; 1598cd4f1d53SSteven Rostedt last; 15992b7d9b21SSteven Rostedt } 1600cd4f1d53SSteven Rostedt } 16012545eb61SSteven Rostedt 16022545eb61SSteven Rostedt doprint $line; 16037faafbd6SSteven Rostedt print DMESG $line; 16042545eb61SSteven Rostedt 16052545eb61SSteven Rostedt # we are not guaranteed to get a full line 16062545eb61SSteven Rostedt $full_line .= $line; 16072545eb61SSteven Rostedt 1608a75fececSSteven Rostedt if ($full_line =~ /$success_line/) { 16092545eb61SSteven Rostedt $booted = 1; 16101c8a617aSSteven Rostedt $success_start = time; 16111c8a617aSSteven Rostedt } 16121c8a617aSSteven Rostedt 16131c8a617aSSteven Rostedt if ($booted && defined($stop_after_success) && 16141c8a617aSSteven Rostedt $stop_after_success >= 0) { 16151c8a617aSSteven Rostedt my $now = time; 16161c8a617aSSteven Rostedt if ($now - $success_start >= $stop_after_success) { 16171c8a617aSSteven Rostedt doprint "Test forced to stop after $stop_after_success seconds after success\n"; 16181c8a617aSSteven Rostedt last; 16191c8a617aSSteven Rostedt } 16202545eb61SSteven Rostedt } 16212545eb61SSteven Rostedt 16225c42fc5bSSteven Rostedt if ($full_line =~ /\[ backtrace testing \]/) { 16235c42fc5bSSteven Rostedt $skip_call_trace = 1; 16245c42fc5bSSteven Rostedt } 16255c42fc5bSSteven Rostedt 16262545eb61SSteven Rostedt if ($full_line =~ /call trace:/i) { 16276ca996ccSSteven Rostedt if (!$bug && !$skip_call_trace) { 16286ca996ccSSteven Rostedt if ($ignore_errors) { 16296ca996ccSSteven Rostedt $bug_ignored = 1; 16306ca996ccSSteven Rostedt } else { 16311c8a617aSSteven Rostedt $bug = 1; 16321c8a617aSSteven Rostedt $failure_start = time; 16331c8a617aSSteven Rostedt } 16341c8a617aSSteven Rostedt } 16356ca996ccSSteven Rostedt } 16361c8a617aSSteven Rostedt 16371c8a617aSSteven Rostedt if ($bug && defined($stop_after_failure) && 16381c8a617aSSteven Rostedt $stop_after_failure >= 0) { 16391c8a617aSSteven Rostedt my $now = time; 16401c8a617aSSteven Rostedt if ($now - $failure_start >= $stop_after_failure) { 16411c8a617aSSteven Rostedt doprint "Test forced to stop after $stop_after_failure seconds after failure\n"; 16421c8a617aSSteven Rostedt last; 16431c8a617aSSteven Rostedt } 16445c42fc5bSSteven Rostedt } 16455c42fc5bSSteven Rostedt 16465c42fc5bSSteven Rostedt if ($full_line =~ /\[ end of backtrace testing \]/) { 16475c42fc5bSSteven Rostedt $skip_call_trace = 0; 16485c42fc5bSSteven Rostedt } 16495c42fc5bSSteven Rostedt 16505c42fc5bSSteven Rostedt if ($full_line =~ /Kernel panic -/) { 165110abf118SSteven Rostedt $failure_start = time; 16522545eb61SSteven Rostedt $bug = 1; 16532545eb61SSteven Rostedt } 16542545eb61SSteven Rostedt 1655f1a5b962SSteven Rostedt # Detect triple faults by testing the banner 1656f1a5b962SSteven Rostedt if ($full_line =~ /\bLinux version (\S+).*\n/) { 1657f1a5b962SSteven Rostedt if ($1 eq $version) { 1658f1a5b962SSteven Rostedt $version_found = 1; 1659f1a5b962SSteven Rostedt } elsif ($version_found && $detect_triplefault) { 1660f1a5b962SSteven Rostedt # We already booted into the kernel we are testing, 1661f1a5b962SSteven Rostedt # but now we booted into another kernel? 1662f1a5b962SSteven Rostedt # Consider this a triple fault. 1663f1a5b962SSteven Rostedt doprint "Aleady booted in Linux kernel $version, but now\n"; 1664f1a5b962SSteven Rostedt doprint "we booted into Linux kernel $1.\n"; 1665f1a5b962SSteven Rostedt doprint "Assuming that this is a triple fault.\n"; 1666f1a5b962SSteven Rostedt doprint "To disable this: set DETECT_TRIPLE_FAULT to 0\n"; 1667f1a5b962SSteven Rostedt last; 1668f1a5b962SSteven Rostedt } 1669f1a5b962SSteven Rostedt } 1670f1a5b962SSteven Rostedt 16712545eb61SSteven Rostedt if ($line =~ /\n/) { 16722545eb61SSteven Rostedt $full_line = ""; 16732545eb61SSteven Rostedt } 16742d01b26aSSteven Rostedt 16752d01b26aSSteven Rostedt if ($stop_test_after > 0 && !$booted && !$bug) { 16762d01b26aSSteven Rostedt if (time - $monitor_start > $stop_test_after) { 16774d62bf51SSteven Rostedt doprint "STOP_TEST_AFTER ($stop_test_after seconds) timed out\n"; 16782d01b26aSSteven Rostedt $done = 1; 16792d01b26aSSteven Rostedt } 16802d01b26aSSteven Rostedt } 16812545eb61SSteven Rostedt } 16822545eb61SSteven Rostedt 16837faafbd6SSteven Rostedt close(DMESG); 16842545eb61SSteven Rostedt 16852545eb61SSteven Rostedt if ($bug) { 16862b7d9b21SSteven Rostedt return 0 if ($in_bisect); 1687576f627cSSteven Rostedt fail "failed - got a bug report" and return 0; 16882545eb61SSteven Rostedt } 16895f9b6cedSSteven Rostedt 1690a75fececSSteven Rostedt if (!$booted) { 1691a75fececSSteven Rostedt return 0 if ($in_bisect); 1692576f627cSSteven Rostedt fail "failed - never got a boot prompt." and return 0; 1693a75fececSSteven Rostedt } 1694a75fececSSteven Rostedt 16956ca996ccSSteven Rostedt if ($bug_ignored) { 16966ca996ccSSteven Rostedt doprint "WARNING: Call Trace detected but ignored due to IGNORE_ERRORS=1\n"; 16976ca996ccSSteven Rostedt } 16986ca996ccSSteven Rostedt 16992b7d9b21SSteven Rostedt return 1; 17002545eb61SSteven Rostedt} 17012545eb61SSteven Rostedt 17022b29b2f8SSteven Rostedtsub eval_kernel_version { 17032b29b2f8SSteven Rostedt my ($option) = @_; 17042b29b2f8SSteven Rostedt 17052b29b2f8SSteven Rostedt $option =~ s/\$KERNEL_VERSION/$version/g; 17062b29b2f8SSteven Rostedt 17072b29b2f8SSteven Rostedt return $option; 17082b29b2f8SSteven Rostedt} 17092b29b2f8SSteven Rostedt 1710db05cfefSSteven Rostedtsub do_post_install { 1711db05cfefSSteven Rostedt 1712db05cfefSSteven Rostedt return if (!defined($post_install)); 1713db05cfefSSteven Rostedt 17142b29b2f8SSteven Rostedt my $cp_post_install = eval_kernel_version $post_install; 1715db05cfefSSteven Rostedt run_command "$cp_post_install" or 1716db05cfefSSteven Rostedt dodie "Failed to run post install"; 1717db05cfefSSteven Rostedt} 1718db05cfefSSteven Rostedt 17192545eb61SSteven Rostedtsub install { 17202545eb61SSteven Rostedt 1721e0a8742eSSteven Rostedt return if ($no_install); 1722e0a8742eSSteven Rostedt 1723e5c2ec11SSteven Rostedt if (defined($pre_install)) { 1724e5c2ec11SSteven Rostedt my $cp_pre_install = eval_kernel_version $pre_install; 1725e5c2ec11SSteven Rostedt run_command "$cp_pre_install" or 1726e5c2ec11SSteven Rostedt dodie "Failed to run pre install"; 1727e5c2ec11SSteven Rostedt } 1728e5c2ec11SSteven Rostedt 17292b29b2f8SSteven Rostedt my $cp_target = eval_kernel_version $target_image; 17302b29b2f8SSteven Rostedt 173102ad2617SSteven Rostedt run_scp_install "$outputdir/$build_target", "$cp_target" or 17325c42fc5bSSteven Rostedt dodie "failed to copy image"; 17335f9b6cedSSteven Rostedt 17345f9b6cedSSteven Rostedt my $install_mods = 0; 17355f9b6cedSSteven Rostedt 17365f9b6cedSSteven Rostedt # should we process modules? 17375f9b6cedSSteven Rostedt $install_mods = 0; 173851ad1dd1SSteven Rostedt open(IN, "$output_config") or dodie("Can't read config file"); 17395f9b6cedSSteven Rostedt while (<IN>) { 17405f9b6cedSSteven Rostedt if (/CONFIG_MODULES(=y)?/) { 17415f9b6cedSSteven Rostedt $install_mods = 1 if (defined($1)); 17425f9b6cedSSteven Rostedt last; 17435f9b6cedSSteven Rostedt } 17445f9b6cedSSteven Rostedt } 17455f9b6cedSSteven Rostedt close(IN); 17465f9b6cedSSteven Rostedt 17475f9b6cedSSteven Rostedt if (!$install_mods) { 1748db05cfefSSteven Rostedt do_post_install; 17495f9b6cedSSteven Rostedt doprint "No modules needed\n"; 17505f9b6cedSSteven Rostedt return; 17512545eb61SSteven Rostedt } 17522545eb61SSteven Rostedt 1753627977d8SSteven Rostedt run_command "$make INSTALL_MOD_STRIP=1 INSTALL_MOD_PATH=$tmpdir modules_install" or 17545f9b6cedSSteven Rostedt dodie "Failed to install modules"; 17555f9b6cedSSteven Rostedt 17562545eb61SSteven Rostedt my $modlib = "/lib/modules/$version"; 1757a57419b3SSteven Rostedt my $modtar = "ktest-mods.tar.bz2"; 17582545eb61SSteven Rostedt 1759e48c5293SSteven Rostedt run_ssh "rm -rf $modlib" or 17605c42fc5bSSteven Rostedt dodie "failed to remove old mods: $modlib"; 17612545eb61SSteven Rostedt 17625c42fc5bSSteven Rostedt # would be nice if scp -r did not follow symbolic links 1763a75fececSSteven Rostedt run_command "cd $tmpdir && tar -cjf $modtar lib/modules/$version" or 17645c42fc5bSSteven Rostedt dodie "making tarball"; 17655c42fc5bSSteven Rostedt 176602ad2617SSteven Rostedt run_scp_mod "$tmpdir/$modtar", "/tmp" or 17675c42fc5bSSteven Rostedt dodie "failed to copy modules"; 17685c42fc5bSSteven Rostedt 1769a75fececSSteven Rostedt unlink "$tmpdir/$modtar"; 17705c42fc5bSSteven Rostedt 1771e7b13441SSteven Rostedt run_ssh "'(cd / && tar xjf /tmp/$modtar)'" or 17725c42fc5bSSteven Rostedt dodie "failed to tar modules"; 17735c42fc5bSSteven Rostedt 1774e48c5293SSteven Rostedt run_ssh "rm -f /tmp/$modtar"; 17758b37ca8cSSteven Rostedt 1776db05cfefSSteven Rostedt do_post_install; 17772545eb61SSteven Rostedt} 17782545eb61SSteven Rostedt 1779ddf607e5SSteven Rostedtsub get_version { 1780ddf607e5SSteven Rostedt # get the release name 1781683a3e64SSteven Rostedt return if ($have_version); 1782ddf607e5SSteven Rostedt doprint "$make kernelrelease ... "; 1783ddf607e5SSteven Rostedt $version = `$make kernelrelease | tail -1`; 1784ddf607e5SSteven Rostedt chomp($version); 1785ddf607e5SSteven Rostedt doprint "$version\n"; 1786683a3e64SSteven Rostedt $have_version = 1; 1787ddf607e5SSteven Rostedt} 1788ddf607e5SSteven Rostedt 1789ddf607e5SSteven Rostedtsub start_monitor_and_boot { 17909f7424ccSSteven Rostedt # Make sure the stable kernel has finished booting 17919f7424ccSSteven Rostedt start_monitor; 17929f7424ccSSteven Rostedt wait_for_monitor 5; 17939f7424ccSSteven Rostedt end_monitor; 17949f7424ccSSteven Rostedt 1795ddf607e5SSteven Rostedt get_grub_index; 1796ddf607e5SSteven Rostedt get_version; 1797ddf607e5SSteven Rostedt install; 1798ddf607e5SSteven Rostedt 1799ddf607e5SSteven Rostedt start_monitor; 1800ddf607e5SSteven Rostedt return monitor; 1801ddf607e5SSteven Rostedt} 1802ddf607e5SSteven Rostedt 18036c5ee0beSSteven Rostedtsub check_buildlog { 18046c5ee0beSSteven Rostedt my ($patch) = @_; 18056c5ee0beSSteven Rostedt 18066c5ee0beSSteven Rostedt my @files = `git show $patch | diffstat -l`; 18076c5ee0beSSteven Rostedt 18086c5ee0beSSteven Rostedt open(IN, "git show $patch |") or 18096c5ee0beSSteven Rostedt dodie "failed to show $patch"; 18106c5ee0beSSteven Rostedt while (<IN>) { 18116c5ee0beSSteven Rostedt if (m,^--- a/(.*),) { 18126c5ee0beSSteven Rostedt chomp $1; 18136c5ee0beSSteven Rostedt $files[$#files] = $1; 18146c5ee0beSSteven Rostedt } 18156c5ee0beSSteven Rostedt } 18166c5ee0beSSteven Rostedt close(IN); 18176c5ee0beSSteven Rostedt 18186c5ee0beSSteven Rostedt open(IN, $buildlog) or dodie "Can't open $buildlog"; 18196c5ee0beSSteven Rostedt while (<IN>) { 18206c5ee0beSSteven Rostedt if (/^\s*(.*?):.*(warning|error)/) { 18216c5ee0beSSteven Rostedt my $err = $1; 18226c5ee0beSSteven Rostedt foreach my $file (@files) { 1823a75fececSSteven Rostedt my $fullpath = "$builddir/$file"; 18246c5ee0beSSteven Rostedt if ($file eq $err || $fullpath eq $err) { 18252b7d9b21SSteven Rostedt fail "$file built with warnings" and return 0; 18266c5ee0beSSteven Rostedt } 18276c5ee0beSSteven Rostedt } 18286c5ee0beSSteven Rostedt } 18296c5ee0beSSteven Rostedt } 18306c5ee0beSSteven Rostedt close(IN); 18312b7d9b21SSteven Rostedt 18322b7d9b21SSteven Rostedt return 1; 18336c5ee0beSSteven Rostedt} 18346c5ee0beSSteven Rostedt 1835fcb3f16aSSteven Rostedtsub apply_min_config { 1836fcb3f16aSSteven Rostedt my $outconfig = "$output_config.new"; 1837612b9e9bSSteven Rostedt 1838fcb3f16aSSteven Rostedt # Read the config file and remove anything that 1839fcb3f16aSSteven Rostedt # is in the force_config hash (from minconfig and others) 1840fcb3f16aSSteven Rostedt # then add the force config back. 1841fcb3f16aSSteven Rostedt 1842fcb3f16aSSteven Rostedt doprint "Applying minimum configurations into $output_config.new\n"; 1843fcb3f16aSSteven Rostedt 1844fcb3f16aSSteven Rostedt open (OUT, ">$outconfig") or 1845fcb3f16aSSteven Rostedt dodie "Can't create $outconfig"; 1846fcb3f16aSSteven Rostedt 1847fcb3f16aSSteven Rostedt if (-f $output_config) { 1848fcb3f16aSSteven Rostedt open (IN, $output_config) or 1849fcb3f16aSSteven Rostedt dodie "Failed to open $output_config"; 1850fcb3f16aSSteven Rostedt while (<IN>) { 1851fcb3f16aSSteven Rostedt if (/^(# )?(CONFIG_[^\s=]*)/) { 1852fcb3f16aSSteven Rostedt next if (defined($force_config{$2})); 1853fcb3f16aSSteven Rostedt } 1854fcb3f16aSSteven Rostedt print OUT; 1855fcb3f16aSSteven Rostedt } 1856fcb3f16aSSteven Rostedt close IN; 1857fcb3f16aSSteven Rostedt } 1858fcb3f16aSSteven Rostedt foreach my $config (keys %force_config) { 1859fcb3f16aSSteven Rostedt print OUT "$force_config{$config}\n"; 1860fcb3f16aSSteven Rostedt } 1861fcb3f16aSSteven Rostedt close OUT; 1862fcb3f16aSSteven Rostedt 1863fcb3f16aSSteven Rostedt run_command "mv $outconfig $output_config"; 1864fcb3f16aSSteven Rostedt} 1865fcb3f16aSSteven Rostedt 1866fcb3f16aSSteven Rostedtsub make_oldconfig { 1867fcb3f16aSSteven Rostedt 18684c4ab120SSteven Rostedt my @force_list = keys %force_config; 18694c4ab120SSteven Rostedt 18704c4ab120SSteven Rostedt if ($#force_list >= 0) { 1871fcb3f16aSSteven Rostedt apply_min_config; 18724c4ab120SSteven Rostedt } 1873fcb3f16aSSteven Rostedt 1874fcb3f16aSSteven Rostedt if (!run_command "$make oldnoconfig") { 1875612b9e9bSSteven Rostedt # Perhaps oldnoconfig doesn't exist in this version of the kernel 1876612b9e9bSSteven Rostedt # try a yes '' | oldconfig 1877612b9e9bSSteven Rostedt doprint "oldnoconfig failed, trying yes '' | make oldconfig\n"; 1878fcb3f16aSSteven Rostedt run_command "yes '' | $make oldconfig" or 1879612b9e9bSSteven Rostedt dodie "failed make config oldconfig"; 1880612b9e9bSSteven Rostedt } 1881612b9e9bSSteven Rostedt} 1882612b9e9bSSteven Rostedt 1883fcb3f16aSSteven Rostedt# read a config file and use this to force new configs. 1884fcb3f16aSSteven Rostedtsub load_force_config { 1885fcb3f16aSSteven Rostedt my ($config) = @_; 1886fcb3f16aSSteven Rostedt 1887cf79fab6SSteven Rostedt doprint "Loading force configs from $config\n"; 1888fcb3f16aSSteven Rostedt open(IN, $config) or 1889fcb3f16aSSteven Rostedt dodie "failed to read $config"; 1890fcb3f16aSSteven Rostedt while (<IN>) { 1891fcb3f16aSSteven Rostedt chomp; 1892fcb3f16aSSteven Rostedt if (/^(CONFIG[^\s=]*)(\s*=.*)/) { 1893fcb3f16aSSteven Rostedt $force_config{$1} = $_; 1894fcb3f16aSSteven Rostedt } elsif (/^# (CONFIG_\S*) is not set/) { 1895fcb3f16aSSteven Rostedt $force_config{$1} = $_; 1896fcb3f16aSSteven Rostedt } 1897fcb3f16aSSteven Rostedt } 1898fcb3f16aSSteven Rostedt close IN; 1899fcb3f16aSSteven Rostedt} 1900fcb3f16aSSteven Rostedt 19012545eb61SSteven Rostedtsub build { 19022545eb61SSteven Rostedt my ($type) = @_; 19032545eb61SSteven Rostedt 19047faafbd6SSteven Rostedt unlink $buildlog; 19057faafbd6SSteven Rostedt 19064ab1cce5SSteven Rostedt # Failed builds should not reboot the target 19074ab1cce5SSteven Rostedt my $save_no_reboot = $no_reboot; 19084ab1cce5SSteven Rostedt $no_reboot = 1; 19094ab1cce5SSteven Rostedt 1910683a3e64SSteven Rostedt # Calculate a new version from here. 1911683a3e64SSteven Rostedt $have_version = 0; 1912683a3e64SSteven Rostedt 19130bd6c1a3SSteven Rostedt if (defined($pre_build)) { 19140bd6c1a3SSteven Rostedt my $ret = run_command $pre_build; 19150bd6c1a3SSteven Rostedt if (!$ret && defined($pre_build_die) && 19160bd6c1a3SSteven Rostedt $pre_build_die) { 19170bd6c1a3SSteven Rostedt dodie "failed to pre_build\n"; 19180bd6c1a3SSteven Rostedt } 19190bd6c1a3SSteven Rostedt } 19200bd6c1a3SSteven Rostedt 192175c3fda7SSteven Rostedt if ($type =~ /^useconfig:(.*)/) { 192251ad1dd1SSteven Rostedt run_command "cp $1 $output_config" or 192375c3fda7SSteven Rostedt dodie "could not copy $1 to .config"; 19245f9b6cedSSteven Rostedt 192575c3fda7SSteven Rostedt $type = "oldconfig"; 192675c3fda7SSteven Rostedt } 192775c3fda7SSteven Rostedt 19285c42fc5bSSteven Rostedt # old config can ask questions 19295c42fc5bSSteven Rostedt if ($type eq "oldconfig") { 19309386c6abSSteven Rostedt $type = "oldnoconfig"; 193175c3fda7SSteven Rostedt 193275c3fda7SSteven Rostedt # allow for empty configs 193351ad1dd1SSteven Rostedt run_command "touch $output_config"; 193475c3fda7SSteven Rostedt 193513488231SAndrew Jones if (!$noclean) { 193651ad1dd1SSteven Rostedt run_command "mv $output_config $outputdir/config_temp" or 19375c42fc5bSSteven Rostedt dodie "moving .config"; 19385c42fc5bSSteven Rostedt 193913488231SAndrew Jones run_command "$make mrproper" or dodie "make mrproper"; 19405c42fc5bSSteven Rostedt 194151ad1dd1SSteven Rostedt run_command "mv $outputdir/config_temp $output_config" or 19425c42fc5bSSteven Rostedt dodie "moving config_temp"; 194313488231SAndrew Jones } 19445c42fc5bSSteven Rostedt 19455c42fc5bSSteven Rostedt } elsif (!$noclean) { 194651ad1dd1SSteven Rostedt unlink "$output_config"; 19475f9b6cedSSteven Rostedt run_command "$make mrproper" or 19485c42fc5bSSteven Rostedt dodie "make mrproper"; 19495c42fc5bSSteven Rostedt } 19502545eb61SSteven Rostedt 19512545eb61SSteven Rostedt # add something to distinguish this build 1952a75fececSSteven Rostedt open(OUT, "> $outputdir/localversion") or dodie("Can't make localversion file"); 1953a75fececSSteven Rostedt print OUT "$localversion\n"; 19542545eb61SSteven Rostedt close(OUT); 19552545eb61SSteven Rostedt 19565f9b6cedSSteven Rostedt if (defined($minconfig)) { 1957fcb3f16aSSteven Rostedt load_force_config($minconfig); 19582545eb61SSteven Rostedt } 19592545eb61SSteven Rostedt 1960fcb3f16aSSteven Rostedt if ($type ne "oldnoconfig") { 1961fcb3f16aSSteven Rostedt run_command "$make $type" or 19625c42fc5bSSteven Rostedt dodie "failed make config"; 1963612b9e9bSSteven Rostedt } 1964fcb3f16aSSteven Rostedt # Run old config regardless, to enforce min configurations 1965fcb3f16aSSteven Rostedt make_oldconfig; 19662545eb61SSteven Rostedt 1967a75fececSSteven Rostedt $redirect = "$buildlog"; 19680bd6c1a3SSteven Rostedt my $build_ret = run_command "$make $build_options"; 19696c5ee0beSSteven Rostedt undef $redirect; 19700bd6c1a3SSteven Rostedt 19710bd6c1a3SSteven Rostedt if (defined($post_build)) { 1972683a3e64SSteven Rostedt # Because a post build may change the kernel version 1973683a3e64SSteven Rostedt # do it now. 1974683a3e64SSteven Rostedt get_version; 19750bd6c1a3SSteven Rostedt my $ret = run_command $post_build; 19760bd6c1a3SSteven Rostedt if (!$ret && defined($post_build_die) && 19770bd6c1a3SSteven Rostedt $post_build_die) { 19780bd6c1a3SSteven Rostedt dodie "failed to post_build\n"; 19790bd6c1a3SSteven Rostedt } 19800bd6c1a3SSteven Rostedt } 19810bd6c1a3SSteven Rostedt 19820bd6c1a3SSteven Rostedt if (!$build_ret) { 19835f9b6cedSSteven Rostedt # bisect may need this to pass 19844ab1cce5SSteven Rostedt if ($in_bisect) { 19854ab1cce5SSteven Rostedt $no_reboot = $save_no_reboot; 19864ab1cce5SSteven Rostedt return 0; 19874ab1cce5SSteven Rostedt } 19882b7d9b21SSteven Rostedt fail "failed build" and return 0; 19892545eb61SSteven Rostedt } 19905f9b6cedSSteven Rostedt 19914ab1cce5SSteven Rostedt $no_reboot = $save_no_reboot; 19924ab1cce5SSteven Rostedt 19932b7d9b21SSteven Rostedt return 1; 19942545eb61SSteven Rostedt} 19952545eb61SSteven Rostedt 199675c3fda7SSteven Rostedtsub halt { 1997e48c5293SSteven Rostedt if (!run_ssh "halt" or defined($power_off)) { 1998576f627cSSteven Rostedt if (defined($poweroff_after_halt)) { 1999576f627cSSteven Rostedt sleep $poweroff_after_halt; 2000576f627cSSteven Rostedt run_command "$power_off"; 2001576f627cSSteven Rostedt } 2002576f627cSSteven Rostedt } else { 200375c3fda7SSteven Rostedt # nope? the zap it! 2004a75fececSSteven Rostedt run_command "$power_off"; 200575c3fda7SSteven Rostedt } 200675c3fda7SSteven Rostedt} 200775c3fda7SSteven Rostedt 20085f9b6cedSSteven Rostedtsub success { 20095f9b6cedSSteven Rostedt my ($i) = @_; 20105f9b6cedSSteven Rostedt 2011921ed4c7SSteven Rostedt if (defined($post_test)) { 2012921ed4c7SSteven Rostedt run_command $post_test; 2013921ed4c7SSteven Rostedt } 2014921ed4c7SSteven Rostedt 2015e48c5293SSteven Rostedt $successes++; 2016e48c5293SSteven Rostedt 20179064af52SSteven Rostedt my $name = ""; 20189064af52SSteven Rostedt 20199064af52SSteven Rostedt if (defined($test_name)) { 20209064af52SSteven Rostedt $name = " ($test_name)"; 20219064af52SSteven Rostedt } 20229064af52SSteven Rostedt 20235f9b6cedSSteven Rostedt doprint "\n\n*******************************************\n"; 20245f9b6cedSSteven Rostedt doprint "*******************************************\n"; 20259064af52SSteven Rostedt doprint "KTEST RESULT: TEST $i$name SUCCESS!!!! **\n"; 20265f9b6cedSSteven Rostedt doprint "*******************************************\n"; 20275f9b6cedSSteven Rostedt doprint "*******************************************\n"; 20285f9b6cedSSteven Rostedt 2029de5b6e3bSRabin Vincent if (defined($store_successes)) { 2030de5b6e3bSRabin Vincent save_logs "success", $store_successes; 2031de5b6e3bSRabin Vincent } 2032de5b6e3bSRabin Vincent 2033576f627cSSteven Rostedt if ($i != $opt{"NUM_TESTS"} && !do_not_reboot) { 2034a75fececSSteven Rostedt doprint "Reboot and wait $sleep_time seconds\n"; 2035bc7c5803SSteven Rostedt reboot_to_good $sleep_time; 20365f9b6cedSSteven Rostedt } 20375f9b6cedSSteven Rostedt} 20385f9b6cedSSteven Rostedt 2039c960bb9fSSteven Rostedtsub answer_bisect { 2040c960bb9fSSteven Rostedt for (;;) { 2041c960bb9fSSteven Rostedt doprint "Pass or fail? [p/f]"; 2042c960bb9fSSteven Rostedt my $ans = <STDIN>; 2043c960bb9fSSteven Rostedt chomp $ans; 2044c960bb9fSSteven Rostedt if ($ans eq "p" || $ans eq "P") { 2045c960bb9fSSteven Rostedt return 1; 2046c960bb9fSSteven Rostedt } elsif ($ans eq "f" || $ans eq "F") { 2047c960bb9fSSteven Rostedt return 0; 2048c960bb9fSSteven Rostedt } else { 2049c960bb9fSSteven Rostedt print "Please answer 'P' or 'F'\n"; 2050c960bb9fSSteven Rostedt } 2051c960bb9fSSteven Rostedt } 2052c960bb9fSSteven Rostedt} 2053c960bb9fSSteven Rostedt 20545a391fbfSSteven Rostedtsub child_run_test { 20557faafbd6SSteven Rostedt my $failed = 0; 20565a391fbfSSteven Rostedt 20577faafbd6SSteven Rostedt # child should have no power 2058a75fececSSteven Rostedt $reboot_on_error = 0; 2059a75fececSSteven Rostedt $poweroff_on_error = 0; 2060a75fececSSteven Rostedt $die_on_failure = 1; 20617faafbd6SSteven Rostedt 2062a9dd5d63SRabin Vincent $redirect = "$testlog"; 20637faafbd6SSteven Rostedt run_command $run_test or $failed = 1; 2064a9dd5d63SRabin Vincent undef $redirect; 2065a9dd5d63SRabin Vincent 20665a391fbfSSteven Rostedt exit $failed; 20675a391fbfSSteven Rostedt} 20685a391fbfSSteven Rostedt 20695a391fbfSSteven Rostedtmy $child_done; 20705a391fbfSSteven Rostedt 20715a391fbfSSteven Rostedtsub child_finished { 20725a391fbfSSteven Rostedt $child_done = 1; 20735a391fbfSSteven Rostedt} 20745a391fbfSSteven Rostedt 20755a391fbfSSteven Rostedtsub do_run_test { 20765a391fbfSSteven Rostedt my $child_pid; 20775a391fbfSSteven Rostedt my $child_exit; 20785a391fbfSSteven Rostedt my $line; 20795a391fbfSSteven Rostedt my $full_line; 20805a391fbfSSteven Rostedt my $bug = 0; 20819b1d367dSSteven Rostedt my $bug_ignored = 0; 20825a391fbfSSteven Rostedt 20837faafbd6SSteven Rostedt wait_for_monitor 1; 20845a391fbfSSteven Rostedt 20857faafbd6SSteven Rostedt doprint "run test $run_test\n"; 20865a391fbfSSteven Rostedt 20875a391fbfSSteven Rostedt $child_done = 0; 20885a391fbfSSteven Rostedt 20895a391fbfSSteven Rostedt $SIG{CHLD} = qw(child_finished); 20905a391fbfSSteven Rostedt 20915a391fbfSSteven Rostedt $child_pid = fork; 20925a391fbfSSteven Rostedt 20935a391fbfSSteven Rostedt child_run_test if (!$child_pid); 20945a391fbfSSteven Rostedt 20955a391fbfSSteven Rostedt $full_line = ""; 20965a391fbfSSteven Rostedt 20975a391fbfSSteven Rostedt do { 20987faafbd6SSteven Rostedt $line = wait_for_input($monitor_fp, 1); 20995a391fbfSSteven Rostedt if (defined($line)) { 21005a391fbfSSteven Rostedt 21015a391fbfSSteven Rostedt # we are not guaranteed to get a full line 21025a391fbfSSteven Rostedt $full_line .= $line; 21038ea0e063SSteven Rostedt doprint $line; 21045a391fbfSSteven Rostedt 21055a391fbfSSteven Rostedt if ($full_line =~ /call trace:/i) { 21069b1d367dSSteven Rostedt if ($ignore_errors) { 21079b1d367dSSteven Rostedt $bug_ignored = 1; 21089b1d367dSSteven Rostedt } else { 21095a391fbfSSteven Rostedt $bug = 1; 21105a391fbfSSteven Rostedt } 21119b1d367dSSteven Rostedt } 21125a391fbfSSteven Rostedt 21135a391fbfSSteven Rostedt if ($full_line =~ /Kernel panic -/) { 21145a391fbfSSteven Rostedt $bug = 1; 21155a391fbfSSteven Rostedt } 21165a391fbfSSteven Rostedt 21175a391fbfSSteven Rostedt if ($line =~ /\n/) { 21185a391fbfSSteven Rostedt $full_line = ""; 21195a391fbfSSteven Rostedt } 21205a391fbfSSteven Rostedt } 21215a391fbfSSteven Rostedt } while (!$child_done && !$bug); 21225a391fbfSSteven Rostedt 21239b1d367dSSteven Rostedt if (!$bug && $bug_ignored) { 21249b1d367dSSteven Rostedt doprint "WARNING: Call Trace detected but ignored due to IGNORE_ERRORS=1\n"; 21259b1d367dSSteven Rostedt } 21269b1d367dSSteven Rostedt 21275a391fbfSSteven Rostedt if ($bug) { 21288ea0e063SSteven Rostedt my $failure_start = time; 21298ea0e063SSteven Rostedt my $now; 21308ea0e063SSteven Rostedt do { 21318ea0e063SSteven Rostedt $line = wait_for_input($monitor_fp, 1); 21328ea0e063SSteven Rostedt if (defined($line)) { 21338ea0e063SSteven Rostedt doprint $line; 21348ea0e063SSteven Rostedt } 21358ea0e063SSteven Rostedt $now = time; 21368ea0e063SSteven Rostedt if ($now - $failure_start >= $stop_after_failure) { 21378ea0e063SSteven Rostedt last; 21388ea0e063SSteven Rostedt } 21398ea0e063SSteven Rostedt } while (defined($line)); 21408ea0e063SSteven Rostedt 21415a391fbfSSteven Rostedt doprint "Detected kernel crash!\n"; 21425a391fbfSSteven Rostedt # kill the child with extreme prejudice 21435a391fbfSSteven Rostedt kill 9, $child_pid; 21445a391fbfSSteven Rostedt } 21455a391fbfSSteven Rostedt 21465a391fbfSSteven Rostedt waitpid $child_pid, 0; 21475a391fbfSSteven Rostedt $child_exit = $?; 21485a391fbfSSteven Rostedt 2149c5dacb88SSteven Rostedt if (!$bug && $in_bisect) { 2150c5dacb88SSteven Rostedt if (defined($bisect_ret_good)) { 2151c5dacb88SSteven Rostedt if ($child_exit == $bisect_ret_good) { 2152c5dacb88SSteven Rostedt return 1; 2153c5dacb88SSteven Rostedt } 2154c5dacb88SSteven Rostedt } 2155c5dacb88SSteven Rostedt if (defined($bisect_ret_skip)) { 2156c5dacb88SSteven Rostedt if ($child_exit == $bisect_ret_skip) { 2157c5dacb88SSteven Rostedt return -1; 2158c5dacb88SSteven Rostedt } 2159c5dacb88SSteven Rostedt } 2160c5dacb88SSteven Rostedt if (defined($bisect_ret_abort)) { 2161c5dacb88SSteven Rostedt if ($child_exit == $bisect_ret_abort) { 2162c5dacb88SSteven Rostedt fail "test abort" and return -2; 2163c5dacb88SSteven Rostedt } 2164c5dacb88SSteven Rostedt } 2165c5dacb88SSteven Rostedt if (defined($bisect_ret_bad)) { 2166c5dacb88SSteven Rostedt if ($child_exit == $bisect_ret_skip) { 2167c5dacb88SSteven Rostedt return 0; 2168c5dacb88SSteven Rostedt } 2169c5dacb88SSteven Rostedt } 2170c5dacb88SSteven Rostedt if (defined($bisect_ret_default)) { 2171c5dacb88SSteven Rostedt if ($bisect_ret_default eq "good") { 2172c5dacb88SSteven Rostedt return 1; 2173c5dacb88SSteven Rostedt } elsif ($bisect_ret_default eq "bad") { 2174c5dacb88SSteven Rostedt return 0; 2175c5dacb88SSteven Rostedt } elsif ($bisect_ret_default eq "skip") { 2176c5dacb88SSteven Rostedt return -1; 2177c5dacb88SSteven Rostedt } elsif ($bisect_ret_default eq "abort") { 2178c5dacb88SSteven Rostedt return -2; 2179c5dacb88SSteven Rostedt } else { 2180c5dacb88SSteven Rostedt fail "unknown default action: $bisect_ret_default" 2181c5dacb88SSteven Rostedt and return -2; 2182c5dacb88SSteven Rostedt } 2183c5dacb88SSteven Rostedt } 2184c5dacb88SSteven Rostedt } 2185c5dacb88SSteven Rostedt 21865a391fbfSSteven Rostedt if ($bug || $child_exit) { 21872b7d9b21SSteven Rostedt return 0 if $in_bisect; 21882b7d9b21SSteven Rostedt fail "test failed" and return 0; 21895a391fbfSSteven Rostedt } 21902b7d9b21SSteven Rostedt return 1; 21915a391fbfSSteven Rostedt} 21925a391fbfSSteven Rostedt 2193a75fececSSteven Rostedtsub run_git_bisect { 2194a75fececSSteven Rostedt my ($command) = @_; 2195a75fececSSteven Rostedt 2196a75fececSSteven Rostedt doprint "$command ... "; 2197a75fececSSteven Rostedt 2198a75fececSSteven Rostedt my $output = `$command 2>&1`; 2199a75fececSSteven Rostedt my $ret = $?; 2200a75fececSSteven Rostedt 2201a75fececSSteven Rostedt logit $output; 2202a75fececSSteven Rostedt 2203a75fececSSteven Rostedt if ($ret) { 2204a75fececSSteven Rostedt doprint "FAILED\n"; 2205a75fececSSteven Rostedt dodie "Failed to git bisect"; 2206a75fececSSteven Rostedt } 2207a75fececSSteven Rostedt 2208a75fececSSteven Rostedt doprint "SUCCESS\n"; 2209a75fececSSteven Rostedt if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\))\s+\[([[:xdigit:]]+)\]/) { 2210a75fececSSteven Rostedt doprint "$1 [$2]\n"; 2211a75fececSSteven Rostedt } elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) { 2212b5f4aea6SSteven Rostedt $bisect_bad_commit = $1; 2213a75fececSSteven Rostedt doprint "Found bad commit... $1\n"; 2214a75fececSSteven Rostedt return 0; 2215a75fececSSteven Rostedt } else { 2216a75fececSSteven Rostedt # we already logged it, just print it now. 2217a75fececSSteven Rostedt print $output; 2218a75fececSSteven Rostedt } 2219a75fececSSteven Rostedt 2220a75fececSSteven Rostedt return 1; 2221a75fececSSteven Rostedt} 2222a75fececSSteven Rostedt 2223c23dca7cSSteven Rostedtsub bisect_reboot { 2224c23dca7cSSteven Rostedt doprint "Reboot and sleep $bisect_sleep_time seconds\n"; 2225bc7c5803SSteven Rostedt reboot_to_good $bisect_sleep_time; 2226c23dca7cSSteven Rostedt} 2227c23dca7cSSteven Rostedt 2228c23dca7cSSteven Rostedt# returns 1 on success, 0 on failure, -1 on skip 22290a05c769SSteven Rostedtsub run_bisect_test { 22300a05c769SSteven Rostedt my ($type, $buildtype) = @_; 22315f9b6cedSSteven Rostedt 22322b7d9b21SSteven Rostedt my $failed = 0; 22335f9b6cedSSteven Rostedt my $result; 22345f9b6cedSSteven Rostedt my $output; 22355f9b6cedSSteven Rostedt my $ret; 22365f9b6cedSSteven Rostedt 22370a05c769SSteven Rostedt $in_bisect = 1; 22380a05c769SSteven Rostedt 22390a05c769SSteven Rostedt build $buildtype or $failed = 1; 22405f9b6cedSSteven Rostedt 22415f9b6cedSSteven Rostedt if ($type ne "build") { 2242c23dca7cSSteven Rostedt if ($failed && $bisect_skip) { 2243c23dca7cSSteven Rostedt $in_bisect = 0; 2244c23dca7cSSteven Rostedt return -1; 2245c23dca7cSSteven Rostedt } 22467faafbd6SSteven Rostedt dodie "Failed on build" if $failed; 22475f9b6cedSSteven Rostedt 22485f9b6cedSSteven Rostedt # Now boot the box 2249ddf607e5SSteven Rostedt start_monitor_and_boot or $failed = 1; 22505f9b6cedSSteven Rostedt 22515f9b6cedSSteven Rostedt if ($type ne "boot") { 2252c23dca7cSSteven Rostedt if ($failed && $bisect_skip) { 2253c23dca7cSSteven Rostedt end_monitor; 2254c23dca7cSSteven Rostedt bisect_reboot; 2255c23dca7cSSteven Rostedt $in_bisect = 0; 2256c23dca7cSSteven Rostedt return -1; 2257c23dca7cSSteven Rostedt } 22587faafbd6SSteven Rostedt dodie "Failed on boot" if $failed; 22595a391fbfSSteven Rostedt 22602b7d9b21SSteven Rostedt do_run_test or $failed = 1; 22615f9b6cedSSteven Rostedt } 22627faafbd6SSteven Rostedt end_monitor; 22635f9b6cedSSteven Rostedt } 22645f9b6cedSSteven Rostedt 22655f9b6cedSSteven Rostedt if ($failed) { 22660a05c769SSteven Rostedt $result = 0; 22675f9b6cedSSteven Rostedt } else { 22680a05c769SSteven Rostedt $result = 1; 22695f9b6cedSSteven Rostedt } 22704025bc62SSteven Rostedt 22714025bc62SSteven Rostedt # reboot the box to a kernel we can ssh to 22724025bc62SSteven Rostedt if ($type ne "build") { 22734025bc62SSteven Rostedt bisect_reboot; 22744025bc62SSteven Rostedt } 22750a05c769SSteven Rostedt $in_bisect = 0; 22760a05c769SSteven Rostedt 22770a05c769SSteven Rostedt return $result; 22780a05c769SSteven Rostedt} 22790a05c769SSteven Rostedt 22800a05c769SSteven Rostedtsub run_bisect { 22810a05c769SSteven Rostedt my ($type) = @_; 22820a05c769SSteven Rostedt my $buildtype = "oldconfig"; 22830a05c769SSteven Rostedt 22840a05c769SSteven Rostedt # We should have a minconfig to use? 22850a05c769SSteven Rostedt if (defined($minconfig)) { 22860a05c769SSteven Rostedt $buildtype = "useconfig:$minconfig"; 22870a05c769SSteven Rostedt } 22880a05c769SSteven Rostedt 22890a05c769SSteven Rostedt my $ret = run_bisect_test $type, $buildtype; 22900a05c769SSteven Rostedt 2291c960bb9fSSteven Rostedt if ($bisect_manual) { 2292c960bb9fSSteven Rostedt $ret = answer_bisect; 2293c960bb9fSSteven Rostedt } 22945f9b6cedSSteven Rostedt 2295d6ce2a0bSSteven Rostedt # Are we looking for where it worked, not failed? 22965158ba3eSRuss Dill if ($reverse_bisect && $ret >= 0) { 22970a05c769SSteven Rostedt $ret = !$ret; 2298d6ce2a0bSSteven Rostedt } 2299d6ce2a0bSSteven Rostedt 2300c23dca7cSSteven Rostedt if ($ret > 0) { 23010a05c769SSteven Rostedt return "good"; 2302c23dca7cSSteven Rostedt } elsif ($ret == 0) { 23030a05c769SSteven Rostedt return "bad"; 2304c23dca7cSSteven Rostedt } elsif ($bisect_skip) { 2305c23dca7cSSteven Rostedt doprint "HIT A BAD COMMIT ... SKIPPING\n"; 2306c23dca7cSSteven Rostedt return "skip"; 23070a05c769SSteven Rostedt } 23085f9b6cedSSteven Rostedt} 23095f9b6cedSSteven Rostedt 2310dad98754SSteven Rostedtsub update_bisect_replay { 2311dad98754SSteven Rostedt my $tmp_log = "$tmpdir/ktest_bisect_log"; 2312dad98754SSteven Rostedt run_command "git bisect log > $tmp_log" or 2313dad98754SSteven Rostedt die "can't create bisect log"; 2314dad98754SSteven Rostedt return $tmp_log; 2315dad98754SSteven Rostedt} 2316dad98754SSteven Rostedt 23175f9b6cedSSteven Rostedtsub bisect { 23185f9b6cedSSteven Rostedt my ($i) = @_; 23195f9b6cedSSteven Rostedt 23205f9b6cedSSteven Rostedt my $result; 23215f9b6cedSSteven Rostedt 2322b5f4aea6SSteven Rostedt die "BISECT_GOOD[$i] not defined\n" if (!defined($bisect_good)); 2323b5f4aea6SSteven Rostedt die "BISECT_BAD[$i] not defined\n" if (!defined($bisect_bad)); 2324b5f4aea6SSteven Rostedt die "BISECT_TYPE[$i] not defined\n" if (!defined($bisect_type)); 23255f9b6cedSSteven Rostedt 2326b5f4aea6SSteven Rostedt my $good = $bisect_good; 2327b5f4aea6SSteven Rostedt my $bad = $bisect_bad; 2328b5f4aea6SSteven Rostedt my $type = $bisect_type; 2329b5f4aea6SSteven Rostedt my $start = $bisect_start; 2330b5f4aea6SSteven Rostedt my $replay = $bisect_replay; 2331b5f4aea6SSteven Rostedt my $start_files = $bisect_files; 23323410f6fdSSteven Rostedt 23333410f6fdSSteven Rostedt if (defined($start_files)) { 23343410f6fdSSteven Rostedt $start_files = " -- " . $start_files; 23353410f6fdSSteven Rostedt } else { 23363410f6fdSSteven Rostedt $start_files = ""; 23373410f6fdSSteven Rostedt } 23385f9b6cedSSteven Rostedt 2339a57419b3SSteven Rostedt # convert to true sha1's 2340a57419b3SSteven Rostedt $good = get_sha1($good); 2341a57419b3SSteven Rostedt $bad = get_sha1($bad); 2342a57419b3SSteven Rostedt 2343b5f4aea6SSteven Rostedt if (defined($bisect_reverse) && $bisect_reverse == 1) { 2344d6ce2a0bSSteven Rostedt doprint "Performing a reverse bisect (bad is good, good is bad!)\n"; 2345d6ce2a0bSSteven Rostedt $reverse_bisect = 1; 2346d6ce2a0bSSteven Rostedt } else { 2347d6ce2a0bSSteven Rostedt $reverse_bisect = 0; 2348d6ce2a0bSSteven Rostedt } 2349d6ce2a0bSSteven Rostedt 23505a391fbfSSteven Rostedt # Can't have a test without having a test to run 23515a391fbfSSteven Rostedt if ($type eq "test" && !defined($run_test)) { 23525a391fbfSSteven Rostedt $type = "boot"; 23535a391fbfSSteven Rostedt } 23545a391fbfSSteven Rostedt 2355dad98754SSteven Rostedt # Check if a bisect was running 2356dad98754SSteven Rostedt my $bisect_start_file = "$builddir/.git/BISECT_START"; 2357dad98754SSteven Rostedt 2358b5f4aea6SSteven Rostedt my $check = $bisect_check; 2359dad98754SSteven Rostedt my $do_check = defined($check) && $check ne "0"; 2360dad98754SSteven Rostedt 2361dad98754SSteven Rostedt if ( -f $bisect_start_file ) { 2362dad98754SSteven Rostedt print "Bisect in progress found\n"; 2363dad98754SSteven Rostedt if ($do_check) { 2364dad98754SSteven Rostedt print " If you say yes, then no checks of good or bad will be done\n"; 2365dad98754SSteven Rostedt } 2366dad98754SSteven Rostedt if (defined($replay)) { 2367dad98754SSteven Rostedt print "** BISECT_REPLAY is defined in config file **"; 2368dad98754SSteven Rostedt print " Ignore config option and perform new git bisect log?\n"; 2369dad98754SSteven Rostedt if (read_ync " (yes, no, or cancel) ") { 2370dad98754SSteven Rostedt $replay = update_bisect_replay; 2371dad98754SSteven Rostedt $do_check = 0; 2372dad98754SSteven Rostedt } 2373dad98754SSteven Rostedt } elsif (read_yn "read git log and continue?") { 2374dad98754SSteven Rostedt $replay = update_bisect_replay; 2375dad98754SSteven Rostedt $do_check = 0; 2376dad98754SSteven Rostedt } 2377dad98754SSteven Rostedt } 2378dad98754SSteven Rostedt 2379dad98754SSteven Rostedt if ($do_check) { 2380a75fececSSteven Rostedt 2381a75fececSSteven Rostedt # get current HEAD 2382a57419b3SSteven Rostedt my $head = get_sha1("HEAD"); 2383a75fececSSteven Rostedt 2384a75fececSSteven Rostedt if ($check ne "good") { 2385a75fececSSteven Rostedt doprint "TESTING BISECT BAD [$bad]\n"; 2386a75fececSSteven Rostedt run_command "git checkout $bad" or 2387a75fececSSteven Rostedt die "Failed to checkout $bad"; 2388a75fececSSteven Rostedt 2389a75fececSSteven Rostedt $result = run_bisect $type; 2390a75fececSSteven Rostedt 2391a75fececSSteven Rostedt if ($result ne "bad") { 2392a75fececSSteven Rostedt fail "Tested BISECT_BAD [$bad] and it succeeded" and return 0; 2393a75fececSSteven Rostedt } 2394a75fececSSteven Rostedt } 2395a75fececSSteven Rostedt 2396a75fececSSteven Rostedt if ($check ne "bad") { 2397a75fececSSteven Rostedt doprint "TESTING BISECT GOOD [$good]\n"; 2398a75fececSSteven Rostedt run_command "git checkout $good" or 2399a75fececSSteven Rostedt die "Failed to checkout $good"; 2400a75fececSSteven Rostedt 2401a75fececSSteven Rostedt $result = run_bisect $type; 2402a75fececSSteven Rostedt 2403a75fececSSteven Rostedt if ($result ne "good") { 2404a75fececSSteven Rostedt fail "Tested BISECT_GOOD [$good] and it failed" and return 0; 2405a75fececSSteven Rostedt } 2406a75fececSSteven Rostedt } 2407a75fececSSteven Rostedt 2408a75fececSSteven Rostedt # checkout where we started 2409a75fececSSteven Rostedt run_command "git checkout $head" or 2410a75fececSSteven Rostedt die "Failed to checkout $head"; 2411a75fececSSteven Rostedt } 2412a75fececSSteven Rostedt 24133410f6fdSSteven Rostedt run_command "git bisect start$start_files" or 2414a75fececSSteven Rostedt dodie "could not start bisect"; 2415a75fececSSteven Rostedt 2416a75fececSSteven Rostedt run_command "git bisect good $good" or 2417a75fececSSteven Rostedt dodie "could not set bisect good to $good"; 2418a75fececSSteven Rostedt 2419a75fececSSteven Rostedt run_git_bisect "git bisect bad $bad" or 2420a75fececSSteven Rostedt dodie "could not set bisect bad to $bad"; 2421a75fececSSteven Rostedt 2422a75fececSSteven Rostedt if (defined($replay)) { 2423a75fececSSteven Rostedt run_command "git bisect replay $replay" or 2424a75fececSSteven Rostedt dodie "failed to run replay"; 2425a75fececSSteven Rostedt } 2426a75fececSSteven Rostedt 2427a75fececSSteven Rostedt if (defined($start)) { 2428a75fececSSteven Rostedt run_command "git checkout $start" or 2429a75fececSSteven Rostedt dodie "failed to checkout $start"; 2430a75fececSSteven Rostedt } 2431a75fececSSteven Rostedt 2432a75fececSSteven Rostedt my $test; 24335f9b6cedSSteven Rostedt do { 24345f9b6cedSSteven Rostedt $result = run_bisect $type; 2435a75fececSSteven Rostedt $test = run_git_bisect "git bisect $result"; 2436a75fececSSteven Rostedt } while ($test); 24375f9b6cedSSteven Rostedt 24385f9b6cedSSteven Rostedt run_command "git bisect log" or 24395f9b6cedSSteven Rostedt dodie "could not capture git bisect log"; 24405f9b6cedSSteven Rostedt 24415f9b6cedSSteven Rostedt run_command "git bisect reset" or 24425f9b6cedSSteven Rostedt dodie "could not reset git bisect"; 24435f9b6cedSSteven Rostedt 2444b5f4aea6SSteven Rostedt doprint "Bad commit was [$bisect_bad_commit]\n"; 24455f9b6cedSSteven Rostedt 24460a05c769SSteven Rostedt success $i; 24470a05c769SSteven Rostedt} 24480a05c769SSteven Rostedt 2449cf79fab6SSteven Rostedt# config_ignore holds the configs that were set (or unset) for 2450cf79fab6SSteven Rostedt# a good config and we will ignore these configs for the rest 2451cf79fab6SSteven Rostedt# of a config bisect. These configs stay as they were. 24520a05c769SSteven Rostedtmy %config_ignore; 2453cf79fab6SSteven Rostedt 2454cf79fab6SSteven Rostedt# config_set holds what all configs were set as. 24550a05c769SSteven Rostedtmy %config_set; 24560a05c769SSteven Rostedt 2457cf79fab6SSteven Rostedt# config_off holds the set of configs that the bad config had disabled. 2458cf79fab6SSteven Rostedt# We need to record them and set them in the .config when running 2459cf79fab6SSteven Rostedt# oldnoconfig, because oldnoconfig does not turn off new symbols, but 2460cf79fab6SSteven Rostedt# instead just keeps the defaults. 2461cf79fab6SSteven Rostedtmy %config_off; 2462cf79fab6SSteven Rostedt 2463cf79fab6SSteven Rostedt# config_off_tmp holds a set of configs to turn off for now 2464cf79fab6SSteven Rostedtmy @config_off_tmp; 2465cf79fab6SSteven Rostedt 2466cf79fab6SSteven Rostedt# config_list is the set of configs that are being tested 24670a05c769SSteven Rostedtmy %config_list; 24680a05c769SSteven Rostedtmy %null_config; 24690a05c769SSteven Rostedt 24700a05c769SSteven Rostedtmy %dependency; 24710a05c769SSteven Rostedt 24724c4ab120SSteven Rostedtsub assign_configs { 24734c4ab120SSteven Rostedt my ($hash, $config) = @_; 24740a05c769SSteven Rostedt 24750a05c769SSteven Rostedt open (IN, $config) 24760a05c769SSteven Rostedt or dodie "Failed to read $config"; 24770a05c769SSteven Rostedt 24780a05c769SSteven Rostedt while (<IN>) { 24799bf71749SSteven Rostedt if (/^((CONFIG\S*)=.*)/) { 24804c4ab120SSteven Rostedt ${$hash}{$2} = $1; 24810a05c769SSteven Rostedt } 24820a05c769SSteven Rostedt } 24830a05c769SSteven Rostedt 24840a05c769SSteven Rostedt close(IN); 24850a05c769SSteven Rostedt} 24860a05c769SSteven Rostedt 24874c4ab120SSteven Rostedtsub process_config_ignore { 24884c4ab120SSteven Rostedt my ($config) = @_; 24894c4ab120SSteven Rostedt 24904c4ab120SSteven Rostedt assign_configs \%config_ignore, $config; 24914c4ab120SSteven Rostedt} 24924c4ab120SSteven Rostedt 24930a05c769SSteven Rostedtsub read_current_config { 24940a05c769SSteven Rostedt my ($config_ref) = @_; 24950a05c769SSteven Rostedt 24960a05c769SSteven Rostedt %{$config_ref} = (); 24970a05c769SSteven Rostedt undef %{$config_ref}; 24980a05c769SSteven Rostedt 24990a05c769SSteven Rostedt my @key = keys %{$config_ref}; 25000a05c769SSteven Rostedt if ($#key >= 0) { 25010a05c769SSteven Rostedt print "did not delete!\n"; 25020a05c769SSteven Rostedt exit; 25030a05c769SSteven Rostedt } 25040a05c769SSteven Rostedt open (IN, "$output_config"); 25050a05c769SSteven Rostedt 25060a05c769SSteven Rostedt while (<IN>) { 25070a05c769SSteven Rostedt if (/^(CONFIG\S+)=(.*)/) { 25080a05c769SSteven Rostedt ${$config_ref}{$1} = $2; 25090a05c769SSteven Rostedt } 25100a05c769SSteven Rostedt } 25110a05c769SSteven Rostedt close(IN); 25120a05c769SSteven Rostedt} 25130a05c769SSteven Rostedt 25140a05c769SSteven Rostedtsub get_dependencies { 25150a05c769SSteven Rostedt my ($config) = @_; 25160a05c769SSteven Rostedt 25170a05c769SSteven Rostedt my $arr = $dependency{$config}; 25180a05c769SSteven Rostedt if (!defined($arr)) { 25190a05c769SSteven Rostedt return (); 25200a05c769SSteven Rostedt } 25210a05c769SSteven Rostedt 25220a05c769SSteven Rostedt my @deps = @{$arr}; 25230a05c769SSteven Rostedt 25240a05c769SSteven Rostedt foreach my $dep (@{$arr}) { 25250a05c769SSteven Rostedt print "ADD DEP $dep\n"; 25260a05c769SSteven Rostedt @deps = (@deps, get_dependencies $dep); 25270a05c769SSteven Rostedt } 25280a05c769SSteven Rostedt 25290a05c769SSteven Rostedt return @deps; 25300a05c769SSteven Rostedt} 25310a05c769SSteven Rostedt 25320a05c769SSteven Rostedtsub create_config { 25330a05c769SSteven Rostedt my @configs = @_; 25340a05c769SSteven Rostedt 25350a05c769SSteven Rostedt open(OUT, ">$output_config") or dodie "Can not write to $output_config"; 25360a05c769SSteven Rostedt 25370a05c769SSteven Rostedt foreach my $config (@configs) { 25380a05c769SSteven Rostedt print OUT "$config_set{$config}\n"; 25390a05c769SSteven Rostedt my @deps = get_dependencies $config; 25400a05c769SSteven Rostedt foreach my $dep (@deps) { 25410a05c769SSteven Rostedt print OUT "$config_set{$dep}\n"; 25420a05c769SSteven Rostedt } 25430a05c769SSteven Rostedt } 25440a05c769SSteven Rostedt 2545cf79fab6SSteven Rostedt # turn off configs to keep off 2546cf79fab6SSteven Rostedt foreach my $config (keys %config_off) { 2547cf79fab6SSteven Rostedt print OUT "# $config is not set\n"; 2548cf79fab6SSteven Rostedt } 2549cf79fab6SSteven Rostedt 2550cf79fab6SSteven Rostedt # turn off configs that should be off for now 2551cf79fab6SSteven Rostedt foreach my $config (@config_off_tmp) { 2552cf79fab6SSteven Rostedt print OUT "# $config is not set\n"; 2553cf79fab6SSteven Rostedt } 2554cf79fab6SSteven Rostedt 25550a05c769SSteven Rostedt foreach my $config (keys %config_ignore) { 25560a05c769SSteven Rostedt print OUT "$config_ignore{$config}\n"; 25570a05c769SSteven Rostedt } 25580a05c769SSteven Rostedt close(OUT); 25590a05c769SSteven Rostedt 2560fcb3f16aSSteven Rostedt make_oldconfig; 25610a05c769SSteven Rostedt} 25620a05c769SSteven Rostedt 25630a05c769SSteven Rostedtsub compare_configs { 25640a05c769SSteven Rostedt my (%a, %b) = @_; 25650a05c769SSteven Rostedt 25660a05c769SSteven Rostedt foreach my $item (keys %a) { 25670a05c769SSteven Rostedt if (!defined($b{$item})) { 25680a05c769SSteven Rostedt print "diff $item\n"; 25690a05c769SSteven Rostedt return 1; 25700a05c769SSteven Rostedt } 25710a05c769SSteven Rostedt delete $b{$item}; 25720a05c769SSteven Rostedt } 25730a05c769SSteven Rostedt 25740a05c769SSteven Rostedt my @keys = keys %b; 25750a05c769SSteven Rostedt if ($#keys) { 25760a05c769SSteven Rostedt print "diff2 $keys[0]\n"; 25770a05c769SSteven Rostedt } 25780a05c769SSteven Rostedt return -1 if ($#keys >= 0); 25790a05c769SSteven Rostedt 25800a05c769SSteven Rostedt return 0; 25810a05c769SSteven Rostedt} 25820a05c769SSteven Rostedt 25830a05c769SSteven Rostedtsub run_config_bisect_test { 25840a05c769SSteven Rostedt my ($type) = @_; 25850a05c769SSteven Rostedt 25860a05c769SSteven Rostedt return run_bisect_test $type, "oldconfig"; 25870a05c769SSteven Rostedt} 25880a05c769SSteven Rostedt 25890a05c769SSteven Rostedtsub process_passed { 25900a05c769SSteven Rostedt my (%configs) = @_; 25910a05c769SSteven Rostedt 25920a05c769SSteven Rostedt doprint "These configs had no failure: (Enabling them for further compiles)\n"; 25930a05c769SSteven Rostedt # Passed! All these configs are part of a good compile. 25940a05c769SSteven Rostedt # Add them to the min options. 25950a05c769SSteven Rostedt foreach my $config (keys %configs) { 25960a05c769SSteven Rostedt if (defined($config_list{$config})) { 25970a05c769SSteven Rostedt doprint " removing $config\n"; 25980a05c769SSteven Rostedt $config_ignore{$config} = $config_list{$config}; 25990a05c769SSteven Rostedt delete $config_list{$config}; 26000a05c769SSteven Rostedt } 26010a05c769SSteven Rostedt } 2602f1a27850SSteven Rostedt doprint "config copied to $outputdir/config_good\n"; 2603f1a27850SSteven Rostedt run_command "cp -f $output_config $outputdir/config_good"; 26040a05c769SSteven Rostedt} 26050a05c769SSteven Rostedt 26060a05c769SSteven Rostedtsub process_failed { 26070a05c769SSteven Rostedt my ($config) = @_; 26080a05c769SSteven Rostedt 26090a05c769SSteven Rostedt doprint "\n\n***************************************\n"; 26100a05c769SSteven Rostedt doprint "Found bad config: $config\n"; 26110a05c769SSteven Rostedt doprint "***************************************\n\n"; 26120a05c769SSteven Rostedt} 26130a05c769SSteven Rostedt 26140a05c769SSteven Rostedtsub run_config_bisect { 26150a05c769SSteven Rostedt 26160a05c769SSteven Rostedt my @start_list = keys %config_list; 26170a05c769SSteven Rostedt 26180a05c769SSteven Rostedt if ($#start_list < 0) { 26190a05c769SSteven Rostedt doprint "No more configs to test!!!\n"; 26200a05c769SSteven Rostedt return -1; 26210a05c769SSteven Rostedt } 26220a05c769SSteven Rostedt 26230a05c769SSteven Rostedt doprint "***** RUN TEST ***\n"; 2624b5f4aea6SSteven Rostedt my $type = $config_bisect_type; 26250a05c769SSteven Rostedt my $ret; 26260a05c769SSteven Rostedt my %current_config; 26270a05c769SSteven Rostedt 26280a05c769SSteven Rostedt my $count = $#start_list + 1; 26290a05c769SSteven Rostedt doprint " $count configs to test\n"; 26300a05c769SSteven Rostedt 26310a05c769SSteven Rostedt my $half = int($#start_list / 2); 26320a05c769SSteven Rostedt 26330a05c769SSteven Rostedt do { 26340a05c769SSteven Rostedt my @tophalf = @start_list[0 .. $half]; 26350a05c769SSteven Rostedt 2636cf79fab6SSteven Rostedt # keep the bottom half off 2637cf79fab6SSteven Rostedt if ($half < $#start_list) { 2638cf79fab6SSteven Rostedt @config_off_tmp = @start_list[$half + 1 .. $#start_list]; 2639cf79fab6SSteven Rostedt } else { 2640cf79fab6SSteven Rostedt @config_off_tmp = (); 2641cf79fab6SSteven Rostedt } 2642cf79fab6SSteven Rostedt 26430a05c769SSteven Rostedt create_config @tophalf; 26440a05c769SSteven Rostedt read_current_config \%current_config; 26450a05c769SSteven Rostedt 26460a05c769SSteven Rostedt $count = $#tophalf + 1; 26470a05c769SSteven Rostedt doprint "Testing $count configs\n"; 26480a05c769SSteven Rostedt my $found = 0; 26490a05c769SSteven Rostedt # make sure we test something 26500a05c769SSteven Rostedt foreach my $config (@tophalf) { 26510a05c769SSteven Rostedt if (defined($current_config{$config})) { 26520a05c769SSteven Rostedt logit " $config\n"; 26530a05c769SSteven Rostedt $found = 1; 26540a05c769SSteven Rostedt } 26550a05c769SSteven Rostedt } 26560a05c769SSteven Rostedt if (!$found) { 26570a05c769SSteven Rostedt # try the other half 26580a05c769SSteven Rostedt doprint "Top half produced no set configs, trying bottom half\n"; 2659cf79fab6SSteven Rostedt 2660cf79fab6SSteven Rostedt # keep the top half off 2661cf79fab6SSteven Rostedt @config_off_tmp = @tophalf; 26624c8cc55bSSteven Rostedt @tophalf = @start_list[$half + 1 .. $#start_list]; 2663cf79fab6SSteven Rostedt 26640a05c769SSteven Rostedt create_config @tophalf; 26650a05c769SSteven Rostedt read_current_config \%current_config; 26660a05c769SSteven Rostedt foreach my $config (@tophalf) { 26670a05c769SSteven Rostedt if (defined($current_config{$config})) { 26680a05c769SSteven Rostedt logit " $config\n"; 26690a05c769SSteven Rostedt $found = 1; 26700a05c769SSteven Rostedt } 26710a05c769SSteven Rostedt } 26720a05c769SSteven Rostedt if (!$found) { 26730a05c769SSteven Rostedt doprint "Failed: Can't make new config with current configs\n"; 26740a05c769SSteven Rostedt foreach my $config (@start_list) { 26750a05c769SSteven Rostedt doprint " CONFIG: $config\n"; 26760a05c769SSteven Rostedt } 26770a05c769SSteven Rostedt return -1; 26780a05c769SSteven Rostedt } 26790a05c769SSteven Rostedt $count = $#tophalf + 1; 26800a05c769SSteven Rostedt doprint "Testing $count configs\n"; 26810a05c769SSteven Rostedt } 26820a05c769SSteven Rostedt 26830a05c769SSteven Rostedt $ret = run_config_bisect_test $type; 2684c960bb9fSSteven Rostedt if ($bisect_manual) { 2685c960bb9fSSteven Rostedt $ret = answer_bisect; 2686c960bb9fSSteven Rostedt } 26870a05c769SSteven Rostedt if ($ret) { 26880a05c769SSteven Rostedt process_passed %current_config; 26890a05c769SSteven Rostedt return 0; 26900a05c769SSteven Rostedt } 26910a05c769SSteven Rostedt 26920a05c769SSteven Rostedt doprint "This config had a failure.\n"; 26930a05c769SSteven Rostedt doprint "Removing these configs that were not set in this config:\n"; 2694f1a27850SSteven Rostedt doprint "config copied to $outputdir/config_bad\n"; 2695f1a27850SSteven Rostedt run_command "cp -f $output_config $outputdir/config_bad"; 26960a05c769SSteven Rostedt 26970a05c769SSteven Rostedt # A config exists in this group that was bad. 26980a05c769SSteven Rostedt foreach my $config (keys %config_list) { 26990a05c769SSteven Rostedt if (!defined($current_config{$config})) { 27000a05c769SSteven Rostedt doprint " removing $config\n"; 27010a05c769SSteven Rostedt delete $config_list{$config}; 27020a05c769SSteven Rostedt } 27030a05c769SSteven Rostedt } 27040a05c769SSteven Rostedt 27050a05c769SSteven Rostedt @start_list = @tophalf; 27060a05c769SSteven Rostedt 27070a05c769SSteven Rostedt if ($#start_list == 0) { 27080a05c769SSteven Rostedt process_failed $start_list[0]; 27090a05c769SSteven Rostedt return 1; 27100a05c769SSteven Rostedt } 27110a05c769SSteven Rostedt 27120a05c769SSteven Rostedt # remove half the configs we are looking at and see if 27130a05c769SSteven Rostedt # they are good. 27140a05c769SSteven Rostedt $half = int($#start_list / 2); 27154c8cc55bSSteven Rostedt } while ($#start_list > 0); 27160a05c769SSteven Rostedt 2717c960bb9fSSteven Rostedt # we found a single config, try it again unless we are running manually 2718c960bb9fSSteven Rostedt 2719c960bb9fSSteven Rostedt if ($bisect_manual) { 2720c960bb9fSSteven Rostedt process_failed $start_list[0]; 2721c960bb9fSSteven Rostedt return 1; 2722c960bb9fSSteven Rostedt } 2723c960bb9fSSteven Rostedt 27240a05c769SSteven Rostedt my @tophalf = @start_list[0 .. 0]; 27250a05c769SSteven Rostedt 27260a05c769SSteven Rostedt $ret = run_config_bisect_test $type; 27270a05c769SSteven Rostedt if ($ret) { 27280a05c769SSteven Rostedt process_passed %current_config; 27290a05c769SSteven Rostedt return 0; 27300a05c769SSteven Rostedt } 27310a05c769SSteven Rostedt 27320a05c769SSteven Rostedt process_failed $start_list[0]; 27330a05c769SSteven Rostedt return 1; 27340a05c769SSteven Rostedt} 27350a05c769SSteven Rostedt 27360a05c769SSteven Rostedtsub config_bisect { 27370a05c769SSteven Rostedt my ($i) = @_; 27380a05c769SSteven Rostedt 2739b5f4aea6SSteven Rostedt my $start_config = $config_bisect; 27400a05c769SSteven Rostedt 27410a05c769SSteven Rostedt my $tmpconfig = "$tmpdir/use_config"; 27420a05c769SSteven Rostedt 274330f75da5SSteven Rostedt if (defined($config_bisect_good)) { 274430f75da5SSteven Rostedt process_config_ignore $config_bisect_good; 274530f75da5SSteven Rostedt } 274630f75da5SSteven Rostedt 27470a05c769SSteven Rostedt # Make the file with the bad config and the min config 27480a05c769SSteven Rostedt if (defined($minconfig)) { 27490a05c769SSteven Rostedt # read the min config for things to ignore 27500a05c769SSteven Rostedt run_command "cp $minconfig $tmpconfig" or 27510a05c769SSteven Rostedt dodie "failed to copy $minconfig to $tmpconfig"; 27520a05c769SSteven Rostedt } else { 27530a05c769SSteven Rostedt unlink $tmpconfig; 27540a05c769SSteven Rostedt } 27550a05c769SSteven Rostedt 27560a05c769SSteven Rostedt if (-f $tmpconfig) { 2757fcb3f16aSSteven Rostedt load_force_config($tmpconfig); 27580a05c769SSteven Rostedt process_config_ignore $tmpconfig; 27590a05c769SSteven Rostedt } 27600a05c769SSteven Rostedt 27610a05c769SSteven Rostedt # now process the start config 27620a05c769SSteven Rostedt run_command "cp $start_config $output_config" or 27630a05c769SSteven Rostedt dodie "failed to copy $start_config to $output_config"; 27640a05c769SSteven Rostedt 27650a05c769SSteven Rostedt # read directly what we want to check 27660a05c769SSteven Rostedt my %config_check; 27670a05c769SSteven Rostedt open (IN, $output_config) 2768f9dee311SMasanari Iida or dodie "failed to open $output_config"; 27690a05c769SSteven Rostedt 27700a05c769SSteven Rostedt while (<IN>) { 27710a05c769SSteven Rostedt if (/^((CONFIG\S*)=.*)/) { 27720a05c769SSteven Rostedt $config_check{$2} = $1; 27730a05c769SSteven Rostedt } 27740a05c769SSteven Rostedt } 27750a05c769SSteven Rostedt close(IN); 27760a05c769SSteven Rostedt 2777250bae8bSSteven Rostedt # Now run oldconfig with the minconfig 2778fcb3f16aSSteven Rostedt make_oldconfig; 27790a05c769SSteven Rostedt 27800a05c769SSteven Rostedt # check to see what we lost (or gained) 27810a05c769SSteven Rostedt open (IN, $output_config) 27820a05c769SSteven Rostedt or dodie "Failed to read $start_config"; 27830a05c769SSteven Rostedt 27840a05c769SSteven Rostedt my %removed_configs; 27850a05c769SSteven Rostedt my %added_configs; 27860a05c769SSteven Rostedt 27870a05c769SSteven Rostedt while (<IN>) { 27880a05c769SSteven Rostedt if (/^((CONFIG\S*)=.*)/) { 27890a05c769SSteven Rostedt # save off all options 27900a05c769SSteven Rostedt $config_set{$2} = $1; 27910a05c769SSteven Rostedt if (defined($config_check{$2})) { 27920a05c769SSteven Rostedt if (defined($config_ignore{$2})) { 27930a05c769SSteven Rostedt $removed_configs{$2} = $1; 27940a05c769SSteven Rostedt } else { 27950a05c769SSteven Rostedt $config_list{$2} = $1; 27960a05c769SSteven Rostedt } 27970a05c769SSteven Rostedt } elsif (!defined($config_ignore{$2})) { 27980a05c769SSteven Rostedt $added_configs{$2} = $1; 27990a05c769SSteven Rostedt $config_list{$2} = $1; 28000a05c769SSteven Rostedt } 2801cf79fab6SSteven Rostedt } elsif (/^# ((CONFIG\S*).*)/) { 2802cf79fab6SSteven Rostedt # Keep these configs disabled 2803cf79fab6SSteven Rostedt $config_set{$2} = $1; 2804cf79fab6SSteven Rostedt $config_off{$2} = $1; 28050a05c769SSteven Rostedt } 28060a05c769SSteven Rostedt } 28070a05c769SSteven Rostedt close(IN); 28080a05c769SSteven Rostedt 28090a05c769SSteven Rostedt my @confs = keys %removed_configs; 28100a05c769SSteven Rostedt if ($#confs >= 0) { 28110a05c769SSteven Rostedt doprint "Configs overridden by default configs and removed from check:\n"; 28120a05c769SSteven Rostedt foreach my $config (@confs) { 28130a05c769SSteven Rostedt doprint " $config\n"; 28140a05c769SSteven Rostedt } 28150a05c769SSteven Rostedt } 28160a05c769SSteven Rostedt @confs = keys %added_configs; 28170a05c769SSteven Rostedt if ($#confs >= 0) { 28180a05c769SSteven Rostedt doprint "Configs appearing in make oldconfig and added:\n"; 28190a05c769SSteven Rostedt foreach my $config (@confs) { 28200a05c769SSteven Rostedt doprint " $config\n"; 28210a05c769SSteven Rostedt } 28220a05c769SSteven Rostedt } 28230a05c769SSteven Rostedt 28240a05c769SSteven Rostedt my %config_test; 28250a05c769SSteven Rostedt my $once = 0; 28260a05c769SSteven Rostedt 2827cf79fab6SSteven Rostedt @config_off_tmp = (); 2828cf79fab6SSteven Rostedt 28290a05c769SSteven Rostedt # Sometimes kconfig does weird things. We must make sure 28300a05c769SSteven Rostedt # that the config we autocreate has everything we need 28310a05c769SSteven Rostedt # to test, otherwise we may miss testing configs, or 28320a05c769SSteven Rostedt # may not be able to create a new config. 28330a05c769SSteven Rostedt # Here we create a config with everything set. 28340a05c769SSteven Rostedt create_config (keys %config_list); 28350a05c769SSteven Rostedt read_current_config \%config_test; 28360a05c769SSteven Rostedt foreach my $config (keys %config_list) { 28370a05c769SSteven Rostedt if (!defined($config_test{$config})) { 28380a05c769SSteven Rostedt if (!$once) { 28390a05c769SSteven Rostedt $once = 1; 28400a05c769SSteven Rostedt doprint "Configs not produced by kconfig (will not be checked):\n"; 28410a05c769SSteven Rostedt } 28420a05c769SSteven Rostedt doprint " $config\n"; 28430a05c769SSteven Rostedt delete $config_list{$config}; 28440a05c769SSteven Rostedt } 28450a05c769SSteven Rostedt } 28460a05c769SSteven Rostedt my $ret; 2847b0918612SSteven Rostedt 2848b0918612SSteven Rostedt if (defined($config_bisect_check) && $config_bisect_check) { 2849b0918612SSteven Rostedt doprint " Checking to make sure bad config with min config fails\n"; 2850b0918612SSteven Rostedt create_config keys %config_list; 2851b0918612SSteven Rostedt $ret = run_config_bisect_test $config_bisect_type; 2852b0918612SSteven Rostedt if ($ret) { 2853b0918612SSteven Rostedt doprint " FAILED! Bad config with min config boots fine\n"; 2854b0918612SSteven Rostedt return -1; 2855b0918612SSteven Rostedt } 2856b0918612SSteven Rostedt doprint " Bad config with min config fails as expected\n"; 2857b0918612SSteven Rostedt } 2858b0918612SSteven Rostedt 28590a05c769SSteven Rostedt do { 28600a05c769SSteven Rostedt $ret = run_config_bisect; 28610a05c769SSteven Rostedt } while (!$ret); 28620a05c769SSteven Rostedt 28630a05c769SSteven Rostedt return $ret if ($ret < 0); 28645f9b6cedSSteven Rostedt 28655f9b6cedSSteven Rostedt success $i; 28665f9b6cedSSteven Rostedt} 28675f9b6cedSSteven Rostedt 286827d934b2SSteven Rostedtsub patchcheck_reboot { 286927d934b2SSteven Rostedt doprint "Reboot and sleep $patchcheck_sleep_time seconds\n"; 2870bc7c5803SSteven Rostedt reboot_to_good $patchcheck_sleep_time; 287127d934b2SSteven Rostedt} 287227d934b2SSteven Rostedt 28736c5ee0beSSteven Rostedtsub patchcheck { 28746c5ee0beSSteven Rostedt my ($i) = @_; 28756c5ee0beSSteven Rostedt 28766c5ee0beSSteven Rostedt die "PATCHCHECK_START[$i] not defined\n" 2877b5f4aea6SSteven Rostedt if (!defined($patchcheck_start)); 28786c5ee0beSSteven Rostedt die "PATCHCHECK_TYPE[$i] not defined\n" 2879b5f4aea6SSteven Rostedt if (!defined($patchcheck_type)); 28806c5ee0beSSteven Rostedt 2881b5f4aea6SSteven Rostedt my $start = $patchcheck_start; 28826c5ee0beSSteven Rostedt 28836c5ee0beSSteven Rostedt my $end = "HEAD"; 2884b5f4aea6SSteven Rostedt if (defined($patchcheck_end)) { 2885b5f4aea6SSteven Rostedt $end = $patchcheck_end; 28866c5ee0beSSteven Rostedt } 28876c5ee0beSSteven Rostedt 2888a57419b3SSteven Rostedt # Get the true sha1's since we can use things like HEAD~3 2889a57419b3SSteven Rostedt $start = get_sha1($start); 2890a57419b3SSteven Rostedt $end = get_sha1($end); 2891a57419b3SSteven Rostedt 2892b5f4aea6SSteven Rostedt my $type = $patchcheck_type; 28936c5ee0beSSteven Rostedt 28946c5ee0beSSteven Rostedt # Can't have a test without having a test to run 28956c5ee0beSSteven Rostedt if ($type eq "test" && !defined($run_test)) { 28966c5ee0beSSteven Rostedt $type = "boot"; 28976c5ee0beSSteven Rostedt } 28986c5ee0beSSteven Rostedt 28996c5ee0beSSteven Rostedt open (IN, "git log --pretty=oneline $end|") or 29006c5ee0beSSteven Rostedt dodie "could not get git list"; 29016c5ee0beSSteven Rostedt 29026c5ee0beSSteven Rostedt my @list; 29036c5ee0beSSteven Rostedt 29046c5ee0beSSteven Rostedt while (<IN>) { 29056c5ee0beSSteven Rostedt chomp; 29066c5ee0beSSteven Rostedt $list[$#list+1] = $_; 29076c5ee0beSSteven Rostedt last if (/^$start/); 29086c5ee0beSSteven Rostedt } 29096c5ee0beSSteven Rostedt close(IN); 29106c5ee0beSSteven Rostedt 29116c5ee0beSSteven Rostedt if ($list[$#list] !~ /^$start/) { 29122b7d9b21SSteven Rostedt fail "SHA1 $start not found"; 29136c5ee0beSSteven Rostedt } 29146c5ee0beSSteven Rostedt 29156c5ee0beSSteven Rostedt # go backwards in the list 29166c5ee0beSSteven Rostedt @list = reverse @list; 29176c5ee0beSSteven Rostedt 29186c5ee0beSSteven Rostedt my $save_clean = $noclean; 29191990207dSSteven Rostedt my %ignored_warnings; 29201990207dSSteven Rostedt 29211990207dSSteven Rostedt if (defined($ignore_warnings)) { 29221990207dSSteven Rostedt foreach my $sha1 (split /\s+/, $ignore_warnings) { 29231990207dSSteven Rostedt $ignored_warnings{$sha1} = 1; 29241990207dSSteven Rostedt } 29251990207dSSteven Rostedt } 29266c5ee0beSSteven Rostedt 29276c5ee0beSSteven Rostedt $in_patchcheck = 1; 29286c5ee0beSSteven Rostedt foreach my $item (@list) { 29296c5ee0beSSteven Rostedt my $sha1 = $item; 29306c5ee0beSSteven Rostedt $sha1 =~ s/^([[:xdigit:]]+).*/$1/; 29316c5ee0beSSteven Rostedt 29326c5ee0beSSteven Rostedt doprint "\nProcessing commit $item\n\n"; 29336c5ee0beSSteven Rostedt 29346c5ee0beSSteven Rostedt run_command "git checkout $sha1" or 29356c5ee0beSSteven Rostedt die "Failed to checkout $sha1"; 29366c5ee0beSSteven Rostedt 29376c5ee0beSSteven Rostedt # only clean on the first and last patch 29386c5ee0beSSteven Rostedt if ($item eq $list[0] || 29396c5ee0beSSteven Rostedt $item eq $list[$#list]) { 29406c5ee0beSSteven Rostedt $noclean = $save_clean; 29416c5ee0beSSteven Rostedt } else { 29426c5ee0beSSteven Rostedt $noclean = 1; 29436c5ee0beSSteven Rostedt } 29446c5ee0beSSteven Rostedt 29456c5ee0beSSteven Rostedt if (defined($minconfig)) { 29462b7d9b21SSteven Rostedt build "useconfig:$minconfig" or return 0; 29476c5ee0beSSteven Rostedt } else { 29486c5ee0beSSteven Rostedt # ?? no config to use? 29492b7d9b21SSteven Rostedt build "oldconfig" or return 0; 29506c5ee0beSSteven Rostedt } 29516c5ee0beSSteven Rostedt 29521990207dSSteven Rostedt 29531990207dSSteven Rostedt if (!defined($ignored_warnings{$sha1})) { 29542b7d9b21SSteven Rostedt check_buildlog $sha1 or return 0; 29551990207dSSteven Rostedt } 29566c5ee0beSSteven Rostedt 29576c5ee0beSSteven Rostedt next if ($type eq "build"); 29586c5ee0beSSteven Rostedt 29597faafbd6SSteven Rostedt my $failed = 0; 29607faafbd6SSteven Rostedt 2961ddf607e5SSteven Rostedt start_monitor_and_boot or $failed = 1; 29627faafbd6SSteven Rostedt 29637faafbd6SSteven Rostedt if (!$failed && $type ne "boot"){ 29647faafbd6SSteven Rostedt do_run_test or $failed = 1; 29657faafbd6SSteven Rostedt } 29667faafbd6SSteven Rostedt end_monitor; 29677faafbd6SSteven Rostedt return 0 if ($failed); 29687faafbd6SSteven Rostedt 296927d934b2SSteven Rostedt patchcheck_reboot; 297027d934b2SSteven Rostedt 29716c5ee0beSSteven Rostedt } 29726c5ee0beSSteven Rostedt $in_patchcheck = 0; 29736c5ee0beSSteven Rostedt success $i; 29742b7d9b21SSteven Rostedt 29752b7d9b21SSteven Rostedt return 1; 29766c5ee0beSSteven Rostedt} 29776c5ee0beSSteven Rostedt 2978b9066f6cSSteven Rostedtmy %depends; 2979ac6974c7SSteven Rostedtmy %depcount; 2980b9066f6cSSteven Rostedtmy $iflevel = 0; 2981b9066f6cSSteven Rostedtmy @ifdeps; 2982b9066f6cSSteven Rostedt 2983b9066f6cSSteven Rostedt# prevent recursion 2984b9066f6cSSteven Rostedtmy %read_kconfigs; 2985b9066f6cSSteven Rostedt 2986ac6974c7SSteven Rostedtsub add_dep { 2987ac6974c7SSteven Rostedt # $config depends on $dep 2988ac6974c7SSteven Rostedt my ($config, $dep) = @_; 2989ac6974c7SSteven Rostedt 2990ac6974c7SSteven Rostedt if (defined($depends{$config})) { 2991ac6974c7SSteven Rostedt $depends{$config} .= " " . $dep; 2992ac6974c7SSteven Rostedt } else { 2993ac6974c7SSteven Rostedt $depends{$config} = $dep; 2994ac6974c7SSteven Rostedt } 2995ac6974c7SSteven Rostedt 2996ac6974c7SSteven Rostedt # record the number of configs depending on $dep 2997ac6974c7SSteven Rostedt if (defined $depcount{$dep}) { 2998ac6974c7SSteven Rostedt $depcount{$dep}++; 2999ac6974c7SSteven Rostedt } else { 3000ac6974c7SSteven Rostedt $depcount{$dep} = 1; 3001ac6974c7SSteven Rostedt } 3002ac6974c7SSteven Rostedt} 3003ac6974c7SSteven Rostedt 3004b9066f6cSSteven Rostedt# taken from streamline_config.pl 3005b9066f6cSSteven Rostedtsub read_kconfig { 3006b9066f6cSSteven Rostedt my ($kconfig) = @_; 3007b9066f6cSSteven Rostedt 3008b9066f6cSSteven Rostedt my $state = "NONE"; 3009b9066f6cSSteven Rostedt my $config; 3010b9066f6cSSteven Rostedt my @kconfigs; 3011b9066f6cSSteven Rostedt 3012b9066f6cSSteven Rostedt my $cont = 0; 3013b9066f6cSSteven Rostedt my $line; 3014b9066f6cSSteven Rostedt 3015b9066f6cSSteven Rostedt 3016b9066f6cSSteven Rostedt if (! -f $kconfig) { 3017b9066f6cSSteven Rostedt doprint "file $kconfig does not exist, skipping\n"; 3018b9066f6cSSteven Rostedt return; 3019b9066f6cSSteven Rostedt } 3020b9066f6cSSteven Rostedt 3021b9066f6cSSteven Rostedt open(KIN, "$kconfig") 3022b9066f6cSSteven Rostedt or die "Can't open $kconfig"; 3023b9066f6cSSteven Rostedt while (<KIN>) { 3024b9066f6cSSteven Rostedt chomp; 3025b9066f6cSSteven Rostedt 3026b9066f6cSSteven Rostedt # Make sure that lines ending with \ continue 3027b9066f6cSSteven Rostedt if ($cont) { 3028b9066f6cSSteven Rostedt $_ = $line . " " . $_; 3029b9066f6cSSteven Rostedt } 3030b9066f6cSSteven Rostedt 3031b9066f6cSSteven Rostedt if (s/\\$//) { 3032b9066f6cSSteven Rostedt $cont = 1; 3033b9066f6cSSteven Rostedt $line = $_; 3034b9066f6cSSteven Rostedt next; 3035b9066f6cSSteven Rostedt } 3036b9066f6cSSteven Rostedt 3037b9066f6cSSteven Rostedt $cont = 0; 3038b9066f6cSSteven Rostedt 3039b9066f6cSSteven Rostedt # collect any Kconfig sources 3040b9066f6cSSteven Rostedt if (/^source\s*"(.*)"/) { 3041b9066f6cSSteven Rostedt $kconfigs[$#kconfigs+1] = $1; 3042b9066f6cSSteven Rostedt } 3043b9066f6cSSteven Rostedt 3044b9066f6cSSteven Rostedt # configs found 3045b9066f6cSSteven Rostedt if (/^\s*(menu)?config\s+(\S+)\s*$/) { 3046b9066f6cSSteven Rostedt $state = "NEW"; 3047b9066f6cSSteven Rostedt $config = $2; 3048b9066f6cSSteven Rostedt 3049b9066f6cSSteven Rostedt for (my $i = 0; $i < $iflevel; $i++) { 3050ac6974c7SSteven Rostedt add_dep $config, $ifdeps[$i]; 3051b9066f6cSSteven Rostedt } 3052b9066f6cSSteven Rostedt 3053b9066f6cSSteven Rostedt # collect the depends for the config 3054b9066f6cSSteven Rostedt } elsif ($state eq "NEW" && /^\s*depends\s+on\s+(.*)$/) { 3055b9066f6cSSteven Rostedt 3056ac6974c7SSteven Rostedt add_dep $config, $1; 3057b9066f6cSSteven Rostedt 3058b9066f6cSSteven Rostedt # Get the configs that select this config 3059ac6974c7SSteven Rostedt } elsif ($state eq "NEW" && /^\s*select\s+(\S+)/) { 3060ac6974c7SSteven Rostedt 3061ac6974c7SSteven Rostedt # selected by depends on config 3062ac6974c7SSteven Rostedt add_dep $1, $config; 3063b9066f6cSSteven Rostedt 3064b9066f6cSSteven Rostedt # Check for if statements 3065b9066f6cSSteven Rostedt } elsif (/^if\s+(.*\S)\s*$/) { 3066b9066f6cSSteven Rostedt my $deps = $1; 3067b9066f6cSSteven Rostedt # remove beginning and ending non text 3068b9066f6cSSteven Rostedt $deps =~ s/^[^a-zA-Z0-9_]*//; 3069b9066f6cSSteven Rostedt $deps =~ s/[^a-zA-Z0-9_]*$//; 3070b9066f6cSSteven Rostedt 3071b9066f6cSSteven Rostedt my @deps = split /[^a-zA-Z0-9_]+/, $deps; 3072b9066f6cSSteven Rostedt 3073b9066f6cSSteven Rostedt $ifdeps[$iflevel++] = join ':', @deps; 3074b9066f6cSSteven Rostedt 3075b9066f6cSSteven Rostedt } elsif (/^endif/) { 3076b9066f6cSSteven Rostedt 3077b9066f6cSSteven Rostedt $iflevel-- if ($iflevel); 3078b9066f6cSSteven Rostedt 3079b9066f6cSSteven Rostedt # stop on "help" 3080b9066f6cSSteven Rostedt } elsif (/^\s*help\s*$/) { 3081b9066f6cSSteven Rostedt $state = "NONE"; 3082b9066f6cSSteven Rostedt } 3083b9066f6cSSteven Rostedt } 3084b9066f6cSSteven Rostedt close(KIN); 3085b9066f6cSSteven Rostedt 3086b9066f6cSSteven Rostedt # read in any configs that were found. 3087b9066f6cSSteven Rostedt foreach $kconfig (@kconfigs) { 3088b9066f6cSSteven Rostedt if (!defined($read_kconfigs{$kconfig})) { 3089b9066f6cSSteven Rostedt $read_kconfigs{$kconfig} = 1; 3090b9066f6cSSteven Rostedt read_kconfig("$builddir/$kconfig"); 3091b9066f6cSSteven Rostedt } 3092b9066f6cSSteven Rostedt } 3093b9066f6cSSteven Rostedt} 3094b9066f6cSSteven Rostedt 3095b9066f6cSSteven Rostedtsub read_depends { 3096b9066f6cSSteven Rostedt # find out which arch this is by the kconfig file 3097b9066f6cSSteven Rostedt open (IN, $output_config) 3098b9066f6cSSteven Rostedt or dodie "Failed to read $output_config"; 3099b9066f6cSSteven Rostedt my $arch; 3100b9066f6cSSteven Rostedt while (<IN>) { 3101b9066f6cSSteven Rostedt if (m,Linux/(\S+)\s+\S+\s+Kernel Configuration,) { 3102b9066f6cSSteven Rostedt $arch = $1; 3103b9066f6cSSteven Rostedt last; 3104b9066f6cSSteven Rostedt } 3105b9066f6cSSteven Rostedt } 3106b9066f6cSSteven Rostedt close IN; 3107b9066f6cSSteven Rostedt 3108b9066f6cSSteven Rostedt if (!defined($arch)) { 3109b9066f6cSSteven Rostedt doprint "Could not find arch from config file\n"; 3110b9066f6cSSteven Rostedt doprint "no dependencies used\n"; 3111b9066f6cSSteven Rostedt return; 3112b9066f6cSSteven Rostedt } 3113b9066f6cSSteven Rostedt 3114b9066f6cSSteven Rostedt # arch is really the subarch, we need to know 3115b9066f6cSSteven Rostedt # what directory to look at. 3116b9066f6cSSteven Rostedt if ($arch eq "i386" || $arch eq "x86_64") { 3117b9066f6cSSteven Rostedt $arch = "x86"; 3118b9066f6cSSteven Rostedt } elsif ($arch =~ /^tile/) { 3119b9066f6cSSteven Rostedt $arch = "tile"; 3120b9066f6cSSteven Rostedt } 3121b9066f6cSSteven Rostedt 3122b9066f6cSSteven Rostedt my $kconfig = "$builddir/arch/$arch/Kconfig"; 3123b9066f6cSSteven Rostedt 3124b9066f6cSSteven Rostedt if (! -f $kconfig && $arch =~ /\d$/) { 3125b9066f6cSSteven Rostedt my $orig = $arch; 3126b9066f6cSSteven Rostedt # some subarchs have numbers, truncate them 3127b9066f6cSSteven Rostedt $arch =~ s/\d*$//; 3128b9066f6cSSteven Rostedt $kconfig = "$builddir/arch/$arch/Kconfig"; 3129b9066f6cSSteven Rostedt if (! -f $kconfig) { 3130b9066f6cSSteven Rostedt doprint "No idea what arch dir $orig is for\n"; 3131b9066f6cSSteven Rostedt doprint "no dependencies used\n"; 3132b9066f6cSSteven Rostedt return; 3133b9066f6cSSteven Rostedt } 3134b9066f6cSSteven Rostedt } 3135b9066f6cSSteven Rostedt 3136b9066f6cSSteven Rostedt read_kconfig($kconfig); 3137b9066f6cSSteven Rostedt} 3138b9066f6cSSteven Rostedt 31394c4ab120SSteven Rostedtsub read_config_list { 31404c4ab120SSteven Rostedt my ($config) = @_; 31414c4ab120SSteven Rostedt 31424c4ab120SSteven Rostedt open (IN, $config) 31434c4ab120SSteven Rostedt or dodie "Failed to read $config"; 31444c4ab120SSteven Rostedt 31454c4ab120SSteven Rostedt while (<IN>) { 31464c4ab120SSteven Rostedt if (/^((CONFIG\S*)=.*)/) { 31474c4ab120SSteven Rostedt if (!defined($config_ignore{$2})) { 31484c4ab120SSteven Rostedt $config_list{$2} = $1; 31494c4ab120SSteven Rostedt } 31504c4ab120SSteven Rostedt } 31514c4ab120SSteven Rostedt } 31524c4ab120SSteven Rostedt 31534c4ab120SSteven Rostedt close(IN); 31544c4ab120SSteven Rostedt} 31554c4ab120SSteven Rostedt 31564c4ab120SSteven Rostedtsub read_output_config { 31574c4ab120SSteven Rostedt my ($config) = @_; 31584c4ab120SSteven Rostedt 31594c4ab120SSteven Rostedt assign_configs \%config_ignore, $config; 31604c4ab120SSteven Rostedt} 31614c4ab120SSteven Rostedt 31624c4ab120SSteven Rostedtsub make_new_config { 31634c4ab120SSteven Rostedt my @configs = @_; 31644c4ab120SSteven Rostedt 31654c4ab120SSteven Rostedt open (OUT, ">$output_config") 31664c4ab120SSteven Rostedt or dodie "Failed to write $output_config"; 31674c4ab120SSteven Rostedt 31684c4ab120SSteven Rostedt foreach my $config (@configs) { 31694c4ab120SSteven Rostedt print OUT "$config\n"; 31704c4ab120SSteven Rostedt } 31714c4ab120SSteven Rostedt close OUT; 31724c4ab120SSteven Rostedt} 31734c4ab120SSteven Rostedt 3174ac6974c7SSteven Rostedtsub chomp_config { 3175ac6974c7SSteven Rostedt my ($config) = @_; 3176ac6974c7SSteven Rostedt 3177ac6974c7SSteven Rostedt $config =~ s/CONFIG_//; 3178ac6974c7SSteven Rostedt 3179ac6974c7SSteven Rostedt return $config; 3180ac6974c7SSteven Rostedt} 3181ac6974c7SSteven Rostedt 3182b9066f6cSSteven Rostedtsub get_depends { 3183b9066f6cSSteven Rostedt my ($dep) = @_; 3184b9066f6cSSteven Rostedt 3185ac6974c7SSteven Rostedt my $kconfig = chomp_config $dep; 3186b9066f6cSSteven Rostedt 3187b9066f6cSSteven Rostedt $dep = $depends{"$kconfig"}; 3188b9066f6cSSteven Rostedt 3189b9066f6cSSteven Rostedt # the dep string we have saves the dependencies as they 3190b9066f6cSSteven Rostedt # were found, including expressions like ! && ||. We 3191b9066f6cSSteven Rostedt # want to split this out into just an array of configs. 3192b9066f6cSSteven Rostedt 3193b9066f6cSSteven Rostedt my $valid = "A-Za-z_0-9"; 3194b9066f6cSSteven Rostedt 3195b9066f6cSSteven Rostedt my @configs; 3196b9066f6cSSteven Rostedt 3197b9066f6cSSteven Rostedt while ($dep =~ /[$valid]/) { 3198b9066f6cSSteven Rostedt 3199b9066f6cSSteven Rostedt if ($dep =~ /^[^$valid]*([$valid]+)/) { 3200b9066f6cSSteven Rostedt my $conf = "CONFIG_" . $1; 3201b9066f6cSSteven Rostedt 3202b9066f6cSSteven Rostedt $configs[$#configs + 1] = $conf; 3203b9066f6cSSteven Rostedt 3204b9066f6cSSteven Rostedt $dep =~ s/^[^$valid]*[$valid]+//; 3205b9066f6cSSteven Rostedt } else { 3206b9066f6cSSteven Rostedt die "this should never happen"; 3207b9066f6cSSteven Rostedt } 3208b9066f6cSSteven Rostedt } 3209b9066f6cSSteven Rostedt 3210b9066f6cSSteven Rostedt return @configs; 3211b9066f6cSSteven Rostedt} 3212b9066f6cSSteven Rostedt 3213b9066f6cSSteven Rostedtmy %min_configs; 3214b9066f6cSSteven Rostedtmy %keep_configs; 321543d1b651SSteven Rostedtmy %save_configs; 3216b9066f6cSSteven Rostedtmy %processed_configs; 3217b9066f6cSSteven Rostedtmy %nochange_config; 3218b9066f6cSSteven Rostedt 3219b9066f6cSSteven Rostedtsub test_this_config { 3220b9066f6cSSteven Rostedt my ($config) = @_; 3221b9066f6cSSteven Rostedt 3222b9066f6cSSteven Rostedt my $found; 3223b9066f6cSSteven Rostedt 3224b9066f6cSSteven Rostedt # if we already processed this config, skip it 3225b9066f6cSSteven Rostedt if (defined($processed_configs{$config})) { 3226b9066f6cSSteven Rostedt return undef; 3227b9066f6cSSteven Rostedt } 3228b9066f6cSSteven Rostedt $processed_configs{$config} = 1; 3229b9066f6cSSteven Rostedt 3230b9066f6cSSteven Rostedt # if this config failed during this round, skip it 3231b9066f6cSSteven Rostedt if (defined($nochange_config{$config})) { 3232b9066f6cSSteven Rostedt return undef; 3233b9066f6cSSteven Rostedt } 3234b9066f6cSSteven Rostedt 3235ac6974c7SSteven Rostedt my $kconfig = chomp_config $config; 3236b9066f6cSSteven Rostedt 3237b9066f6cSSteven Rostedt # Test dependencies first 3238b9066f6cSSteven Rostedt if (defined($depends{"$kconfig"})) { 3239b9066f6cSSteven Rostedt my @parents = get_depends $config; 3240b9066f6cSSteven Rostedt foreach my $parent (@parents) { 3241b9066f6cSSteven Rostedt # if the parent is in the min config, check it first 3242b9066f6cSSteven Rostedt next if (!defined($min_configs{$parent})); 3243b9066f6cSSteven Rostedt $found = test_this_config($parent); 3244b9066f6cSSteven Rostedt if (defined($found)) { 3245b9066f6cSSteven Rostedt return $found; 3246b9066f6cSSteven Rostedt } 3247b9066f6cSSteven Rostedt } 3248b9066f6cSSteven Rostedt } 3249b9066f6cSSteven Rostedt 3250b9066f6cSSteven Rostedt # Remove this config from the list of configs 3251b9066f6cSSteven Rostedt # do a make oldnoconfig and then read the resulting 3252b9066f6cSSteven Rostedt # .config to make sure it is missing the config that 3253b9066f6cSSteven Rostedt # we had before 3254b9066f6cSSteven Rostedt my %configs = %min_configs; 3255b9066f6cSSteven Rostedt delete $configs{$config}; 3256b9066f6cSSteven Rostedt make_new_config ((values %configs), (values %keep_configs)); 3257b9066f6cSSteven Rostedt make_oldconfig; 3258b9066f6cSSteven Rostedt undef %configs; 3259b9066f6cSSteven Rostedt assign_configs \%configs, $output_config; 3260b9066f6cSSteven Rostedt 3261b9066f6cSSteven Rostedt return $config if (!defined($configs{$config})); 3262b9066f6cSSteven Rostedt 3263b9066f6cSSteven Rostedt doprint "disabling config $config did not change .config\n"; 3264b9066f6cSSteven Rostedt 3265b9066f6cSSteven Rostedt $nochange_config{$config} = 1; 3266b9066f6cSSteven Rostedt 3267b9066f6cSSteven Rostedt return undef; 3268b9066f6cSSteven Rostedt} 3269b9066f6cSSteven Rostedt 32704c4ab120SSteven Rostedtsub make_min_config { 32714c4ab120SSteven Rostedt my ($i) = @_; 32724c4ab120SSteven Rostedt 3273ccc513b6SSteven Rostedt my $type = $minconfig_type; 3274ccc513b6SSteven Rostedt if ($type ne "boot" && $type ne "test") { 3275ccc513b6SSteven Rostedt fail "Invalid MIN_CONFIG_TYPE '$minconfig_type'\n" . 3276ccc513b6SSteven Rostedt " make_min_config works only with 'boot' and 'test'\n" and return; 3277ccc513b6SSteven Rostedt } 3278ccc513b6SSteven Rostedt 32794c4ab120SSteven Rostedt if (!defined($output_minconfig)) { 32804c4ab120SSteven Rostedt fail "OUTPUT_MIN_CONFIG not defined" and return; 32814c4ab120SSteven Rostedt } 328235ce5952SSteven Rostedt 328335ce5952SSteven Rostedt # If output_minconfig exists, and the start_minconfig 328435ce5952SSteven Rostedt # came from min_config, than ask if we should use 328535ce5952SSteven Rostedt # that instead. 328635ce5952SSteven Rostedt if (-f $output_minconfig && !$start_minconfig_defined) { 328735ce5952SSteven Rostedt print "$output_minconfig exists\n"; 328843de3316SSteven Rostedt if (!defined($use_output_minconfig)) { 328935ce5952SSteven Rostedt if (read_yn " Use it as minconfig?") { 329035ce5952SSteven Rostedt $start_minconfig = $output_minconfig; 329135ce5952SSteven Rostedt } 329243de3316SSteven Rostedt } elsif ($use_output_minconfig > 0) { 329343de3316SSteven Rostedt doprint "Using $output_minconfig as MIN_CONFIG\n"; 329443de3316SSteven Rostedt $start_minconfig = $output_minconfig; 329543de3316SSteven Rostedt } else { 329643de3316SSteven Rostedt doprint "Set to still use MIN_CONFIG as starting point\n"; 329743de3316SSteven Rostedt } 329835ce5952SSteven Rostedt } 329935ce5952SSteven Rostedt 33004c4ab120SSteven Rostedt if (!defined($start_minconfig)) { 33014c4ab120SSteven Rostedt fail "START_MIN_CONFIG or MIN_CONFIG not defined" and return; 33024c4ab120SSteven Rostedt } 33034c4ab120SSteven Rostedt 330435ce5952SSteven Rostedt my $temp_config = "$tmpdir/temp_config"; 330535ce5952SSteven Rostedt 33064c4ab120SSteven Rostedt # First things first. We build an allnoconfig to find 33074c4ab120SSteven Rostedt # out what the defaults are that we can't touch. 33084c4ab120SSteven Rostedt # Some are selections, but we really can't handle selections. 33094c4ab120SSteven Rostedt 33104c4ab120SSteven Rostedt my $save_minconfig = $minconfig; 33114c4ab120SSteven Rostedt undef $minconfig; 33124c4ab120SSteven Rostedt 33134c4ab120SSteven Rostedt run_command "$make allnoconfig" or return 0; 33144c4ab120SSteven Rostedt 3315b9066f6cSSteven Rostedt read_depends; 3316b9066f6cSSteven Rostedt 33174c4ab120SSteven Rostedt process_config_ignore $output_config; 3318b9066f6cSSteven Rostedt 331943d1b651SSteven Rostedt undef %save_configs; 3320b9066f6cSSteven Rostedt undef %min_configs; 33214c4ab120SSteven Rostedt 33224c4ab120SSteven Rostedt if (defined($ignore_config)) { 33234c4ab120SSteven Rostedt # make sure the file exists 33244c4ab120SSteven Rostedt `touch $ignore_config`; 332543d1b651SSteven Rostedt assign_configs \%save_configs, $ignore_config; 33264c4ab120SSteven Rostedt } 33274c4ab120SSteven Rostedt 332843d1b651SSteven Rostedt %keep_configs = %save_configs; 332943d1b651SSteven Rostedt 33304c4ab120SSteven Rostedt doprint "Load initial configs from $start_minconfig\n"; 33314c4ab120SSteven Rostedt 33324c4ab120SSteven Rostedt # Look at the current min configs, and save off all the 33334c4ab120SSteven Rostedt # ones that were set via the allnoconfig 33344c4ab120SSteven Rostedt assign_configs \%min_configs, $start_minconfig; 33354c4ab120SSteven Rostedt 33364c4ab120SSteven Rostedt my @config_keys = keys %min_configs; 33374c4ab120SSteven Rostedt 3338ac6974c7SSteven Rostedt # All configs need a depcount 3339ac6974c7SSteven Rostedt foreach my $config (@config_keys) { 3340ac6974c7SSteven Rostedt my $kconfig = chomp_config $config; 3341ac6974c7SSteven Rostedt if (!defined $depcount{$kconfig}) { 3342ac6974c7SSteven Rostedt $depcount{$kconfig} = 0; 3343ac6974c7SSteven Rostedt } 3344ac6974c7SSteven Rostedt } 3345ac6974c7SSteven Rostedt 33464c4ab120SSteven Rostedt # Remove anything that was set by the make allnoconfig 33474c4ab120SSteven Rostedt # we shouldn't need them as they get set for us anyway. 33484c4ab120SSteven Rostedt foreach my $config (@config_keys) { 33494c4ab120SSteven Rostedt # Remove anything in the ignore_config 33504c4ab120SSteven Rostedt if (defined($keep_configs{$config})) { 33514c4ab120SSteven Rostedt my $file = $ignore_config; 33524c4ab120SSteven Rostedt $file =~ s,.*/(.*?)$,$1,; 33534c4ab120SSteven Rostedt doprint "$config set by $file ... ignored\n"; 33544c4ab120SSteven Rostedt delete $min_configs{$config}; 33554c4ab120SSteven Rostedt next; 33564c4ab120SSteven Rostedt } 33574c4ab120SSteven Rostedt # But make sure the settings are the same. If a min config 33584c4ab120SSteven Rostedt # sets a selection, we do not want to get rid of it if 33594c4ab120SSteven Rostedt # it is not the same as what we have. Just move it into 33604c4ab120SSteven Rostedt # the keep configs. 33614c4ab120SSteven Rostedt if (defined($config_ignore{$config})) { 33624c4ab120SSteven Rostedt if ($config_ignore{$config} ne $min_configs{$config}) { 33634c4ab120SSteven Rostedt doprint "$config is in allnoconfig as '$config_ignore{$config}'"; 33644c4ab120SSteven Rostedt doprint " but it is '$min_configs{$config}' in minconfig .. keeping\n"; 33654c4ab120SSteven Rostedt $keep_configs{$config} = $min_configs{$config}; 33664c4ab120SSteven Rostedt } else { 33674c4ab120SSteven Rostedt doprint "$config set by allnoconfig ... ignored\n"; 33684c4ab120SSteven Rostedt } 33694c4ab120SSteven Rostedt delete $min_configs{$config}; 33704c4ab120SSteven Rostedt } 33714c4ab120SSteven Rostedt } 33724c4ab120SSteven Rostedt 33734c4ab120SSteven Rostedt my $done = 0; 3374b9066f6cSSteven Rostedt my $take_two = 0; 33754c4ab120SSteven Rostedt 33764c4ab120SSteven Rostedt while (!$done) { 33774c4ab120SSteven Rostedt 33784c4ab120SSteven Rostedt my $config; 33794c4ab120SSteven Rostedt my $found; 33804c4ab120SSteven Rostedt 33814c4ab120SSteven Rostedt # Now disable each config one by one and do a make oldconfig 33824c4ab120SSteven Rostedt # till we find a config that changes our list. 33834c4ab120SSteven Rostedt 33844c4ab120SSteven Rostedt my @test_configs = keys %min_configs; 3385ac6974c7SSteven Rostedt 3386ac6974c7SSteven Rostedt # Sort keys by who is most dependent on 3387ac6974c7SSteven Rostedt @test_configs = sort { $depcount{chomp_config($b)} <=> $depcount{chomp_config($a)} } 3388ac6974c7SSteven Rostedt @test_configs ; 3389ac6974c7SSteven Rostedt 3390ac6974c7SSteven Rostedt # Put configs that did not modify the config at the end. 33914c4ab120SSteven Rostedt my $reset = 1; 33924c4ab120SSteven Rostedt for (my $i = 0; $i < $#test_configs; $i++) { 33934c4ab120SSteven Rostedt if (!defined($nochange_config{$test_configs[0]})) { 33944c4ab120SSteven Rostedt $reset = 0; 33954c4ab120SSteven Rostedt last; 33964c4ab120SSteven Rostedt } 33974c4ab120SSteven Rostedt # This config didn't change the .config last time. 33984c4ab120SSteven Rostedt # Place it at the end 33994c4ab120SSteven Rostedt my $config = shift @test_configs; 34004c4ab120SSteven Rostedt push @test_configs, $config; 34014c4ab120SSteven Rostedt } 34024c4ab120SSteven Rostedt 34034c4ab120SSteven Rostedt # if every test config has failed to modify the .config file 34044c4ab120SSteven Rostedt # in the past, then reset and start over. 34054c4ab120SSteven Rostedt if ($reset) { 34064c4ab120SSteven Rostedt undef %nochange_config; 34074c4ab120SSteven Rostedt } 34084c4ab120SSteven Rostedt 3409b9066f6cSSteven Rostedt undef %processed_configs; 3410b9066f6cSSteven Rostedt 34114c4ab120SSteven Rostedt foreach my $config (@test_configs) { 34124c4ab120SSteven Rostedt 3413b9066f6cSSteven Rostedt $found = test_this_config $config; 34144c4ab120SSteven Rostedt 3415b9066f6cSSteven Rostedt last if (defined($found)); 34164c4ab120SSteven Rostedt 34174c4ab120SSteven Rostedt # oh well, try another config 34184c4ab120SSteven Rostedt } 34194c4ab120SSteven Rostedt 34204c4ab120SSteven Rostedt if (!defined($found)) { 3421b9066f6cSSteven Rostedt # we could have failed due to the nochange_config hash 3422b9066f6cSSteven Rostedt # reset and try again 3423b9066f6cSSteven Rostedt if (!$take_two) { 3424b9066f6cSSteven Rostedt undef %nochange_config; 3425b9066f6cSSteven Rostedt $take_two = 1; 3426b9066f6cSSteven Rostedt next; 3427b9066f6cSSteven Rostedt } 34284c4ab120SSteven Rostedt doprint "No more configs found that we can disable\n"; 34294c4ab120SSteven Rostedt $done = 1; 34304c4ab120SSteven Rostedt last; 34314c4ab120SSteven Rostedt } 3432b9066f6cSSteven Rostedt $take_two = 0; 34334c4ab120SSteven Rostedt 34344c4ab120SSteven Rostedt $config = $found; 34354c4ab120SSteven Rostedt 34364c4ab120SSteven Rostedt doprint "Test with $config disabled\n"; 34374c4ab120SSteven Rostedt 34384c4ab120SSteven Rostedt # set in_bisect to keep build and monitor from dieing 34394c4ab120SSteven Rostedt $in_bisect = 1; 34404c4ab120SSteven Rostedt 34414c4ab120SSteven Rostedt my $failed = 0; 3442bf1c95abSSteven Rostedt build "oldconfig" or $failed = 1; 3443bf1c95abSSteven Rostedt if (!$failed) { 34444c4ab120SSteven Rostedt start_monitor_and_boot or $failed = 1; 3445ccc513b6SSteven Rostedt 3446ccc513b6SSteven Rostedt if ($type eq "test" && !$failed) { 3447ccc513b6SSteven Rostedt do_run_test or $failed = 1; 3448ccc513b6SSteven Rostedt } 3449ccc513b6SSteven Rostedt 34504c4ab120SSteven Rostedt end_monitor; 3451bf1c95abSSteven Rostedt } 34524c4ab120SSteven Rostedt 34534c4ab120SSteven Rostedt $in_bisect = 0; 34544c4ab120SSteven Rostedt 34554c4ab120SSteven Rostedt if ($failed) { 3456b9066f6cSSteven Rostedt doprint "$min_configs{$config} is needed to boot the box... keeping\n"; 34574c4ab120SSteven Rostedt # this config is needed, add it to the ignore list. 34584c4ab120SSteven Rostedt $keep_configs{$config} = $min_configs{$config}; 345943d1b651SSteven Rostedt $save_configs{$config} = $min_configs{$config}; 34604c4ab120SSteven Rostedt delete $min_configs{$config}; 346135ce5952SSteven Rostedt 346235ce5952SSteven Rostedt # update new ignore configs 346335ce5952SSteven Rostedt if (defined($ignore_config)) { 346435ce5952SSteven Rostedt open (OUT, ">$temp_config") 346535ce5952SSteven Rostedt or die "Can't write to $temp_config"; 346643d1b651SSteven Rostedt foreach my $config (keys %save_configs) { 346743d1b651SSteven Rostedt print OUT "$save_configs{$config}\n"; 346835ce5952SSteven Rostedt } 346935ce5952SSteven Rostedt close OUT; 347035ce5952SSteven Rostedt run_command "mv $temp_config $ignore_config" or 347135ce5952SSteven Rostedt dodie "failed to copy update to $ignore_config"; 347235ce5952SSteven Rostedt } 347335ce5952SSteven Rostedt 34744c4ab120SSteven Rostedt } else { 34754c4ab120SSteven Rostedt # We booted without this config, remove it from the minconfigs. 34764c4ab120SSteven Rostedt doprint "$config is not needed, disabling\n"; 34774c4ab120SSteven Rostedt 34784c4ab120SSteven Rostedt delete $min_configs{$config}; 34794c4ab120SSteven Rostedt 34804c4ab120SSteven Rostedt # Also disable anything that is not enabled in this config 34814c4ab120SSteven Rostedt my %configs; 34824c4ab120SSteven Rostedt assign_configs \%configs, $output_config; 34834c4ab120SSteven Rostedt my @config_keys = keys %min_configs; 34844c4ab120SSteven Rostedt foreach my $config (@config_keys) { 34854c4ab120SSteven Rostedt if (!defined($configs{$config})) { 34864c4ab120SSteven Rostedt doprint "$config is not set, disabling\n"; 34874c4ab120SSteven Rostedt delete $min_configs{$config}; 34884c4ab120SSteven Rostedt } 34894c4ab120SSteven Rostedt } 34904c4ab120SSteven Rostedt 34914c4ab120SSteven Rostedt # Save off all the current mandidory configs 349235ce5952SSteven Rostedt open (OUT, ">$temp_config") 349335ce5952SSteven Rostedt or die "Can't write to $temp_config"; 34944c4ab120SSteven Rostedt foreach my $config (keys %keep_configs) { 34954c4ab120SSteven Rostedt print OUT "$keep_configs{$config}\n"; 34964c4ab120SSteven Rostedt } 34974c4ab120SSteven Rostedt foreach my $config (keys %min_configs) { 34984c4ab120SSteven Rostedt print OUT "$min_configs{$config}\n"; 34994c4ab120SSteven Rostedt } 35004c4ab120SSteven Rostedt close OUT; 350135ce5952SSteven Rostedt 350235ce5952SSteven Rostedt run_command "mv $temp_config $output_minconfig" or 350335ce5952SSteven Rostedt dodie "failed to copy update to $output_minconfig"; 35044c4ab120SSteven Rostedt } 35054c4ab120SSteven Rostedt 35064c4ab120SSteven Rostedt doprint "Reboot and wait $sleep_time seconds\n"; 3507bc7c5803SSteven Rostedt reboot_to_good $sleep_time; 35084c4ab120SSteven Rostedt } 35094c4ab120SSteven Rostedt 35104c4ab120SSteven Rostedt success $i; 35114c4ab120SSteven Rostedt return 1; 35124c4ab120SSteven Rostedt} 35134c4ab120SSteven Rostedt 35148d1491baSSteven Rostedt$#ARGV < 1 or die "ktest.pl version: $VERSION\n usage: ktest.pl config-file\n"; 35152545eb61SSteven Rostedt 35168d1491baSSteven Rostedtif ($#ARGV == 0) { 35178d1491baSSteven Rostedt $ktest_config = $ARGV[0]; 35188d1491baSSteven Rostedt if (! -f $ktest_config) { 35198d1491baSSteven Rostedt print "$ktest_config does not exist.\n"; 352035ce5952SSteven Rostedt if (!read_yn "Create it?") { 35218d1491baSSteven Rostedt exit 0; 35228d1491baSSteven Rostedt } 35238d1491baSSteven Rostedt } 35248d1491baSSteven Rostedt} else { 35258d1491baSSteven Rostedt $ktest_config = "ktest.conf"; 35268d1491baSSteven Rostedt} 35278d1491baSSteven Rostedt 35288d1491baSSteven Rostedtif (! -f $ktest_config) { 3529dbd3783bSSteven Rostedt $newconfig = 1; 3530c4261d0fSSteven Rostedt get_test_case; 35318d1491baSSteven Rostedt open(OUT, ">$ktest_config") or die "Can not create $ktest_config"; 35328d1491baSSteven Rostedt print OUT << "EOF" 35338d1491baSSteven Rostedt# Generated by ktest.pl 35348d1491baSSteven Rostedt# 35350e7a22deSSteven Rostedt 35360e7a22deSSteven Rostedt# PWD is a ktest.pl variable that will result in the process working 35370e7a22deSSteven Rostedt# directory that ktest.pl is executed in. 35380e7a22deSSteven Rostedt 35390e7a22deSSteven Rostedt# THIS_DIR is automatically assigned the PWD of the path that generated 35400e7a22deSSteven Rostedt# the config file. It is best to use this variable when assigning other 35410e7a22deSSteven Rostedt# directory paths within this directory. This allows you to easily 35420e7a22deSSteven Rostedt# move the test cases to other locations or to other machines. 35430e7a22deSSteven Rostedt# 35440e7a22deSSteven RostedtTHIS_DIR := $variable{"PWD"} 35450e7a22deSSteven Rostedt 35468d1491baSSteven Rostedt# Define each test with TEST_START 35478d1491baSSteven Rostedt# The config options below it will override the defaults 35488d1491baSSteven RostedtTEST_START 3549c4261d0fSSteven RostedtTEST_TYPE = $default{"TEST_TYPE"} 35508d1491baSSteven Rostedt 35518d1491baSSteven RostedtDEFAULTS 35528d1491baSSteven RostedtEOF 35538d1491baSSteven Rostedt; 35548d1491baSSteven Rostedt close(OUT); 35558d1491baSSteven Rostedt} 35568d1491baSSteven Rostedtread_config $ktest_config; 35578d1491baSSteven Rostedt 355823715c3cSSteven Rostedtif (defined($opt{"LOG_FILE"})) { 355923715c3cSSteven Rostedt $opt{"LOG_FILE"} = eval_option($opt{"LOG_FILE"}, -1); 356023715c3cSSteven Rostedt} 356123715c3cSSteven Rostedt 35628d1491baSSteven Rostedt# Append any configs entered in manually to the config file. 35638d1491baSSteven Rostedtmy @new_configs = keys %entered_configs; 35648d1491baSSteven Rostedtif ($#new_configs >= 0) { 35658d1491baSSteven Rostedt print "\nAppending entered in configs to $ktest_config\n"; 35668d1491baSSteven Rostedt open(OUT, ">>$ktest_config") or die "Can not append to $ktest_config"; 35678d1491baSSteven Rostedt foreach my $config (@new_configs) { 35688d1491baSSteven Rostedt print OUT "$config = $entered_configs{$config}\n"; 35690e7a22deSSteven Rostedt $opt{$config} = process_variables($entered_configs{$config}); 35708d1491baSSteven Rostedt } 35718d1491baSSteven Rostedt} 35722545eb61SSteven Rostedt 35732b7d9b21SSteven Rostedtif ($opt{"CLEAR_LOG"} && defined($opt{"LOG_FILE"})) { 35742b7d9b21SSteven Rostedt unlink $opt{"LOG_FILE"}; 35752b7d9b21SSteven Rostedt} 35762545eb61SSteven Rostedt 35772b7d9b21SSteven Rostedtdoprint "\n\nSTARTING AUTOMATED TESTS\n\n"; 35782b7d9b21SSteven Rostedt 3579a57419b3SSteven Rostedtfor (my $i = 0, my $repeat = 1; $i <= $opt{"NUM_TESTS"}; $i += $repeat) { 3580a57419b3SSteven Rostedt 3581a57419b3SSteven Rostedt if (!$i) { 3582a57419b3SSteven Rostedt doprint "DEFAULT OPTIONS:\n"; 3583a57419b3SSteven Rostedt } else { 3584a57419b3SSteven Rostedt doprint "\nTEST $i OPTIONS"; 3585a57419b3SSteven Rostedt if (defined($repeat_tests{$i})) { 3586a57419b3SSteven Rostedt $repeat = $repeat_tests{$i}; 3587a57419b3SSteven Rostedt doprint " ITERATE $repeat"; 3588a57419b3SSteven Rostedt } 3589a57419b3SSteven Rostedt doprint "\n"; 3590a57419b3SSteven Rostedt } 3591a57419b3SSteven Rostedt 35922b7d9b21SSteven Rostedt foreach my $option (sort keys %opt) { 3593a57419b3SSteven Rostedt 3594a57419b3SSteven Rostedt if ($option =~ /\[(\d+)\]$/) { 3595a57419b3SSteven Rostedt next if ($i != $1); 3596a57419b3SSteven Rostedt } else { 3597a57419b3SSteven Rostedt next if ($i); 3598a57419b3SSteven Rostedt } 3599a57419b3SSteven Rostedt 36002b7d9b21SSteven Rostedt doprint "$option = $opt{$option}\n"; 36012b7d9b21SSteven Rostedt } 3602a57419b3SSteven Rostedt} 36032545eb61SSteven Rostedt 36042a62512bSSteven Rostedtsub __set_test_option { 36055a391fbfSSteven Rostedt my ($name, $i) = @_; 36065a391fbfSSteven Rostedt 36075a391fbfSSteven Rostedt my $option = "$name\[$i\]"; 36085a391fbfSSteven Rostedt 36095a391fbfSSteven Rostedt if (defined($opt{$option})) { 36105a391fbfSSteven Rostedt return $opt{$option}; 36115a391fbfSSteven Rostedt } 36125a391fbfSSteven Rostedt 3613a57419b3SSteven Rostedt foreach my $test (keys %repeat_tests) { 3614a57419b3SSteven Rostedt if ($i >= $test && 3615a57419b3SSteven Rostedt $i < $test + $repeat_tests{$test}) { 3616a57419b3SSteven Rostedt $option = "$name\[$test\]"; 3617a57419b3SSteven Rostedt if (defined($opt{$option})) { 3618a57419b3SSteven Rostedt return $opt{$option}; 3619a57419b3SSteven Rostedt } 3620a57419b3SSteven Rostedt } 3621a57419b3SSteven Rostedt } 3622a57419b3SSteven Rostedt 36235a391fbfSSteven Rostedt if (defined($opt{$name})) { 36245a391fbfSSteven Rostedt return $opt{$name}; 36255a391fbfSSteven Rostedt } 36265a391fbfSSteven Rostedt 36275a391fbfSSteven Rostedt return undef; 36285a391fbfSSteven Rostedt} 36295a391fbfSSteven Rostedt 36302a62512bSSteven Rostedtsub set_test_option { 36312a62512bSSteven Rostedt my ($name, $i) = @_; 36322a62512bSSteven Rostedt 36332a62512bSSteven Rostedt my $option = __set_test_option($name, $i); 36342a62512bSSteven Rostedt return $option if (!defined($option)); 36352a62512bSSteven Rostedt 363623715c3cSSteven Rostedt return eval_option($option, $i); 36372a62512bSSteven Rostedt} 36382a62512bSSteven Rostedt 36392545eb61SSteven Rostedt# First we need to do is the builds 3640a75fececSSteven Rostedtfor (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) { 36412545eb61SSteven Rostedt 36424ab1cce5SSteven Rostedt # Do not reboot on failing test options 36434ab1cce5SSteven Rostedt $no_reboot = 1; 3644759a3cc6SSteven Rostedt $reboot_success = 0; 36454ab1cce5SSteven Rostedt 3646683a3e64SSteven Rostedt $have_version = 0; 3647683a3e64SSteven Rostedt 3648576f627cSSteven Rostedt $iteration = $i; 3649576f627cSSteven Rostedt 3650c1434dccSSteven Rostedt undef %force_config; 3651c1434dccSSteven Rostedt 3652a75fececSSteven Rostedt my $makecmd = set_test_option("MAKE_CMD", $i); 3653a75fececSSteven Rostedt 36549cc9e091SSteven Rostedt # Load all the options into their mapped variable names 36559cc9e091SSteven Rostedt foreach my $opt (keys %option_map) { 36569cc9e091SSteven Rostedt ${$option_map{$opt}} = set_test_option($opt, $i); 36579cc9e091SSteven Rostedt } 3658b5f4aea6SSteven Rostedt 365935ce5952SSteven Rostedt $start_minconfig_defined = 1; 366035ce5952SSteven Rostedt 3661921ed4c7SSteven Rostedt # The first test may override the PRE_KTEST option 3662921ed4c7SSteven Rostedt if (defined($pre_ktest) && $i == 1) { 3663921ed4c7SSteven Rostedt doprint "\n"; 3664921ed4c7SSteven Rostedt run_command $pre_ktest; 3665921ed4c7SSteven Rostedt } 3666921ed4c7SSteven Rostedt 3667921ed4c7SSteven Rostedt # Any test can override the POST_KTEST option 3668921ed4c7SSteven Rostedt # The last test takes precedence. 3669921ed4c7SSteven Rostedt if (defined($post_ktest)) { 3670921ed4c7SSteven Rostedt $final_post_ktest = $post_ktest; 3671921ed4c7SSteven Rostedt } 3672921ed4c7SSteven Rostedt 36734c4ab120SSteven Rostedt if (!defined($start_minconfig)) { 367435ce5952SSteven Rostedt $start_minconfig_defined = 0; 36754c4ab120SSteven Rostedt $start_minconfig = $minconfig; 36764c4ab120SSteven Rostedt } 36774c4ab120SSteven Rostedt 3678a75fececSSteven Rostedt chdir $builddir || die "can't change directory to $builddir"; 3679a75fececSSteven Rostedt 3680a908a665SAndrew Jones foreach my $dir ($tmpdir, $outputdir) { 3681a908a665SAndrew Jones if (!-d $dir) { 3682a908a665SAndrew Jones mkpath($dir) or 3683a908a665SAndrew Jones die "can't create $dir"; 3684a908a665SAndrew Jones } 3685a75fececSSteven Rostedt } 3686a75fececSSteven Rostedt 3687e48c5293SSteven Rostedt $ENV{"SSH_USER"} = $ssh_user; 3688e48c5293SSteven Rostedt $ENV{"MACHINE"} = $machine; 3689e48c5293SSteven Rostedt 3690a75fececSSteven Rostedt $buildlog = "$tmpdir/buildlog-$machine"; 3691a9dd5d63SRabin Vincent $testlog = "$tmpdir/testlog-$machine"; 3692a75fececSSteven Rostedt $dmesg = "$tmpdir/dmesg-$machine"; 3693a75fececSSteven Rostedt $make = "$makecmd O=$outputdir"; 369451ad1dd1SSteven Rostedt $output_config = "$outputdir/.config"; 3695a75fececSSteven Rostedt 3696bb8474b1SSteven Rostedt if (!$buildonly) { 3697bb8474b1SSteven Rostedt $target = "$ssh_user\@$machine"; 3698a75fececSSteven Rostedt if ($reboot_type eq "grub") { 3699576f627cSSteven Rostedt dodie "GRUB_MENU not defined" if (!defined($grub_menu)); 3700a75fececSSteven Rostedt } 3701bb8474b1SSteven Rostedt } 3702a75fececSSteven Rostedt 3703a75fececSSteven Rostedt my $run_type = $build_type; 3704a75fececSSteven Rostedt if ($test_type eq "patchcheck") { 3705b5f4aea6SSteven Rostedt $run_type = $patchcheck_type; 3706a75fececSSteven Rostedt } elsif ($test_type eq "bisect") { 3707b5f4aea6SSteven Rostedt $run_type = $bisect_type; 37080a05c769SSteven Rostedt } elsif ($test_type eq "config_bisect") { 3709b5f4aea6SSteven Rostedt $run_type = $config_bisect_type; 3710a75fececSSteven Rostedt } 3711a75fececSSteven Rostedt 37124c4ab120SSteven Rostedt if ($test_type eq "make_min_config") { 37134c4ab120SSteven Rostedt $run_type = ""; 37144c4ab120SSteven Rostedt } 37154c4ab120SSteven Rostedt 3716a75fececSSteven Rostedt # mistake in config file? 3717a75fececSSteven Rostedt if (!defined($run_type)) { 3718a75fececSSteven Rostedt $run_type = "ERROR"; 3719a75fececSSteven Rostedt } 37202545eb61SSteven Rostedt 3721e0a8742eSSteven Rostedt my $installme = ""; 3722e0a8742eSSteven Rostedt $installme = " no_install" if ($no_install); 3723e0a8742eSSteven Rostedt 37242545eb61SSteven Rostedt doprint "\n\n"; 3725e0a8742eSSteven Rostedt doprint "RUNNING TEST $i of $opt{NUM_TESTS} with option $test_type $run_type$installme\n\n"; 37267faafbd6SSteven Rostedt 3727921ed4c7SSteven Rostedt if (defined($pre_test)) { 3728921ed4c7SSteven Rostedt run_command $pre_test; 3729921ed4c7SSteven Rostedt } 3730921ed4c7SSteven Rostedt 37317faafbd6SSteven Rostedt unlink $dmesg; 37327faafbd6SSteven Rostedt unlink $buildlog; 3733a9dd5d63SRabin Vincent unlink $testlog; 37342545eb61SSteven Rostedt 3735250bae8bSSteven Rostedt if (defined($addconfig)) { 3736250bae8bSSteven Rostedt my $min = $minconfig; 37372b7d9b21SSteven Rostedt if (!defined($minconfig)) { 3738250bae8bSSteven Rostedt $min = ""; 3739250bae8bSSteven Rostedt } 3740250bae8bSSteven Rostedt run_command "cat $addconfig $min > $tmpdir/add_config" or 37412b7d9b21SSteven Rostedt dodie "Failed to create temp config"; 37429be2e6b5SSteven Rostedt $minconfig = "$tmpdir/add_config"; 37432b7d9b21SSteven Rostedt } 37442b7d9b21SSteven Rostedt 37456c5ee0beSSteven Rostedt if (defined($checkout)) { 37466c5ee0beSSteven Rostedt run_command "git checkout $checkout" or 37476c5ee0beSSteven Rostedt die "failed to checkout $checkout"; 37486c5ee0beSSteven Rostedt } 37496c5ee0beSSteven Rostedt 3750759a3cc6SSteven Rostedt $no_reboot = 0; 3751759a3cc6SSteven Rostedt 3752648a182cSSteven Rostedt # A test may opt to not reboot the box 3753648a182cSSteven Rostedt if ($reboot_on_success) { 3754759a3cc6SSteven Rostedt $reboot_success = 1; 3755648a182cSSteven Rostedt } 37564ab1cce5SSteven Rostedt 3757a75fececSSteven Rostedt if ($test_type eq "bisect") { 37585f9b6cedSSteven Rostedt bisect $i; 37595f9b6cedSSteven Rostedt next; 37600a05c769SSteven Rostedt } elsif ($test_type eq "config_bisect") { 37610a05c769SSteven Rostedt config_bisect $i; 37620a05c769SSteven Rostedt next; 3763a75fececSSteven Rostedt } elsif ($test_type eq "patchcheck") { 37646c5ee0beSSteven Rostedt patchcheck $i; 37656c5ee0beSSteven Rostedt next; 37664c4ab120SSteven Rostedt } elsif ($test_type eq "make_min_config") { 37674c4ab120SSteven Rostedt make_min_config $i; 37684c4ab120SSteven Rostedt next; 37695f9b6cedSSteven Rostedt } 37705f9b6cedSSteven Rostedt 37717faafbd6SSteven Rostedt if ($build_type ne "nobuild") { 37727faafbd6SSteven Rostedt build $build_type or next; 37732545eb61SSteven Rostedt } 37742545eb61SSteven Rostedt 3775cd8e368fSSteven Rostedt if ($test_type eq "install") { 3776cd8e368fSSteven Rostedt get_version; 3777cd8e368fSSteven Rostedt install; 3778cd8e368fSSteven Rostedt success $i; 3779cd8e368fSSteven Rostedt next; 3780cd8e368fSSteven Rostedt } 3781cd8e368fSSteven Rostedt 3782a75fececSSteven Rostedt if ($test_type ne "build") { 37837faafbd6SSteven Rostedt my $failed = 0; 3784ddf607e5SSteven Rostedt start_monitor_and_boot or $failed = 1; 3785a75fececSSteven Rostedt 3786a75fececSSteven Rostedt if (!$failed && $test_type ne "boot" && defined($run_test)) { 37877faafbd6SSteven Rostedt do_run_test or $failed = 1; 37885a391fbfSSteven Rostedt } 37897faafbd6SSteven Rostedt end_monitor; 37907faafbd6SSteven Rostedt next if ($failed); 3791a75fececSSteven Rostedt } 37925a391fbfSSteven Rostedt 37935f9b6cedSSteven Rostedt success $i; 379475c3fda7SSteven Rostedt} 37952545eb61SSteven Rostedt 3796921ed4c7SSteven Rostedtif (defined($final_post_ktest)) { 3797921ed4c7SSteven Rostedt run_command $final_post_ktest; 3798921ed4c7SSteven Rostedt} 3799921ed4c7SSteven Rostedt 38005c42fc5bSSteven Rostedtif ($opt{"POWEROFF_ON_SUCCESS"}) { 380175c3fda7SSteven Rostedt halt; 3802759a3cc6SSteven Rostedt} elsif ($opt{"REBOOT_ON_SUCCESS"} && !do_not_reboot && $reboot_success) { 3803bc7c5803SSteven Rostedt reboot_to_good; 3804648a182cSSteven Rostedt} elsif (defined($switch_to_good)) { 3805648a182cSSteven Rostedt # still need to get to the good kernel 3806648a182cSSteven Rostedt run_command $switch_to_good; 38075c42fc5bSSteven Rostedt} 380875c3fda7SSteven Rostedt 3809648a182cSSteven Rostedt 3810e48c5293SSteven Rostedtdoprint "\n $successes of $opt{NUM_TESTS} tests were successful\n\n"; 3811e48c5293SSteven Rostedt 38122545eb61SSteven Rostedtexit 0; 3813