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", 285a5d8e48SSatoru Takeuchi "CLOSE_CONSOLE_SIGNAL" => "INT", 294f43e0dcSSteven Rostedt "TIMEOUT" => 120, 304f43e0dcSSteven Rostedt "TMP_DIR" => "/tmp/ktest/\${MACHINE}", 314f43e0dcSSteven Rostedt "SLEEP_TIME" => 60, # sleep time between tests 324f43e0dcSSteven Rostedt "BUILD_NOCLEAN" => 0, 334f43e0dcSSteven Rostedt "REBOOT_ON_ERROR" => 0, 344f43e0dcSSteven Rostedt "POWEROFF_ON_ERROR" => 0, 354f43e0dcSSteven Rostedt "REBOOT_ON_SUCCESS" => 1, 364f43e0dcSSteven Rostedt "POWEROFF_ON_SUCCESS" => 0, 374f43e0dcSSteven Rostedt "BUILD_OPTIONS" => "", 384f43e0dcSSteven Rostedt "BISECT_SLEEP_TIME" => 60, # sleep time between bisects 394f43e0dcSSteven Rostedt "PATCHCHECK_SLEEP_TIME" => 60, # sleep time between patch checks 404f43e0dcSSteven Rostedt "CLEAR_LOG" => 0, 414f43e0dcSSteven Rostedt "BISECT_MANUAL" => 0, 424f43e0dcSSteven Rostedt "BISECT_SKIP" => 1, 43ccc513b6SSteven Rostedt "MIN_CONFIG_TYPE" => "boot", 444f43e0dcSSteven Rostedt "SUCCESS_LINE" => "login:", 454f43e0dcSSteven Rostedt "DETECT_TRIPLE_FAULT" => 1, 464f43e0dcSSteven Rostedt "NO_INSTALL" => 0, 474f43e0dcSSteven Rostedt "BOOTED_TIMEOUT" => 1, 484f43e0dcSSteven Rostedt "DIE_ON_FAILURE" => 1, 494f43e0dcSSteven Rostedt "SSH_EXEC" => "ssh \$SSH_USER\@\$MACHINE \$SSH_COMMAND", 504f43e0dcSSteven Rostedt "SCP_TO_TARGET" => "scp \$SRC_FILE \$SSH_USER\@\$MACHINE:\$DST_FILE", 5102ad2617SSteven Rostedt "SCP_TO_TARGET_INSTALL" => "\${SCP_TO_TARGET}", 524f43e0dcSSteven Rostedt "REBOOT" => "ssh \$SSH_USER\@\$MACHINE reboot", 534f43e0dcSSteven Rostedt "STOP_AFTER_SUCCESS" => 10, 544f43e0dcSSteven Rostedt "STOP_AFTER_FAILURE" => 60, 554f43e0dcSSteven Rostedt "STOP_TEST_AFTER" => 600, 56407b95b7SSteven Rostedt "MAX_MONITOR_WAIT" => 1800, 57a15ba913SSteven Rostedt "GRUB_REBOOT" => "grub2-reboot", 587786954cSSteven Rostedt "SYSLINUX" => "extlinux", 597786954cSSteven Rostedt "SYSLINUX_PATH" => "/boot/extlinux", 60600bbf0aSSteven Rostedt 61600bbf0aSSteven Rostedt# required, and we will ask users if they don't have them but we keep the default 62600bbf0aSSteven Rostedt# value something that is common. 634f43e0dcSSteven Rostedt "REBOOT_TYPE" => "grub", 644f43e0dcSSteven Rostedt "LOCALVERSION" => "-test", 654f43e0dcSSteven Rostedt "SSH_USER" => "root", 664f43e0dcSSteven Rostedt "BUILD_TARGET" => "arch/x86/boot/bzImage", 674f43e0dcSSteven Rostedt "TARGET_IMAGE" => "/boot/vmlinuz-test", 689cc9e091SSteven Rostedt 699cc9e091SSteven Rostedt "LOG_FILE" => undef, 709cc9e091SSteven Rostedt "IGNORE_UNUSED" => 0, 714f43e0dcSSteven Rostedt); 722545eb61SSteven Rostedt 738d1491baSSteven Rostedtmy $ktest_config; 742545eb61SSteven Rostedtmy $version; 75683a3e64SSteven Rostedtmy $have_version = 0; 76a75fececSSteven Rostedtmy $machine; 77df5f7c66SSteven Rostedt (Red Hat)my $last_machine; 78e48c5293SSteven Rostedtmy $ssh_user; 79a75fececSSteven Rostedtmy $tmpdir; 80a75fececSSteven Rostedtmy $builddir; 81a75fececSSteven Rostedtmy $outputdir; 8251ad1dd1SSteven Rostedtmy $output_config; 83a75fececSSteven Rostedtmy $test_type; 847faafbd6SSteven Rostedtmy $build_type; 85a75fececSSteven Rostedtmy $build_options; 86921ed4c7SSteven Rostedtmy $final_post_ktest; 87921ed4c7SSteven Rostedtmy $pre_ktest; 88921ed4c7SSteven Rostedtmy $post_ktest; 89921ed4c7SSteven Rostedtmy $pre_test; 90921ed4c7SSteven Rostedtmy $post_test; 910bd6c1a3SSteven Rostedtmy $pre_build; 920bd6c1a3SSteven Rostedtmy $post_build; 930bd6c1a3SSteven Rostedtmy $pre_build_die; 940bd6c1a3SSteven Rostedtmy $post_build_die; 95a75fececSSteven Rostedtmy $reboot_type; 96a75fececSSteven Rostedtmy $reboot_script; 97a75fececSSteven Rostedtmy $power_cycle; 98e48c5293SSteven Rostedtmy $reboot; 99a75fececSSteven Rostedtmy $reboot_on_error; 100bc7c5803SSteven Rostedtmy $switch_to_good; 101bc7c5803SSteven Rostedtmy $switch_to_test; 102a75fececSSteven Rostedtmy $poweroff_on_error; 103648a182cSSteven Rostedtmy $reboot_on_success; 104a75fececSSteven Rostedtmy $die_on_failure; 105576f627cSSteven Rostedtmy $powercycle_after_reboot; 106576f627cSSteven Rostedtmy $poweroff_after_halt; 107407b95b7SSteven Rostedtmy $max_monitor_wait; 108e48c5293SSteven Rostedtmy $ssh_exec; 109e48c5293SSteven Rostedtmy $scp_to_target; 11002ad2617SSteven Rostedtmy $scp_to_target_install; 111a75fececSSteven Rostedtmy $power_off; 112a75fececSSteven Rostedtmy $grub_menu; 113752d9665SSteven Rostedt (Red Hat)my $last_grub_menu; 114a15ba913SSteven Rostedtmy $grub_file; 1152545eb61SSteven Rostedtmy $grub_number; 116a15ba913SSteven Rostedtmy $grub_reboot; 1177786954cSSteven Rostedtmy $syslinux; 1187786954cSSteven Rostedtmy $syslinux_path; 1197786954cSSteven Rostedtmy $syslinux_label; 1202545eb61SSteven Rostedtmy $target; 1212545eb61SSteven Rostedtmy $make; 122e5c2ec11SSteven Rostedtmy $pre_install; 1238b37ca8cSSteven Rostedtmy $post_install; 124e0a8742eSSteven Rostedtmy $no_install; 1255c42fc5bSSteven Rostedtmy $noclean; 1265f9b6cedSSteven Rostedtmy $minconfig; 1274c4ab120SSteven Rostedtmy $start_minconfig; 12835ce5952SSteven Rostedtmy $start_minconfig_defined; 1294c4ab120SSteven Rostedtmy $output_minconfig; 130ccc513b6SSteven Rostedtmy $minconfig_type; 13143de3316SSteven Rostedtmy $use_output_minconfig; 1324283b169SSteven Rostedt (Red Hat)my $warnings_file; 1334c4ab120SSteven Rostedtmy $ignore_config; 134be405f95SSteven Rostedtmy $ignore_errors; 1352b7d9b21SSteven Rostedtmy $addconfig; 1365f9b6cedSSteven Rostedtmy $in_bisect = 0; 137b5f4aea6SSteven Rostedtmy $bisect_bad_commit = ""; 138d6ce2a0bSSteven Rostedtmy $reverse_bisect; 139c960bb9fSSteven Rostedtmy $bisect_manual; 140c23dca7cSSteven Rostedtmy $bisect_skip; 14130f75da5SSteven Rostedtmy $config_bisect_good; 142c5dacb88SSteven Rostedtmy $bisect_ret_good; 143c5dacb88SSteven Rostedtmy $bisect_ret_bad; 144c5dacb88SSteven Rostedtmy $bisect_ret_skip; 145c5dacb88SSteven Rostedtmy $bisect_ret_abort; 146c5dacb88SSteven Rostedtmy $bisect_ret_default; 1476c5ee0beSSteven Rostedtmy $in_patchcheck = 0; 1485a391fbfSSteven Rostedtmy $run_test; 1496c5ee0beSSteven Rostedtmy $redirect; 1507faafbd6SSteven Rostedtmy $buildlog; 151a9dd5d63SRabin Vincentmy $testlog; 1527faafbd6SSteven Rostedtmy $dmesg; 1537faafbd6SSteven Rostedtmy $monitor_fp; 1547faafbd6SSteven Rostedtmy $monitor_pid; 1557faafbd6SSteven Rostedtmy $monitor_cnt = 0; 156a75fececSSteven Rostedtmy $sleep_time; 157a75fececSSteven Rostedtmy $bisect_sleep_time; 15827d934b2SSteven Rostedtmy $patchcheck_sleep_time; 1591990207dSSteven Rostedtmy $ignore_warnings; 160a75fececSSteven Rostedtmy $store_failures; 161de5b6e3bSRabin Vincentmy $store_successes; 1629064af52SSteven Rostedtmy $test_name; 163a75fececSSteven Rostedtmy $timeout; 164a75fececSSteven Rostedtmy $booted_timeout; 165f1a5b962SSteven Rostedtmy $detect_triplefault; 166a75fececSSteven Rostedtmy $console; 1675a5d8e48SSatoru Takeuchimy $close_console_signal; 1682b803365SSteven Rostedtmy $reboot_success_line; 169a75fececSSteven Rostedtmy $success_line; 1701c8a617aSSteven Rostedtmy $stop_after_success; 1711c8a617aSSteven Rostedtmy $stop_after_failure; 1722d01b26aSSteven Rostedtmy $stop_test_after; 173a75fececSSteven Rostedtmy $build_target; 174a75fececSSteven Rostedtmy $target_image; 175b5f4aea6SSteven Rostedtmy $checkout; 176a75fececSSteven Rostedtmy $localversion; 177576f627cSSteven Rostedtmy $iteration = 0; 178e48c5293SSteven Rostedtmy $successes = 0; 1792545eb61SSteven Rostedt 180b5f4aea6SSteven Rostedtmy $bisect_good; 181b5f4aea6SSteven Rostedtmy $bisect_bad; 182b5f4aea6SSteven Rostedtmy $bisect_type; 183b5f4aea6SSteven Rostedtmy $bisect_start; 184b5f4aea6SSteven Rostedtmy $bisect_replay; 185b5f4aea6SSteven Rostedtmy $bisect_files; 186b5f4aea6SSteven Rostedtmy $bisect_reverse; 187b5f4aea6SSteven Rostedtmy $bisect_check; 188b5f4aea6SSteven Rostedt 189b5f4aea6SSteven Rostedtmy $config_bisect; 190b5f4aea6SSteven Rostedtmy $config_bisect_type; 191b0918612SSteven Rostedtmy $config_bisect_check; 192b5f4aea6SSteven Rostedt 193b5f4aea6SSteven Rostedtmy $patchcheck_type; 194b5f4aea6SSteven Rostedtmy $patchcheck_start; 195b5f4aea6SSteven Rostedtmy $patchcheck_end; 196b5f4aea6SSteven Rostedt 197165708b2SSteven Rostedt# set when a test is something other that just building or install 198bb8474b1SSteven Rostedt# which would require more options. 199bb8474b1SSteven Rostedtmy $buildonly = 1; 200bb8474b1SSteven Rostedt 2014283b169SSteven Rostedt (Red Hat)# tell build not to worry about warnings, even when WARNINGS_FILE is set 2024283b169SSteven Rostedt (Red Hat)my $warnings_ok = 0; 2034283b169SSteven Rostedt (Red Hat) 204dbd3783bSSteven Rostedt# set when creating a new config 205dbd3783bSSteven Rostedtmy $newconfig = 0; 206dbd3783bSSteven Rostedt 2078d1491baSSteven Rostedtmy %entered_configs; 2088d1491baSSteven Rostedtmy %config_help; 20977d942ceSSteven Rostedtmy %variable; 210cf79fab6SSteven Rostedt 211cf79fab6SSteven Rostedt# force_config is the list of configs that we force enabled (or disabled) 212cf79fab6SSteven Rostedt# in a .config file. The MIN_CONFIG and ADD_CONFIG configs. 213fcb3f16aSSteven Rostedtmy %force_config; 2148d1491baSSteven Rostedt 2154ab1cce5SSteven Rostedt# do not force reboots on config problems 2164ab1cce5SSteven Rostedtmy $no_reboot = 1; 2174ab1cce5SSteven Rostedt 218759a3cc6SSteven Rostedt# reboot on success 219759a3cc6SSteven Rostedtmy $reboot_success = 0; 220759a3cc6SSteven Rostedt 2219cc9e091SSteven Rostedtmy %option_map = ( 2229cc9e091SSteven Rostedt "MACHINE" => \$machine, 2239cc9e091SSteven Rostedt "SSH_USER" => \$ssh_user, 2249cc9e091SSteven Rostedt "TMP_DIR" => \$tmpdir, 2259cc9e091SSteven Rostedt "OUTPUT_DIR" => \$outputdir, 2269cc9e091SSteven Rostedt "BUILD_DIR" => \$builddir, 2279cc9e091SSteven Rostedt "TEST_TYPE" => \$test_type, 228921ed4c7SSteven Rostedt "PRE_KTEST" => \$pre_ktest, 229921ed4c7SSteven Rostedt "POST_KTEST" => \$post_ktest, 230921ed4c7SSteven Rostedt "PRE_TEST" => \$pre_test, 231921ed4c7SSteven Rostedt "POST_TEST" => \$post_test, 2329cc9e091SSteven Rostedt "BUILD_TYPE" => \$build_type, 2339cc9e091SSteven Rostedt "BUILD_OPTIONS" => \$build_options, 2349cc9e091SSteven Rostedt "PRE_BUILD" => \$pre_build, 2359cc9e091SSteven Rostedt "POST_BUILD" => \$post_build, 2369cc9e091SSteven Rostedt "PRE_BUILD_DIE" => \$pre_build_die, 2379cc9e091SSteven Rostedt "POST_BUILD_DIE" => \$post_build_die, 2389cc9e091SSteven Rostedt "POWER_CYCLE" => \$power_cycle, 2399cc9e091SSteven Rostedt "REBOOT" => \$reboot, 2409cc9e091SSteven Rostedt "BUILD_NOCLEAN" => \$noclean, 2419cc9e091SSteven Rostedt "MIN_CONFIG" => \$minconfig, 2429cc9e091SSteven Rostedt "OUTPUT_MIN_CONFIG" => \$output_minconfig, 2439cc9e091SSteven Rostedt "START_MIN_CONFIG" => \$start_minconfig, 244ccc513b6SSteven Rostedt "MIN_CONFIG_TYPE" => \$minconfig_type, 24543de3316SSteven Rostedt "USE_OUTPUT_MIN_CONFIG" => \$use_output_minconfig, 2464283b169SSteven Rostedt (Red Hat) "WARNINGS_FILE" => \$warnings_file, 2479cc9e091SSteven Rostedt "IGNORE_CONFIG" => \$ignore_config, 2489cc9e091SSteven Rostedt "TEST" => \$run_test, 2499cc9e091SSteven Rostedt "ADD_CONFIG" => \$addconfig, 2509cc9e091SSteven Rostedt "REBOOT_TYPE" => \$reboot_type, 2519cc9e091SSteven Rostedt "GRUB_MENU" => \$grub_menu, 252a15ba913SSteven Rostedt "GRUB_FILE" => \$grub_file, 253a15ba913SSteven Rostedt "GRUB_REBOOT" => \$grub_reboot, 2547786954cSSteven Rostedt "SYSLINUX" => \$syslinux, 2557786954cSSteven Rostedt "SYSLINUX_PATH" => \$syslinux_path, 2567786954cSSteven Rostedt "SYSLINUX_LABEL" => \$syslinux_label, 257e5c2ec11SSteven Rostedt "PRE_INSTALL" => \$pre_install, 2589cc9e091SSteven Rostedt "POST_INSTALL" => \$post_install, 2599cc9e091SSteven Rostedt "NO_INSTALL" => \$no_install, 2609cc9e091SSteven Rostedt "REBOOT_SCRIPT" => \$reboot_script, 2619cc9e091SSteven Rostedt "REBOOT_ON_ERROR" => \$reboot_on_error, 2629cc9e091SSteven Rostedt "SWITCH_TO_GOOD" => \$switch_to_good, 2639cc9e091SSteven Rostedt "SWITCH_TO_TEST" => \$switch_to_test, 2649cc9e091SSteven Rostedt "POWEROFF_ON_ERROR" => \$poweroff_on_error, 265648a182cSSteven Rostedt "REBOOT_ON_SUCCESS" => \$reboot_on_success, 2669cc9e091SSteven Rostedt "DIE_ON_FAILURE" => \$die_on_failure, 2679cc9e091SSteven Rostedt "POWER_OFF" => \$power_off, 2689cc9e091SSteven Rostedt "POWERCYCLE_AFTER_REBOOT" => \$powercycle_after_reboot, 2699cc9e091SSteven Rostedt "POWEROFF_AFTER_HALT" => \$poweroff_after_halt, 270407b95b7SSteven Rostedt "MAX_MONITOR_WAIT" => \$max_monitor_wait, 2719cc9e091SSteven Rostedt "SLEEP_TIME" => \$sleep_time, 2729cc9e091SSteven Rostedt "BISECT_SLEEP_TIME" => \$bisect_sleep_time, 2739cc9e091SSteven Rostedt "PATCHCHECK_SLEEP_TIME" => \$patchcheck_sleep_time, 2749cc9e091SSteven Rostedt "IGNORE_WARNINGS" => \$ignore_warnings, 275be405f95SSteven Rostedt "IGNORE_ERRORS" => \$ignore_errors, 2769cc9e091SSteven Rostedt "BISECT_MANUAL" => \$bisect_manual, 2779cc9e091SSteven Rostedt "BISECT_SKIP" => \$bisect_skip, 2789cc9e091SSteven Rostedt "CONFIG_BISECT_GOOD" => \$config_bisect_good, 2799cc9e091SSteven Rostedt "BISECT_RET_GOOD" => \$bisect_ret_good, 2809cc9e091SSteven Rostedt "BISECT_RET_BAD" => \$bisect_ret_bad, 2819cc9e091SSteven Rostedt "BISECT_RET_SKIP" => \$bisect_ret_skip, 2829cc9e091SSteven Rostedt "BISECT_RET_ABORT" => \$bisect_ret_abort, 2839cc9e091SSteven Rostedt "BISECT_RET_DEFAULT" => \$bisect_ret_default, 2849cc9e091SSteven Rostedt "STORE_FAILURES" => \$store_failures, 2859cc9e091SSteven Rostedt "STORE_SUCCESSES" => \$store_successes, 2869cc9e091SSteven Rostedt "TEST_NAME" => \$test_name, 2879cc9e091SSteven Rostedt "TIMEOUT" => \$timeout, 2889cc9e091SSteven Rostedt "BOOTED_TIMEOUT" => \$booted_timeout, 2899cc9e091SSteven Rostedt "CONSOLE" => \$console, 2905a5d8e48SSatoru Takeuchi "CLOSE_CONSOLE_SIGNAL" => \$close_console_signal, 2919cc9e091SSteven Rostedt "DETECT_TRIPLE_FAULT" => \$detect_triplefault, 2929cc9e091SSteven Rostedt "SUCCESS_LINE" => \$success_line, 2939cc9e091SSteven Rostedt "REBOOT_SUCCESS_LINE" => \$reboot_success_line, 2949cc9e091SSteven Rostedt "STOP_AFTER_SUCCESS" => \$stop_after_success, 2959cc9e091SSteven Rostedt "STOP_AFTER_FAILURE" => \$stop_after_failure, 2969cc9e091SSteven Rostedt "STOP_TEST_AFTER" => \$stop_test_after, 2979cc9e091SSteven Rostedt "BUILD_TARGET" => \$build_target, 2989cc9e091SSteven Rostedt "SSH_EXEC" => \$ssh_exec, 2999cc9e091SSteven Rostedt "SCP_TO_TARGET" => \$scp_to_target, 30002ad2617SSteven Rostedt "SCP_TO_TARGET_INSTALL" => \$scp_to_target_install, 3019cc9e091SSteven Rostedt "CHECKOUT" => \$checkout, 3029cc9e091SSteven Rostedt "TARGET_IMAGE" => \$target_image, 3039cc9e091SSteven Rostedt "LOCALVERSION" => \$localversion, 3049cc9e091SSteven Rostedt 3059cc9e091SSteven Rostedt "BISECT_GOOD" => \$bisect_good, 3069cc9e091SSteven Rostedt "BISECT_BAD" => \$bisect_bad, 3079cc9e091SSteven Rostedt "BISECT_TYPE" => \$bisect_type, 3089cc9e091SSteven Rostedt "BISECT_START" => \$bisect_start, 3099cc9e091SSteven Rostedt "BISECT_REPLAY" => \$bisect_replay, 3109cc9e091SSteven Rostedt "BISECT_FILES" => \$bisect_files, 3119cc9e091SSteven Rostedt "BISECT_REVERSE" => \$bisect_reverse, 3129cc9e091SSteven Rostedt "BISECT_CHECK" => \$bisect_check, 3139cc9e091SSteven Rostedt 3149cc9e091SSteven Rostedt "CONFIG_BISECT" => \$config_bisect, 3159cc9e091SSteven Rostedt "CONFIG_BISECT_TYPE" => \$config_bisect_type, 316b0918612SSteven Rostedt "CONFIG_BISECT_CHECK" => \$config_bisect_check, 3179cc9e091SSteven Rostedt 3189cc9e091SSteven Rostedt "PATCHCHECK_TYPE" => \$patchcheck_type, 3199cc9e091SSteven Rostedt "PATCHCHECK_START" => \$patchcheck_start, 3209cc9e091SSteven Rostedt "PATCHCHECK_END" => \$patchcheck_end, 3219cc9e091SSteven Rostedt); 3229cc9e091SSteven Rostedt 3239cc9e091SSteven Rostedt# Options may be used by other options, record them. 3249cc9e091SSteven Rostedtmy %used_options; 3259cc9e091SSteven Rostedt 3267bf51073SSteven Rostedt# default variables that can be used 3277bf51073SSteven Rostedtchomp ($variable{"PWD"} = `pwd`); 3287bf51073SSteven Rostedt 3298d1491baSSteven Rostedt$config_help{"MACHINE"} = << "EOF" 3308d1491baSSteven Rostedt The machine hostname that you will test. 331bb8474b1SSteven Rostedt For build only tests, it is still needed to differentiate log files. 3328d1491baSSteven RostedtEOF 3338d1491baSSteven Rostedt ; 3348d1491baSSteven Rostedt$config_help{"SSH_USER"} = << "EOF" 3358d1491baSSteven Rostedt The box is expected to have ssh on normal bootup, provide the user 3368d1491baSSteven Rostedt (most likely root, since you need privileged operations) 3378d1491baSSteven RostedtEOF 3388d1491baSSteven Rostedt ; 3398d1491baSSteven Rostedt$config_help{"BUILD_DIR"} = << "EOF" 3408d1491baSSteven Rostedt The directory that contains the Linux source code (full path). 3410e7a22deSSteven Rostedt You can use \${PWD} that will be the path where ktest.pl is run, or use 3420e7a22deSSteven Rostedt \${THIS_DIR} which is assigned \${PWD} but may be changed later. 3438d1491baSSteven RostedtEOF 3448d1491baSSteven Rostedt ; 3458d1491baSSteven Rostedt$config_help{"OUTPUT_DIR"} = << "EOF" 3468d1491baSSteven Rostedt The directory that the objects will be built (full path). 3478d1491baSSteven Rostedt (can not be same as BUILD_DIR) 3480e7a22deSSteven Rostedt You can use \${PWD} that will be the path where ktest.pl is run, or use 3490e7a22deSSteven Rostedt \${THIS_DIR} which is assigned \${PWD} but may be changed later. 3508d1491baSSteven RostedtEOF 3518d1491baSSteven Rostedt ; 3528d1491baSSteven Rostedt$config_help{"BUILD_TARGET"} = << "EOF" 3538d1491baSSteven Rostedt The location of the compiled file to copy to the target. 3548d1491baSSteven Rostedt (relative to OUTPUT_DIR) 3558d1491baSSteven RostedtEOF 3568d1491baSSteven Rostedt ; 357dbd3783bSSteven Rostedt$config_help{"BUILD_OPTIONS"} = << "EOF" 358dbd3783bSSteven Rostedt Options to add to \"make\" when building. 359dbd3783bSSteven Rostedt i.e. -j20 360dbd3783bSSteven RostedtEOF 361dbd3783bSSteven Rostedt ; 3628d1491baSSteven Rostedt$config_help{"TARGET_IMAGE"} = << "EOF" 3638d1491baSSteven Rostedt The place to put your image on the test machine. 3648d1491baSSteven RostedtEOF 3658d1491baSSteven Rostedt ; 3668d1491baSSteven Rostedt$config_help{"POWER_CYCLE"} = << "EOF" 3678d1491baSSteven Rostedt A script or command to reboot the box. 3688d1491baSSteven Rostedt 3698d1491baSSteven Rostedt Here is a digital loggers power switch example 3708d1491baSSteven Rostedt POWER_CYCLE = wget --no-proxy -O /dev/null -q --auth-no-challenge 'http://admin:admin\@power/outlet?5=CCL' 3718d1491baSSteven Rostedt 3728d1491baSSteven Rostedt Here is an example to reboot a virtual box on the current host 3738d1491baSSteven Rostedt with the name "Guest". 3748d1491baSSteven Rostedt POWER_CYCLE = virsh destroy Guest; sleep 5; virsh start Guest 3758d1491baSSteven RostedtEOF 3768d1491baSSteven Rostedt ; 3778d1491baSSteven Rostedt$config_help{"CONSOLE"} = << "EOF" 3788d1491baSSteven Rostedt The script or command that reads the console 3798d1491baSSteven Rostedt 3808d1491baSSteven Rostedt If you use ttywatch server, something like the following would work. 3818d1491baSSteven RostedtCONSOLE = nc -d localhost 3001 3828d1491baSSteven Rostedt 3838d1491baSSteven Rostedt For a virtual machine with guest name "Guest". 3848d1491baSSteven RostedtCONSOLE = virsh console Guest 3858d1491baSSteven RostedtEOF 3868d1491baSSteven Rostedt ; 3878d1491baSSteven Rostedt$config_help{"LOCALVERSION"} = << "EOF" 3888d1491baSSteven Rostedt Required version ending to differentiate the test 3898d1491baSSteven Rostedt from other linux builds on the system. 3908d1491baSSteven RostedtEOF 3918d1491baSSteven Rostedt ; 3928d1491baSSteven Rostedt$config_help{"REBOOT_TYPE"} = << "EOF" 3938d1491baSSteven Rostedt Way to reboot the box to the test kernel. 3947786954cSSteven Rostedt Only valid options so far are "grub", "grub2", "syslinux", and "script". 3958d1491baSSteven Rostedt 3968d1491baSSteven Rostedt If you specify grub, it will assume grub version 1 3978d1491baSSteven Rostedt and will search in /boot/grub/menu.lst for the title \$GRUB_MENU 3988d1491baSSteven Rostedt and select that target to reboot to the kernel. If this is not 3998d1491baSSteven Rostedt your setup, then specify "script" and have a command or script 4008d1491baSSteven Rostedt specified in REBOOT_SCRIPT to boot to the target. 4018d1491baSSteven Rostedt 4028d1491baSSteven Rostedt The entry in /boot/grub/menu.lst must be entered in manually. 4038d1491baSSteven Rostedt The test will not modify that file. 404a15ba913SSteven Rostedt 405a15ba913SSteven Rostedt If you specify grub2, then you also need to specify both \$GRUB_MENU 406a15ba913SSteven Rostedt and \$GRUB_FILE. 4077786954cSSteven Rostedt 4087786954cSSteven Rostedt If you specify syslinux, then you may use SYSLINUX to define the syslinux 4097786954cSSteven Rostedt command (defaults to extlinux), and SYSLINUX_PATH to specify the path to 4107786954cSSteven Rostedt the syslinux install (defaults to /boot/extlinux). But you have to specify 4117786954cSSteven Rostedt SYSLINUX_LABEL to define the label to boot to for the test kernel. 4128d1491baSSteven RostedtEOF 4138d1491baSSteven Rostedt ; 4148d1491baSSteven Rostedt$config_help{"GRUB_MENU"} = << "EOF" 4158d1491baSSteven Rostedt The grub title name for the test kernel to boot 416a15ba913SSteven Rostedt (Only mandatory if REBOOT_TYPE = grub or grub2) 4178d1491baSSteven Rostedt 4188d1491baSSteven Rostedt Note, ktest.pl will not update the grub menu.lst, you need to 4198d1491baSSteven Rostedt manually add an option for the test. ktest.pl will search 4208d1491baSSteven Rostedt the grub menu.lst for this option to find what kernel to 4218d1491baSSteven Rostedt reboot into. 4228d1491baSSteven Rostedt 4238d1491baSSteven Rostedt For example, if in the /boot/grub/menu.lst the test kernel title has: 4248d1491baSSteven Rostedt title Test Kernel 4258d1491baSSteven Rostedt kernel vmlinuz-test 4268d1491baSSteven Rostedt GRUB_MENU = Test Kernel 427a15ba913SSteven Rostedt 428a15ba913SSteven Rostedt For grub2, a search of \$GRUB_FILE is performed for the lines 429a15ba913SSteven Rostedt that begin with "menuentry". It will not detect submenus. The 430a15ba913SSteven Rostedt menu must be a non-nested menu. Add the quotes used in the menu 431a15ba913SSteven Rostedt to guarantee your selection, as the first menuentry with the content 432a15ba913SSteven Rostedt of \$GRUB_MENU that is found will be used. 433a15ba913SSteven RostedtEOF 434a15ba913SSteven Rostedt ; 435a15ba913SSteven Rostedt$config_help{"GRUB_FILE"} = << "EOF" 436a15ba913SSteven Rostedt If grub2 is used, the full path for the grub.cfg file is placed 437a15ba913SSteven Rostedt here. Use something like /boot/grub2/grub.cfg to search. 4388d1491baSSteven RostedtEOF 4398d1491baSSteven Rostedt ; 4407786954cSSteven Rostedt$config_help{"SYSLINUX_LABEL"} = << "EOF" 4417786954cSSteven Rostedt If syslinux is used, the label that boots the target kernel must 4427786954cSSteven Rostedt be specified with SYSLINUX_LABEL. 4437786954cSSteven RostedtEOF 4447786954cSSteven Rostedt ; 4458d1491baSSteven Rostedt$config_help{"REBOOT_SCRIPT"} = << "EOF" 4468d1491baSSteven Rostedt A script to reboot the target into the test kernel 4478d1491baSSteven Rostedt (Only mandatory if REBOOT_TYPE = script) 4488d1491baSSteven RostedtEOF 4498d1491baSSteven Rostedt ; 4508d1491baSSteven Rostedt 451dad98754SSteven Rostedtsub read_prompt { 452dad98754SSteven Rostedt my ($cancel, $prompt) = @_; 45335ce5952SSteven Rostedt 45435ce5952SSteven Rostedt my $ans; 45535ce5952SSteven Rostedt 45635ce5952SSteven Rostedt for (;;) { 457dad98754SSteven Rostedt if ($cancel) { 458dad98754SSteven Rostedt print "$prompt [y/n/C] "; 459dad98754SSteven Rostedt } else { 46035ce5952SSteven Rostedt print "$prompt [Y/n] "; 461dad98754SSteven Rostedt } 46235ce5952SSteven Rostedt $ans = <STDIN>; 46335ce5952SSteven Rostedt chomp $ans; 46435ce5952SSteven Rostedt if ($ans =~ /^\s*$/) { 465dad98754SSteven Rostedt if ($cancel) { 466dad98754SSteven Rostedt $ans = "c"; 467dad98754SSteven Rostedt } else { 46835ce5952SSteven Rostedt $ans = "y"; 46935ce5952SSteven Rostedt } 470dad98754SSteven Rostedt } 47135ce5952SSteven Rostedt last if ($ans =~ /^y$/i || $ans =~ /^n$/i); 472dad98754SSteven Rostedt if ($cancel) { 473dad98754SSteven Rostedt last if ($ans =~ /^c$/i); 474dad98754SSteven Rostedt print "Please answer either 'y', 'n' or 'c'.\n"; 475dad98754SSteven Rostedt } else { 47635ce5952SSteven Rostedt print "Please answer either 'y' or 'n'.\n"; 47735ce5952SSteven Rostedt } 478dad98754SSteven Rostedt } 479dad98754SSteven Rostedt if ($ans =~ /^c/i) { 480dad98754SSteven Rostedt exit; 481dad98754SSteven Rostedt } 48235ce5952SSteven Rostedt if ($ans !~ /^y$/i) { 48335ce5952SSteven Rostedt return 0; 48435ce5952SSteven Rostedt } 48535ce5952SSteven Rostedt return 1; 48635ce5952SSteven Rostedt} 4878d1491baSSteven Rostedt 488dad98754SSteven Rostedtsub read_yn { 489dad98754SSteven Rostedt my ($prompt) = @_; 490dad98754SSteven Rostedt 491dad98754SSteven Rostedt return read_prompt 0, $prompt; 492dad98754SSteven Rostedt} 493dad98754SSteven Rostedt 494dad98754SSteven Rostedtsub read_ync { 495dad98754SSteven Rostedt my ($prompt) = @_; 496dad98754SSteven Rostedt 497dad98754SSteven Rostedt return read_prompt 1, $prompt; 498dad98754SSteven Rostedt} 499dad98754SSteven Rostedt 5008d1491baSSteven Rostedtsub get_ktest_config { 5018d1491baSSteven Rostedt my ($config) = @_; 502815e2bd7SSteven Rostedt my $ans; 5038d1491baSSteven Rostedt 5048d1491baSSteven Rostedt return if (defined($opt{$config})); 5058d1491baSSteven Rostedt 5068d1491baSSteven Rostedt if (defined($config_help{$config})) { 5078d1491baSSteven Rostedt print "\n"; 5088d1491baSSteven Rostedt print $config_help{$config}; 5098d1491baSSteven Rostedt } 5108d1491baSSteven Rostedt 5118d1491baSSteven Rostedt for (;;) { 5128d1491baSSteven Rostedt print "$config = "; 513dbd3783bSSteven Rostedt if (defined($default{$config}) && length($default{$config})) { 5148d1491baSSteven Rostedt print "\[$default{$config}\] "; 5158d1491baSSteven Rostedt } 516815e2bd7SSteven Rostedt $ans = <STDIN>; 517815e2bd7SSteven Rostedt $ans =~ s/^\s*(.*\S)\s*$/$1/; 518815e2bd7SSteven Rostedt if ($ans =~ /^\s*$/) { 5198d1491baSSteven Rostedt if ($default{$config}) { 520815e2bd7SSteven Rostedt $ans = $default{$config}; 5218d1491baSSteven Rostedt } else { 5228d1491baSSteven Rostedt print "Your answer can not be blank\n"; 5238d1491baSSteven Rostedt next; 5248d1491baSSteven Rostedt } 5258d1491baSSteven Rostedt } 5260e7a22deSSteven Rostedt $entered_configs{$config} = ${ans}; 5278d1491baSSteven Rostedt last; 5288d1491baSSteven Rostedt } 5298d1491baSSteven Rostedt} 5308d1491baSSteven Rostedt 5318d1491baSSteven Rostedtsub get_ktest_configs { 5328d1491baSSteven Rostedt get_ktest_config("MACHINE"); 5338d1491baSSteven Rostedt get_ktest_config("BUILD_DIR"); 5348d1491baSSteven Rostedt get_ktest_config("OUTPUT_DIR"); 535bb8474b1SSteven Rostedt 536dbd3783bSSteven Rostedt if ($newconfig) { 537dbd3783bSSteven Rostedt get_ktest_config("BUILD_OPTIONS"); 538dbd3783bSSteven Rostedt } 539dbd3783bSSteven Rostedt 540bb8474b1SSteven Rostedt # options required for other than just building a kernel 541bb8474b1SSteven Rostedt if (!$buildonly) { 542165708b2SSteven Rostedt get_ktest_config("POWER_CYCLE"); 543165708b2SSteven Rostedt get_ktest_config("CONSOLE"); 544165708b2SSteven Rostedt } 545165708b2SSteven Rostedt 546165708b2SSteven Rostedt # options required for install and more 547165708b2SSteven Rostedt if ($buildonly != 1) { 548bb8474b1SSteven Rostedt get_ktest_config("SSH_USER"); 5498d1491baSSteven Rostedt get_ktest_config("BUILD_TARGET"); 5508d1491baSSteven Rostedt get_ktest_config("TARGET_IMAGE"); 551bb8474b1SSteven Rostedt } 552bb8474b1SSteven Rostedt 5538d1491baSSteven Rostedt get_ktest_config("LOCALVERSION"); 5548d1491baSSteven Rostedt 555bb8474b1SSteven Rostedt return if ($buildonly); 556bb8474b1SSteven Rostedt 5578d1491baSSteven Rostedt my $rtype = $opt{"REBOOT_TYPE"}; 5588d1491baSSteven Rostedt 5598d1491baSSteven Rostedt if (!defined($rtype)) { 5608d1491baSSteven Rostedt if (!defined($opt{"GRUB_MENU"})) { 5618d1491baSSteven Rostedt get_ktest_config("REBOOT_TYPE"); 5628d1491baSSteven Rostedt $rtype = $entered_configs{"REBOOT_TYPE"}; 5638d1491baSSteven Rostedt } else { 5648d1491baSSteven Rostedt $rtype = "grub"; 5658d1491baSSteven Rostedt } 5668d1491baSSteven Rostedt } 5678d1491baSSteven Rostedt 5688d1491baSSteven Rostedt if ($rtype eq "grub") { 5698d1491baSSteven Rostedt get_ktest_config("GRUB_MENU"); 5708d1491baSSteven Rostedt } 571a15ba913SSteven Rostedt 572a15ba913SSteven Rostedt if ($rtype eq "grub2") { 573a15ba913SSteven Rostedt get_ktest_config("GRUB_MENU"); 574a15ba913SSteven Rostedt get_ktest_config("GRUB_FILE"); 575a15ba913SSteven Rostedt } 5767786954cSSteven Rostedt 5777786954cSSteven Rostedt if ($rtype eq "syslinux") { 5787786954cSSteven Rostedt get_ktest_config("SYSLINUX_LABEL"); 5797786954cSSteven Rostedt } 5808d1491baSSteven Rostedt} 5818d1491baSSteven Rostedt 58277d942ceSSteven Rostedtsub process_variables { 5838d735212SSteven Rostedt my ($value, $remove_undef) = @_; 58477d942ceSSteven Rostedt my $retval = ""; 58577d942ceSSteven Rostedt 58677d942ceSSteven Rostedt # We want to check for '\', and it is just easier 58777d942ceSSteven Rostedt # to check the previous characet of '$' and not need 58877d942ceSSteven Rostedt # to worry if '$' is the first character. By adding 58977d942ceSSteven Rostedt # a space to $value, we can just check [^\\]\$ and 59077d942ceSSteven Rostedt # it will still work. 59177d942ceSSteven Rostedt $value = " $value"; 59277d942ceSSteven Rostedt 59377d942ceSSteven Rostedt while ($value =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) { 59477d942ceSSteven Rostedt my $begin = $1; 59577d942ceSSteven Rostedt my $var = $2; 59677d942ceSSteven Rostedt my $end = $3; 59777d942ceSSteven Rostedt # append beginning of value to retval 59877d942ceSSteven Rostedt $retval = "$retval$begin"; 59977d942ceSSteven Rostedt if (defined($variable{$var})) { 60077d942ceSSteven Rostedt $retval = "$retval$variable{$var}"; 6018d735212SSteven Rostedt } elsif (defined($remove_undef) && $remove_undef) { 6028d735212SSteven Rostedt # for if statements, any variable that is not defined, 6038d735212SSteven Rostedt # we simple convert to 0 6048d735212SSteven Rostedt $retval = "${retval}0"; 60577d942ceSSteven Rostedt } else { 60677d942ceSSteven Rostedt # put back the origin piece. 60777d942ceSSteven Rostedt $retval = "$retval\$\{$var\}"; 6089cc9e091SSteven Rostedt # This could be an option that is used later, save 6099cc9e091SSteven Rostedt # it so we don't warn if this option is not one of 6109cc9e091SSteven Rostedt # ktests options. 6119cc9e091SSteven Rostedt $used_options{$var} = 1; 61277d942ceSSteven Rostedt } 61377d942ceSSteven Rostedt $value = $end; 61477d942ceSSteven Rostedt } 61577d942ceSSteven Rostedt $retval = "$retval$value"; 61677d942ceSSteven Rostedt 61777d942ceSSteven Rostedt # remove the space added in the beginning 61877d942ceSSteven Rostedt $retval =~ s/ //; 61977d942ceSSteven Rostedt 62077d942ceSSteven Rostedt return "$retval" 62177d942ceSSteven Rostedt} 62277d942ceSSteven Rostedt 623a57419b3SSteven Rostedtsub set_value { 6243d1cc414SSteven Rostedt my ($lvalue, $rvalue, $override, $overrides, $name) = @_; 6252545eb61SSteven Rostedt 626cad96669SSteven Rostedt my $prvalue = process_variables($rvalue); 627cad96669SSteven Rostedt 628cad96669SSteven Rostedt if ($buildonly && $lvalue =~ /^TEST_TYPE(\[.*\])?$/ && $prvalue ne "build") { 629bb8474b1SSteven Rostedt # Note if a test is something other than build, then we 630bb8474b1SSteven Rostedt # will need other manditory options. 631cad96669SSteven Rostedt if ($prvalue ne "install") { 632319ab14fSSteven Rostedt (Red Hat) # for bisect, we need to check BISECT_TYPE 633319ab14fSSteven Rostedt (Red Hat) if ($prvalue ne "bisect") { 634319ab14fSSteven Rostedt (Red Hat) $buildonly = 0; 635319ab14fSSteven Rostedt (Red Hat) } 636319ab14fSSteven Rostedt (Red Hat) } else { 637319ab14fSSteven Rostedt (Red Hat) # install still limits some manditory options. 638319ab14fSSteven Rostedt (Red Hat) $buildonly = 2; 639319ab14fSSteven Rostedt (Red Hat) } 640319ab14fSSteven Rostedt (Red Hat) } 641319ab14fSSteven Rostedt (Red Hat) 642319ab14fSSteven Rostedt (Red Hat) if ($buildonly && $lvalue =~ /^BISECT_TYPE(\[.*\])?$/ && $prvalue ne "build") { 643319ab14fSSteven Rostedt (Red Hat) if ($prvalue ne "install") { 644bb8474b1SSteven Rostedt $buildonly = 0; 645165708b2SSteven Rostedt } else { 646165708b2SSteven Rostedt # install still limits some manditory options. 647165708b2SSteven Rostedt $buildonly = 2; 648165708b2SSteven Rostedt } 649bb8474b1SSteven Rostedt } 650bb8474b1SSteven Rostedt 651a75fececSSteven Rostedt if (defined($opt{$lvalue})) { 6523d1cc414SSteven Rostedt if (!$override || defined(${$overrides}{$lvalue})) { 6533d1cc414SSteven Rostedt my $extra = ""; 6543d1cc414SSteven Rostedt if ($override) { 6553d1cc414SSteven Rostedt $extra = "In the same override section!\n"; 6563d1cc414SSteven Rostedt } 6573d1cc414SSteven Rostedt die "$name: $.: Option $lvalue defined more than once!\n$extra"; 6583d1cc414SSteven Rostedt } 659cad96669SSteven Rostedt ${$overrides}{$lvalue} = $prvalue; 660a75fececSSteven Rostedt } 66121a9679fSSteven Rostedt if ($rvalue =~ /^\s*$/) { 66221a9679fSSteven Rostedt delete $opt{$lvalue}; 66321a9679fSSteven Rostedt } else { 664cad96669SSteven Rostedt $opt{$lvalue} = $prvalue; 66521a9679fSSteven Rostedt } 6662545eb61SSteven Rostedt} 667a57419b3SSteven Rostedt 66877d942ceSSteven Rostedtsub set_variable { 66977d942ceSSteven Rostedt my ($lvalue, $rvalue) = @_; 67077d942ceSSteven Rostedt 67177d942ceSSteven Rostedt if ($rvalue =~ /^\s*$/) { 67277d942ceSSteven Rostedt delete $variable{$lvalue}; 67377d942ceSSteven Rostedt } else { 67477d942ceSSteven Rostedt $rvalue = process_variables($rvalue); 67577d942ceSSteven Rostedt $variable{$lvalue} = $rvalue; 67677d942ceSSteven Rostedt } 67777d942ceSSteven Rostedt} 67877d942ceSSteven Rostedt 679ab7a3f52SSteven Rostedtsub process_compare { 680ab7a3f52SSteven Rostedt my ($lval, $cmp, $rval) = @_; 681ab7a3f52SSteven Rostedt 682ab7a3f52SSteven Rostedt # remove whitespace 683ab7a3f52SSteven Rostedt 684ab7a3f52SSteven Rostedt $lval =~ s/^\s*//; 685ab7a3f52SSteven Rostedt $lval =~ s/\s*$//; 686ab7a3f52SSteven Rostedt 687ab7a3f52SSteven Rostedt $rval =~ s/^\s*//; 688ab7a3f52SSteven Rostedt $rval =~ s/\s*$//; 689ab7a3f52SSteven Rostedt 690ab7a3f52SSteven Rostedt if ($cmp eq "==") { 691ab7a3f52SSteven Rostedt return $lval eq $rval; 692ab7a3f52SSteven Rostedt } elsif ($cmp eq "!=") { 693ab7a3f52SSteven Rostedt return $lval ne $rval; 6948fddbe9bSSteven Rostedt } elsif ($cmp eq "=~") { 6958fddbe9bSSteven Rostedt return $lval =~ m/$rval/; 6968fddbe9bSSteven Rostedt } elsif ($cmp eq "!~") { 6978fddbe9bSSteven Rostedt return $lval !~ m/$rval/; 698ab7a3f52SSteven Rostedt } 699ab7a3f52SSteven Rostedt 700ab7a3f52SSteven Rostedt my $statement = "$lval $cmp $rval"; 701ab7a3f52SSteven Rostedt my $ret = eval $statement; 702ab7a3f52SSteven Rostedt 703ab7a3f52SSteven Rostedt # $@ stores error of eval 704ab7a3f52SSteven Rostedt if ($@) { 705ab7a3f52SSteven Rostedt return -1; 706ab7a3f52SSteven Rostedt } 707ab7a3f52SSteven Rostedt 708ab7a3f52SSteven Rostedt return $ret; 709ab7a3f52SSteven Rostedt} 710ab7a3f52SSteven Rostedt 7119900b5dcSSteven Rostedtsub value_defined { 7129900b5dcSSteven Rostedt my ($val) = @_; 7139900b5dcSSteven Rostedt 7149900b5dcSSteven Rostedt return defined($variable{$2}) || 7159900b5dcSSteven Rostedt defined($opt{$2}); 7169900b5dcSSteven Rostedt} 7179900b5dcSSteven Rostedt 7188d735212SSteven Rostedtmy $d = 0; 7198d735212SSteven Rostedtsub process_expression { 7208d735212SSteven Rostedt my ($name, $val) = @_; 72145d73a5dSSteven Rostedt 7228d735212SSteven Rostedt my $c = $d++; 7238d735212SSteven Rostedt 7248d735212SSteven Rostedt while ($val =~ s/\(([^\(]*?)\)/\&\&\&\&VAL\&\&\&\&/) { 7258d735212SSteven Rostedt my $express = $1; 7268d735212SSteven Rostedt 7278d735212SSteven Rostedt if (process_expression($name, $express)) { 7288d735212SSteven Rostedt $val =~ s/\&\&\&\&VAL\&\&\&\&/ 1 /; 7298d735212SSteven Rostedt } else { 7308d735212SSteven Rostedt $val =~ s/\&\&\&\&VAL\&\&\&\&/ 0 /; 7318d735212SSteven Rostedt } 7328d735212SSteven Rostedt } 7338d735212SSteven Rostedt 7348d735212SSteven Rostedt $d--; 7358d735212SSteven Rostedt my $OR = "\\|\\|"; 7368d735212SSteven Rostedt my $AND = "\\&\\&"; 7378d735212SSteven Rostedt 7388d735212SSteven Rostedt while ($val =~ s/^(.*?)($OR|$AND)//) { 7398d735212SSteven Rostedt my $express = $1; 7408d735212SSteven Rostedt my $op = $2; 7418d735212SSteven Rostedt 7428d735212SSteven Rostedt if (process_expression($name, $express)) { 7438d735212SSteven Rostedt if ($op eq "||") { 7448d735212SSteven Rostedt return 1; 7458d735212SSteven Rostedt } 7468d735212SSteven Rostedt } else { 7478d735212SSteven Rostedt if ($op eq "&&") { 7488d735212SSteven Rostedt return 0; 7498d735212SSteven Rostedt } 7508d735212SSteven Rostedt } 7518d735212SSteven Rostedt } 75245d73a5dSSteven Rostedt 7538fddbe9bSSteven Rostedt if ($val =~ /(.*)(==|\!=|>=|<=|>|<|=~|\!~)(.*)/) { 754ab7a3f52SSteven Rostedt my $ret = process_compare($1, $2, $3); 755ab7a3f52SSteven Rostedt if ($ret < 0) { 756ab7a3f52SSteven Rostedt die "$name: $.: Unable to process comparison\n"; 757ab7a3f52SSteven Rostedt } 758ab7a3f52SSteven Rostedt return $ret; 759ab7a3f52SSteven Rostedt } 760ab7a3f52SSteven Rostedt 7619900b5dcSSteven Rostedt if ($val =~ /^\s*(NOT\s*)?DEFINED\s+(\S+)\s*$/) { 7629900b5dcSSteven Rostedt if (defined $1) { 7639900b5dcSSteven Rostedt return !value_defined($2); 7649900b5dcSSteven Rostedt } else { 7659900b5dcSSteven Rostedt return value_defined($2); 7669900b5dcSSteven Rostedt } 7679900b5dcSSteven Rostedt } 7689900b5dcSSteven Rostedt 76945d73a5dSSteven Rostedt if ($val =~ /^\s*0\s*$/) { 77045d73a5dSSteven Rostedt return 0; 77145d73a5dSSteven Rostedt } elsif ($val =~ /^\s*\d+\s*$/) { 77245d73a5dSSteven Rostedt return 1; 77345d73a5dSSteven Rostedt } 77445d73a5dSSteven Rostedt 7759900b5dcSSteven Rostedt die ("$name: $.: Undefined content $val in if statement\n"); 7768d735212SSteven Rostedt} 7778d735212SSteven Rostedt 7788d735212SSteven Rostedtsub process_if { 7798d735212SSteven Rostedt my ($name, $value) = @_; 7808d735212SSteven Rostedt 7818d735212SSteven Rostedt # Convert variables and replace undefined ones with 0 7828d735212SSteven Rostedt my $val = process_variables($value, 1); 7838d735212SSteven Rostedt my $ret = process_expression $name, $val; 7848d735212SSteven Rostedt 7858d735212SSteven Rostedt return $ret; 78645d73a5dSSteven Rostedt} 78745d73a5dSSteven Rostedt 7882ed3b161SSteven Rostedtsub __read_config { 7892ed3b161SSteven Rostedt my ($config, $current_test_num) = @_; 790a57419b3SSteven Rostedt 7912ed3b161SSteven Rostedt my $in; 7922ed3b161SSteven Rostedt open($in, $config) || die "can't read file $config"; 793a57419b3SSteven Rostedt 794a57419b3SSteven Rostedt my $name = $config; 795a57419b3SSteven Rostedt $name =~ s,.*/(.*),$1,; 796a57419b3SSteven Rostedt 7972ed3b161SSteven Rostedt my $test_num = $$current_test_num; 798a57419b3SSteven Rostedt my $default = 1; 799a57419b3SSteven Rostedt my $repeat = 1; 800a57419b3SSteven Rostedt my $num_tests_set = 0; 801a57419b3SSteven Rostedt my $skip = 0; 802a57419b3SSteven Rostedt my $rest; 803a9f84424SSteven Rostedt my $line; 8040df213caSSteven Rostedt my $test_case = 0; 80545d73a5dSSteven Rostedt my $if = 0; 80645d73a5dSSteven Rostedt my $if_set = 0; 8073d1cc414SSteven Rostedt my $override = 0; 8083d1cc414SSteven Rostedt 8093d1cc414SSteven Rostedt my %overrides; 810a57419b3SSteven Rostedt 8112ed3b161SSteven Rostedt while (<$in>) { 812a57419b3SSteven Rostedt 813a57419b3SSteven Rostedt # ignore blank lines and comments 814a57419b3SSteven Rostedt next if (/^\s*$/ || /\s*\#/); 815a57419b3SSteven Rostedt 8160050b6bbSSteven Rostedt if (/^\s*(TEST_START|DEFAULTS)\b(.*)/) { 817a57419b3SSteven Rostedt 8180050b6bbSSteven Rostedt my $type = $1; 8190050b6bbSSteven Rostedt $rest = $2; 820a9f84424SSteven Rostedt $line = $2; 8210050b6bbSSteven Rostedt 8220050b6bbSSteven Rostedt my $old_test_num; 8230050b6bbSSteven Rostedt my $old_repeat; 8243d1cc414SSteven Rostedt $override = 0; 8250050b6bbSSteven Rostedt 8260050b6bbSSteven Rostedt if ($type eq "TEST_START") { 827a57419b3SSteven Rostedt 828a57419b3SSteven Rostedt if ($num_tests_set) { 829a57419b3SSteven Rostedt die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n"; 830a57419b3SSteven Rostedt } 831a57419b3SSteven Rostedt 8320050b6bbSSteven Rostedt $old_test_num = $test_num; 8330050b6bbSSteven Rostedt $old_repeat = $repeat; 834a57419b3SSteven Rostedt 835a57419b3SSteven Rostedt $test_num += $repeat; 836a57419b3SSteven Rostedt $default = 0; 837a57419b3SSteven Rostedt $repeat = 1; 8380050b6bbSSteven Rostedt } else { 8390050b6bbSSteven Rostedt $default = 1; 8400050b6bbSSteven Rostedt } 841a57419b3SSteven Rostedt 842a9f84424SSteven Rostedt # If SKIP is anywhere in the line, the command will be skipped 843a9f84424SSteven Rostedt if ($rest =~ s/\s+SKIP\b//) { 844a57419b3SSteven Rostedt $skip = 1; 845a57419b3SSteven Rostedt } else { 8460df213caSSteven Rostedt $test_case = 1; 847a57419b3SSteven Rostedt $skip = 0; 848a57419b3SSteven Rostedt } 849a57419b3SSteven Rostedt 850a9f84424SSteven Rostedt if ($rest =~ s/\sELSE\b//) { 851a9f84424SSteven Rostedt if (!$if) { 852a9f84424SSteven Rostedt die "$name: $.: ELSE found with out matching IF section\n$_"; 853a57419b3SSteven Rostedt } 854a9f84424SSteven Rostedt $if = 0; 855a9f84424SSteven Rostedt 856a9f84424SSteven Rostedt if ($if_set) { 857a9f84424SSteven Rostedt $skip = 1; 858a9f84424SSteven Rostedt } else { 859a9f84424SSteven Rostedt $skip = 0; 8603d1cc414SSteven Rostedt } 8613d1cc414SSteven Rostedt } 862a57419b3SSteven Rostedt 863a9f84424SSteven Rostedt if ($rest =~ s/\sIF\s+(.*)//) { 86445d73a5dSSteven Rostedt if (process_if($name, $1)) { 86545d73a5dSSteven Rostedt $if_set = 1; 86645d73a5dSSteven Rostedt } else { 867a57419b3SSteven Rostedt $skip = 1; 868a57419b3SSteven Rostedt } 86945d73a5dSSteven Rostedt $if = 1; 87045d73a5dSSteven Rostedt } else { 87145d73a5dSSteven Rostedt $if = 0; 872a9f84424SSteven Rostedt $if_set = 0; 87345d73a5dSSteven Rostedt } 874a57419b3SSteven Rostedt 875a9f84424SSteven Rostedt if (!$skip) { 876a9f84424SSteven Rostedt if ($type eq "TEST_START") { 877a9f84424SSteven Rostedt if ($rest =~ s/\s+ITERATE\s+(\d+)//) { 878a9f84424SSteven Rostedt $repeat = $1; 879a9f84424SSteven Rostedt $repeat_tests{"$test_num"} = $repeat; 880a9f84424SSteven Rostedt } 881a9f84424SSteven Rostedt } elsif ($rest =~ s/\sOVERRIDE\b//) { 882a9f84424SSteven Rostedt # DEFAULT only 883a9f84424SSteven Rostedt $override = 1; 884a9f84424SSteven Rostedt # Clear previous overrides 885a9f84424SSteven Rostedt %overrides = (); 886a9f84424SSteven Rostedt } 887a9f84424SSteven Rostedt } 888a9f84424SSteven Rostedt 889a9f84424SSteven Rostedt if (!$skip && $rest !~ /^\s*$/) { 8900050b6bbSSteven Rostedt die "$name: $.: Gargbage found after $type\n$_"; 891a57419b3SSteven Rostedt } 892a57419b3SSteven Rostedt 8930050b6bbSSteven Rostedt if ($skip && $type eq "TEST_START") { 894a57419b3SSteven Rostedt $test_num = $old_test_num; 895e48c5293SSteven Rostedt $repeat = $old_repeat; 896a57419b3SSteven Rostedt } 897a57419b3SSteven Rostedt 898ab7a3f52SSteven Rostedt } elsif (/^\s*ELSE\b(.*)$/) { 89945d73a5dSSteven Rostedt if (!$if) { 90045d73a5dSSteven Rostedt die "$name: $.: ELSE found with out matching IF section\n$_"; 90145d73a5dSSteven Rostedt } 90245d73a5dSSteven Rostedt $rest = $1; 90345d73a5dSSteven Rostedt if ($if_set) { 90445d73a5dSSteven Rostedt $skip = 1; 905ab7a3f52SSteven Rostedt $rest = ""; 90645d73a5dSSteven Rostedt } else { 90745d73a5dSSteven Rostedt $skip = 0; 90845d73a5dSSteven Rostedt 909ab7a3f52SSteven Rostedt if ($rest =~ /\sIF\s+(.*)/) { 91045d73a5dSSteven Rostedt # May be a ELSE IF section. 91195f57838SSteven Rostedt if (process_if($name, $1)) { 91295f57838SSteven Rostedt $if_set = 1; 91395f57838SSteven Rostedt } else { 91445d73a5dSSteven Rostedt $skip = 1; 91545d73a5dSSteven Rostedt } 916ab7a3f52SSteven Rostedt $rest = ""; 91745d73a5dSSteven Rostedt } else { 91845d73a5dSSteven Rostedt $if = 0; 91945d73a5dSSteven Rostedt } 92045d73a5dSSteven Rostedt } 92145d73a5dSSteven Rostedt 922ab7a3f52SSteven Rostedt if ($rest !~ /^\s*$/) { 923ab7a3f52SSteven Rostedt die "$name: $.: Gargbage found after DEFAULTS\n$_"; 924ab7a3f52SSteven Rostedt } 925ab7a3f52SSteven Rostedt 9262ed3b161SSteven Rostedt } elsif (/^\s*INCLUDE\s+(\S+)/) { 9272ed3b161SSteven Rostedt 9282ed3b161SSteven Rostedt next if ($skip); 9292ed3b161SSteven Rostedt 9302ed3b161SSteven Rostedt if (!$default) { 9312ed3b161SSteven Rostedt die "$name: $.: INCLUDE can only be done in default sections\n$_"; 9322ed3b161SSteven Rostedt } 9332ed3b161SSteven Rostedt 9342ed3b161SSteven Rostedt my $file = process_variables($1); 9352ed3b161SSteven Rostedt 9362ed3b161SSteven Rostedt if ($file !~ m,^/,) { 9372ed3b161SSteven Rostedt # check the path of the config file first 9382ed3b161SSteven Rostedt if ($config =~ m,(.*)/,) { 9392ed3b161SSteven Rostedt if (-f "$1/$file") { 9402ed3b161SSteven Rostedt $file = "$1/$file"; 9412ed3b161SSteven Rostedt } 9422ed3b161SSteven Rostedt } 9432ed3b161SSteven Rostedt } 9442ed3b161SSteven Rostedt 9452ed3b161SSteven Rostedt if ( ! -r $file ) { 9462ed3b161SSteven Rostedt die "$name: $.: Can't read file $file\n$_"; 9472ed3b161SSteven Rostedt } 9482ed3b161SSteven Rostedt 9492ed3b161SSteven Rostedt if (__read_config($file, \$test_num)) { 9502ed3b161SSteven Rostedt $test_case = 1; 9512ed3b161SSteven Rostedt } 9522ed3b161SSteven Rostedt 953a57419b3SSteven Rostedt } elsif (/^\s*([A-Z_\[\]\d]+)\s*=\s*(.*?)\s*$/) { 954a57419b3SSteven Rostedt 955a57419b3SSteven Rostedt next if ($skip); 956a57419b3SSteven Rostedt 957a57419b3SSteven Rostedt my $lvalue = $1; 958a57419b3SSteven Rostedt my $rvalue = $2; 959a57419b3SSteven Rostedt 960a57419b3SSteven Rostedt if (!$default && 961a57419b3SSteven Rostedt ($lvalue eq "NUM_TESTS" || 962a57419b3SSteven Rostedt $lvalue eq "LOG_FILE" || 963a57419b3SSteven Rostedt $lvalue eq "CLEAR_LOG")) { 964a57419b3SSteven Rostedt die "$name: $.: $lvalue must be set in DEFAULTS section\n"; 965a57419b3SSteven Rostedt } 966a57419b3SSteven Rostedt 967a57419b3SSteven Rostedt if ($lvalue eq "NUM_TESTS") { 968a57419b3SSteven Rostedt if ($test_num) { 969a57419b3SSteven Rostedt die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n"; 970a57419b3SSteven Rostedt } 971a57419b3SSteven Rostedt if (!$default) { 972a57419b3SSteven Rostedt die "$name: $.: NUM_TESTS must be set in default section\n"; 973a57419b3SSteven Rostedt } 974a57419b3SSteven Rostedt $num_tests_set = 1; 975a57419b3SSteven Rostedt } 976a57419b3SSteven Rostedt 977a57419b3SSteven Rostedt if ($default || $lvalue =~ /\[\d+\]$/) { 9783d1cc414SSteven Rostedt set_value($lvalue, $rvalue, $override, \%overrides, $name); 979a57419b3SSteven Rostedt } else { 980a57419b3SSteven Rostedt my $val = "$lvalue\[$test_num\]"; 9813d1cc414SSteven Rostedt set_value($val, $rvalue, $override, \%overrides, $name); 982a57419b3SSteven Rostedt 983a57419b3SSteven Rostedt if ($repeat > 1) { 984a57419b3SSteven Rostedt $repeats{$val} = $repeat; 985a57419b3SSteven Rostedt } 986a57419b3SSteven Rostedt } 98777d942ceSSteven Rostedt } elsif (/^\s*([A-Z_\[\]\d]+)\s*:=\s*(.*?)\s*$/) { 98877d942ceSSteven Rostedt next if ($skip); 98977d942ceSSteven Rostedt 99077d942ceSSteven Rostedt my $lvalue = $1; 99177d942ceSSteven Rostedt my $rvalue = $2; 99277d942ceSSteven Rostedt 99377d942ceSSteven Rostedt # process config variables. 99477d942ceSSteven Rostedt # Config variables are only active while reading the 99577d942ceSSteven Rostedt # config and can be defined anywhere. They also ignore 99677d942ceSSteven Rostedt # TEST_START and DEFAULTS, but are skipped if they are in 99777d942ceSSteven Rostedt # on of these sections that have SKIP defined. 99877d942ceSSteven Rostedt # The save variable can be 99977d942ceSSteven Rostedt # defined multiple times and the new one simply overrides 100077d942ceSSteven Rostedt # the prevous one. 100177d942ceSSteven Rostedt set_variable($lvalue, $rvalue); 100277d942ceSSteven Rostedt 1003a57419b3SSteven Rostedt } else { 1004a57419b3SSteven Rostedt die "$name: $.: Garbage found in config\n$_"; 1005a57419b3SSteven Rostedt } 10062545eb61SSteven Rostedt } 10072545eb61SSteven Rostedt 1008a57419b3SSteven Rostedt if ($test_num) { 1009a57419b3SSteven Rostedt $test_num += $repeat - 1; 1010a57419b3SSteven Rostedt $opt{"NUM_TESTS"} = $test_num; 1011a57419b3SSteven Rostedt } 1012a57419b3SSteven Rostedt 10132ed3b161SSteven Rostedt close($in); 10142ed3b161SSteven Rostedt 10152ed3b161SSteven Rostedt $$current_test_num = $test_num; 10162ed3b161SSteven Rostedt 10172ed3b161SSteven Rostedt return $test_case; 10182ed3b161SSteven Rostedt} 10192ed3b161SSteven Rostedt 1020c4261d0fSSteven Rostedtsub get_test_case { 1021c4261d0fSSteven Rostedt print "What test case would you like to run?\n"; 1022c4261d0fSSteven Rostedt print " (build, install or boot)\n"; 1023c4261d0fSSteven Rostedt print " Other tests are available but require editing the config file\n"; 1024c4261d0fSSteven Rostedt my $ans = <STDIN>; 1025c4261d0fSSteven Rostedt chomp $ans; 1026c4261d0fSSteven Rostedt $default{"TEST_TYPE"} = $ans; 1027c4261d0fSSteven Rostedt} 1028c4261d0fSSteven Rostedt 10292ed3b161SSteven Rostedtsub read_config { 10302ed3b161SSteven Rostedt my ($config) = @_; 10312ed3b161SSteven Rostedt 10322ed3b161SSteven Rostedt my $test_case; 10332ed3b161SSteven Rostedt my $test_num = 0; 10342ed3b161SSteven Rostedt 10352ed3b161SSteven Rostedt $test_case = __read_config $config, \$test_num; 10362ed3b161SSteven Rostedt 10378d1491baSSteven Rostedt # make sure we have all mandatory configs 10388d1491baSSteven Rostedt get_ktest_configs; 10398d1491baSSteven Rostedt 10400df213caSSteven Rostedt # was a test specified? 10410df213caSSteven Rostedt if (!$test_case) { 10420df213caSSteven Rostedt print "No test case specified.\n"; 1043c4261d0fSSteven Rostedt get_test_case; 10440df213caSSteven Rostedt } 10450df213caSSteven Rostedt 1046a75fececSSteven Rostedt # set any defaults 1047a75fececSSteven Rostedt 1048a75fececSSteven Rostedt foreach my $default (keys %default) { 1049a75fececSSteven Rostedt if (!defined($opt{$default})) { 1050a75fececSSteven Rostedt $opt{$default} = $default{$default}; 1051a75fececSSteven Rostedt } 1052a75fececSSteven Rostedt } 10539cc9e091SSteven Rostedt 10549cc9e091SSteven Rostedt if ($opt{"IGNORE_UNUSED"} == 1) { 10559cc9e091SSteven Rostedt return; 10569cc9e091SSteven Rostedt } 10579cc9e091SSteven Rostedt 10589cc9e091SSteven Rostedt my %not_used; 10599cc9e091SSteven Rostedt 10609cc9e091SSteven Rostedt # check if there are any stragglers (typos?) 10619cc9e091SSteven Rostedt foreach my $option (keys %opt) { 10629cc9e091SSteven Rostedt my $op = $option; 10639cc9e091SSteven Rostedt # remove per test labels. 10649cc9e091SSteven Rostedt $op =~ s/\[.*\]//; 10659cc9e091SSteven Rostedt if (!exists($option_map{$op}) && 10669cc9e091SSteven Rostedt !exists($default{$op}) && 10679cc9e091SSteven Rostedt !exists($used_options{$op})) { 10689cc9e091SSteven Rostedt $not_used{$op} = 1; 10699cc9e091SSteven Rostedt } 10709cc9e091SSteven Rostedt } 10719cc9e091SSteven Rostedt 10729cc9e091SSteven Rostedt if (%not_used) { 10739cc9e091SSteven Rostedt my $s = "s are"; 10749cc9e091SSteven Rostedt $s = " is" if (keys %not_used == 1); 10759cc9e091SSteven Rostedt print "The following option$s not used; could be a typo:\n"; 10769cc9e091SSteven Rostedt foreach my $option (keys %not_used) { 10779cc9e091SSteven Rostedt print "$option\n"; 10789cc9e091SSteven Rostedt } 10799cc9e091SSteven Rostedt print "Set IGRNORE_UNUSED = 1 to have ktest ignore unused variables\n"; 10809cc9e091SSteven Rostedt if (!read_yn "Do you want to continue?") { 10819cc9e091SSteven Rostedt exit -1; 10829cc9e091SSteven Rostedt } 10839cc9e091SSteven Rostedt } 10842545eb61SSteven Rostedt} 10852545eb61SSteven Rostedt 108623715c3cSSteven Rostedtsub __eval_option { 108704262be3SSteven Rostedt (Red Hat) my ($name, $option, $i) = @_; 108823715c3cSSteven Rostedt 108923715c3cSSteven Rostedt # Add space to evaluate the character before $ 109023715c3cSSteven Rostedt $option = " $option"; 109123715c3cSSteven Rostedt my $retval = ""; 1092f9dfb65bSRabin Vincent my $repeated = 0; 1093f9dfb65bSRabin Vincent my $parent = 0; 1094f9dfb65bSRabin Vincent 1095f9dfb65bSRabin Vincent foreach my $test (keys %repeat_tests) { 1096f9dfb65bSRabin Vincent if ($i >= $test && 1097f9dfb65bSRabin Vincent $i < $test + $repeat_tests{$test}) { 1098f9dfb65bSRabin Vincent 1099f9dfb65bSRabin Vincent $repeated = 1; 1100f9dfb65bSRabin Vincent $parent = $test; 1101f9dfb65bSRabin Vincent last; 1102f9dfb65bSRabin Vincent } 1103f9dfb65bSRabin Vincent } 110423715c3cSSteven Rostedt 110523715c3cSSteven Rostedt while ($option =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) { 110623715c3cSSteven Rostedt my $start = $1; 110723715c3cSSteven Rostedt my $var = $2; 110823715c3cSSteven Rostedt my $end = $3; 110923715c3cSSteven Rostedt 111023715c3cSSteven Rostedt # Append beginning of line 111123715c3cSSteven Rostedt $retval = "$retval$start"; 111223715c3cSSteven Rostedt 111323715c3cSSteven Rostedt # If the iteration option OPT[$i] exists, then use that. 111423715c3cSSteven Rostedt # otherwise see if the default OPT (without [$i]) exists. 111523715c3cSSteven Rostedt 111623715c3cSSteven Rostedt my $o = "$var\[$i\]"; 1117f9dfb65bSRabin Vincent my $parento = "$var\[$parent\]"; 111823715c3cSSteven Rostedt 111904262be3SSteven Rostedt (Red Hat) # If a variable contains itself, use the default var 112004262be3SSteven Rostedt (Red Hat) if (($var eq $name) && defined($opt{$var})) { 112104262be3SSteven Rostedt (Red Hat) $o = $opt{$var}; 112204262be3SSteven Rostedt (Red Hat) $retval = "$retval$o"; 112304262be3SSteven Rostedt (Red Hat) } elsif (defined($opt{$o})) { 112423715c3cSSteven Rostedt $o = $opt{$o}; 112523715c3cSSteven Rostedt $retval = "$retval$o"; 1126f9dfb65bSRabin Vincent } elsif ($repeated && defined($opt{$parento})) { 1127f9dfb65bSRabin Vincent $o = $opt{$parento}; 1128f9dfb65bSRabin Vincent $retval = "$retval$o"; 112923715c3cSSteven Rostedt } elsif (defined($opt{$var})) { 113023715c3cSSteven Rostedt $o = $opt{$var}; 113123715c3cSSteven Rostedt $retval = "$retval$o"; 1132*8e80bf05SSteven Rostedt (Red Hat) } elsif ($var eq "KERNEL_VERSION" && defined($make)) { 1133*8e80bf05SSteven Rostedt (Red Hat) # special option KERNEL_VERSION uses kernel version 1134*8e80bf05SSteven Rostedt (Red Hat) get_version(); 1135*8e80bf05SSteven Rostedt (Red Hat) $retval = "$retval$version"; 113623715c3cSSteven Rostedt } else { 113723715c3cSSteven Rostedt $retval = "$retval\$\{$var\}"; 113823715c3cSSteven Rostedt } 113923715c3cSSteven Rostedt 114023715c3cSSteven Rostedt $option = $end; 114123715c3cSSteven Rostedt } 114223715c3cSSteven Rostedt 114323715c3cSSteven Rostedt $retval = "$retval$option"; 114423715c3cSSteven Rostedt 114523715c3cSSteven Rostedt $retval =~ s/^ //; 114623715c3cSSteven Rostedt 114723715c3cSSteven Rostedt return $retval; 114823715c3cSSteven Rostedt} 114923715c3cSSteven Rostedt 115023715c3cSSteven Rostedtsub eval_option { 115104262be3SSteven Rostedt (Red Hat) my ($name, $option, $i) = @_; 115223715c3cSSteven Rostedt 115323715c3cSSteven Rostedt my $prev = ""; 115423715c3cSSteven Rostedt 115523715c3cSSteven Rostedt # Since an option can evaluate to another option, 115623715c3cSSteven Rostedt # keep iterating until we do not evaluate any more 115723715c3cSSteven Rostedt # options. 115823715c3cSSteven Rostedt my $r = 0; 115923715c3cSSteven Rostedt while ($prev ne $option) { 116023715c3cSSteven Rostedt # Check for recursive evaluations. 116123715c3cSSteven Rostedt # 100 deep should be more than enough. 116223715c3cSSteven Rostedt if ($r++ > 100) { 116323715c3cSSteven Rostedt die "Over 100 evaluations accurred with $option\n" . 116423715c3cSSteven Rostedt "Check for recursive variables\n"; 116523715c3cSSteven Rostedt } 116623715c3cSSteven Rostedt $prev = $option; 116704262be3SSteven Rostedt (Red Hat) $option = __eval_option($name, $option, $i); 116823715c3cSSteven Rostedt } 116923715c3cSSteven Rostedt 117023715c3cSSteven Rostedt return $option; 117123715c3cSSteven Rostedt} 117223715c3cSSteven Rostedt 1173d1e2f22aSSteven Rostedtsub _logit { 11742545eb61SSteven Rostedt if (defined($opt{"LOG_FILE"})) { 11752545eb61SSteven Rostedt open(OUT, ">> $opt{LOG_FILE}") or die "Can't write to $opt{LOG_FILE}"; 11762545eb61SSteven Rostedt print OUT @_; 11772545eb61SSteven Rostedt close(OUT); 11782545eb61SSteven Rostedt } 11792545eb61SSteven Rostedt} 11802545eb61SSteven Rostedt 1181d1e2f22aSSteven Rostedtsub logit { 1182d1e2f22aSSteven Rostedt if (defined($opt{"LOG_FILE"})) { 1183d1e2f22aSSteven Rostedt _logit @_; 1184d1e2f22aSSteven Rostedt } else { 1185d1e2f22aSSteven Rostedt print @_; 1186d1e2f22aSSteven Rostedt } 1187d1e2f22aSSteven Rostedt} 1188d1e2f22aSSteven Rostedt 11895f9b6cedSSteven Rostedtsub doprint { 11905f9b6cedSSteven Rostedt print @_; 1191d1e2f22aSSteven Rostedt _logit @_; 11925f9b6cedSSteven Rostedt} 11935f9b6cedSSteven Rostedt 11947faafbd6SSteven Rostedtsub run_command; 11952728be41SAndrew Jonessub start_monitor; 11962728be41SAndrew Jonessub end_monitor; 11972728be41SAndrew Jonessub wait_for_monitor; 11987faafbd6SSteven Rostedt 11997faafbd6SSteven Rostedtsub reboot { 12002728be41SAndrew Jones my ($time) = @_; 12012728be41SAndrew Jones 1202a4968722SSteven Rostedt # Make sure everything has been written to disk 1203a4968722SSteven Rostedt run_ssh("sync"); 1204a4968722SSteven Rostedt 12052b803365SSteven Rostedt if (defined($time)) { 12062b803365SSteven Rostedt start_monitor; 12072b803365SSteven Rostedt # flush out current monitor 12082b803365SSteven Rostedt # May contain the reboot success line 12092b803365SSteven Rostedt wait_for_monitor 1; 12102b803365SSteven Rostedt } 12112b803365SSteven Rostedt 12127faafbd6SSteven Rostedt # try to reboot normally 1213e48c5293SSteven Rostedt if (run_command $reboot) { 1214576f627cSSteven Rostedt if (defined($powercycle_after_reboot)) { 1215576f627cSSteven Rostedt sleep $powercycle_after_reboot; 1216576f627cSSteven Rostedt run_command "$power_cycle"; 1217576f627cSSteven Rostedt } 1218576f627cSSteven Rostedt } else { 12197faafbd6SSteven Rostedt # nope? power cycle it. 1220a75fececSSteven Rostedt run_command "$power_cycle"; 12217faafbd6SSteven Rostedt } 12222728be41SAndrew Jones 12232728be41SAndrew Jones if (defined($time)) { 12244c0b67a2SSteven Rostedt (Red Hat) 12254c0b67a2SSteven Rostedt (Red Hat) # We only want to get to the new kernel, don't fail 12264c0b67a2SSteven Rostedt (Red Hat) # if we stumble over a call trace. 12274c0b67a2SSteven Rostedt (Red Hat) my $save_ignore_errors = $ignore_errors; 12284c0b67a2SSteven Rostedt (Red Hat) $ignore_errors = 1; 12294c0b67a2SSteven Rostedt (Red Hat) 1230d6845536SSteven Rostedt (Red Hat) # Look for the good kernel to boot 1231d6845536SSteven Rostedt (Red Hat) if (wait_for_monitor($time, "Linux version")) { 1232407b95b7SSteven Rostedt # reboot got stuck? 12338a80c727SSteven Rostedt doprint "Reboot did not finish. Forcing power cycle\n"; 1234407b95b7SSteven Rostedt run_command "$power_cycle"; 1235407b95b7SSteven Rostedt } 1236d6845536SSteven Rostedt (Red Hat) 12374c0b67a2SSteven Rostedt (Red Hat) $ignore_errors = $save_ignore_errors; 12384c0b67a2SSteven Rostedt (Red Hat) 1239d6845536SSteven Rostedt (Red Hat) # Still need to wait for the reboot to finish 1240d6845536SSteven Rostedt (Red Hat) wait_for_monitor($time, $reboot_success_line); 1241d6845536SSteven Rostedt (Red Hat) 12422728be41SAndrew Jones end_monitor; 12432728be41SAndrew Jones } 12447faafbd6SSteven Rostedt} 12457faafbd6SSteven Rostedt 1246bc7c5803SSteven Rostedtsub reboot_to_good { 1247bc7c5803SSteven Rostedt my ($time) = @_; 1248bc7c5803SSteven Rostedt 1249bc7c5803SSteven Rostedt if (defined($switch_to_good)) { 1250bc7c5803SSteven Rostedt run_command $switch_to_good; 1251bc7c5803SSteven Rostedt } 1252bc7c5803SSteven Rostedt 1253bc7c5803SSteven Rostedt reboot $time; 1254bc7c5803SSteven Rostedt} 1255bc7c5803SSteven Rostedt 1256576f627cSSteven Rostedtsub do_not_reboot { 1257576f627cSSteven Rostedt my $i = $iteration; 1258576f627cSSteven Rostedt 12594ab1cce5SSteven Rostedt return $test_type eq "build" || $no_reboot || 1260576f627cSSteven Rostedt ($test_type eq "patchcheck" && $opt{"PATCHCHECK_TYPE[$i]"} eq "build") || 1261576f627cSSteven Rostedt ($test_type eq "bisect" && $opt{"BISECT_TYPE[$i]"} eq "build"); 1262576f627cSSteven Rostedt} 1263576f627cSSteven Rostedt 12645c42fc5bSSteven Rostedtsub dodie { 12655a391fbfSSteven Rostedt doprint "CRITICAL FAILURE... ", @_, "\n"; 12665c42fc5bSSteven Rostedt 1267576f627cSSteven Rostedt my $i = $iteration; 1268576f627cSSteven Rostedt 1269576f627cSSteven Rostedt if ($reboot_on_error && !do_not_reboot) { 1270576f627cSSteven Rostedt 127175c3fda7SSteven Rostedt doprint "REBOOTING\n"; 1272bc7c5803SSteven Rostedt reboot_to_good; 127375c3fda7SSteven Rostedt 1274a75fececSSteven Rostedt } elsif ($poweroff_on_error && defined($power_off)) { 12755c42fc5bSSteven Rostedt doprint "POWERING OFF\n"; 1276a75fececSSteven Rostedt `$power_off`; 12775c42fc5bSSteven Rostedt } 127875c3fda7SSteven Rostedt 1279f80802cbSSteven Rostedt if (defined($opt{"LOG_FILE"})) { 1280f80802cbSSteven Rostedt print " See $opt{LOG_FILE} for more info.\n"; 1281f80802cbSSteven Rostedt } 1282f80802cbSSteven Rostedt 1283576f627cSSteven Rostedt die @_, "\n"; 12845c42fc5bSSteven Rostedt} 12855c42fc5bSSteven Rostedt 12867faafbd6SSteven Rostedtsub open_console { 12877faafbd6SSteven Rostedt my ($fp) = @_; 12887faafbd6SSteven Rostedt 12897faafbd6SSteven Rostedt my $flags; 12907faafbd6SSteven Rostedt 1291a75fececSSteven Rostedt my $pid = open($fp, "$console|") or 1292a75fececSSteven Rostedt dodie "Can't open console $console"; 12937faafbd6SSteven Rostedt 12947faafbd6SSteven Rostedt $flags = fcntl($fp, F_GETFL, 0) or 1295576f627cSSteven Rostedt dodie "Can't get flags for the socket: $!"; 12967faafbd6SSteven Rostedt $flags = fcntl($fp, F_SETFL, $flags | O_NONBLOCK) or 1297576f627cSSteven Rostedt dodie "Can't set flags for the socket: $!"; 12987faafbd6SSteven Rostedt 12997faafbd6SSteven Rostedt return $pid; 13007faafbd6SSteven Rostedt} 13017faafbd6SSteven Rostedt 13027faafbd6SSteven Rostedtsub close_console { 13037faafbd6SSteven Rostedt my ($fp, $pid) = @_; 13047faafbd6SSteven Rostedt 13057faafbd6SSteven Rostedt doprint "kill child process $pid\n"; 13065a5d8e48SSatoru Takeuchi kill $close_console_signal, $pid; 13077faafbd6SSteven Rostedt 13087faafbd6SSteven Rostedt print "closing!\n"; 13097faafbd6SSteven Rostedt close($fp); 13107faafbd6SSteven Rostedt} 13117faafbd6SSteven Rostedt 13127faafbd6SSteven Rostedtsub start_monitor { 13137faafbd6SSteven Rostedt if ($monitor_cnt++) { 13147faafbd6SSteven Rostedt return; 13157faafbd6SSteven Rostedt } 13167faafbd6SSteven Rostedt $monitor_fp = \*MONFD; 13177faafbd6SSteven Rostedt $monitor_pid = open_console $monitor_fp; 1318a75fececSSteven Rostedt 1319a75fececSSteven Rostedt return; 1320a75fececSSteven Rostedt 1321a75fececSSteven Rostedt open(MONFD, "Stop perl from warning about single use of MONFD"); 13227faafbd6SSteven Rostedt} 13237faafbd6SSteven Rostedt 13247faafbd6SSteven Rostedtsub end_monitor { 1325319ab14fSSteven Rostedt (Red Hat) return if (!defined $console); 13267faafbd6SSteven Rostedt if (--$monitor_cnt) { 13277faafbd6SSteven Rostedt return; 13287faafbd6SSteven Rostedt } 13297faafbd6SSteven Rostedt close_console($monitor_fp, $monitor_pid); 13307faafbd6SSteven Rostedt} 13317faafbd6SSteven Rostedt 13327faafbd6SSteven Rostedtsub wait_for_monitor { 13332b803365SSteven Rostedt my ($time, $stop) = @_; 13342b803365SSteven Rostedt my $full_line = ""; 13357faafbd6SSteven Rostedt my $line; 13362b803365SSteven Rostedt my $booted = 0; 1337407b95b7SSteven Rostedt my $start_time = time; 13388a80c727SSteven Rostedt my $skip_call_trace = 0; 13398a80c727SSteven Rostedt my $bug = 0; 13408a80c727SSteven Rostedt my $bug_ignored = 0; 1341407b95b7SSteven Rostedt my $now; 13427faafbd6SSteven Rostedt 1343a75fececSSteven Rostedt doprint "** Wait for monitor to settle down **\n"; 13447faafbd6SSteven Rostedt 13457faafbd6SSteven Rostedt # read the monitor and wait for the system to calm down 13462b803365SSteven Rostedt while (!$booted) { 13477faafbd6SSteven Rostedt $line = wait_for_input($monitor_fp, $time); 13482b803365SSteven Rostedt last if (!defined($line)); 13492b803365SSteven Rostedt print "$line"; 13502b803365SSteven Rostedt $full_line .= $line; 13512b803365SSteven Rostedt 13522b803365SSteven Rostedt if (defined($stop) && $full_line =~ /$stop/) { 13532b803365SSteven Rostedt doprint "wait for monitor detected $stop\n"; 13542b803365SSteven Rostedt $booted = 1; 13552b803365SSteven Rostedt } 13562b803365SSteven Rostedt 13578a80c727SSteven Rostedt if ($full_line =~ /\[ backtrace testing \]/) { 13588a80c727SSteven Rostedt $skip_call_trace = 1; 13598a80c727SSteven Rostedt } 13608a80c727SSteven Rostedt 13618a80c727SSteven Rostedt if ($full_line =~ /call trace:/i) { 13628a80c727SSteven Rostedt if (!$bug && !$skip_call_trace) { 13638a80c727SSteven Rostedt if ($ignore_errors) { 13648a80c727SSteven Rostedt $bug_ignored = 1; 13658a80c727SSteven Rostedt } else { 13668a80c727SSteven Rostedt $bug = 1; 13678a80c727SSteven Rostedt } 13688a80c727SSteven Rostedt } 13698a80c727SSteven Rostedt } 13708a80c727SSteven Rostedt 13718a80c727SSteven Rostedt if ($full_line =~ /\[ end of backtrace testing \]/) { 13728a80c727SSteven Rostedt $skip_call_trace = 0; 13738a80c727SSteven Rostedt } 13748a80c727SSteven Rostedt 13758a80c727SSteven Rostedt if ($full_line =~ /Kernel panic -/) { 13768a80c727SSteven Rostedt $bug = 1; 13778a80c727SSteven Rostedt } 13788a80c727SSteven Rostedt 13792b803365SSteven Rostedt if ($line =~ /\n/) { 13802b803365SSteven Rostedt $full_line = ""; 13812b803365SSteven Rostedt } 1382407b95b7SSteven Rostedt $now = time; 1383407b95b7SSteven Rostedt if ($now - $start_time >= $max_monitor_wait) { 1384407b95b7SSteven Rostedt doprint "Exiting monitor flush due to hitting MAX_MONITOR_WAIT\n"; 1385407b95b7SSteven Rostedt return 1; 1386407b95b7SSteven Rostedt } 13872b803365SSteven Rostedt } 1388a75fececSSteven Rostedt print "** Monitor flushed **\n"; 13898a80c727SSteven Rostedt return $bug; 13907faafbd6SSteven Rostedt} 13917faafbd6SSteven Rostedt 1392de5b6e3bSRabin Vincentsub save_logs { 1393de5b6e3bSRabin Vincent my ($result, $basedir) = @_; 1394de5b6e3bSRabin Vincent my @t = localtime; 1395de5b6e3bSRabin Vincent my $date = sprintf "%04d%02d%02d%02d%02d%02d", 1396de5b6e3bSRabin Vincent 1900+$t[5],$t[4],$t[3],$t[2],$t[1],$t[0]; 1397de5b6e3bSRabin Vincent 1398de5b6e3bSRabin Vincent my $type = $build_type; 1399de5b6e3bSRabin Vincent if ($type =~ /useconfig/) { 1400de5b6e3bSRabin Vincent $type = "useconfig"; 1401de5b6e3bSRabin Vincent } 1402de5b6e3bSRabin Vincent 1403de5b6e3bSRabin Vincent my $dir = "$machine-$test_type-$type-$result-$date"; 1404de5b6e3bSRabin Vincent 1405de5b6e3bSRabin Vincent $dir = "$basedir/$dir"; 1406de5b6e3bSRabin Vincent 1407de5b6e3bSRabin Vincent if (!-d $dir) { 1408de5b6e3bSRabin Vincent mkpath($dir) or 1409de5b6e3bSRabin Vincent die "can't create $dir"; 1410de5b6e3bSRabin Vincent } 1411de5b6e3bSRabin Vincent 1412de5b6e3bSRabin Vincent my %files = ( 1413de5b6e3bSRabin Vincent "config" => $output_config, 1414de5b6e3bSRabin Vincent "buildlog" => $buildlog, 1415de5b6e3bSRabin Vincent "dmesg" => $dmesg, 1416de5b6e3bSRabin Vincent "testlog" => $testlog, 1417de5b6e3bSRabin Vincent ); 1418de5b6e3bSRabin Vincent 1419de5b6e3bSRabin Vincent while (my ($name, $source) = each(%files)) { 1420de5b6e3bSRabin Vincent if (-f "$source") { 1421de5b6e3bSRabin Vincent cp "$source", "$dir/$name" or 1422de5b6e3bSRabin Vincent die "failed to copy $source"; 1423de5b6e3bSRabin Vincent } 1424de5b6e3bSRabin Vincent } 1425de5b6e3bSRabin Vincent 1426de5b6e3bSRabin Vincent doprint "*** Saved info to $dir ***\n"; 1427de5b6e3bSRabin Vincent} 1428de5b6e3bSRabin Vincent 14292b7d9b21SSteven Rostedtsub fail { 14302b7d9b21SSteven Rostedt 1431921ed4c7SSteven Rostedt if (defined($post_test)) { 1432921ed4c7SSteven Rostedt run_command $post_test; 1433921ed4c7SSteven Rostedt } 1434921ed4c7SSteven Rostedt 1435a75fececSSteven Rostedt if ($die_on_failure) { 14362b7d9b21SSteven Rostedt dodie @_; 14372b7d9b21SSteven Rostedt } 14382b7d9b21SSteven Rostedt 1439a75fececSSteven Rostedt doprint "FAILED\n"; 14407faafbd6SSteven Rostedt 1441576f627cSSteven Rostedt my $i = $iteration; 1442576f627cSSteven Rostedt 1443a75fececSSteven Rostedt # no need to reboot for just building. 1444576f627cSSteven Rostedt if (!do_not_reboot) { 14457faafbd6SSteven Rostedt doprint "REBOOTING\n"; 1446bc7c5803SSteven Rostedt reboot_to_good $sleep_time; 1447a75fececSSteven Rostedt } 14487faafbd6SSteven Rostedt 14499064af52SSteven Rostedt my $name = ""; 14509064af52SSteven Rostedt 14519064af52SSteven Rostedt if (defined($test_name)) { 14529064af52SSteven Rostedt $name = " ($test_name)"; 14539064af52SSteven Rostedt } 14549064af52SSteven Rostedt 1455576f627cSSteven Rostedt doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"; 1456576f627cSSteven Rostedt doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"; 14579064af52SSteven Rostedt doprint "KTEST RESULT: TEST $i$name Failed: ", @_, "\n"; 1458576f627cSSteven Rostedt doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"; 1459576f627cSSteven Rostedt doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"; 1460a75fececSSteven Rostedt 1461de5b6e3bSRabin Vincent if (defined($store_failures)) { 1462de5b6e3bSRabin Vincent save_logs "fail", $store_failures; 1463cccae1a6SSteven Rostedt } 1464cccae1a6SSteven Rostedt 14652b7d9b21SSteven Rostedt return 1; 14662b7d9b21SSteven Rostedt} 14672b7d9b21SSteven Rostedt 14682545eb61SSteven Rostedtsub run_command { 14692545eb61SSteven Rostedt my ($command) = @_; 1470d6ce2a0bSSteven Rostedt my $dolog = 0; 1471d6ce2a0bSSteven Rostedt my $dord = 0; 1472d6ce2a0bSSteven Rostedt my $pid; 1473d6ce2a0bSSteven Rostedt 1474e48c5293SSteven Rostedt $command =~ s/\$SSH_USER/$ssh_user/g; 1475e48c5293SSteven Rostedt $command =~ s/\$MACHINE/$machine/g; 1476e48c5293SSteven Rostedt 1477d6ce2a0bSSteven Rostedt doprint("$command ... "); 1478d6ce2a0bSSteven Rostedt 1479d6ce2a0bSSteven Rostedt $pid = open(CMD, "$command 2>&1 |") or 14802b7d9b21SSteven Rostedt (fail "unable to exec $command" and return 0); 14812545eb61SSteven Rostedt 14822545eb61SSteven Rostedt if (defined($opt{"LOG_FILE"})) { 1483d6ce2a0bSSteven Rostedt open(LOG, ">>$opt{LOG_FILE}") or 1484d6ce2a0bSSteven Rostedt dodie "failed to write to log"; 1485d6ce2a0bSSteven Rostedt $dolog = 1; 14866c5ee0beSSteven Rostedt } 14876c5ee0beSSteven Rostedt 14886c5ee0beSSteven Rostedt if (defined($redirect)) { 1489d6ce2a0bSSteven Rostedt open (RD, ">$redirect") or 1490d6ce2a0bSSteven Rostedt dodie "failed to write to redirect $redirect"; 1491d6ce2a0bSSteven Rostedt $dord = 1; 14922545eb61SSteven Rostedt } 14932545eb61SSteven Rostedt 1494d6ce2a0bSSteven Rostedt while (<CMD>) { 1495d6ce2a0bSSteven Rostedt print LOG if ($dolog); 1496d6ce2a0bSSteven Rostedt print RD if ($dord); 1497d6ce2a0bSSteven Rostedt } 14982545eb61SSteven Rostedt 1499d6ce2a0bSSteven Rostedt waitpid($pid, 0); 15002545eb61SSteven Rostedt my $failed = $?; 15012545eb61SSteven Rostedt 1502d6ce2a0bSSteven Rostedt close(CMD); 1503d6ce2a0bSSteven Rostedt close(LOG) if ($dolog); 1504d6ce2a0bSSteven Rostedt close(RD) if ($dord); 1505d6ce2a0bSSteven Rostedt 15062545eb61SSteven Rostedt if ($failed) { 15072545eb61SSteven Rostedt doprint "FAILED!\n"; 15082545eb61SSteven Rostedt } else { 15092545eb61SSteven Rostedt doprint "SUCCESS\n"; 15102545eb61SSteven Rostedt } 15112545eb61SSteven Rostedt 15125f9b6cedSSteven Rostedt return !$failed; 15135f9b6cedSSteven Rostedt} 15145f9b6cedSSteven Rostedt 1515e48c5293SSteven Rostedtsub run_ssh { 1516e48c5293SSteven Rostedt my ($cmd) = @_; 1517e48c5293SSteven Rostedt my $cp_exec = $ssh_exec; 1518e48c5293SSteven Rostedt 1519e48c5293SSteven Rostedt $cp_exec =~ s/\$SSH_COMMAND/$cmd/g; 1520e48c5293SSteven Rostedt return run_command "$cp_exec"; 1521e48c5293SSteven Rostedt} 1522e48c5293SSteven Rostedt 1523e48c5293SSteven Rostedtsub run_scp { 152402ad2617SSteven Rostedt my ($src, $dst, $cp_scp) = @_; 1525e48c5293SSteven Rostedt 1526e48c5293SSteven Rostedt $cp_scp =~ s/\$SRC_FILE/$src/g; 1527e48c5293SSteven Rostedt $cp_scp =~ s/\$DST_FILE/$dst/g; 1528e48c5293SSteven Rostedt 1529e48c5293SSteven Rostedt return run_command "$cp_scp"; 1530e48c5293SSteven Rostedt} 1531e48c5293SSteven Rostedt 153202ad2617SSteven Rostedtsub run_scp_install { 153302ad2617SSteven Rostedt my ($src, $dst) = @_; 153402ad2617SSteven Rostedt 153502ad2617SSteven Rostedt my $cp_scp = $scp_to_target_install; 153602ad2617SSteven Rostedt 153702ad2617SSteven Rostedt return run_scp($src, $dst, $cp_scp); 153802ad2617SSteven Rostedt} 153902ad2617SSteven Rostedt 154002ad2617SSteven Rostedtsub run_scp_mod { 154102ad2617SSteven Rostedt my ($src, $dst) = @_; 154202ad2617SSteven Rostedt 154302ad2617SSteven Rostedt my $cp_scp = $scp_to_target; 154402ad2617SSteven Rostedt 154502ad2617SSteven Rostedt return run_scp($src, $dst, $cp_scp); 154602ad2617SSteven Rostedt} 154702ad2617SSteven Rostedt 1548a15ba913SSteven Rostedtsub get_grub2_index { 1549a15ba913SSteven Rostedt 1550752d9665SSteven Rostedt (Red Hat) return if (defined($grub_number) && defined($last_grub_menu) && 1551df5f7c66SSteven Rostedt (Red Hat) $last_grub_menu eq $grub_menu && defined($last_machine) && 1552df5f7c66SSteven Rostedt (Red Hat) $last_machine eq $machine); 1553a15ba913SSteven Rostedt 1554a15ba913SSteven Rostedt doprint "Find grub2 menu ... "; 1555a15ba913SSteven Rostedt $grub_number = -1; 1556a15ba913SSteven Rostedt 1557a15ba913SSteven Rostedt my $ssh_grub = $ssh_exec; 1558a15ba913SSteven Rostedt $ssh_grub =~ s,\$SSH_COMMAND,cat $grub_file,g; 1559a15ba913SSteven Rostedt 1560a15ba913SSteven Rostedt open(IN, "$ssh_grub |") 1561a15ba913SSteven Rostedt or die "unable to get $grub_file"; 1562a15ba913SSteven Rostedt 1563a15ba913SSteven Rostedt my $found = 0; 1564a15ba913SSteven Rostedt 1565a15ba913SSteven Rostedt while (<IN>) { 1566a15ba913SSteven Rostedt if (/^menuentry.*$grub_menu/) { 1567a15ba913SSteven Rostedt $grub_number++; 1568a15ba913SSteven Rostedt $found = 1; 1569a15ba913SSteven Rostedt last; 1570a15ba913SSteven Rostedt } elsif (/^menuentry\s/) { 1571a15ba913SSteven Rostedt $grub_number++; 1572a15ba913SSteven Rostedt } 1573a15ba913SSteven Rostedt } 1574a15ba913SSteven Rostedt close(IN); 1575a15ba913SSteven Rostedt 1576a15ba913SSteven Rostedt die "Could not find '$grub_menu' in $grub_file on $machine" 1577a15ba913SSteven Rostedt if (!$found); 1578a15ba913SSteven Rostedt doprint "$grub_number\n"; 1579752d9665SSteven Rostedt (Red Hat) $last_grub_menu = $grub_menu; 1580df5f7c66SSteven Rostedt (Red Hat) $last_machine = $machine; 1581a15ba913SSteven Rostedt} 1582a15ba913SSteven Rostedt 15835f9b6cedSSteven Rostedtsub get_grub_index { 15845f9b6cedSSteven Rostedt 1585a15ba913SSteven Rostedt if ($reboot_type eq "grub2") { 1586a15ba913SSteven Rostedt get_grub2_index; 1587a15ba913SSteven Rostedt return; 1588a15ba913SSteven Rostedt } 1589a15ba913SSteven Rostedt 1590a75fececSSteven Rostedt if ($reboot_type ne "grub") { 1591a75fececSSteven Rostedt return; 1592a75fececSSteven Rostedt } 1593752d9665SSteven Rostedt (Red Hat) return if (defined($grub_number) && defined($last_grub_menu) && 1594df5f7c66SSteven Rostedt (Red Hat) $last_grub_menu eq $grub_menu && defined($last_machine) && 1595df5f7c66SSteven Rostedt (Red Hat) $last_machine eq $machine); 15965f9b6cedSSteven Rostedt 15975f9b6cedSSteven Rostedt doprint "Find grub menu ... "; 15985f9b6cedSSteven Rostedt $grub_number = -1; 1599e48c5293SSteven Rostedt 1600e48c5293SSteven Rostedt my $ssh_grub = $ssh_exec; 1601e48c5293SSteven Rostedt $ssh_grub =~ s,\$SSH_COMMAND,cat /boot/grub/menu.lst,g; 1602e48c5293SSteven Rostedt 1603e48c5293SSteven Rostedt open(IN, "$ssh_grub |") 16045f9b6cedSSteven Rostedt or die "unable to get menu.lst"; 1605e48c5293SSteven Rostedt 1606eaa1fe25SSteven Rostedt my $found = 0; 1607eaa1fe25SSteven Rostedt 16085f9b6cedSSteven Rostedt while (<IN>) { 1609a75fececSSteven Rostedt if (/^\s*title\s+$grub_menu\s*$/) { 16105f9b6cedSSteven Rostedt $grub_number++; 1611eaa1fe25SSteven Rostedt $found = 1; 16125f9b6cedSSteven Rostedt last; 16135f9b6cedSSteven Rostedt } elsif (/^\s*title\s/) { 16145f9b6cedSSteven Rostedt $grub_number++; 16155f9b6cedSSteven Rostedt } 16165f9b6cedSSteven Rostedt } 16175f9b6cedSSteven Rostedt close(IN); 16185f9b6cedSSteven Rostedt 1619a75fececSSteven Rostedt die "Could not find '$grub_menu' in /boot/grub/menu on $machine" 1620eaa1fe25SSteven Rostedt if (!$found); 16215f9b6cedSSteven Rostedt doprint "$grub_number\n"; 1622752d9665SSteven Rostedt (Red Hat) $last_grub_menu = $grub_menu; 1623df5f7c66SSteven Rostedt (Red Hat) $last_machine = $machine; 16242545eb61SSteven Rostedt} 16252545eb61SSteven Rostedt 16262545eb61SSteven Rostedtsub wait_for_input 16272545eb61SSteven Rostedt{ 16282545eb61SSteven Rostedt my ($fp, $time) = @_; 16292545eb61SSteven Rostedt my $rin; 16302545eb61SSteven Rostedt my $ready; 16312545eb61SSteven Rostedt my $line; 16322545eb61SSteven Rostedt my $ch; 16332545eb61SSteven Rostedt 16342545eb61SSteven Rostedt if (!defined($time)) { 16352545eb61SSteven Rostedt $time = $timeout; 16362545eb61SSteven Rostedt } 16372545eb61SSteven Rostedt 16382545eb61SSteven Rostedt $rin = ''; 16392545eb61SSteven Rostedt vec($rin, fileno($fp), 1) = 1; 1640319ab14fSSteven Rostedt (Red Hat) ($ready, $time) = select($rin, undef, undef, $time); 16412545eb61SSteven Rostedt 16422545eb61SSteven Rostedt $line = ""; 16432545eb61SSteven Rostedt 16442545eb61SSteven Rostedt # try to read one char at a time 16452545eb61SSteven Rostedt while (sysread $fp, $ch, 1) { 16462545eb61SSteven Rostedt $line .= $ch; 16472545eb61SSteven Rostedt last if ($ch eq "\n"); 16482545eb61SSteven Rostedt } 16492545eb61SSteven Rostedt 16502545eb61SSteven Rostedt if (!length($line)) { 16512545eb61SSteven Rostedt return undef; 16522545eb61SSteven Rostedt } 16532545eb61SSteven Rostedt 16542545eb61SSteven Rostedt return $line; 16552545eb61SSteven Rostedt} 16562545eb61SSteven Rostedt 165775c3fda7SSteven Rostedtsub reboot_to { 1658bc7c5803SSteven Rostedt if (defined($switch_to_test)) { 1659bc7c5803SSteven Rostedt run_command $switch_to_test; 1660bc7c5803SSteven Rostedt } 1661bc7c5803SSteven Rostedt 1662a75fececSSteven Rostedt if ($reboot_type eq "grub") { 1663c54367f9SSteven Rostedt run_ssh "'(echo \"savedefault --default=$grub_number --once\" | grub --batch)'"; 1664a15ba913SSteven Rostedt } elsif ($reboot_type eq "grub2") { 1665a15ba913SSteven Rostedt run_ssh "$grub_reboot $grub_number"; 16667786954cSSteven Rostedt } elsif ($reboot_type eq "syslinux") { 16677786954cSSteven Rostedt run_ssh "$syslinux --once \\\"$syslinux_label\\\" $syslinux_path"; 166896f6a0dfSSteven Rostedt } elsif (defined $reboot_script) { 1669a75fececSSteven Rostedt run_command "$reboot_script"; 16702545eb61SSteven Rostedt } 167196f6a0dfSSteven Rostedt reboot; 167296f6a0dfSSteven Rostedt} 16732545eb61SSteven Rostedt 1674a57419b3SSteven Rostedtsub get_sha1 { 1675a57419b3SSteven Rostedt my ($commit) = @_; 1676a57419b3SSteven Rostedt 1677a57419b3SSteven Rostedt doprint "git rev-list --max-count=1 $commit ... "; 1678a57419b3SSteven Rostedt my $sha1 = `git rev-list --max-count=1 $commit`; 1679a57419b3SSteven Rostedt my $ret = $?; 1680a57419b3SSteven Rostedt 1681a57419b3SSteven Rostedt logit $sha1; 1682a57419b3SSteven Rostedt 1683a57419b3SSteven Rostedt if ($ret) { 1684a57419b3SSteven Rostedt doprint "FAILED\n"; 1685a57419b3SSteven Rostedt dodie "Failed to get git $commit"; 1686a57419b3SSteven Rostedt } 1687a57419b3SSteven Rostedt 1688a57419b3SSteven Rostedt print "SUCCESS\n"; 1689a57419b3SSteven Rostedt 1690a57419b3SSteven Rostedt chomp $sha1; 1691a57419b3SSteven Rostedt 1692a57419b3SSteven Rostedt return $sha1; 1693a57419b3SSteven Rostedt} 1694a57419b3SSteven Rostedt 16955a391fbfSSteven Rostedtsub monitor { 16962545eb61SSteven Rostedt my $booted = 0; 16972545eb61SSteven Rostedt my $bug = 0; 16986ca996ccSSteven Rostedt my $bug_ignored = 0; 16995c42fc5bSSteven Rostedt my $skip_call_trace = 0; 17002b7d9b21SSteven Rostedt my $loops; 17012545eb61SSteven Rostedt 17027faafbd6SSteven Rostedt wait_for_monitor 5; 17032545eb61SSteven Rostedt 17042545eb61SSteven Rostedt my $line; 17052545eb61SSteven Rostedt my $full_line = ""; 17062545eb61SSteven Rostedt 17077faafbd6SSteven Rostedt open(DMESG, "> $dmesg") or 17087faafbd6SSteven Rostedt die "unable to write to $dmesg"; 17092545eb61SSteven Rostedt 171075c3fda7SSteven Rostedt reboot_to; 17112545eb61SSteven Rostedt 17121c8a617aSSteven Rostedt my $success_start; 17131c8a617aSSteven Rostedt my $failure_start; 17142d01b26aSSteven Rostedt my $monitor_start = time; 17152d01b26aSSteven Rostedt my $done = 0; 1716f1a5b962SSteven Rostedt my $version_found = 0; 17171c8a617aSSteven Rostedt 17182d01b26aSSteven Rostedt while (!$done) { 17192545eb61SSteven Rostedt 1720ecaf8e52SSteven Rostedt if ($bug && defined($stop_after_failure) && 1721ecaf8e52SSteven Rostedt $stop_after_failure >= 0) { 1722ecaf8e52SSteven Rostedt my $time = $stop_after_failure - (time - $failure_start); 1723ecaf8e52SSteven Rostedt $line = wait_for_input($monitor_fp, $time); 1724ecaf8e52SSteven Rostedt if (!defined($line)) { 1725ecaf8e52SSteven Rostedt doprint "bug timed out after $booted_timeout seconds\n"; 1726ecaf8e52SSteven Rostedt doprint "Test forced to stop after $stop_after_failure seconds after failure\n"; 1727ecaf8e52SSteven Rostedt last; 1728ecaf8e52SSteven Rostedt } 1729ecaf8e52SSteven Rostedt } elsif ($booted) { 1730a75fececSSteven Rostedt $line = wait_for_input($monitor_fp, $booted_timeout); 1731cd4f1d53SSteven Rostedt if (!defined($line)) { 1732cd4f1d53SSteven Rostedt my $s = $booted_timeout == 1 ? "" : "s"; 1733cd4f1d53SSteven Rostedt doprint "Successful boot found: break after $booted_timeout second$s\n"; 1734cd4f1d53SSteven Rostedt last; 1735cd4f1d53SSteven Rostedt } 17362b7d9b21SSteven Rostedt } else { 17377faafbd6SSteven Rostedt $line = wait_for_input($monitor_fp); 1738cd4f1d53SSteven Rostedt if (!defined($line)) { 1739cd4f1d53SSteven Rostedt my $s = $timeout == 1 ? "" : "s"; 1740cd4f1d53SSteven Rostedt doprint "Timed out after $timeout second$s\n"; 1741cd4f1d53SSteven Rostedt last; 17422b7d9b21SSteven Rostedt } 1743cd4f1d53SSteven Rostedt } 17442545eb61SSteven Rostedt 17452545eb61SSteven Rostedt doprint $line; 17467faafbd6SSteven Rostedt print DMESG $line; 17472545eb61SSteven Rostedt 17482545eb61SSteven Rostedt # we are not guaranteed to get a full line 17492545eb61SSteven Rostedt $full_line .= $line; 17502545eb61SSteven Rostedt 1751a75fececSSteven Rostedt if ($full_line =~ /$success_line/) { 17522545eb61SSteven Rostedt $booted = 1; 17531c8a617aSSteven Rostedt $success_start = time; 17541c8a617aSSteven Rostedt } 17551c8a617aSSteven Rostedt 17561c8a617aSSteven Rostedt if ($booted && defined($stop_after_success) && 17571c8a617aSSteven Rostedt $stop_after_success >= 0) { 17581c8a617aSSteven Rostedt my $now = time; 17591c8a617aSSteven Rostedt if ($now - $success_start >= $stop_after_success) { 17601c8a617aSSteven Rostedt doprint "Test forced to stop after $stop_after_success seconds after success\n"; 17611c8a617aSSteven Rostedt last; 17621c8a617aSSteven Rostedt } 17632545eb61SSteven Rostedt } 17642545eb61SSteven Rostedt 17655c42fc5bSSteven Rostedt if ($full_line =~ /\[ backtrace testing \]/) { 17665c42fc5bSSteven Rostedt $skip_call_trace = 1; 17675c42fc5bSSteven Rostedt } 17685c42fc5bSSteven Rostedt 17692545eb61SSteven Rostedt if ($full_line =~ /call trace:/i) { 17706ca996ccSSteven Rostedt if (!$bug && !$skip_call_trace) { 17716ca996ccSSteven Rostedt if ($ignore_errors) { 17726ca996ccSSteven Rostedt $bug_ignored = 1; 17736ca996ccSSteven Rostedt } else { 17741c8a617aSSteven Rostedt $bug = 1; 17751c8a617aSSteven Rostedt $failure_start = time; 17761c8a617aSSteven Rostedt } 17771c8a617aSSteven Rostedt } 17786ca996ccSSteven Rostedt } 17791c8a617aSSteven Rostedt 17801c8a617aSSteven Rostedt if ($bug && defined($stop_after_failure) && 17811c8a617aSSteven Rostedt $stop_after_failure >= 0) { 17821c8a617aSSteven Rostedt my $now = time; 17831c8a617aSSteven Rostedt if ($now - $failure_start >= $stop_after_failure) { 17841c8a617aSSteven Rostedt doprint "Test forced to stop after $stop_after_failure seconds after failure\n"; 17851c8a617aSSteven Rostedt last; 17861c8a617aSSteven Rostedt } 17875c42fc5bSSteven Rostedt } 17885c42fc5bSSteven Rostedt 17895c42fc5bSSteven Rostedt if ($full_line =~ /\[ end of backtrace testing \]/) { 17905c42fc5bSSteven Rostedt $skip_call_trace = 0; 17915c42fc5bSSteven Rostedt } 17925c42fc5bSSteven Rostedt 17935c42fc5bSSteven Rostedt if ($full_line =~ /Kernel panic -/) { 179410abf118SSteven Rostedt $failure_start = time; 17952545eb61SSteven Rostedt $bug = 1; 17962545eb61SSteven Rostedt } 17972545eb61SSteven Rostedt 1798f1a5b962SSteven Rostedt # Detect triple faults by testing the banner 1799f1a5b962SSteven Rostedt if ($full_line =~ /\bLinux version (\S+).*\n/) { 1800f1a5b962SSteven Rostedt if ($1 eq $version) { 1801f1a5b962SSteven Rostedt $version_found = 1; 1802f1a5b962SSteven Rostedt } elsif ($version_found && $detect_triplefault) { 1803f1a5b962SSteven Rostedt # We already booted into the kernel we are testing, 1804f1a5b962SSteven Rostedt # but now we booted into another kernel? 1805f1a5b962SSteven Rostedt # Consider this a triple fault. 1806f1a5b962SSteven Rostedt doprint "Aleady booted in Linux kernel $version, but now\n"; 1807f1a5b962SSteven Rostedt doprint "we booted into Linux kernel $1.\n"; 1808f1a5b962SSteven Rostedt doprint "Assuming that this is a triple fault.\n"; 1809f1a5b962SSteven Rostedt doprint "To disable this: set DETECT_TRIPLE_FAULT to 0\n"; 1810f1a5b962SSteven Rostedt last; 1811f1a5b962SSteven Rostedt } 1812f1a5b962SSteven Rostedt } 1813f1a5b962SSteven Rostedt 18142545eb61SSteven Rostedt if ($line =~ /\n/) { 18152545eb61SSteven Rostedt $full_line = ""; 18162545eb61SSteven Rostedt } 18172d01b26aSSteven Rostedt 18182d01b26aSSteven Rostedt if ($stop_test_after > 0 && !$booted && !$bug) { 18192d01b26aSSteven Rostedt if (time - $monitor_start > $stop_test_after) { 18204d62bf51SSteven Rostedt doprint "STOP_TEST_AFTER ($stop_test_after seconds) timed out\n"; 18212d01b26aSSteven Rostedt $done = 1; 18222d01b26aSSteven Rostedt } 18232d01b26aSSteven Rostedt } 18242545eb61SSteven Rostedt } 18252545eb61SSteven Rostedt 18267faafbd6SSteven Rostedt close(DMESG); 18272545eb61SSteven Rostedt 18282545eb61SSteven Rostedt if ($bug) { 18292b7d9b21SSteven Rostedt return 0 if ($in_bisect); 1830576f627cSSteven Rostedt fail "failed - got a bug report" and return 0; 18312545eb61SSteven Rostedt } 18325f9b6cedSSteven Rostedt 1833a75fececSSteven Rostedt if (!$booted) { 1834a75fececSSteven Rostedt return 0 if ($in_bisect); 1835576f627cSSteven Rostedt fail "failed - never got a boot prompt." and return 0; 1836a75fececSSteven Rostedt } 1837a75fececSSteven Rostedt 18386ca996ccSSteven Rostedt if ($bug_ignored) { 18396ca996ccSSteven Rostedt doprint "WARNING: Call Trace detected but ignored due to IGNORE_ERRORS=1\n"; 18406ca996ccSSteven Rostedt } 18416ca996ccSSteven Rostedt 18422b7d9b21SSteven Rostedt return 1; 18432545eb61SSteven Rostedt} 18442545eb61SSteven Rostedt 18452b29b2f8SSteven Rostedtsub eval_kernel_version { 18462b29b2f8SSteven Rostedt my ($option) = @_; 18472b29b2f8SSteven Rostedt 18482b29b2f8SSteven Rostedt $option =~ s/\$KERNEL_VERSION/$version/g; 18492b29b2f8SSteven Rostedt 18502b29b2f8SSteven Rostedt return $option; 18512b29b2f8SSteven Rostedt} 18522b29b2f8SSteven Rostedt 1853db05cfefSSteven Rostedtsub do_post_install { 1854db05cfefSSteven Rostedt 1855db05cfefSSteven Rostedt return if (!defined($post_install)); 1856db05cfefSSteven Rostedt 18572b29b2f8SSteven Rostedt my $cp_post_install = eval_kernel_version $post_install; 1858db05cfefSSteven Rostedt run_command "$cp_post_install" or 1859db05cfefSSteven Rostedt dodie "Failed to run post install"; 1860db05cfefSSteven Rostedt} 1861db05cfefSSteven Rostedt 1862e1a6c3d7SSteven Rostedt# Sometimes the reboot fails, and will hang. We try to ssh to the box 1863e1a6c3d7SSteven Rostedt# and if we fail, we force another reboot, that should powercycle it. 1864e1a6c3d7SSteven Rostedtsub test_booted { 1865e1a6c3d7SSteven Rostedt if (!run_ssh "echo testing connection") { 1866e1a6c3d7SSteven Rostedt reboot $sleep_time; 1867e1a6c3d7SSteven Rostedt } 1868e1a6c3d7SSteven Rostedt} 1869e1a6c3d7SSteven Rostedt 18702545eb61SSteven Rostedtsub install { 18712545eb61SSteven Rostedt 1872e0a8742eSSteven Rostedt return if ($no_install); 1873e0a8742eSSteven Rostedt 1874e5c2ec11SSteven Rostedt if (defined($pre_install)) { 1875e5c2ec11SSteven Rostedt my $cp_pre_install = eval_kernel_version $pre_install; 1876e5c2ec11SSteven Rostedt run_command "$cp_pre_install" or 1877e5c2ec11SSteven Rostedt dodie "Failed to run pre install"; 1878e5c2ec11SSteven Rostedt } 1879e5c2ec11SSteven Rostedt 18802b29b2f8SSteven Rostedt my $cp_target = eval_kernel_version $target_image; 18812b29b2f8SSteven Rostedt 1882e1a6c3d7SSteven Rostedt test_booted; 1883e1a6c3d7SSteven Rostedt 188402ad2617SSteven Rostedt run_scp_install "$outputdir/$build_target", "$cp_target" or 18855c42fc5bSSteven Rostedt dodie "failed to copy image"; 18865f9b6cedSSteven Rostedt 18875f9b6cedSSteven Rostedt my $install_mods = 0; 18885f9b6cedSSteven Rostedt 18895f9b6cedSSteven Rostedt # should we process modules? 18905f9b6cedSSteven Rostedt $install_mods = 0; 189151ad1dd1SSteven Rostedt open(IN, "$output_config") or dodie("Can't read config file"); 18925f9b6cedSSteven Rostedt while (<IN>) { 18935f9b6cedSSteven Rostedt if (/CONFIG_MODULES(=y)?/) { 18948bc5e4eaSSteven Rostedt if (defined($1)) { 18958bc5e4eaSSteven Rostedt $install_mods = 1; 18965f9b6cedSSteven Rostedt last; 18975f9b6cedSSteven Rostedt } 18985f9b6cedSSteven Rostedt } 18998bc5e4eaSSteven Rostedt } 19005f9b6cedSSteven Rostedt close(IN); 19015f9b6cedSSteven Rostedt 19025f9b6cedSSteven Rostedt if (!$install_mods) { 1903db05cfefSSteven Rostedt do_post_install; 19045f9b6cedSSteven Rostedt doprint "No modules needed\n"; 19055f9b6cedSSteven Rostedt return; 19062545eb61SSteven Rostedt } 19072545eb61SSteven Rostedt 1908627977d8SSteven Rostedt run_command "$make INSTALL_MOD_STRIP=1 INSTALL_MOD_PATH=$tmpdir modules_install" or 19095f9b6cedSSteven Rostedt dodie "Failed to install modules"; 19105f9b6cedSSteven Rostedt 19112545eb61SSteven Rostedt my $modlib = "/lib/modules/$version"; 1912a57419b3SSteven Rostedt my $modtar = "ktest-mods.tar.bz2"; 19132545eb61SSteven Rostedt 1914e48c5293SSteven Rostedt run_ssh "rm -rf $modlib" or 19155c42fc5bSSteven Rostedt dodie "failed to remove old mods: $modlib"; 19162545eb61SSteven Rostedt 19175c42fc5bSSteven Rostedt # would be nice if scp -r did not follow symbolic links 1918a75fececSSteven Rostedt run_command "cd $tmpdir && tar -cjf $modtar lib/modules/$version" or 19195c42fc5bSSteven Rostedt dodie "making tarball"; 19205c42fc5bSSteven Rostedt 192102ad2617SSteven Rostedt run_scp_mod "$tmpdir/$modtar", "/tmp" or 19225c42fc5bSSteven Rostedt dodie "failed to copy modules"; 19235c42fc5bSSteven Rostedt 1924a75fececSSteven Rostedt unlink "$tmpdir/$modtar"; 19255c42fc5bSSteven Rostedt 1926e7b13441SSteven Rostedt run_ssh "'(cd / && tar xjf /tmp/$modtar)'" or 19275c42fc5bSSteven Rostedt dodie "failed to tar modules"; 19285c42fc5bSSteven Rostedt 1929e48c5293SSteven Rostedt run_ssh "rm -f /tmp/$modtar"; 19308b37ca8cSSteven Rostedt 1931db05cfefSSteven Rostedt do_post_install; 19322545eb61SSteven Rostedt} 19332545eb61SSteven Rostedt 1934ddf607e5SSteven Rostedtsub get_version { 1935ddf607e5SSteven Rostedt # get the release name 1936683a3e64SSteven Rostedt return if ($have_version); 1937ddf607e5SSteven Rostedt doprint "$make kernelrelease ... "; 1938ddf607e5SSteven Rostedt $version = `$make kernelrelease | tail -1`; 1939ddf607e5SSteven Rostedt chomp($version); 1940ddf607e5SSteven Rostedt doprint "$version\n"; 1941683a3e64SSteven Rostedt $have_version = 1; 1942ddf607e5SSteven Rostedt} 1943ddf607e5SSteven Rostedt 1944ddf607e5SSteven Rostedtsub start_monitor_and_boot { 19459f7424ccSSteven Rostedt # Make sure the stable kernel has finished booting 1946319ab14fSSteven Rostedt (Red Hat) 1947319ab14fSSteven Rostedt (Red Hat) # Install bisects, don't need console 1948319ab14fSSteven Rostedt (Red Hat) if (defined $console) { 19499f7424ccSSteven Rostedt start_monitor; 19509f7424ccSSteven Rostedt wait_for_monitor 5; 19519f7424ccSSteven Rostedt end_monitor; 1952319ab14fSSteven Rostedt (Red Hat) } 19539f7424ccSSteven Rostedt 1954ddf607e5SSteven Rostedt get_grub_index; 1955ddf607e5SSteven Rostedt get_version; 1956ddf607e5SSteven Rostedt install; 1957ddf607e5SSteven Rostedt 1958319ab14fSSteven Rostedt (Red Hat) start_monitor if (defined $console); 1959ddf607e5SSteven Rostedt return monitor; 1960ddf607e5SSteven Rostedt} 1961ddf607e5SSteven Rostedt 19624283b169SSteven Rostedt (Red Hat)my $check_build_re = ".*:.*(warning|error|Error):.*"; 19634283b169SSteven Rostedt (Red Hat)my $utf8_quote = "\\x{e2}\\x{80}(\\x{98}|\\x{99})"; 19644283b169SSteven Rostedt (Red Hat) 19657328735cSSteven Rostedt (Red Hat)sub process_warning_line { 19667328735cSSteven Rostedt (Red Hat) my ($line) = @_; 19677328735cSSteven Rostedt (Red Hat) 19687328735cSSteven Rostedt (Red Hat) chomp $line; 19697328735cSSteven Rostedt (Red Hat) 19707328735cSSteven Rostedt (Red Hat) # for distcc heterogeneous systems, some compilers 19717328735cSSteven Rostedt (Red Hat) # do things differently causing warning lines 19727328735cSSteven Rostedt (Red Hat) # to be slightly different. This makes an attempt 19737328735cSSteven Rostedt (Red Hat) # to fixe those issues. 19747328735cSSteven Rostedt (Red Hat) 19757328735cSSteven Rostedt (Red Hat) # chop off the index into the line 19767328735cSSteven Rostedt (Red Hat) # using distcc, some compilers give different indexes 19777328735cSSteven Rostedt (Red Hat) # depending on white space 19787328735cSSteven Rostedt (Red Hat) $line =~ s/^(\s*\S+:\d+:)\d+/$1/; 19797328735cSSteven Rostedt (Red Hat) 19807328735cSSteven Rostedt (Red Hat) # Some compilers use UTF-8 extended for quotes and some don't. 19817328735cSSteven Rostedt (Red Hat) $line =~ s/$utf8_quote/'/g; 19827328735cSSteven Rostedt (Red Hat) 19837328735cSSteven Rostedt (Red Hat) return $line; 19847328735cSSteven Rostedt (Red Hat)} 19857328735cSSteven Rostedt (Red Hat) 19864283b169SSteven Rostedt (Red Hat)# Read buildlog and check against warnings file for any 19874283b169SSteven Rostedt (Red Hat)# new warnings. 19884283b169SSteven Rostedt (Red Hat)# 19894283b169SSteven Rostedt (Red Hat)# Returns 1 if OK 19904283b169SSteven Rostedt (Red Hat)# 0 otherwise 19916c5ee0beSSteven Rostedtsub check_buildlog { 19924283b169SSteven Rostedt (Red Hat) return 1 if (!defined $warnings_file); 19934283b169SSteven Rostedt (Red Hat) 19944283b169SSteven Rostedt (Red Hat) my %warnings_list; 19954283b169SSteven Rostedt (Red Hat) 19964283b169SSteven Rostedt (Red Hat) # Failed builds should not reboot the target 19974283b169SSteven Rostedt (Red Hat) my $save_no_reboot = $no_reboot; 19984283b169SSteven Rostedt (Red Hat) $no_reboot = 1; 19994283b169SSteven Rostedt (Red Hat) 20004283b169SSteven Rostedt (Red Hat) if (-f $warnings_file) { 20014283b169SSteven Rostedt (Red Hat) open(IN, $warnings_file) or 20024283b169SSteven Rostedt (Red Hat) dodie "Error opening $warnings_file"; 20034283b169SSteven Rostedt (Red Hat) 20044283b169SSteven Rostedt (Red Hat) while (<IN>) { 20054283b169SSteven Rostedt (Red Hat) if (/$check_build_re/) { 20067328735cSSteven Rostedt (Red Hat) my $warning = process_warning_line $_; 20077328735cSSteven Rostedt (Red Hat) 20087328735cSSteven Rostedt (Red Hat) $warnings_list{$warning} = 1; 20094283b169SSteven Rostedt (Red Hat) } 20104283b169SSteven Rostedt (Red Hat) } 20114283b169SSteven Rostedt (Red Hat) close(IN); 20124283b169SSteven Rostedt (Red Hat) } 20134283b169SSteven Rostedt (Red Hat) 20144283b169SSteven Rostedt (Red Hat) # If warnings file didn't exist, and WARNINGS_FILE exist, 20154283b169SSteven Rostedt (Red Hat) # then we fail on any warning! 20164283b169SSteven Rostedt (Red Hat) 20174283b169SSteven Rostedt (Red Hat) open(IN, $buildlog) or dodie "Can't open $buildlog"; 20184283b169SSteven Rostedt (Red Hat) while (<IN>) { 20194283b169SSteven Rostedt (Red Hat) if (/$check_build_re/) { 20207328735cSSteven Rostedt (Red Hat) my $warning = process_warning_line $_; 20214283b169SSteven Rostedt (Red Hat) 20227328735cSSteven Rostedt (Red Hat) if (!defined $warnings_list{$warning}) { 20234283b169SSteven Rostedt (Red Hat) fail "New warning found (not in $warnings_file)\n$_\n"; 20244283b169SSteven Rostedt (Red Hat) $no_reboot = $save_no_reboot; 20254283b169SSteven Rostedt (Red Hat) return 0; 20264283b169SSteven Rostedt (Red Hat) } 20274283b169SSteven Rostedt (Red Hat) } 20284283b169SSteven Rostedt (Red Hat) } 20294283b169SSteven Rostedt (Red Hat) $no_reboot = $save_no_reboot; 20304283b169SSteven Rostedt (Red Hat) close(IN); 20314283b169SSteven Rostedt (Red Hat)} 20324283b169SSteven Rostedt (Red Hat) 20334283b169SSteven Rostedt (Red Hat)sub check_patch_buildlog { 20346c5ee0beSSteven Rostedt my ($patch) = @_; 20356c5ee0beSSteven Rostedt 20366c5ee0beSSteven Rostedt my @files = `git show $patch | diffstat -l`; 20376c5ee0beSSteven Rostedt 203835275685SSteven Rostedt (Red Hat) foreach my $file (@files) { 203935275685SSteven Rostedt (Red Hat) chomp $file; 204035275685SSteven Rostedt (Red Hat) } 204135275685SSteven Rostedt (Red Hat) 20426c5ee0beSSteven Rostedt open(IN, "git show $patch |") or 20436c5ee0beSSteven Rostedt dodie "failed to show $patch"; 20446c5ee0beSSteven Rostedt while (<IN>) { 20456c5ee0beSSteven Rostedt if (m,^--- a/(.*),) { 20466c5ee0beSSteven Rostedt chomp $1; 20476c5ee0beSSteven Rostedt $files[$#files] = $1; 20486c5ee0beSSteven Rostedt } 20496c5ee0beSSteven Rostedt } 20506c5ee0beSSteven Rostedt close(IN); 20516c5ee0beSSteven Rostedt 20526c5ee0beSSteven Rostedt open(IN, $buildlog) or dodie "Can't open $buildlog"; 20536c5ee0beSSteven Rostedt while (<IN>) { 20546c5ee0beSSteven Rostedt if (/^\s*(.*?):.*(warning|error)/) { 20556c5ee0beSSteven Rostedt my $err = $1; 20566c5ee0beSSteven Rostedt foreach my $file (@files) { 2057a75fececSSteven Rostedt my $fullpath = "$builddir/$file"; 20586c5ee0beSSteven Rostedt if ($file eq $err || $fullpath eq $err) { 20592b7d9b21SSteven Rostedt fail "$file built with warnings" and return 0; 20606c5ee0beSSteven Rostedt } 20616c5ee0beSSteven Rostedt } 20626c5ee0beSSteven Rostedt } 20636c5ee0beSSteven Rostedt } 20646c5ee0beSSteven Rostedt close(IN); 20652b7d9b21SSteven Rostedt 20662b7d9b21SSteven Rostedt return 1; 20676c5ee0beSSteven Rostedt} 20686c5ee0beSSteven Rostedt 2069fcb3f16aSSteven Rostedtsub apply_min_config { 2070fcb3f16aSSteven Rostedt my $outconfig = "$output_config.new"; 2071612b9e9bSSteven Rostedt 2072fcb3f16aSSteven Rostedt # Read the config file and remove anything that 2073fcb3f16aSSteven Rostedt # is in the force_config hash (from minconfig and others) 2074fcb3f16aSSteven Rostedt # then add the force config back. 2075fcb3f16aSSteven Rostedt 2076fcb3f16aSSteven Rostedt doprint "Applying minimum configurations into $output_config.new\n"; 2077fcb3f16aSSteven Rostedt 2078fcb3f16aSSteven Rostedt open (OUT, ">$outconfig") or 2079fcb3f16aSSteven Rostedt dodie "Can't create $outconfig"; 2080fcb3f16aSSteven Rostedt 2081fcb3f16aSSteven Rostedt if (-f $output_config) { 2082fcb3f16aSSteven Rostedt open (IN, $output_config) or 2083fcb3f16aSSteven Rostedt dodie "Failed to open $output_config"; 2084fcb3f16aSSteven Rostedt while (<IN>) { 2085fcb3f16aSSteven Rostedt if (/^(# )?(CONFIG_[^\s=]*)/) { 2086fcb3f16aSSteven Rostedt next if (defined($force_config{$2})); 2087fcb3f16aSSteven Rostedt } 2088fcb3f16aSSteven Rostedt print OUT; 2089fcb3f16aSSteven Rostedt } 2090fcb3f16aSSteven Rostedt close IN; 2091fcb3f16aSSteven Rostedt } 2092fcb3f16aSSteven Rostedt foreach my $config (keys %force_config) { 2093fcb3f16aSSteven Rostedt print OUT "$force_config{$config}\n"; 2094fcb3f16aSSteven Rostedt } 2095fcb3f16aSSteven Rostedt close OUT; 2096fcb3f16aSSteven Rostedt 2097fcb3f16aSSteven Rostedt run_command "mv $outconfig $output_config"; 2098fcb3f16aSSteven Rostedt} 2099fcb3f16aSSteven Rostedt 2100fcb3f16aSSteven Rostedtsub make_oldconfig { 2101fcb3f16aSSteven Rostedt 21024c4ab120SSteven Rostedt my @force_list = keys %force_config; 21034c4ab120SSteven Rostedt 21044c4ab120SSteven Rostedt if ($#force_list >= 0) { 2105fcb3f16aSSteven Rostedt apply_min_config; 21064c4ab120SSteven Rostedt } 2107fcb3f16aSSteven Rostedt 2108fb16d891SAdam Lee if (!run_command "$make olddefconfig") { 2109fb16d891SAdam Lee # Perhaps olddefconfig doesn't exist in this version of the kernel 211018925170SSteven Rostedt # try oldnoconfig 211118925170SSteven Rostedt doprint "olddefconfig failed, trying make oldnoconfig\n"; 211218925170SSteven Rostedt if (!run_command "$make oldnoconfig") { 211318925170SSteven Rostedt doprint "oldnoconfig failed, trying yes '' | make oldconfig\n"; 2114612b9e9bSSteven Rostedt # try a yes '' | oldconfig 2115fcb3f16aSSteven Rostedt run_command "yes '' | $make oldconfig" or 2116612b9e9bSSteven Rostedt dodie "failed make config oldconfig"; 2117612b9e9bSSteven Rostedt } 2118612b9e9bSSteven Rostedt } 211918925170SSteven Rostedt} 2120612b9e9bSSteven Rostedt 2121fcb3f16aSSteven Rostedt# read a config file and use this to force new configs. 2122fcb3f16aSSteven Rostedtsub load_force_config { 2123fcb3f16aSSteven Rostedt my ($config) = @_; 2124fcb3f16aSSteven Rostedt 2125cf79fab6SSteven Rostedt doprint "Loading force configs from $config\n"; 2126fcb3f16aSSteven Rostedt open(IN, $config) or 2127fcb3f16aSSteven Rostedt dodie "failed to read $config"; 2128fcb3f16aSSteven Rostedt while (<IN>) { 2129fcb3f16aSSteven Rostedt chomp; 2130fcb3f16aSSteven Rostedt if (/^(CONFIG[^\s=]*)(\s*=.*)/) { 2131fcb3f16aSSteven Rostedt $force_config{$1} = $_; 2132fcb3f16aSSteven Rostedt } elsif (/^# (CONFIG_\S*) is not set/) { 2133fcb3f16aSSteven Rostedt $force_config{$1} = $_; 2134fcb3f16aSSteven Rostedt } 2135fcb3f16aSSteven Rostedt } 2136fcb3f16aSSteven Rostedt close IN; 2137fcb3f16aSSteven Rostedt} 2138fcb3f16aSSteven Rostedt 21392545eb61SSteven Rostedtsub build { 21402545eb61SSteven Rostedt my ($type) = @_; 21412545eb61SSteven Rostedt 21427faafbd6SSteven Rostedt unlink $buildlog; 21437faafbd6SSteven Rostedt 21444ab1cce5SSteven Rostedt # Failed builds should not reboot the target 21454ab1cce5SSteven Rostedt my $save_no_reboot = $no_reboot; 21464ab1cce5SSteven Rostedt $no_reboot = 1; 21474ab1cce5SSteven Rostedt 2148683a3e64SSteven Rostedt # Calculate a new version from here. 2149683a3e64SSteven Rostedt $have_version = 0; 2150683a3e64SSteven Rostedt 21510bd6c1a3SSteven Rostedt if (defined($pre_build)) { 21520bd6c1a3SSteven Rostedt my $ret = run_command $pre_build; 21530bd6c1a3SSteven Rostedt if (!$ret && defined($pre_build_die) && 21540bd6c1a3SSteven Rostedt $pre_build_die) { 21550bd6c1a3SSteven Rostedt dodie "failed to pre_build\n"; 21560bd6c1a3SSteven Rostedt } 21570bd6c1a3SSteven Rostedt } 21580bd6c1a3SSteven Rostedt 215975c3fda7SSteven Rostedt if ($type =~ /^useconfig:(.*)/) { 216051ad1dd1SSteven Rostedt run_command "cp $1 $output_config" or 216175c3fda7SSteven Rostedt dodie "could not copy $1 to .config"; 21625f9b6cedSSteven Rostedt 216375c3fda7SSteven Rostedt $type = "oldconfig"; 216475c3fda7SSteven Rostedt } 216575c3fda7SSteven Rostedt 21665c42fc5bSSteven Rostedt # old config can ask questions 21675c42fc5bSSteven Rostedt if ($type eq "oldconfig") { 2168fb16d891SAdam Lee $type = "olddefconfig"; 216975c3fda7SSteven Rostedt 217075c3fda7SSteven Rostedt # allow for empty configs 217151ad1dd1SSteven Rostedt run_command "touch $output_config"; 217275c3fda7SSteven Rostedt 217313488231SAndrew Jones if (!$noclean) { 217451ad1dd1SSteven Rostedt run_command "mv $output_config $outputdir/config_temp" or 21755c42fc5bSSteven Rostedt dodie "moving .config"; 21765c42fc5bSSteven Rostedt 217713488231SAndrew Jones run_command "$make mrproper" or dodie "make mrproper"; 21785c42fc5bSSteven Rostedt 217951ad1dd1SSteven Rostedt run_command "mv $outputdir/config_temp $output_config" or 21805c42fc5bSSteven Rostedt dodie "moving config_temp"; 218113488231SAndrew Jones } 21825c42fc5bSSteven Rostedt 21835c42fc5bSSteven Rostedt } elsif (!$noclean) { 218451ad1dd1SSteven Rostedt unlink "$output_config"; 21855f9b6cedSSteven Rostedt run_command "$make mrproper" or 21865c42fc5bSSteven Rostedt dodie "make mrproper"; 21875c42fc5bSSteven Rostedt } 21882545eb61SSteven Rostedt 21892545eb61SSteven Rostedt # add something to distinguish this build 2190a75fececSSteven Rostedt open(OUT, "> $outputdir/localversion") or dodie("Can't make localversion file"); 2191a75fececSSteven Rostedt print OUT "$localversion\n"; 21922545eb61SSteven Rostedt close(OUT); 21932545eb61SSteven Rostedt 21945f9b6cedSSteven Rostedt if (defined($minconfig)) { 2195fcb3f16aSSteven Rostedt load_force_config($minconfig); 21962545eb61SSteven Rostedt } 21972545eb61SSteven Rostedt 2198fb16d891SAdam Lee if ($type ne "olddefconfig") { 2199fcb3f16aSSteven Rostedt run_command "$make $type" or 22005c42fc5bSSteven Rostedt dodie "failed make config"; 2201612b9e9bSSteven Rostedt } 2202fcb3f16aSSteven Rostedt # Run old config regardless, to enforce min configurations 2203fcb3f16aSSteven Rostedt make_oldconfig; 22042545eb61SSteven Rostedt 2205a75fececSSteven Rostedt $redirect = "$buildlog"; 22060bd6c1a3SSteven Rostedt my $build_ret = run_command "$make $build_options"; 22076c5ee0beSSteven Rostedt undef $redirect; 22080bd6c1a3SSteven Rostedt 22090bd6c1a3SSteven Rostedt if (defined($post_build)) { 2210683a3e64SSteven Rostedt # Because a post build may change the kernel version 2211683a3e64SSteven Rostedt # do it now. 2212683a3e64SSteven Rostedt get_version; 22130bd6c1a3SSteven Rostedt my $ret = run_command $post_build; 22140bd6c1a3SSteven Rostedt if (!$ret && defined($post_build_die) && 22150bd6c1a3SSteven Rostedt $post_build_die) { 22160bd6c1a3SSteven Rostedt dodie "failed to post_build\n"; 22170bd6c1a3SSteven Rostedt } 22180bd6c1a3SSteven Rostedt } 22190bd6c1a3SSteven Rostedt 22200bd6c1a3SSteven Rostedt if (!$build_ret) { 22215f9b6cedSSteven Rostedt # bisect may need this to pass 22224ab1cce5SSteven Rostedt if ($in_bisect) { 22234ab1cce5SSteven Rostedt $no_reboot = $save_no_reboot; 22244ab1cce5SSteven Rostedt return 0; 22254ab1cce5SSteven Rostedt } 22262b7d9b21SSteven Rostedt fail "failed build" and return 0; 22272545eb61SSteven Rostedt } 22285f9b6cedSSteven Rostedt 22294ab1cce5SSteven Rostedt $no_reboot = $save_no_reboot; 22304ab1cce5SSteven Rostedt 22312b7d9b21SSteven Rostedt return 1; 22322545eb61SSteven Rostedt} 22332545eb61SSteven Rostedt 223475c3fda7SSteven Rostedtsub halt { 2235e48c5293SSteven Rostedt if (!run_ssh "halt" or defined($power_off)) { 2236576f627cSSteven Rostedt if (defined($poweroff_after_halt)) { 2237576f627cSSteven Rostedt sleep $poweroff_after_halt; 2238576f627cSSteven Rostedt run_command "$power_off"; 2239576f627cSSteven Rostedt } 2240576f627cSSteven Rostedt } else { 224175c3fda7SSteven Rostedt # nope? the zap it! 2242a75fececSSteven Rostedt run_command "$power_off"; 224375c3fda7SSteven Rostedt } 224475c3fda7SSteven Rostedt} 224575c3fda7SSteven Rostedt 22465f9b6cedSSteven Rostedtsub success { 22475f9b6cedSSteven Rostedt my ($i) = @_; 22485f9b6cedSSteven Rostedt 2249921ed4c7SSteven Rostedt if (defined($post_test)) { 2250921ed4c7SSteven Rostedt run_command $post_test; 2251921ed4c7SSteven Rostedt } 2252921ed4c7SSteven Rostedt 2253e48c5293SSteven Rostedt $successes++; 2254e48c5293SSteven Rostedt 22559064af52SSteven Rostedt my $name = ""; 22569064af52SSteven Rostedt 22579064af52SSteven Rostedt if (defined($test_name)) { 22589064af52SSteven Rostedt $name = " ($test_name)"; 22599064af52SSteven Rostedt } 22609064af52SSteven Rostedt 22615f9b6cedSSteven Rostedt doprint "\n\n*******************************************\n"; 22625f9b6cedSSteven Rostedt doprint "*******************************************\n"; 22639064af52SSteven Rostedt doprint "KTEST RESULT: TEST $i$name SUCCESS!!!! **\n"; 22645f9b6cedSSteven Rostedt doprint "*******************************************\n"; 22655f9b6cedSSteven Rostedt doprint "*******************************************\n"; 22665f9b6cedSSteven Rostedt 2267de5b6e3bSRabin Vincent if (defined($store_successes)) { 2268de5b6e3bSRabin Vincent save_logs "success", $store_successes; 2269de5b6e3bSRabin Vincent } 2270de5b6e3bSRabin Vincent 2271576f627cSSteven Rostedt if ($i != $opt{"NUM_TESTS"} && !do_not_reboot) { 2272a75fececSSteven Rostedt doprint "Reboot and wait $sleep_time seconds\n"; 2273bc7c5803SSteven Rostedt reboot_to_good $sleep_time; 22745f9b6cedSSteven Rostedt } 22755f9b6cedSSteven Rostedt} 22765f9b6cedSSteven Rostedt 2277c960bb9fSSteven Rostedtsub answer_bisect { 2278c960bb9fSSteven Rostedt for (;;) { 2279c960bb9fSSteven Rostedt doprint "Pass or fail? [p/f]"; 2280c960bb9fSSteven Rostedt my $ans = <STDIN>; 2281c960bb9fSSteven Rostedt chomp $ans; 2282c960bb9fSSteven Rostedt if ($ans eq "p" || $ans eq "P") { 2283c960bb9fSSteven Rostedt return 1; 2284c960bb9fSSteven Rostedt } elsif ($ans eq "f" || $ans eq "F") { 2285c960bb9fSSteven Rostedt return 0; 2286c960bb9fSSteven Rostedt } else { 2287c960bb9fSSteven Rostedt print "Please answer 'P' or 'F'\n"; 2288c960bb9fSSteven Rostedt } 2289c960bb9fSSteven Rostedt } 2290c960bb9fSSteven Rostedt} 2291c960bb9fSSteven Rostedt 22925a391fbfSSteven Rostedtsub child_run_test { 22937faafbd6SSteven Rostedt my $failed = 0; 22945a391fbfSSteven Rostedt 22957faafbd6SSteven Rostedt # child should have no power 2296a75fececSSteven Rostedt $reboot_on_error = 0; 2297a75fececSSteven Rostedt $poweroff_on_error = 0; 2298a75fececSSteven Rostedt $die_on_failure = 1; 22997faafbd6SSteven Rostedt 2300a9dd5d63SRabin Vincent $redirect = "$testlog"; 23017faafbd6SSteven Rostedt run_command $run_test or $failed = 1; 2302a9dd5d63SRabin Vincent undef $redirect; 2303a9dd5d63SRabin Vincent 23045a391fbfSSteven Rostedt exit $failed; 23055a391fbfSSteven Rostedt} 23065a391fbfSSteven Rostedt 23075a391fbfSSteven Rostedtmy $child_done; 23085a391fbfSSteven Rostedt 23095a391fbfSSteven Rostedtsub child_finished { 23105a391fbfSSteven Rostedt $child_done = 1; 23115a391fbfSSteven Rostedt} 23125a391fbfSSteven Rostedt 23135a391fbfSSteven Rostedtsub do_run_test { 23145a391fbfSSteven Rostedt my $child_pid; 23155a391fbfSSteven Rostedt my $child_exit; 23165a391fbfSSteven Rostedt my $line; 23175a391fbfSSteven Rostedt my $full_line; 23185a391fbfSSteven Rostedt my $bug = 0; 23199b1d367dSSteven Rostedt my $bug_ignored = 0; 23205a391fbfSSteven Rostedt 23217faafbd6SSteven Rostedt wait_for_monitor 1; 23225a391fbfSSteven Rostedt 23237faafbd6SSteven Rostedt doprint "run test $run_test\n"; 23245a391fbfSSteven Rostedt 23255a391fbfSSteven Rostedt $child_done = 0; 23265a391fbfSSteven Rostedt 23275a391fbfSSteven Rostedt $SIG{CHLD} = qw(child_finished); 23285a391fbfSSteven Rostedt 23295a391fbfSSteven Rostedt $child_pid = fork; 23305a391fbfSSteven Rostedt 23315a391fbfSSteven Rostedt child_run_test if (!$child_pid); 23325a391fbfSSteven Rostedt 23335a391fbfSSteven Rostedt $full_line = ""; 23345a391fbfSSteven Rostedt 23355a391fbfSSteven Rostedt do { 23367faafbd6SSteven Rostedt $line = wait_for_input($monitor_fp, 1); 23375a391fbfSSteven Rostedt if (defined($line)) { 23385a391fbfSSteven Rostedt 23395a391fbfSSteven Rostedt # we are not guaranteed to get a full line 23405a391fbfSSteven Rostedt $full_line .= $line; 23418ea0e063SSteven Rostedt doprint $line; 23425a391fbfSSteven Rostedt 23435a391fbfSSteven Rostedt if ($full_line =~ /call trace:/i) { 23449b1d367dSSteven Rostedt if ($ignore_errors) { 23459b1d367dSSteven Rostedt $bug_ignored = 1; 23469b1d367dSSteven Rostedt } else { 23475a391fbfSSteven Rostedt $bug = 1; 23485a391fbfSSteven Rostedt } 23499b1d367dSSteven Rostedt } 23505a391fbfSSteven Rostedt 23515a391fbfSSteven Rostedt if ($full_line =~ /Kernel panic -/) { 23525a391fbfSSteven Rostedt $bug = 1; 23535a391fbfSSteven Rostedt } 23545a391fbfSSteven Rostedt 23555a391fbfSSteven Rostedt if ($line =~ /\n/) { 23565a391fbfSSteven Rostedt $full_line = ""; 23575a391fbfSSteven Rostedt } 23585a391fbfSSteven Rostedt } 23595a391fbfSSteven Rostedt } while (!$child_done && !$bug); 23605a391fbfSSteven Rostedt 23619b1d367dSSteven Rostedt if (!$bug && $bug_ignored) { 23629b1d367dSSteven Rostedt doprint "WARNING: Call Trace detected but ignored due to IGNORE_ERRORS=1\n"; 23639b1d367dSSteven Rostedt } 23649b1d367dSSteven Rostedt 23655a391fbfSSteven Rostedt if ($bug) { 23668ea0e063SSteven Rostedt my $failure_start = time; 23678ea0e063SSteven Rostedt my $now; 23688ea0e063SSteven Rostedt do { 23698ea0e063SSteven Rostedt $line = wait_for_input($monitor_fp, 1); 23708ea0e063SSteven Rostedt if (defined($line)) { 23718ea0e063SSteven Rostedt doprint $line; 23728ea0e063SSteven Rostedt } 23738ea0e063SSteven Rostedt $now = time; 23748ea0e063SSteven Rostedt if ($now - $failure_start >= $stop_after_failure) { 23758ea0e063SSteven Rostedt last; 23768ea0e063SSteven Rostedt } 23778ea0e063SSteven Rostedt } while (defined($line)); 23788ea0e063SSteven Rostedt 23795a391fbfSSteven Rostedt doprint "Detected kernel crash!\n"; 23805a391fbfSSteven Rostedt # kill the child with extreme prejudice 23815a391fbfSSteven Rostedt kill 9, $child_pid; 23825a391fbfSSteven Rostedt } 23835a391fbfSSteven Rostedt 23845a391fbfSSteven Rostedt waitpid $child_pid, 0; 23855a391fbfSSteven Rostedt $child_exit = $?; 23865a391fbfSSteven Rostedt 2387c5dacb88SSteven Rostedt if (!$bug && $in_bisect) { 2388c5dacb88SSteven Rostedt if (defined($bisect_ret_good)) { 2389c5dacb88SSteven Rostedt if ($child_exit == $bisect_ret_good) { 2390c5dacb88SSteven Rostedt return 1; 2391c5dacb88SSteven Rostedt } 2392c5dacb88SSteven Rostedt } 2393c5dacb88SSteven Rostedt if (defined($bisect_ret_skip)) { 2394c5dacb88SSteven Rostedt if ($child_exit == $bisect_ret_skip) { 2395c5dacb88SSteven Rostedt return -1; 2396c5dacb88SSteven Rostedt } 2397c5dacb88SSteven Rostedt } 2398c5dacb88SSteven Rostedt if (defined($bisect_ret_abort)) { 2399c5dacb88SSteven Rostedt if ($child_exit == $bisect_ret_abort) { 2400c5dacb88SSteven Rostedt fail "test abort" and return -2; 2401c5dacb88SSteven Rostedt } 2402c5dacb88SSteven Rostedt } 2403c5dacb88SSteven Rostedt if (defined($bisect_ret_bad)) { 2404c5dacb88SSteven Rostedt if ($child_exit == $bisect_ret_skip) { 2405c5dacb88SSteven Rostedt return 0; 2406c5dacb88SSteven Rostedt } 2407c5dacb88SSteven Rostedt } 2408c5dacb88SSteven Rostedt if (defined($bisect_ret_default)) { 2409c5dacb88SSteven Rostedt if ($bisect_ret_default eq "good") { 2410c5dacb88SSteven Rostedt return 1; 2411c5dacb88SSteven Rostedt } elsif ($bisect_ret_default eq "bad") { 2412c5dacb88SSteven Rostedt return 0; 2413c5dacb88SSteven Rostedt } elsif ($bisect_ret_default eq "skip") { 2414c5dacb88SSteven Rostedt return -1; 2415c5dacb88SSteven Rostedt } elsif ($bisect_ret_default eq "abort") { 2416c5dacb88SSteven Rostedt return -2; 2417c5dacb88SSteven Rostedt } else { 2418c5dacb88SSteven Rostedt fail "unknown default action: $bisect_ret_default" 2419c5dacb88SSteven Rostedt and return -2; 2420c5dacb88SSteven Rostedt } 2421c5dacb88SSteven Rostedt } 2422c5dacb88SSteven Rostedt } 2423c5dacb88SSteven Rostedt 24245a391fbfSSteven Rostedt if ($bug || $child_exit) { 24252b7d9b21SSteven Rostedt return 0 if $in_bisect; 24262b7d9b21SSteven Rostedt fail "test failed" and return 0; 24275a391fbfSSteven Rostedt } 24282b7d9b21SSteven Rostedt return 1; 24295a391fbfSSteven Rostedt} 24305a391fbfSSteven Rostedt 2431a75fececSSteven Rostedtsub run_git_bisect { 2432a75fececSSteven Rostedt my ($command) = @_; 2433a75fececSSteven Rostedt 2434a75fececSSteven Rostedt doprint "$command ... "; 2435a75fececSSteven Rostedt 2436a75fececSSteven Rostedt my $output = `$command 2>&1`; 2437a75fececSSteven Rostedt my $ret = $?; 2438a75fececSSteven Rostedt 2439a75fececSSteven Rostedt logit $output; 2440a75fececSSteven Rostedt 2441a75fececSSteven Rostedt if ($ret) { 2442a75fececSSteven Rostedt doprint "FAILED\n"; 2443a75fececSSteven Rostedt dodie "Failed to git bisect"; 2444a75fececSSteven Rostedt } 2445a75fececSSteven Rostedt 2446a75fececSSteven Rostedt doprint "SUCCESS\n"; 2447a75fececSSteven Rostedt if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\))\s+\[([[:xdigit:]]+)\]/) { 2448a75fececSSteven Rostedt doprint "$1 [$2]\n"; 2449a75fececSSteven Rostedt } elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) { 2450b5f4aea6SSteven Rostedt $bisect_bad_commit = $1; 2451a75fececSSteven Rostedt doprint "Found bad commit... $1\n"; 2452a75fececSSteven Rostedt return 0; 2453a75fececSSteven Rostedt } else { 2454a75fececSSteven Rostedt # we already logged it, just print it now. 2455a75fececSSteven Rostedt print $output; 2456a75fececSSteven Rostedt } 2457a75fececSSteven Rostedt 2458a75fececSSteven Rostedt return 1; 2459a75fececSSteven Rostedt} 2460a75fececSSteven Rostedt 2461c23dca7cSSteven Rostedtsub bisect_reboot { 2462c23dca7cSSteven Rostedt doprint "Reboot and sleep $bisect_sleep_time seconds\n"; 2463bc7c5803SSteven Rostedt reboot_to_good $bisect_sleep_time; 2464c23dca7cSSteven Rostedt} 2465c23dca7cSSteven Rostedt 2466c23dca7cSSteven Rostedt# returns 1 on success, 0 on failure, -1 on skip 24670a05c769SSteven Rostedtsub run_bisect_test { 24680a05c769SSteven Rostedt my ($type, $buildtype) = @_; 24695f9b6cedSSteven Rostedt 24702b7d9b21SSteven Rostedt my $failed = 0; 24715f9b6cedSSteven Rostedt my $result; 24725f9b6cedSSteven Rostedt my $output; 24735f9b6cedSSteven Rostedt my $ret; 24745f9b6cedSSteven Rostedt 24750a05c769SSteven Rostedt $in_bisect = 1; 24760a05c769SSteven Rostedt 24770a05c769SSteven Rostedt build $buildtype or $failed = 1; 24785f9b6cedSSteven Rostedt 24795f9b6cedSSteven Rostedt if ($type ne "build") { 2480c23dca7cSSteven Rostedt if ($failed && $bisect_skip) { 2481c23dca7cSSteven Rostedt $in_bisect = 0; 2482c23dca7cSSteven Rostedt return -1; 2483c23dca7cSSteven Rostedt } 24847faafbd6SSteven Rostedt dodie "Failed on build" if $failed; 24855f9b6cedSSteven Rostedt 24865f9b6cedSSteven Rostedt # Now boot the box 2487ddf607e5SSteven Rostedt start_monitor_and_boot or $failed = 1; 24885f9b6cedSSteven Rostedt 24895f9b6cedSSteven Rostedt if ($type ne "boot") { 2490c23dca7cSSteven Rostedt if ($failed && $bisect_skip) { 2491c23dca7cSSteven Rostedt end_monitor; 2492c23dca7cSSteven Rostedt bisect_reboot; 2493c23dca7cSSteven Rostedt $in_bisect = 0; 2494c23dca7cSSteven Rostedt return -1; 2495c23dca7cSSteven Rostedt } 24967faafbd6SSteven Rostedt dodie "Failed on boot" if $failed; 24975a391fbfSSteven Rostedt 24982b7d9b21SSteven Rostedt do_run_test or $failed = 1; 24995f9b6cedSSteven Rostedt } 25007faafbd6SSteven Rostedt end_monitor; 25015f9b6cedSSteven Rostedt } 25025f9b6cedSSteven Rostedt 25035f9b6cedSSteven Rostedt if ($failed) { 25040a05c769SSteven Rostedt $result = 0; 25055f9b6cedSSteven Rostedt } else { 25060a05c769SSteven Rostedt $result = 1; 25075f9b6cedSSteven Rostedt } 25084025bc62SSteven Rostedt 25094025bc62SSteven Rostedt # reboot the box to a kernel we can ssh to 25104025bc62SSteven Rostedt if ($type ne "build") { 25114025bc62SSteven Rostedt bisect_reboot; 25124025bc62SSteven Rostedt } 25130a05c769SSteven Rostedt $in_bisect = 0; 25140a05c769SSteven Rostedt 25150a05c769SSteven Rostedt return $result; 25160a05c769SSteven Rostedt} 25170a05c769SSteven Rostedt 25180a05c769SSteven Rostedtsub run_bisect { 25190a05c769SSteven Rostedt my ($type) = @_; 25200a05c769SSteven Rostedt my $buildtype = "oldconfig"; 25210a05c769SSteven Rostedt 25220a05c769SSteven Rostedt # We should have a minconfig to use? 25230a05c769SSteven Rostedt if (defined($minconfig)) { 25240a05c769SSteven Rostedt $buildtype = "useconfig:$minconfig"; 25250a05c769SSteven Rostedt } 25260a05c769SSteven Rostedt 25270a05c769SSteven Rostedt my $ret = run_bisect_test $type, $buildtype; 25280a05c769SSteven Rostedt 2529c960bb9fSSteven Rostedt if ($bisect_manual) { 2530c960bb9fSSteven Rostedt $ret = answer_bisect; 2531c960bb9fSSteven Rostedt } 25325f9b6cedSSteven Rostedt 2533d6ce2a0bSSteven Rostedt # Are we looking for where it worked, not failed? 25345158ba3eSRuss Dill if ($reverse_bisect && $ret >= 0) { 25350a05c769SSteven Rostedt $ret = !$ret; 2536d6ce2a0bSSteven Rostedt } 2537d6ce2a0bSSteven Rostedt 2538c23dca7cSSteven Rostedt if ($ret > 0) { 25390a05c769SSteven Rostedt return "good"; 2540c23dca7cSSteven Rostedt } elsif ($ret == 0) { 25410a05c769SSteven Rostedt return "bad"; 2542c23dca7cSSteven Rostedt } elsif ($bisect_skip) { 2543c23dca7cSSteven Rostedt doprint "HIT A BAD COMMIT ... SKIPPING\n"; 2544c23dca7cSSteven Rostedt return "skip"; 25450a05c769SSteven Rostedt } 25465f9b6cedSSteven Rostedt} 25475f9b6cedSSteven Rostedt 2548dad98754SSteven Rostedtsub update_bisect_replay { 2549dad98754SSteven Rostedt my $tmp_log = "$tmpdir/ktest_bisect_log"; 2550dad98754SSteven Rostedt run_command "git bisect log > $tmp_log" or 2551dad98754SSteven Rostedt die "can't create bisect log"; 2552dad98754SSteven Rostedt return $tmp_log; 2553dad98754SSteven Rostedt} 2554dad98754SSteven Rostedt 25555f9b6cedSSteven Rostedtsub bisect { 25565f9b6cedSSteven Rostedt my ($i) = @_; 25575f9b6cedSSteven Rostedt 25585f9b6cedSSteven Rostedt my $result; 25595f9b6cedSSteven Rostedt 2560b5f4aea6SSteven Rostedt die "BISECT_GOOD[$i] not defined\n" if (!defined($bisect_good)); 2561b5f4aea6SSteven Rostedt die "BISECT_BAD[$i] not defined\n" if (!defined($bisect_bad)); 2562b5f4aea6SSteven Rostedt die "BISECT_TYPE[$i] not defined\n" if (!defined($bisect_type)); 25635f9b6cedSSteven Rostedt 2564b5f4aea6SSteven Rostedt my $good = $bisect_good; 2565b5f4aea6SSteven Rostedt my $bad = $bisect_bad; 2566b5f4aea6SSteven Rostedt my $type = $bisect_type; 2567b5f4aea6SSteven Rostedt my $start = $bisect_start; 2568b5f4aea6SSteven Rostedt my $replay = $bisect_replay; 2569b5f4aea6SSteven Rostedt my $start_files = $bisect_files; 25703410f6fdSSteven Rostedt 25713410f6fdSSteven Rostedt if (defined($start_files)) { 25723410f6fdSSteven Rostedt $start_files = " -- " . $start_files; 25733410f6fdSSteven Rostedt } else { 25743410f6fdSSteven Rostedt $start_files = ""; 25753410f6fdSSteven Rostedt } 25765f9b6cedSSteven Rostedt 2577a57419b3SSteven Rostedt # convert to true sha1's 2578a57419b3SSteven Rostedt $good = get_sha1($good); 2579a57419b3SSteven Rostedt $bad = get_sha1($bad); 2580a57419b3SSteven Rostedt 2581b5f4aea6SSteven Rostedt if (defined($bisect_reverse) && $bisect_reverse == 1) { 2582d6ce2a0bSSteven Rostedt doprint "Performing a reverse bisect (bad is good, good is bad!)\n"; 2583d6ce2a0bSSteven Rostedt $reverse_bisect = 1; 2584d6ce2a0bSSteven Rostedt } else { 2585d6ce2a0bSSteven Rostedt $reverse_bisect = 0; 2586d6ce2a0bSSteven Rostedt } 2587d6ce2a0bSSteven Rostedt 25885a391fbfSSteven Rostedt # Can't have a test without having a test to run 25895a391fbfSSteven Rostedt if ($type eq "test" && !defined($run_test)) { 25905a391fbfSSteven Rostedt $type = "boot"; 25915a391fbfSSteven Rostedt } 25925a391fbfSSteven Rostedt 2593dad98754SSteven Rostedt # Check if a bisect was running 2594dad98754SSteven Rostedt my $bisect_start_file = "$builddir/.git/BISECT_START"; 2595dad98754SSteven Rostedt 2596b5f4aea6SSteven Rostedt my $check = $bisect_check; 2597dad98754SSteven Rostedt my $do_check = defined($check) && $check ne "0"; 2598dad98754SSteven Rostedt 2599dad98754SSteven Rostedt if ( -f $bisect_start_file ) { 2600dad98754SSteven Rostedt print "Bisect in progress found\n"; 2601dad98754SSteven Rostedt if ($do_check) { 2602dad98754SSteven Rostedt print " If you say yes, then no checks of good or bad will be done\n"; 2603dad98754SSteven Rostedt } 2604dad98754SSteven Rostedt if (defined($replay)) { 2605dad98754SSteven Rostedt print "** BISECT_REPLAY is defined in config file **"; 2606dad98754SSteven Rostedt print " Ignore config option and perform new git bisect log?\n"; 2607dad98754SSteven Rostedt if (read_ync " (yes, no, or cancel) ") { 2608dad98754SSteven Rostedt $replay = update_bisect_replay; 2609dad98754SSteven Rostedt $do_check = 0; 2610dad98754SSteven Rostedt } 2611dad98754SSteven Rostedt } elsif (read_yn "read git log and continue?") { 2612dad98754SSteven Rostedt $replay = update_bisect_replay; 2613dad98754SSteven Rostedt $do_check = 0; 2614dad98754SSteven Rostedt } 2615dad98754SSteven Rostedt } 2616dad98754SSteven Rostedt 2617dad98754SSteven Rostedt if ($do_check) { 2618a75fececSSteven Rostedt 2619a75fececSSteven Rostedt # get current HEAD 2620a57419b3SSteven Rostedt my $head = get_sha1("HEAD"); 2621a75fececSSteven Rostedt 2622a75fececSSteven Rostedt if ($check ne "good") { 2623a75fececSSteven Rostedt doprint "TESTING BISECT BAD [$bad]\n"; 2624a75fececSSteven Rostedt run_command "git checkout $bad" or 2625a75fececSSteven Rostedt die "Failed to checkout $bad"; 2626a75fececSSteven Rostedt 2627a75fececSSteven Rostedt $result = run_bisect $type; 2628a75fececSSteven Rostedt 2629a75fececSSteven Rostedt if ($result ne "bad") { 2630a75fececSSteven Rostedt fail "Tested BISECT_BAD [$bad] and it succeeded" and return 0; 2631a75fececSSteven Rostedt } 2632a75fececSSteven Rostedt } 2633a75fececSSteven Rostedt 2634a75fececSSteven Rostedt if ($check ne "bad") { 2635a75fececSSteven Rostedt doprint "TESTING BISECT GOOD [$good]\n"; 2636a75fececSSteven Rostedt run_command "git checkout $good" or 2637a75fececSSteven Rostedt die "Failed to checkout $good"; 2638a75fececSSteven Rostedt 2639a75fececSSteven Rostedt $result = run_bisect $type; 2640a75fececSSteven Rostedt 2641a75fececSSteven Rostedt if ($result ne "good") { 2642a75fececSSteven Rostedt fail "Tested BISECT_GOOD [$good] and it failed" and return 0; 2643a75fececSSteven Rostedt } 2644a75fececSSteven Rostedt } 2645a75fececSSteven Rostedt 2646a75fececSSteven Rostedt # checkout where we started 2647a75fececSSteven Rostedt run_command "git checkout $head" or 2648a75fececSSteven Rostedt die "Failed to checkout $head"; 2649a75fececSSteven Rostedt } 2650a75fececSSteven Rostedt 26513410f6fdSSteven Rostedt run_command "git bisect start$start_files" or 2652a75fececSSteven Rostedt dodie "could not start bisect"; 2653a75fececSSteven Rostedt 2654a75fececSSteven Rostedt run_command "git bisect good $good" or 2655a75fececSSteven Rostedt dodie "could not set bisect good to $good"; 2656a75fececSSteven Rostedt 2657a75fececSSteven Rostedt run_git_bisect "git bisect bad $bad" or 2658a75fececSSteven Rostedt dodie "could not set bisect bad to $bad"; 2659a75fececSSteven Rostedt 2660a75fececSSteven Rostedt if (defined($replay)) { 2661a75fececSSteven Rostedt run_command "git bisect replay $replay" or 2662a75fececSSteven Rostedt dodie "failed to run replay"; 2663a75fececSSteven Rostedt } 2664a75fececSSteven Rostedt 2665a75fececSSteven Rostedt if (defined($start)) { 2666a75fececSSteven Rostedt run_command "git checkout $start" or 2667a75fececSSteven Rostedt dodie "failed to checkout $start"; 2668a75fececSSteven Rostedt } 2669a75fececSSteven Rostedt 2670a75fececSSteven Rostedt my $test; 26715f9b6cedSSteven Rostedt do { 26725f9b6cedSSteven Rostedt $result = run_bisect $type; 2673a75fececSSteven Rostedt $test = run_git_bisect "git bisect $result"; 2674a75fececSSteven Rostedt } while ($test); 26755f9b6cedSSteven Rostedt 26765f9b6cedSSteven Rostedt run_command "git bisect log" or 26775f9b6cedSSteven Rostedt dodie "could not capture git bisect log"; 26785f9b6cedSSteven Rostedt 26795f9b6cedSSteven Rostedt run_command "git bisect reset" or 26805f9b6cedSSteven Rostedt dodie "could not reset git bisect"; 26815f9b6cedSSteven Rostedt 2682b5f4aea6SSteven Rostedt doprint "Bad commit was [$bisect_bad_commit]\n"; 26835f9b6cedSSteven Rostedt 26840a05c769SSteven Rostedt success $i; 26850a05c769SSteven Rostedt} 26860a05c769SSteven Rostedt 2687cf79fab6SSteven Rostedt# config_ignore holds the configs that were set (or unset) for 2688cf79fab6SSteven Rostedt# a good config and we will ignore these configs for the rest 2689cf79fab6SSteven Rostedt# of a config bisect. These configs stay as they were. 26900a05c769SSteven Rostedtmy %config_ignore; 2691cf79fab6SSteven Rostedt 2692cf79fab6SSteven Rostedt# config_set holds what all configs were set as. 26930a05c769SSteven Rostedtmy %config_set; 26940a05c769SSteven Rostedt 2695cf79fab6SSteven Rostedt# config_off holds the set of configs that the bad config had disabled. 2696cf79fab6SSteven Rostedt# We need to record them and set them in the .config when running 2697fb16d891SAdam Lee# olddefconfig, because olddefconfig keeps the defaults. 2698cf79fab6SSteven Rostedtmy %config_off; 2699cf79fab6SSteven Rostedt 2700cf79fab6SSteven Rostedt# config_off_tmp holds a set of configs to turn off for now 2701cf79fab6SSteven Rostedtmy @config_off_tmp; 2702cf79fab6SSteven Rostedt 2703cf79fab6SSteven Rostedt# config_list is the set of configs that are being tested 27040a05c769SSteven Rostedtmy %config_list; 27050a05c769SSteven Rostedtmy %null_config; 27060a05c769SSteven Rostedt 27070a05c769SSteven Rostedtmy %dependency; 27080a05c769SSteven Rostedt 27094c4ab120SSteven Rostedtsub assign_configs { 27104c4ab120SSteven Rostedt my ($hash, $config) = @_; 27110a05c769SSteven Rostedt 27120a05c769SSteven Rostedt open (IN, $config) 27130a05c769SSteven Rostedt or dodie "Failed to read $config"; 27140a05c769SSteven Rostedt 27150a05c769SSteven Rostedt while (<IN>) { 27169bf71749SSteven Rostedt if (/^((CONFIG\S*)=.*)/) { 27174c4ab120SSteven Rostedt ${$hash}{$2} = $1; 27180a05c769SSteven Rostedt } 27190a05c769SSteven Rostedt } 27200a05c769SSteven Rostedt 27210a05c769SSteven Rostedt close(IN); 27220a05c769SSteven Rostedt} 27230a05c769SSteven Rostedt 27244c4ab120SSteven Rostedtsub process_config_ignore { 27254c4ab120SSteven Rostedt my ($config) = @_; 27264c4ab120SSteven Rostedt 27274c4ab120SSteven Rostedt assign_configs \%config_ignore, $config; 27284c4ab120SSteven Rostedt} 27294c4ab120SSteven Rostedt 27300a05c769SSteven Rostedtsub read_current_config { 27310a05c769SSteven Rostedt my ($config_ref) = @_; 27320a05c769SSteven Rostedt 27330a05c769SSteven Rostedt %{$config_ref} = (); 27340a05c769SSteven Rostedt undef %{$config_ref}; 27350a05c769SSteven Rostedt 27360a05c769SSteven Rostedt my @key = keys %{$config_ref}; 27370a05c769SSteven Rostedt if ($#key >= 0) { 27380a05c769SSteven Rostedt print "did not delete!\n"; 27390a05c769SSteven Rostedt exit; 27400a05c769SSteven Rostedt } 27410a05c769SSteven Rostedt open (IN, "$output_config"); 27420a05c769SSteven Rostedt 27430a05c769SSteven Rostedt while (<IN>) { 27440a05c769SSteven Rostedt if (/^(CONFIG\S+)=(.*)/) { 27450a05c769SSteven Rostedt ${$config_ref}{$1} = $2; 27460a05c769SSteven Rostedt } 27470a05c769SSteven Rostedt } 27480a05c769SSteven Rostedt close(IN); 27490a05c769SSteven Rostedt} 27500a05c769SSteven Rostedt 27510a05c769SSteven Rostedtsub get_dependencies { 27520a05c769SSteven Rostedt my ($config) = @_; 27530a05c769SSteven Rostedt 27540a05c769SSteven Rostedt my $arr = $dependency{$config}; 27550a05c769SSteven Rostedt if (!defined($arr)) { 27560a05c769SSteven Rostedt return (); 27570a05c769SSteven Rostedt } 27580a05c769SSteven Rostedt 27590a05c769SSteven Rostedt my @deps = @{$arr}; 27600a05c769SSteven Rostedt 27610a05c769SSteven Rostedt foreach my $dep (@{$arr}) { 27620a05c769SSteven Rostedt print "ADD DEP $dep\n"; 27630a05c769SSteven Rostedt @deps = (@deps, get_dependencies $dep); 27640a05c769SSteven Rostedt } 27650a05c769SSteven Rostedt 27660a05c769SSteven Rostedt return @deps; 27670a05c769SSteven Rostedt} 27680a05c769SSteven Rostedt 27690a05c769SSteven Rostedtsub create_config { 27700a05c769SSteven Rostedt my @configs = @_; 27710a05c769SSteven Rostedt 27720a05c769SSteven Rostedt open(OUT, ">$output_config") or dodie "Can not write to $output_config"; 27730a05c769SSteven Rostedt 27740a05c769SSteven Rostedt foreach my $config (@configs) { 27750a05c769SSteven Rostedt print OUT "$config_set{$config}\n"; 27760a05c769SSteven Rostedt my @deps = get_dependencies $config; 27770a05c769SSteven Rostedt foreach my $dep (@deps) { 27780a05c769SSteven Rostedt print OUT "$config_set{$dep}\n"; 27790a05c769SSteven Rostedt } 27800a05c769SSteven Rostedt } 27810a05c769SSteven Rostedt 2782cf79fab6SSteven Rostedt # turn off configs to keep off 2783cf79fab6SSteven Rostedt foreach my $config (keys %config_off) { 2784cf79fab6SSteven Rostedt print OUT "# $config is not set\n"; 2785cf79fab6SSteven Rostedt } 2786cf79fab6SSteven Rostedt 2787cf79fab6SSteven Rostedt # turn off configs that should be off for now 2788cf79fab6SSteven Rostedt foreach my $config (@config_off_tmp) { 2789cf79fab6SSteven Rostedt print OUT "# $config is not set\n"; 2790cf79fab6SSteven Rostedt } 2791cf79fab6SSteven Rostedt 27920a05c769SSteven Rostedt foreach my $config (keys %config_ignore) { 27930a05c769SSteven Rostedt print OUT "$config_ignore{$config}\n"; 27940a05c769SSteven Rostedt } 27950a05c769SSteven Rostedt close(OUT); 27960a05c769SSteven Rostedt 2797fcb3f16aSSteven Rostedt make_oldconfig; 27980a05c769SSteven Rostedt} 27990a05c769SSteven Rostedt 28000a05c769SSteven Rostedtsub compare_configs { 28010a05c769SSteven Rostedt my (%a, %b) = @_; 28020a05c769SSteven Rostedt 28030a05c769SSteven Rostedt foreach my $item (keys %a) { 28040a05c769SSteven Rostedt if (!defined($b{$item})) { 28050a05c769SSteven Rostedt print "diff $item\n"; 28060a05c769SSteven Rostedt return 1; 28070a05c769SSteven Rostedt } 28080a05c769SSteven Rostedt delete $b{$item}; 28090a05c769SSteven Rostedt } 28100a05c769SSteven Rostedt 28110a05c769SSteven Rostedt my @keys = keys %b; 28120a05c769SSteven Rostedt if ($#keys) { 28130a05c769SSteven Rostedt print "diff2 $keys[0]\n"; 28140a05c769SSteven Rostedt } 28150a05c769SSteven Rostedt return -1 if ($#keys >= 0); 28160a05c769SSteven Rostedt 28170a05c769SSteven Rostedt return 0; 28180a05c769SSteven Rostedt} 28190a05c769SSteven Rostedt 28200a05c769SSteven Rostedtsub run_config_bisect_test { 28210a05c769SSteven Rostedt my ($type) = @_; 28220a05c769SSteven Rostedt 28230a05c769SSteven Rostedt return run_bisect_test $type, "oldconfig"; 28240a05c769SSteven Rostedt} 28250a05c769SSteven Rostedt 28260a05c769SSteven Rostedtsub process_passed { 28270a05c769SSteven Rostedt my (%configs) = @_; 28280a05c769SSteven Rostedt 28290a05c769SSteven Rostedt doprint "These configs had no failure: (Enabling them for further compiles)\n"; 28300a05c769SSteven Rostedt # Passed! All these configs are part of a good compile. 28310a05c769SSteven Rostedt # Add them to the min options. 28320a05c769SSteven Rostedt foreach my $config (keys %configs) { 28330a05c769SSteven Rostedt if (defined($config_list{$config})) { 28340a05c769SSteven Rostedt doprint " removing $config\n"; 28350a05c769SSteven Rostedt $config_ignore{$config} = $config_list{$config}; 28360a05c769SSteven Rostedt delete $config_list{$config}; 28370a05c769SSteven Rostedt } 28380a05c769SSteven Rostedt } 2839f1a27850SSteven Rostedt doprint "config copied to $outputdir/config_good\n"; 2840f1a27850SSteven Rostedt run_command "cp -f $output_config $outputdir/config_good"; 28410a05c769SSteven Rostedt} 28420a05c769SSteven Rostedt 28430a05c769SSteven Rostedtsub process_failed { 28440a05c769SSteven Rostedt my ($config) = @_; 28450a05c769SSteven Rostedt 28460a05c769SSteven Rostedt doprint "\n\n***************************************\n"; 28470a05c769SSteven Rostedt doprint "Found bad config: $config\n"; 28480a05c769SSteven Rostedt doprint "***************************************\n\n"; 28490a05c769SSteven Rostedt} 28500a05c769SSteven Rostedt 28510a05c769SSteven Rostedtsub run_config_bisect { 28520a05c769SSteven Rostedt 28530a05c769SSteven Rostedt my @start_list = keys %config_list; 28540a05c769SSteven Rostedt 28550a05c769SSteven Rostedt if ($#start_list < 0) { 28560a05c769SSteven Rostedt doprint "No more configs to test!!!\n"; 28570a05c769SSteven Rostedt return -1; 28580a05c769SSteven Rostedt } 28590a05c769SSteven Rostedt 28600a05c769SSteven Rostedt doprint "***** RUN TEST ***\n"; 2861b5f4aea6SSteven Rostedt my $type = $config_bisect_type; 28620a05c769SSteven Rostedt my $ret; 28630a05c769SSteven Rostedt my %current_config; 28640a05c769SSteven Rostedt 28650a05c769SSteven Rostedt my $count = $#start_list + 1; 28660a05c769SSteven Rostedt doprint " $count configs to test\n"; 28670a05c769SSteven Rostedt 28680a05c769SSteven Rostedt my $half = int($#start_list / 2); 28690a05c769SSteven Rostedt 28700a05c769SSteven Rostedt do { 28710a05c769SSteven Rostedt my @tophalf = @start_list[0 .. $half]; 28720a05c769SSteven Rostedt 2873cf79fab6SSteven Rostedt # keep the bottom half off 2874cf79fab6SSteven Rostedt if ($half < $#start_list) { 2875cf79fab6SSteven Rostedt @config_off_tmp = @start_list[$half + 1 .. $#start_list]; 2876cf79fab6SSteven Rostedt } else { 2877cf79fab6SSteven Rostedt @config_off_tmp = (); 2878cf79fab6SSteven Rostedt } 2879cf79fab6SSteven Rostedt 28800a05c769SSteven Rostedt create_config @tophalf; 28810a05c769SSteven Rostedt read_current_config \%current_config; 28820a05c769SSteven Rostedt 28830a05c769SSteven Rostedt $count = $#tophalf + 1; 28840a05c769SSteven Rostedt doprint "Testing $count configs\n"; 28850a05c769SSteven Rostedt my $found = 0; 28860a05c769SSteven Rostedt # make sure we test something 28870a05c769SSteven Rostedt foreach my $config (@tophalf) { 28880a05c769SSteven Rostedt if (defined($current_config{$config})) { 28890a05c769SSteven Rostedt logit " $config\n"; 28900a05c769SSteven Rostedt $found = 1; 28910a05c769SSteven Rostedt } 28920a05c769SSteven Rostedt } 28930a05c769SSteven Rostedt if (!$found) { 28940a05c769SSteven Rostedt # try the other half 28950a05c769SSteven Rostedt doprint "Top half produced no set configs, trying bottom half\n"; 2896cf79fab6SSteven Rostedt 2897cf79fab6SSteven Rostedt # keep the top half off 2898cf79fab6SSteven Rostedt @config_off_tmp = @tophalf; 28994c8cc55bSSteven Rostedt @tophalf = @start_list[$half + 1 .. $#start_list]; 2900cf79fab6SSteven Rostedt 29010a05c769SSteven Rostedt create_config @tophalf; 29020a05c769SSteven Rostedt read_current_config \%current_config; 29030a05c769SSteven Rostedt foreach my $config (@tophalf) { 29040a05c769SSteven Rostedt if (defined($current_config{$config})) { 29050a05c769SSteven Rostedt logit " $config\n"; 29060a05c769SSteven Rostedt $found = 1; 29070a05c769SSteven Rostedt } 29080a05c769SSteven Rostedt } 29090a05c769SSteven Rostedt if (!$found) { 29100a05c769SSteven Rostedt doprint "Failed: Can't make new config with current configs\n"; 29110a05c769SSteven Rostedt foreach my $config (@start_list) { 29120a05c769SSteven Rostedt doprint " CONFIG: $config\n"; 29130a05c769SSteven Rostedt } 29140a05c769SSteven Rostedt return -1; 29150a05c769SSteven Rostedt } 29160a05c769SSteven Rostedt $count = $#tophalf + 1; 29170a05c769SSteven Rostedt doprint "Testing $count configs\n"; 29180a05c769SSteven Rostedt } 29190a05c769SSteven Rostedt 29200a05c769SSteven Rostedt $ret = run_config_bisect_test $type; 2921c960bb9fSSteven Rostedt if ($bisect_manual) { 2922c960bb9fSSteven Rostedt $ret = answer_bisect; 2923c960bb9fSSteven Rostedt } 29240a05c769SSteven Rostedt if ($ret) { 29250a05c769SSteven Rostedt process_passed %current_config; 29260a05c769SSteven Rostedt return 0; 29270a05c769SSteven Rostedt } 29280a05c769SSteven Rostedt 29290a05c769SSteven Rostedt doprint "This config had a failure.\n"; 29300a05c769SSteven Rostedt doprint "Removing these configs that were not set in this config:\n"; 2931f1a27850SSteven Rostedt doprint "config copied to $outputdir/config_bad\n"; 2932f1a27850SSteven Rostedt run_command "cp -f $output_config $outputdir/config_bad"; 29330a05c769SSteven Rostedt 29340a05c769SSteven Rostedt # A config exists in this group that was bad. 29350a05c769SSteven Rostedt foreach my $config (keys %config_list) { 29360a05c769SSteven Rostedt if (!defined($current_config{$config})) { 29370a05c769SSteven Rostedt doprint " removing $config\n"; 29380a05c769SSteven Rostedt delete $config_list{$config}; 29390a05c769SSteven Rostedt } 29400a05c769SSteven Rostedt } 29410a05c769SSteven Rostedt 29420a05c769SSteven Rostedt @start_list = @tophalf; 29430a05c769SSteven Rostedt 29440a05c769SSteven Rostedt if ($#start_list == 0) { 29450a05c769SSteven Rostedt process_failed $start_list[0]; 29460a05c769SSteven Rostedt return 1; 29470a05c769SSteven Rostedt } 29480a05c769SSteven Rostedt 29490a05c769SSteven Rostedt # remove half the configs we are looking at and see if 29500a05c769SSteven Rostedt # they are good. 29510a05c769SSteven Rostedt $half = int($#start_list / 2); 29524c8cc55bSSteven Rostedt } while ($#start_list > 0); 29530a05c769SSteven Rostedt 2954c960bb9fSSteven Rostedt # we found a single config, try it again unless we are running manually 2955c960bb9fSSteven Rostedt 2956c960bb9fSSteven Rostedt if ($bisect_manual) { 2957c960bb9fSSteven Rostedt process_failed $start_list[0]; 2958c960bb9fSSteven Rostedt return 1; 2959c960bb9fSSteven Rostedt } 2960c960bb9fSSteven Rostedt 29610a05c769SSteven Rostedt my @tophalf = @start_list[0 .. 0]; 29620a05c769SSteven Rostedt 29630a05c769SSteven Rostedt $ret = run_config_bisect_test $type; 29640a05c769SSteven Rostedt if ($ret) { 29650a05c769SSteven Rostedt process_passed %current_config; 29660a05c769SSteven Rostedt return 0; 29670a05c769SSteven Rostedt } 29680a05c769SSteven Rostedt 29690a05c769SSteven Rostedt process_failed $start_list[0]; 29700a05c769SSteven Rostedt return 1; 29710a05c769SSteven Rostedt} 29720a05c769SSteven Rostedt 29730a05c769SSteven Rostedtsub config_bisect { 29740a05c769SSteven Rostedt my ($i) = @_; 29750a05c769SSteven Rostedt 2976b5f4aea6SSteven Rostedt my $start_config = $config_bisect; 29770a05c769SSteven Rostedt 29780a05c769SSteven Rostedt my $tmpconfig = "$tmpdir/use_config"; 29790a05c769SSteven Rostedt 298030f75da5SSteven Rostedt if (defined($config_bisect_good)) { 298130f75da5SSteven Rostedt process_config_ignore $config_bisect_good; 298230f75da5SSteven Rostedt } 298330f75da5SSteven Rostedt 29840a05c769SSteven Rostedt # Make the file with the bad config and the min config 29850a05c769SSteven Rostedt if (defined($minconfig)) { 29860a05c769SSteven Rostedt # read the min config for things to ignore 29870a05c769SSteven Rostedt run_command "cp $minconfig $tmpconfig" or 29880a05c769SSteven Rostedt dodie "failed to copy $minconfig to $tmpconfig"; 29890a05c769SSteven Rostedt } else { 29900a05c769SSteven Rostedt unlink $tmpconfig; 29910a05c769SSteven Rostedt } 29920a05c769SSteven Rostedt 29930a05c769SSteven Rostedt if (-f $tmpconfig) { 2994fcb3f16aSSteven Rostedt load_force_config($tmpconfig); 29950a05c769SSteven Rostedt process_config_ignore $tmpconfig; 29960a05c769SSteven Rostedt } 29970a05c769SSteven Rostedt 29980a05c769SSteven Rostedt # now process the start config 29990a05c769SSteven Rostedt run_command "cp $start_config $output_config" or 30000a05c769SSteven Rostedt dodie "failed to copy $start_config to $output_config"; 30010a05c769SSteven Rostedt 30020a05c769SSteven Rostedt # read directly what we want to check 30030a05c769SSteven Rostedt my %config_check; 30040a05c769SSteven Rostedt open (IN, $output_config) 3005f9dee311SMasanari Iida or dodie "failed to open $output_config"; 30060a05c769SSteven Rostedt 30070a05c769SSteven Rostedt while (<IN>) { 30080a05c769SSteven Rostedt if (/^((CONFIG\S*)=.*)/) { 30090a05c769SSteven Rostedt $config_check{$2} = $1; 30100a05c769SSteven Rostedt } 30110a05c769SSteven Rostedt } 30120a05c769SSteven Rostedt close(IN); 30130a05c769SSteven Rostedt 3014250bae8bSSteven Rostedt # Now run oldconfig with the minconfig 3015fcb3f16aSSteven Rostedt make_oldconfig; 30160a05c769SSteven Rostedt 30170a05c769SSteven Rostedt # check to see what we lost (or gained) 30180a05c769SSteven Rostedt open (IN, $output_config) 30190a05c769SSteven Rostedt or dodie "Failed to read $start_config"; 30200a05c769SSteven Rostedt 30210a05c769SSteven Rostedt my %removed_configs; 30220a05c769SSteven Rostedt my %added_configs; 30230a05c769SSteven Rostedt 30240a05c769SSteven Rostedt while (<IN>) { 30250a05c769SSteven Rostedt if (/^((CONFIG\S*)=.*)/) { 30260a05c769SSteven Rostedt # save off all options 30270a05c769SSteven Rostedt $config_set{$2} = $1; 30280a05c769SSteven Rostedt if (defined($config_check{$2})) { 30290a05c769SSteven Rostedt if (defined($config_ignore{$2})) { 30300a05c769SSteven Rostedt $removed_configs{$2} = $1; 30310a05c769SSteven Rostedt } else { 30320a05c769SSteven Rostedt $config_list{$2} = $1; 30330a05c769SSteven Rostedt } 30340a05c769SSteven Rostedt } elsif (!defined($config_ignore{$2})) { 30350a05c769SSteven Rostedt $added_configs{$2} = $1; 30360a05c769SSteven Rostedt $config_list{$2} = $1; 30370a05c769SSteven Rostedt } 3038cf79fab6SSteven Rostedt } elsif (/^# ((CONFIG\S*).*)/) { 3039cf79fab6SSteven Rostedt # Keep these configs disabled 3040cf79fab6SSteven Rostedt $config_set{$2} = $1; 3041cf79fab6SSteven Rostedt $config_off{$2} = $1; 30420a05c769SSteven Rostedt } 30430a05c769SSteven Rostedt } 30440a05c769SSteven Rostedt close(IN); 30450a05c769SSteven Rostedt 30460a05c769SSteven Rostedt my @confs = keys %removed_configs; 30470a05c769SSteven Rostedt if ($#confs >= 0) { 30480a05c769SSteven Rostedt doprint "Configs overridden by default configs and removed from check:\n"; 30490a05c769SSteven Rostedt foreach my $config (@confs) { 30500a05c769SSteven Rostedt doprint " $config\n"; 30510a05c769SSteven Rostedt } 30520a05c769SSteven Rostedt } 30530a05c769SSteven Rostedt @confs = keys %added_configs; 30540a05c769SSteven Rostedt if ($#confs >= 0) { 30550a05c769SSteven Rostedt doprint "Configs appearing in make oldconfig and added:\n"; 30560a05c769SSteven Rostedt foreach my $config (@confs) { 30570a05c769SSteven Rostedt doprint " $config\n"; 30580a05c769SSteven Rostedt } 30590a05c769SSteven Rostedt } 30600a05c769SSteven Rostedt 30610a05c769SSteven Rostedt my %config_test; 30620a05c769SSteven Rostedt my $once = 0; 30630a05c769SSteven Rostedt 3064cf79fab6SSteven Rostedt @config_off_tmp = (); 3065cf79fab6SSteven Rostedt 30660a05c769SSteven Rostedt # Sometimes kconfig does weird things. We must make sure 30670a05c769SSteven Rostedt # that the config we autocreate has everything we need 30680a05c769SSteven Rostedt # to test, otherwise we may miss testing configs, or 30690a05c769SSteven Rostedt # may not be able to create a new config. 30700a05c769SSteven Rostedt # Here we create a config with everything set. 30710a05c769SSteven Rostedt create_config (keys %config_list); 30720a05c769SSteven Rostedt read_current_config \%config_test; 30730a05c769SSteven Rostedt foreach my $config (keys %config_list) { 30740a05c769SSteven Rostedt if (!defined($config_test{$config})) { 30750a05c769SSteven Rostedt if (!$once) { 30760a05c769SSteven Rostedt $once = 1; 30770a05c769SSteven Rostedt doprint "Configs not produced by kconfig (will not be checked):\n"; 30780a05c769SSteven Rostedt } 30790a05c769SSteven Rostedt doprint " $config\n"; 30800a05c769SSteven Rostedt delete $config_list{$config}; 30810a05c769SSteven Rostedt } 30820a05c769SSteven Rostedt } 30830a05c769SSteven Rostedt my $ret; 3084b0918612SSteven Rostedt 3085b0918612SSteven Rostedt if (defined($config_bisect_check) && $config_bisect_check) { 3086b0918612SSteven Rostedt doprint " Checking to make sure bad config with min config fails\n"; 3087b0918612SSteven Rostedt create_config keys %config_list; 3088b0918612SSteven Rostedt $ret = run_config_bisect_test $config_bisect_type; 3089b0918612SSteven Rostedt if ($ret) { 3090b0918612SSteven Rostedt doprint " FAILED! Bad config with min config boots fine\n"; 3091b0918612SSteven Rostedt return -1; 3092b0918612SSteven Rostedt } 3093b0918612SSteven Rostedt doprint " Bad config with min config fails as expected\n"; 3094b0918612SSteven Rostedt } 3095b0918612SSteven Rostedt 30960a05c769SSteven Rostedt do { 30970a05c769SSteven Rostedt $ret = run_config_bisect; 30980a05c769SSteven Rostedt } while (!$ret); 30990a05c769SSteven Rostedt 31000a05c769SSteven Rostedt return $ret if ($ret < 0); 31015f9b6cedSSteven Rostedt 31025f9b6cedSSteven Rostedt success $i; 31035f9b6cedSSteven Rostedt} 31045f9b6cedSSteven Rostedt 310527d934b2SSteven Rostedtsub patchcheck_reboot { 310627d934b2SSteven Rostedt doprint "Reboot and sleep $patchcheck_sleep_time seconds\n"; 3107bc7c5803SSteven Rostedt reboot_to_good $patchcheck_sleep_time; 310827d934b2SSteven Rostedt} 310927d934b2SSteven Rostedt 31106c5ee0beSSteven Rostedtsub patchcheck { 31116c5ee0beSSteven Rostedt my ($i) = @_; 31126c5ee0beSSteven Rostedt 31136c5ee0beSSteven Rostedt die "PATCHCHECK_START[$i] not defined\n" 3114b5f4aea6SSteven Rostedt if (!defined($patchcheck_start)); 31156c5ee0beSSteven Rostedt die "PATCHCHECK_TYPE[$i] not defined\n" 3116b5f4aea6SSteven Rostedt if (!defined($patchcheck_type)); 31176c5ee0beSSteven Rostedt 3118b5f4aea6SSteven Rostedt my $start = $patchcheck_start; 31196c5ee0beSSteven Rostedt 31206c5ee0beSSteven Rostedt my $end = "HEAD"; 3121b5f4aea6SSteven Rostedt if (defined($patchcheck_end)) { 3122b5f4aea6SSteven Rostedt $end = $patchcheck_end; 31236c5ee0beSSteven Rostedt } 31246c5ee0beSSteven Rostedt 3125a57419b3SSteven Rostedt # Get the true sha1's since we can use things like HEAD~3 3126a57419b3SSteven Rostedt $start = get_sha1($start); 3127a57419b3SSteven Rostedt $end = get_sha1($end); 3128a57419b3SSteven Rostedt 3129b5f4aea6SSteven Rostedt my $type = $patchcheck_type; 31306c5ee0beSSteven Rostedt 31316c5ee0beSSteven Rostedt # Can't have a test without having a test to run 31326c5ee0beSSteven Rostedt if ($type eq "test" && !defined($run_test)) { 31336c5ee0beSSteven Rostedt $type = "boot"; 31346c5ee0beSSteven Rostedt } 31356c5ee0beSSteven Rostedt 31366c5ee0beSSteven Rostedt open (IN, "git log --pretty=oneline $end|") or 31376c5ee0beSSteven Rostedt dodie "could not get git list"; 31386c5ee0beSSteven Rostedt 31396c5ee0beSSteven Rostedt my @list; 31406c5ee0beSSteven Rostedt 31416c5ee0beSSteven Rostedt while (<IN>) { 31426c5ee0beSSteven Rostedt chomp; 31436c5ee0beSSteven Rostedt $list[$#list+1] = $_; 31446c5ee0beSSteven Rostedt last if (/^$start/); 31456c5ee0beSSteven Rostedt } 31466c5ee0beSSteven Rostedt close(IN); 31476c5ee0beSSteven Rostedt 31486c5ee0beSSteven Rostedt if ($list[$#list] !~ /^$start/) { 31492b7d9b21SSteven Rostedt fail "SHA1 $start not found"; 31506c5ee0beSSteven Rostedt } 31516c5ee0beSSteven Rostedt 31526c5ee0beSSteven Rostedt # go backwards in the list 31536c5ee0beSSteven Rostedt @list = reverse @list; 31546c5ee0beSSteven Rostedt 31556c5ee0beSSteven Rostedt my $save_clean = $noclean; 31561990207dSSteven Rostedt my %ignored_warnings; 31571990207dSSteven Rostedt 31581990207dSSteven Rostedt if (defined($ignore_warnings)) { 31591990207dSSteven Rostedt foreach my $sha1 (split /\s+/, $ignore_warnings) { 31601990207dSSteven Rostedt $ignored_warnings{$sha1} = 1; 31611990207dSSteven Rostedt } 31621990207dSSteven Rostedt } 31636c5ee0beSSteven Rostedt 31646c5ee0beSSteven Rostedt $in_patchcheck = 1; 31656c5ee0beSSteven Rostedt foreach my $item (@list) { 31666c5ee0beSSteven Rostedt my $sha1 = $item; 31676c5ee0beSSteven Rostedt $sha1 =~ s/^([[:xdigit:]]+).*/$1/; 31686c5ee0beSSteven Rostedt 31696c5ee0beSSteven Rostedt doprint "\nProcessing commit $item\n\n"; 31706c5ee0beSSteven Rostedt 31716c5ee0beSSteven Rostedt run_command "git checkout $sha1" or 31726c5ee0beSSteven Rostedt die "Failed to checkout $sha1"; 31736c5ee0beSSteven Rostedt 31746c5ee0beSSteven Rostedt # only clean on the first and last patch 31756c5ee0beSSteven Rostedt if ($item eq $list[0] || 31766c5ee0beSSteven Rostedt $item eq $list[$#list]) { 31776c5ee0beSSteven Rostedt $noclean = $save_clean; 31786c5ee0beSSteven Rostedt } else { 31796c5ee0beSSteven Rostedt $noclean = 1; 31806c5ee0beSSteven Rostedt } 31816c5ee0beSSteven Rostedt 31826c5ee0beSSteven Rostedt if (defined($minconfig)) { 31832b7d9b21SSteven Rostedt build "useconfig:$minconfig" or return 0; 31846c5ee0beSSteven Rostedt } else { 31856c5ee0beSSteven Rostedt # ?? no config to use? 31862b7d9b21SSteven Rostedt build "oldconfig" or return 0; 31876c5ee0beSSteven Rostedt } 31886c5ee0beSSteven Rostedt 31894283b169SSteven Rostedt (Red Hat) # No need to do per patch checking if warnings file exists 31904283b169SSteven Rostedt (Red Hat) if (!defined($warnings_file) && !defined($ignored_warnings{$sha1})) { 31914283b169SSteven Rostedt (Red Hat) check_patch_buildlog $sha1 or return 0; 31921990207dSSteven Rostedt } 31936c5ee0beSSteven Rostedt 31944283b169SSteven Rostedt (Red Hat) check_buildlog or return 0; 31954283b169SSteven Rostedt (Red Hat) 31966c5ee0beSSteven Rostedt next if ($type eq "build"); 31976c5ee0beSSteven Rostedt 31987faafbd6SSteven Rostedt my $failed = 0; 31997faafbd6SSteven Rostedt 3200ddf607e5SSteven Rostedt start_monitor_and_boot or $failed = 1; 32017faafbd6SSteven Rostedt 32027faafbd6SSteven Rostedt if (!$failed && $type ne "boot"){ 32037faafbd6SSteven Rostedt do_run_test or $failed = 1; 32047faafbd6SSteven Rostedt } 32057faafbd6SSteven Rostedt end_monitor; 32067faafbd6SSteven Rostedt return 0 if ($failed); 32077faafbd6SSteven Rostedt 320827d934b2SSteven Rostedt patchcheck_reboot; 320927d934b2SSteven Rostedt 32106c5ee0beSSteven Rostedt } 32116c5ee0beSSteven Rostedt $in_patchcheck = 0; 32126c5ee0beSSteven Rostedt success $i; 32132b7d9b21SSteven Rostedt 32142b7d9b21SSteven Rostedt return 1; 32156c5ee0beSSteven Rostedt} 32166c5ee0beSSteven Rostedt 3217b9066f6cSSteven Rostedtmy %depends; 3218ac6974c7SSteven Rostedtmy %depcount; 3219b9066f6cSSteven Rostedtmy $iflevel = 0; 3220b9066f6cSSteven Rostedtmy @ifdeps; 3221b9066f6cSSteven Rostedt 3222b9066f6cSSteven Rostedt# prevent recursion 3223b9066f6cSSteven Rostedtmy %read_kconfigs; 3224b9066f6cSSteven Rostedt 3225ac6974c7SSteven Rostedtsub add_dep { 3226ac6974c7SSteven Rostedt # $config depends on $dep 3227ac6974c7SSteven Rostedt my ($config, $dep) = @_; 3228ac6974c7SSteven Rostedt 3229ac6974c7SSteven Rostedt if (defined($depends{$config})) { 3230ac6974c7SSteven Rostedt $depends{$config} .= " " . $dep; 3231ac6974c7SSteven Rostedt } else { 3232ac6974c7SSteven Rostedt $depends{$config} = $dep; 3233ac6974c7SSteven Rostedt } 3234ac6974c7SSteven Rostedt 3235ac6974c7SSteven Rostedt # record the number of configs depending on $dep 3236ac6974c7SSteven Rostedt if (defined $depcount{$dep}) { 3237ac6974c7SSteven Rostedt $depcount{$dep}++; 3238ac6974c7SSteven Rostedt } else { 3239ac6974c7SSteven Rostedt $depcount{$dep} = 1; 3240ac6974c7SSteven Rostedt } 3241ac6974c7SSteven Rostedt} 3242ac6974c7SSteven Rostedt 3243b9066f6cSSteven Rostedt# taken from streamline_config.pl 3244b9066f6cSSteven Rostedtsub read_kconfig { 3245b9066f6cSSteven Rostedt my ($kconfig) = @_; 3246b9066f6cSSteven Rostedt 3247b9066f6cSSteven Rostedt my $state = "NONE"; 3248b9066f6cSSteven Rostedt my $config; 3249b9066f6cSSteven Rostedt my @kconfigs; 3250b9066f6cSSteven Rostedt 3251b9066f6cSSteven Rostedt my $cont = 0; 3252b9066f6cSSteven Rostedt my $line; 3253b9066f6cSSteven Rostedt 3254b9066f6cSSteven Rostedt 3255b9066f6cSSteven Rostedt if (! -f $kconfig) { 3256b9066f6cSSteven Rostedt doprint "file $kconfig does not exist, skipping\n"; 3257b9066f6cSSteven Rostedt return; 3258b9066f6cSSteven Rostedt } 3259b9066f6cSSteven Rostedt 3260b9066f6cSSteven Rostedt open(KIN, "$kconfig") 3261b9066f6cSSteven Rostedt or die "Can't open $kconfig"; 3262b9066f6cSSteven Rostedt while (<KIN>) { 3263b9066f6cSSteven Rostedt chomp; 3264b9066f6cSSteven Rostedt 3265b9066f6cSSteven Rostedt # Make sure that lines ending with \ continue 3266b9066f6cSSteven Rostedt if ($cont) { 3267b9066f6cSSteven Rostedt $_ = $line . " " . $_; 3268b9066f6cSSteven Rostedt } 3269b9066f6cSSteven Rostedt 3270b9066f6cSSteven Rostedt if (s/\\$//) { 3271b9066f6cSSteven Rostedt $cont = 1; 3272b9066f6cSSteven Rostedt $line = $_; 3273b9066f6cSSteven Rostedt next; 3274b9066f6cSSteven Rostedt } 3275b9066f6cSSteven Rostedt 3276b9066f6cSSteven Rostedt $cont = 0; 3277b9066f6cSSteven Rostedt 3278b9066f6cSSteven Rostedt # collect any Kconfig sources 3279b9066f6cSSteven Rostedt if (/^source\s*"(.*)"/) { 3280b9066f6cSSteven Rostedt $kconfigs[$#kconfigs+1] = $1; 3281b9066f6cSSteven Rostedt } 3282b9066f6cSSteven Rostedt 3283b9066f6cSSteven Rostedt # configs found 3284b9066f6cSSteven Rostedt if (/^\s*(menu)?config\s+(\S+)\s*$/) { 3285b9066f6cSSteven Rostedt $state = "NEW"; 3286b9066f6cSSteven Rostedt $config = $2; 3287b9066f6cSSteven Rostedt 3288b9066f6cSSteven Rostedt for (my $i = 0; $i < $iflevel; $i++) { 3289ac6974c7SSteven Rostedt add_dep $config, $ifdeps[$i]; 3290b9066f6cSSteven Rostedt } 3291b9066f6cSSteven Rostedt 3292b9066f6cSSteven Rostedt # collect the depends for the config 3293b9066f6cSSteven Rostedt } elsif ($state eq "NEW" && /^\s*depends\s+on\s+(.*)$/) { 3294b9066f6cSSteven Rostedt 3295ac6974c7SSteven Rostedt add_dep $config, $1; 3296b9066f6cSSteven Rostedt 3297b9066f6cSSteven Rostedt # Get the configs that select this config 3298ac6974c7SSteven Rostedt } elsif ($state eq "NEW" && /^\s*select\s+(\S+)/) { 3299ac6974c7SSteven Rostedt 3300ac6974c7SSteven Rostedt # selected by depends on config 3301ac6974c7SSteven Rostedt add_dep $1, $config; 3302b9066f6cSSteven Rostedt 3303b9066f6cSSteven Rostedt # Check for if statements 3304b9066f6cSSteven Rostedt } elsif (/^if\s+(.*\S)\s*$/) { 3305b9066f6cSSteven Rostedt my $deps = $1; 3306b9066f6cSSteven Rostedt # remove beginning and ending non text 3307b9066f6cSSteven Rostedt $deps =~ s/^[^a-zA-Z0-9_]*//; 3308b9066f6cSSteven Rostedt $deps =~ s/[^a-zA-Z0-9_]*$//; 3309b9066f6cSSteven Rostedt 3310b9066f6cSSteven Rostedt my @deps = split /[^a-zA-Z0-9_]+/, $deps; 3311b9066f6cSSteven Rostedt 3312b9066f6cSSteven Rostedt $ifdeps[$iflevel++] = join ':', @deps; 3313b9066f6cSSteven Rostedt 3314b9066f6cSSteven Rostedt } elsif (/^endif/) { 3315b9066f6cSSteven Rostedt 3316b9066f6cSSteven Rostedt $iflevel-- if ($iflevel); 3317b9066f6cSSteven Rostedt 3318b9066f6cSSteven Rostedt # stop on "help" 3319b9066f6cSSteven Rostedt } elsif (/^\s*help\s*$/) { 3320b9066f6cSSteven Rostedt $state = "NONE"; 3321b9066f6cSSteven Rostedt } 3322b9066f6cSSteven Rostedt } 3323b9066f6cSSteven Rostedt close(KIN); 3324b9066f6cSSteven Rostedt 3325b9066f6cSSteven Rostedt # read in any configs that were found. 3326b9066f6cSSteven Rostedt foreach $kconfig (@kconfigs) { 3327b9066f6cSSteven Rostedt if (!defined($read_kconfigs{$kconfig})) { 3328b9066f6cSSteven Rostedt $read_kconfigs{$kconfig} = 1; 3329b9066f6cSSteven Rostedt read_kconfig("$builddir/$kconfig"); 3330b9066f6cSSteven Rostedt } 3331b9066f6cSSteven Rostedt } 3332b9066f6cSSteven Rostedt} 3333b9066f6cSSteven Rostedt 3334b9066f6cSSteven Rostedtsub read_depends { 3335b9066f6cSSteven Rostedt # find out which arch this is by the kconfig file 3336b9066f6cSSteven Rostedt open (IN, $output_config) 3337b9066f6cSSteven Rostedt or dodie "Failed to read $output_config"; 3338b9066f6cSSteven Rostedt my $arch; 3339b9066f6cSSteven Rostedt while (<IN>) { 3340b9066f6cSSteven Rostedt if (m,Linux/(\S+)\s+\S+\s+Kernel Configuration,) { 3341b9066f6cSSteven Rostedt $arch = $1; 3342b9066f6cSSteven Rostedt last; 3343b9066f6cSSteven Rostedt } 3344b9066f6cSSteven Rostedt } 3345b9066f6cSSteven Rostedt close IN; 3346b9066f6cSSteven Rostedt 3347b9066f6cSSteven Rostedt if (!defined($arch)) { 3348b9066f6cSSteven Rostedt doprint "Could not find arch from config file\n"; 3349b9066f6cSSteven Rostedt doprint "no dependencies used\n"; 3350b9066f6cSSteven Rostedt return; 3351b9066f6cSSteven Rostedt } 3352b9066f6cSSteven Rostedt 3353b9066f6cSSteven Rostedt # arch is really the subarch, we need to know 3354b9066f6cSSteven Rostedt # what directory to look at. 3355b9066f6cSSteven Rostedt if ($arch eq "i386" || $arch eq "x86_64") { 3356b9066f6cSSteven Rostedt $arch = "x86"; 3357b9066f6cSSteven Rostedt } elsif ($arch =~ /^tile/) { 3358b9066f6cSSteven Rostedt $arch = "tile"; 3359b9066f6cSSteven Rostedt } 3360b9066f6cSSteven Rostedt 3361b9066f6cSSteven Rostedt my $kconfig = "$builddir/arch/$arch/Kconfig"; 3362b9066f6cSSteven Rostedt 3363b9066f6cSSteven Rostedt if (! -f $kconfig && $arch =~ /\d$/) { 3364b9066f6cSSteven Rostedt my $orig = $arch; 3365b9066f6cSSteven Rostedt # some subarchs have numbers, truncate them 3366b9066f6cSSteven Rostedt $arch =~ s/\d*$//; 3367b9066f6cSSteven Rostedt $kconfig = "$builddir/arch/$arch/Kconfig"; 3368b9066f6cSSteven Rostedt if (! -f $kconfig) { 3369b9066f6cSSteven Rostedt doprint "No idea what arch dir $orig is for\n"; 3370b9066f6cSSteven Rostedt doprint "no dependencies used\n"; 3371b9066f6cSSteven Rostedt return; 3372b9066f6cSSteven Rostedt } 3373b9066f6cSSteven Rostedt } 3374b9066f6cSSteven Rostedt 3375b9066f6cSSteven Rostedt read_kconfig($kconfig); 3376b9066f6cSSteven Rostedt} 3377b9066f6cSSteven Rostedt 33784c4ab120SSteven Rostedtsub read_config_list { 33794c4ab120SSteven Rostedt my ($config) = @_; 33804c4ab120SSteven Rostedt 33814c4ab120SSteven Rostedt open (IN, $config) 33824c4ab120SSteven Rostedt or dodie "Failed to read $config"; 33834c4ab120SSteven Rostedt 33844c4ab120SSteven Rostedt while (<IN>) { 33854c4ab120SSteven Rostedt if (/^((CONFIG\S*)=.*)/) { 33864c4ab120SSteven Rostedt if (!defined($config_ignore{$2})) { 33874c4ab120SSteven Rostedt $config_list{$2} = $1; 33884c4ab120SSteven Rostedt } 33894c4ab120SSteven Rostedt } 33904c4ab120SSteven Rostedt } 33914c4ab120SSteven Rostedt 33924c4ab120SSteven Rostedt close(IN); 33934c4ab120SSteven Rostedt} 33944c4ab120SSteven Rostedt 33954c4ab120SSteven Rostedtsub read_output_config { 33964c4ab120SSteven Rostedt my ($config) = @_; 33974c4ab120SSteven Rostedt 33984c4ab120SSteven Rostedt assign_configs \%config_ignore, $config; 33994c4ab120SSteven Rostedt} 34004c4ab120SSteven Rostedt 34014c4ab120SSteven Rostedtsub make_new_config { 34024c4ab120SSteven Rostedt my @configs = @_; 34034c4ab120SSteven Rostedt 34044c4ab120SSteven Rostedt open (OUT, ">$output_config") 34054c4ab120SSteven Rostedt or dodie "Failed to write $output_config"; 34064c4ab120SSteven Rostedt 34074c4ab120SSteven Rostedt foreach my $config (@configs) { 34084c4ab120SSteven Rostedt print OUT "$config\n"; 34094c4ab120SSteven Rostedt } 34104c4ab120SSteven Rostedt close OUT; 34114c4ab120SSteven Rostedt} 34124c4ab120SSteven Rostedt 3413ac6974c7SSteven Rostedtsub chomp_config { 3414ac6974c7SSteven Rostedt my ($config) = @_; 3415ac6974c7SSteven Rostedt 3416ac6974c7SSteven Rostedt $config =~ s/CONFIG_//; 3417ac6974c7SSteven Rostedt 3418ac6974c7SSteven Rostedt return $config; 3419ac6974c7SSteven Rostedt} 3420ac6974c7SSteven Rostedt 3421b9066f6cSSteven Rostedtsub get_depends { 3422b9066f6cSSteven Rostedt my ($dep) = @_; 3423b9066f6cSSteven Rostedt 3424ac6974c7SSteven Rostedt my $kconfig = chomp_config $dep; 3425b9066f6cSSteven Rostedt 3426b9066f6cSSteven Rostedt $dep = $depends{"$kconfig"}; 3427b9066f6cSSteven Rostedt 3428b9066f6cSSteven Rostedt # the dep string we have saves the dependencies as they 3429b9066f6cSSteven Rostedt # were found, including expressions like ! && ||. We 3430b9066f6cSSteven Rostedt # want to split this out into just an array of configs. 3431b9066f6cSSteven Rostedt 3432b9066f6cSSteven Rostedt my $valid = "A-Za-z_0-9"; 3433b9066f6cSSteven Rostedt 3434b9066f6cSSteven Rostedt my @configs; 3435b9066f6cSSteven Rostedt 3436b9066f6cSSteven Rostedt while ($dep =~ /[$valid]/) { 3437b9066f6cSSteven Rostedt 3438b9066f6cSSteven Rostedt if ($dep =~ /^[^$valid]*([$valid]+)/) { 3439b9066f6cSSteven Rostedt my $conf = "CONFIG_" . $1; 3440b9066f6cSSteven Rostedt 3441b9066f6cSSteven Rostedt $configs[$#configs + 1] = $conf; 3442b9066f6cSSteven Rostedt 3443b9066f6cSSteven Rostedt $dep =~ s/^[^$valid]*[$valid]+//; 3444b9066f6cSSteven Rostedt } else { 3445b9066f6cSSteven Rostedt die "this should never happen"; 3446b9066f6cSSteven Rostedt } 3447b9066f6cSSteven Rostedt } 3448b9066f6cSSteven Rostedt 3449b9066f6cSSteven Rostedt return @configs; 3450b9066f6cSSteven Rostedt} 3451b9066f6cSSteven Rostedt 3452b9066f6cSSteven Rostedtmy %min_configs; 3453b9066f6cSSteven Rostedtmy %keep_configs; 345443d1b651SSteven Rostedtmy %save_configs; 3455b9066f6cSSteven Rostedtmy %processed_configs; 3456b9066f6cSSteven Rostedtmy %nochange_config; 3457b9066f6cSSteven Rostedt 3458b9066f6cSSteven Rostedtsub test_this_config { 3459b9066f6cSSteven Rostedt my ($config) = @_; 3460b9066f6cSSteven Rostedt 3461b9066f6cSSteven Rostedt my $found; 3462b9066f6cSSteven Rostedt 3463b9066f6cSSteven Rostedt # if we already processed this config, skip it 3464b9066f6cSSteven Rostedt if (defined($processed_configs{$config})) { 3465b9066f6cSSteven Rostedt return undef; 3466b9066f6cSSteven Rostedt } 3467b9066f6cSSteven Rostedt $processed_configs{$config} = 1; 3468b9066f6cSSteven Rostedt 3469b9066f6cSSteven Rostedt # if this config failed during this round, skip it 3470b9066f6cSSteven Rostedt if (defined($nochange_config{$config})) { 3471b9066f6cSSteven Rostedt return undef; 3472b9066f6cSSteven Rostedt } 3473b9066f6cSSteven Rostedt 3474ac6974c7SSteven Rostedt my $kconfig = chomp_config $config; 3475b9066f6cSSteven Rostedt 3476b9066f6cSSteven Rostedt # Test dependencies first 3477b9066f6cSSteven Rostedt if (defined($depends{"$kconfig"})) { 3478b9066f6cSSteven Rostedt my @parents = get_depends $config; 3479b9066f6cSSteven Rostedt foreach my $parent (@parents) { 3480b9066f6cSSteven Rostedt # if the parent is in the min config, check it first 3481b9066f6cSSteven Rostedt next if (!defined($min_configs{$parent})); 3482b9066f6cSSteven Rostedt $found = test_this_config($parent); 3483b9066f6cSSteven Rostedt if (defined($found)) { 3484b9066f6cSSteven Rostedt return $found; 3485b9066f6cSSteven Rostedt } 3486b9066f6cSSteven Rostedt } 3487b9066f6cSSteven Rostedt } 3488b9066f6cSSteven Rostedt 3489b9066f6cSSteven Rostedt # Remove this config from the list of configs 3490fb16d891SAdam Lee # do a make olddefconfig and then read the resulting 3491b9066f6cSSteven Rostedt # .config to make sure it is missing the config that 3492b9066f6cSSteven Rostedt # we had before 3493b9066f6cSSteven Rostedt my %configs = %min_configs; 3494b9066f6cSSteven Rostedt delete $configs{$config}; 3495b9066f6cSSteven Rostedt make_new_config ((values %configs), (values %keep_configs)); 3496b9066f6cSSteven Rostedt make_oldconfig; 3497b9066f6cSSteven Rostedt undef %configs; 3498b9066f6cSSteven Rostedt assign_configs \%configs, $output_config; 3499b9066f6cSSteven Rostedt 3500b9066f6cSSteven Rostedt return $config if (!defined($configs{$config})); 3501b9066f6cSSteven Rostedt 3502b9066f6cSSteven Rostedt doprint "disabling config $config did not change .config\n"; 3503b9066f6cSSteven Rostedt 3504b9066f6cSSteven Rostedt $nochange_config{$config} = 1; 3505b9066f6cSSteven Rostedt 3506b9066f6cSSteven Rostedt return undef; 3507b9066f6cSSteven Rostedt} 3508b9066f6cSSteven Rostedt 35094c4ab120SSteven Rostedtsub make_min_config { 35104c4ab120SSteven Rostedt my ($i) = @_; 35114c4ab120SSteven Rostedt 3512ccc513b6SSteven Rostedt my $type = $minconfig_type; 3513ccc513b6SSteven Rostedt if ($type ne "boot" && $type ne "test") { 3514ccc513b6SSteven Rostedt fail "Invalid MIN_CONFIG_TYPE '$minconfig_type'\n" . 3515ccc513b6SSteven Rostedt " make_min_config works only with 'boot' and 'test'\n" and return; 3516ccc513b6SSteven Rostedt } 3517ccc513b6SSteven Rostedt 35184c4ab120SSteven Rostedt if (!defined($output_minconfig)) { 35194c4ab120SSteven Rostedt fail "OUTPUT_MIN_CONFIG not defined" and return; 35204c4ab120SSteven Rostedt } 352135ce5952SSteven Rostedt 352235ce5952SSteven Rostedt # If output_minconfig exists, and the start_minconfig 352335ce5952SSteven Rostedt # came from min_config, than ask if we should use 352435ce5952SSteven Rostedt # that instead. 352535ce5952SSteven Rostedt if (-f $output_minconfig && !$start_minconfig_defined) { 352635ce5952SSteven Rostedt print "$output_minconfig exists\n"; 352743de3316SSteven Rostedt if (!defined($use_output_minconfig)) { 352835ce5952SSteven Rostedt if (read_yn " Use it as minconfig?") { 352935ce5952SSteven Rostedt $start_minconfig = $output_minconfig; 353035ce5952SSteven Rostedt } 353143de3316SSteven Rostedt } elsif ($use_output_minconfig > 0) { 353243de3316SSteven Rostedt doprint "Using $output_minconfig as MIN_CONFIG\n"; 353343de3316SSteven Rostedt $start_minconfig = $output_minconfig; 353443de3316SSteven Rostedt } else { 353543de3316SSteven Rostedt doprint "Set to still use MIN_CONFIG as starting point\n"; 353643de3316SSteven Rostedt } 353735ce5952SSteven Rostedt } 353835ce5952SSteven Rostedt 35394c4ab120SSteven Rostedt if (!defined($start_minconfig)) { 35404c4ab120SSteven Rostedt fail "START_MIN_CONFIG or MIN_CONFIG not defined" and return; 35414c4ab120SSteven Rostedt } 35424c4ab120SSteven Rostedt 354335ce5952SSteven Rostedt my $temp_config = "$tmpdir/temp_config"; 354435ce5952SSteven Rostedt 35454c4ab120SSteven Rostedt # First things first. We build an allnoconfig to find 35464c4ab120SSteven Rostedt # out what the defaults are that we can't touch. 35474c4ab120SSteven Rostedt # Some are selections, but we really can't handle selections. 35484c4ab120SSteven Rostedt 35494c4ab120SSteven Rostedt my $save_minconfig = $minconfig; 35504c4ab120SSteven Rostedt undef $minconfig; 35514c4ab120SSteven Rostedt 35524c4ab120SSteven Rostedt run_command "$make allnoconfig" or return 0; 35534c4ab120SSteven Rostedt 3554b9066f6cSSteven Rostedt read_depends; 3555b9066f6cSSteven Rostedt 35564c4ab120SSteven Rostedt process_config_ignore $output_config; 3557b9066f6cSSteven Rostedt 355843d1b651SSteven Rostedt undef %save_configs; 3559b9066f6cSSteven Rostedt undef %min_configs; 35604c4ab120SSteven Rostedt 35614c4ab120SSteven Rostedt if (defined($ignore_config)) { 35624c4ab120SSteven Rostedt # make sure the file exists 35634c4ab120SSteven Rostedt `touch $ignore_config`; 356443d1b651SSteven Rostedt assign_configs \%save_configs, $ignore_config; 35654c4ab120SSteven Rostedt } 35664c4ab120SSteven Rostedt 356743d1b651SSteven Rostedt %keep_configs = %save_configs; 356843d1b651SSteven Rostedt 35694c4ab120SSteven Rostedt doprint "Load initial configs from $start_minconfig\n"; 35704c4ab120SSteven Rostedt 35714c4ab120SSteven Rostedt # Look at the current min configs, and save off all the 35724c4ab120SSteven Rostedt # ones that were set via the allnoconfig 35734c4ab120SSteven Rostedt assign_configs \%min_configs, $start_minconfig; 35744c4ab120SSteven Rostedt 35754c4ab120SSteven Rostedt my @config_keys = keys %min_configs; 35764c4ab120SSteven Rostedt 3577ac6974c7SSteven Rostedt # All configs need a depcount 3578ac6974c7SSteven Rostedt foreach my $config (@config_keys) { 3579ac6974c7SSteven Rostedt my $kconfig = chomp_config $config; 3580ac6974c7SSteven Rostedt if (!defined $depcount{$kconfig}) { 3581ac6974c7SSteven Rostedt $depcount{$kconfig} = 0; 3582ac6974c7SSteven Rostedt } 3583ac6974c7SSteven Rostedt } 3584ac6974c7SSteven Rostedt 35854c4ab120SSteven Rostedt # Remove anything that was set by the make allnoconfig 35864c4ab120SSteven Rostedt # we shouldn't need them as they get set for us anyway. 35874c4ab120SSteven Rostedt foreach my $config (@config_keys) { 35884c4ab120SSteven Rostedt # Remove anything in the ignore_config 35894c4ab120SSteven Rostedt if (defined($keep_configs{$config})) { 35904c4ab120SSteven Rostedt my $file = $ignore_config; 35914c4ab120SSteven Rostedt $file =~ s,.*/(.*?)$,$1,; 35924c4ab120SSteven Rostedt doprint "$config set by $file ... ignored\n"; 35934c4ab120SSteven Rostedt delete $min_configs{$config}; 35944c4ab120SSteven Rostedt next; 35954c4ab120SSteven Rostedt } 35964c4ab120SSteven Rostedt # But make sure the settings are the same. If a min config 35974c4ab120SSteven Rostedt # sets a selection, we do not want to get rid of it if 35984c4ab120SSteven Rostedt # it is not the same as what we have. Just move it into 35994c4ab120SSteven Rostedt # the keep configs. 36004c4ab120SSteven Rostedt if (defined($config_ignore{$config})) { 36014c4ab120SSteven Rostedt if ($config_ignore{$config} ne $min_configs{$config}) { 36024c4ab120SSteven Rostedt doprint "$config is in allnoconfig as '$config_ignore{$config}'"; 36034c4ab120SSteven Rostedt doprint " but it is '$min_configs{$config}' in minconfig .. keeping\n"; 36044c4ab120SSteven Rostedt $keep_configs{$config} = $min_configs{$config}; 36054c4ab120SSteven Rostedt } else { 36064c4ab120SSteven Rostedt doprint "$config set by allnoconfig ... ignored\n"; 36074c4ab120SSteven Rostedt } 36084c4ab120SSteven Rostedt delete $min_configs{$config}; 36094c4ab120SSteven Rostedt } 36104c4ab120SSteven Rostedt } 36114c4ab120SSteven Rostedt 36124c4ab120SSteven Rostedt my $done = 0; 3613b9066f6cSSteven Rostedt my $take_two = 0; 36144c4ab120SSteven Rostedt 36154c4ab120SSteven Rostedt while (!$done) { 36164c4ab120SSteven Rostedt 36174c4ab120SSteven Rostedt my $config; 36184c4ab120SSteven Rostedt my $found; 36194c4ab120SSteven Rostedt 36204c4ab120SSteven Rostedt # Now disable each config one by one and do a make oldconfig 36214c4ab120SSteven Rostedt # till we find a config that changes our list. 36224c4ab120SSteven Rostedt 36234c4ab120SSteven Rostedt my @test_configs = keys %min_configs; 3624ac6974c7SSteven Rostedt 3625ac6974c7SSteven Rostedt # Sort keys by who is most dependent on 3626ac6974c7SSteven Rostedt @test_configs = sort { $depcount{chomp_config($b)} <=> $depcount{chomp_config($a)} } 3627ac6974c7SSteven Rostedt @test_configs ; 3628ac6974c7SSteven Rostedt 3629ac6974c7SSteven Rostedt # Put configs that did not modify the config at the end. 36304c4ab120SSteven Rostedt my $reset = 1; 36314c4ab120SSteven Rostedt for (my $i = 0; $i < $#test_configs; $i++) { 36324c4ab120SSteven Rostedt if (!defined($nochange_config{$test_configs[0]})) { 36334c4ab120SSteven Rostedt $reset = 0; 36344c4ab120SSteven Rostedt last; 36354c4ab120SSteven Rostedt } 36364c4ab120SSteven Rostedt # This config didn't change the .config last time. 36374c4ab120SSteven Rostedt # Place it at the end 36384c4ab120SSteven Rostedt my $config = shift @test_configs; 36394c4ab120SSteven Rostedt push @test_configs, $config; 36404c4ab120SSteven Rostedt } 36414c4ab120SSteven Rostedt 36424c4ab120SSteven Rostedt # if every test config has failed to modify the .config file 36434c4ab120SSteven Rostedt # in the past, then reset and start over. 36444c4ab120SSteven Rostedt if ($reset) { 36454c4ab120SSteven Rostedt undef %nochange_config; 36464c4ab120SSteven Rostedt } 36474c4ab120SSteven Rostedt 3648b9066f6cSSteven Rostedt undef %processed_configs; 3649b9066f6cSSteven Rostedt 36504c4ab120SSteven Rostedt foreach my $config (@test_configs) { 36514c4ab120SSteven Rostedt 3652b9066f6cSSteven Rostedt $found = test_this_config $config; 36534c4ab120SSteven Rostedt 3654b9066f6cSSteven Rostedt last if (defined($found)); 36554c4ab120SSteven Rostedt 36564c4ab120SSteven Rostedt # oh well, try another config 36574c4ab120SSteven Rostedt } 36584c4ab120SSteven Rostedt 36594c4ab120SSteven Rostedt if (!defined($found)) { 3660b9066f6cSSteven Rostedt # we could have failed due to the nochange_config hash 3661b9066f6cSSteven Rostedt # reset and try again 3662b9066f6cSSteven Rostedt if (!$take_two) { 3663b9066f6cSSteven Rostedt undef %nochange_config; 3664b9066f6cSSteven Rostedt $take_two = 1; 3665b9066f6cSSteven Rostedt next; 3666b9066f6cSSteven Rostedt } 36674c4ab120SSteven Rostedt doprint "No more configs found that we can disable\n"; 36684c4ab120SSteven Rostedt $done = 1; 36694c4ab120SSteven Rostedt last; 36704c4ab120SSteven Rostedt } 3671b9066f6cSSteven Rostedt $take_two = 0; 36724c4ab120SSteven Rostedt 36734c4ab120SSteven Rostedt $config = $found; 36744c4ab120SSteven Rostedt 36754c4ab120SSteven Rostedt doprint "Test with $config disabled\n"; 36764c4ab120SSteven Rostedt 36774c4ab120SSteven Rostedt # set in_bisect to keep build and monitor from dieing 36784c4ab120SSteven Rostedt $in_bisect = 1; 36794c4ab120SSteven Rostedt 36804c4ab120SSteven Rostedt my $failed = 0; 3681bf1c95abSSteven Rostedt build "oldconfig" or $failed = 1; 3682bf1c95abSSteven Rostedt if (!$failed) { 36834c4ab120SSteven Rostedt start_monitor_and_boot or $failed = 1; 3684ccc513b6SSteven Rostedt 3685ccc513b6SSteven Rostedt if ($type eq "test" && !$failed) { 3686ccc513b6SSteven Rostedt do_run_test or $failed = 1; 3687ccc513b6SSteven Rostedt } 3688ccc513b6SSteven Rostedt 36894c4ab120SSteven Rostedt end_monitor; 3690bf1c95abSSteven Rostedt } 36914c4ab120SSteven Rostedt 36924c4ab120SSteven Rostedt $in_bisect = 0; 36934c4ab120SSteven Rostedt 36944c4ab120SSteven Rostedt if ($failed) { 3695b9066f6cSSteven Rostedt doprint "$min_configs{$config} is needed to boot the box... keeping\n"; 36964c4ab120SSteven Rostedt # this config is needed, add it to the ignore list. 36974c4ab120SSteven Rostedt $keep_configs{$config} = $min_configs{$config}; 369843d1b651SSteven Rostedt $save_configs{$config} = $min_configs{$config}; 36994c4ab120SSteven Rostedt delete $min_configs{$config}; 370035ce5952SSteven Rostedt 370135ce5952SSteven Rostedt # update new ignore configs 370235ce5952SSteven Rostedt if (defined($ignore_config)) { 370335ce5952SSteven Rostedt open (OUT, ">$temp_config") 370435ce5952SSteven Rostedt or die "Can't write to $temp_config"; 370543d1b651SSteven Rostedt foreach my $config (keys %save_configs) { 370643d1b651SSteven Rostedt print OUT "$save_configs{$config}\n"; 370735ce5952SSteven Rostedt } 370835ce5952SSteven Rostedt close OUT; 370935ce5952SSteven Rostedt run_command "mv $temp_config $ignore_config" or 371035ce5952SSteven Rostedt dodie "failed to copy update to $ignore_config"; 371135ce5952SSteven Rostedt } 371235ce5952SSteven Rostedt 37134c4ab120SSteven Rostedt } else { 37144c4ab120SSteven Rostedt # We booted without this config, remove it from the minconfigs. 37154c4ab120SSteven Rostedt doprint "$config is not needed, disabling\n"; 37164c4ab120SSteven Rostedt 37174c4ab120SSteven Rostedt delete $min_configs{$config}; 37184c4ab120SSteven Rostedt 37194c4ab120SSteven Rostedt # Also disable anything that is not enabled in this config 37204c4ab120SSteven Rostedt my %configs; 37214c4ab120SSteven Rostedt assign_configs \%configs, $output_config; 37224c4ab120SSteven Rostedt my @config_keys = keys %min_configs; 37234c4ab120SSteven Rostedt foreach my $config (@config_keys) { 37244c4ab120SSteven Rostedt if (!defined($configs{$config})) { 37254c4ab120SSteven Rostedt doprint "$config is not set, disabling\n"; 37264c4ab120SSteven Rostedt delete $min_configs{$config}; 37274c4ab120SSteven Rostedt } 37284c4ab120SSteven Rostedt } 37294c4ab120SSteven Rostedt 37304c4ab120SSteven Rostedt # Save off all the current mandidory configs 373135ce5952SSteven Rostedt open (OUT, ">$temp_config") 373235ce5952SSteven Rostedt or die "Can't write to $temp_config"; 37334c4ab120SSteven Rostedt foreach my $config (keys %keep_configs) { 37344c4ab120SSteven Rostedt print OUT "$keep_configs{$config}\n"; 37354c4ab120SSteven Rostedt } 37364c4ab120SSteven Rostedt foreach my $config (keys %min_configs) { 37374c4ab120SSteven Rostedt print OUT "$min_configs{$config}\n"; 37384c4ab120SSteven Rostedt } 37394c4ab120SSteven Rostedt close OUT; 374035ce5952SSteven Rostedt 374135ce5952SSteven Rostedt run_command "mv $temp_config $output_minconfig" or 374235ce5952SSteven Rostedt dodie "failed to copy update to $output_minconfig"; 37434c4ab120SSteven Rostedt } 37444c4ab120SSteven Rostedt 37454c4ab120SSteven Rostedt doprint "Reboot and wait $sleep_time seconds\n"; 3746bc7c5803SSteven Rostedt reboot_to_good $sleep_time; 37474c4ab120SSteven Rostedt } 37484c4ab120SSteven Rostedt 37494c4ab120SSteven Rostedt success $i; 37504c4ab120SSteven Rostedt return 1; 37514c4ab120SSteven Rostedt} 37524c4ab120SSteven Rostedt 37534283b169SSteven Rostedt (Red Hat)sub make_warnings_file { 37544283b169SSteven Rostedt (Red Hat) my ($i) = @_; 37554283b169SSteven Rostedt (Red Hat) 37564283b169SSteven Rostedt (Red Hat) if (!defined($warnings_file)) { 37574283b169SSteven Rostedt (Red Hat) dodie "Must define WARNINGS_FILE for make_warnings_file test"; 37584283b169SSteven Rostedt (Red Hat) } 37594283b169SSteven Rostedt (Red Hat) 37604283b169SSteven Rostedt (Red Hat) if ($build_type eq "nobuild") { 37614283b169SSteven Rostedt (Red Hat) dodie "BUILD_TYPE can not be 'nobuild' for make_warnings_file test"; 37624283b169SSteven Rostedt (Red Hat) } 37634283b169SSteven Rostedt (Red Hat) 37644283b169SSteven Rostedt (Red Hat) build $build_type or dodie "Failed to build"; 37654283b169SSteven Rostedt (Red Hat) 37664283b169SSteven Rostedt (Red Hat) open(OUT, ">$warnings_file") or dodie "Can't create $warnings_file"; 37674283b169SSteven Rostedt (Red Hat) 37684283b169SSteven Rostedt (Red Hat) open(IN, $buildlog) or dodie "Can't open $buildlog"; 37694283b169SSteven Rostedt (Red Hat) while (<IN>) { 37704283b169SSteven Rostedt (Red Hat) 37714283b169SSteven Rostedt (Red Hat) # Some compilers use UTF-8 extended for quotes 37724283b169SSteven Rostedt (Red Hat) # for distcc heterogeneous systems, this causes issues 37734283b169SSteven Rostedt (Red Hat) s/$utf8_quote/'/g; 37744283b169SSteven Rostedt (Red Hat) 37754283b169SSteven Rostedt (Red Hat) if (/$check_build_re/) { 37764283b169SSteven Rostedt (Red Hat) print OUT; 37774283b169SSteven Rostedt (Red Hat) } 37784283b169SSteven Rostedt (Red Hat) } 37794283b169SSteven Rostedt (Red Hat) close(IN); 37804283b169SSteven Rostedt (Red Hat) 37814283b169SSteven Rostedt (Red Hat) close(OUT); 37824283b169SSteven Rostedt (Red Hat) 37834283b169SSteven Rostedt (Red Hat) success $i; 37844283b169SSteven Rostedt (Red Hat)} 37854283b169SSteven Rostedt (Red Hat) 37868d1491baSSteven Rostedt$#ARGV < 1 or die "ktest.pl version: $VERSION\n usage: ktest.pl config-file\n"; 37872545eb61SSteven Rostedt 37888d1491baSSteven Rostedtif ($#ARGV == 0) { 37898d1491baSSteven Rostedt $ktest_config = $ARGV[0]; 37908d1491baSSteven Rostedt if (! -f $ktest_config) { 37918d1491baSSteven Rostedt print "$ktest_config does not exist.\n"; 379235ce5952SSteven Rostedt if (!read_yn "Create it?") { 37938d1491baSSteven Rostedt exit 0; 37948d1491baSSteven Rostedt } 37958d1491baSSteven Rostedt } 37968d1491baSSteven Rostedt} else { 37978d1491baSSteven Rostedt $ktest_config = "ktest.conf"; 37988d1491baSSteven Rostedt} 37998d1491baSSteven Rostedt 38008d1491baSSteven Rostedtif (! -f $ktest_config) { 3801dbd3783bSSteven Rostedt $newconfig = 1; 3802c4261d0fSSteven Rostedt get_test_case; 38038d1491baSSteven Rostedt open(OUT, ">$ktest_config") or die "Can not create $ktest_config"; 38048d1491baSSteven Rostedt print OUT << "EOF" 38058d1491baSSteven Rostedt# Generated by ktest.pl 38068d1491baSSteven Rostedt# 38070e7a22deSSteven Rostedt 38080e7a22deSSteven Rostedt# PWD is a ktest.pl variable that will result in the process working 38090e7a22deSSteven Rostedt# directory that ktest.pl is executed in. 38100e7a22deSSteven Rostedt 38110e7a22deSSteven Rostedt# THIS_DIR is automatically assigned the PWD of the path that generated 38120e7a22deSSteven Rostedt# the config file. It is best to use this variable when assigning other 38130e7a22deSSteven Rostedt# directory paths within this directory. This allows you to easily 38140e7a22deSSteven Rostedt# move the test cases to other locations or to other machines. 38150e7a22deSSteven Rostedt# 38160e7a22deSSteven RostedtTHIS_DIR := $variable{"PWD"} 38170e7a22deSSteven Rostedt 38188d1491baSSteven Rostedt# Define each test with TEST_START 38198d1491baSSteven Rostedt# The config options below it will override the defaults 38208d1491baSSteven RostedtTEST_START 3821c4261d0fSSteven RostedtTEST_TYPE = $default{"TEST_TYPE"} 38228d1491baSSteven Rostedt 38238d1491baSSteven RostedtDEFAULTS 38248d1491baSSteven RostedtEOF 38258d1491baSSteven Rostedt; 38268d1491baSSteven Rostedt close(OUT); 38278d1491baSSteven Rostedt} 38288d1491baSSteven Rostedtread_config $ktest_config; 38298d1491baSSteven Rostedt 383023715c3cSSteven Rostedtif (defined($opt{"LOG_FILE"})) { 383104262be3SSteven Rostedt (Red Hat) $opt{"LOG_FILE"} = eval_option("LOG_FILE", $opt{"LOG_FILE"}, -1); 383223715c3cSSteven Rostedt} 383323715c3cSSteven Rostedt 38348d1491baSSteven Rostedt# Append any configs entered in manually to the config file. 38358d1491baSSteven Rostedtmy @new_configs = keys %entered_configs; 38368d1491baSSteven Rostedtif ($#new_configs >= 0) { 38378d1491baSSteven Rostedt print "\nAppending entered in configs to $ktest_config\n"; 38388d1491baSSteven Rostedt open(OUT, ">>$ktest_config") or die "Can not append to $ktest_config"; 38398d1491baSSteven Rostedt foreach my $config (@new_configs) { 38408d1491baSSteven Rostedt print OUT "$config = $entered_configs{$config}\n"; 38410e7a22deSSteven Rostedt $opt{$config} = process_variables($entered_configs{$config}); 38428d1491baSSteven Rostedt } 38438d1491baSSteven Rostedt} 38442545eb61SSteven Rostedt 38452b7d9b21SSteven Rostedtif ($opt{"CLEAR_LOG"} && defined($opt{"LOG_FILE"})) { 38462b7d9b21SSteven Rostedt unlink $opt{"LOG_FILE"}; 38472b7d9b21SSteven Rostedt} 38482545eb61SSteven Rostedt 38492b7d9b21SSteven Rostedtdoprint "\n\nSTARTING AUTOMATED TESTS\n\n"; 38502b7d9b21SSteven Rostedt 3851a57419b3SSteven Rostedtfor (my $i = 0, my $repeat = 1; $i <= $opt{"NUM_TESTS"}; $i += $repeat) { 3852a57419b3SSteven Rostedt 3853a57419b3SSteven Rostedt if (!$i) { 3854a57419b3SSteven Rostedt doprint "DEFAULT OPTIONS:\n"; 3855a57419b3SSteven Rostedt } else { 3856a57419b3SSteven Rostedt doprint "\nTEST $i OPTIONS"; 3857a57419b3SSteven Rostedt if (defined($repeat_tests{$i})) { 3858a57419b3SSteven Rostedt $repeat = $repeat_tests{$i}; 3859a57419b3SSteven Rostedt doprint " ITERATE $repeat"; 3860a57419b3SSteven Rostedt } 3861a57419b3SSteven Rostedt doprint "\n"; 3862a57419b3SSteven Rostedt } 3863a57419b3SSteven Rostedt 38642b7d9b21SSteven Rostedt foreach my $option (sort keys %opt) { 3865a57419b3SSteven Rostedt 3866a57419b3SSteven Rostedt if ($option =~ /\[(\d+)\]$/) { 3867a57419b3SSteven Rostedt next if ($i != $1); 3868a57419b3SSteven Rostedt } else { 3869a57419b3SSteven Rostedt next if ($i); 3870a57419b3SSteven Rostedt } 3871a57419b3SSteven Rostedt 38722b7d9b21SSteven Rostedt doprint "$option = $opt{$option}\n"; 38732b7d9b21SSteven Rostedt } 3874a57419b3SSteven Rostedt} 38752545eb61SSteven Rostedt 38762a62512bSSteven Rostedtsub __set_test_option { 38775a391fbfSSteven Rostedt my ($name, $i) = @_; 38785a391fbfSSteven Rostedt 38795a391fbfSSteven Rostedt my $option = "$name\[$i\]"; 38805a391fbfSSteven Rostedt 38815a391fbfSSteven Rostedt if (defined($opt{$option})) { 38825a391fbfSSteven Rostedt return $opt{$option}; 38835a391fbfSSteven Rostedt } 38845a391fbfSSteven Rostedt 3885a57419b3SSteven Rostedt foreach my $test (keys %repeat_tests) { 3886a57419b3SSteven Rostedt if ($i >= $test && 3887a57419b3SSteven Rostedt $i < $test + $repeat_tests{$test}) { 3888a57419b3SSteven Rostedt $option = "$name\[$test\]"; 3889a57419b3SSteven Rostedt if (defined($opt{$option})) { 3890a57419b3SSteven Rostedt return $opt{$option}; 3891a57419b3SSteven Rostedt } 3892a57419b3SSteven Rostedt } 3893a57419b3SSteven Rostedt } 3894a57419b3SSteven Rostedt 38955a391fbfSSteven Rostedt if (defined($opt{$name})) { 38965a391fbfSSteven Rostedt return $opt{$name}; 38975a391fbfSSteven Rostedt } 38985a391fbfSSteven Rostedt 38995a391fbfSSteven Rostedt return undef; 39005a391fbfSSteven Rostedt} 39015a391fbfSSteven Rostedt 39022a62512bSSteven Rostedtsub set_test_option { 39032a62512bSSteven Rostedt my ($name, $i) = @_; 39042a62512bSSteven Rostedt 39052a62512bSSteven Rostedt my $option = __set_test_option($name, $i); 39062a62512bSSteven Rostedt return $option if (!defined($option)); 39072a62512bSSteven Rostedt 390804262be3SSteven Rostedt (Red Hat) return eval_option($name, $option, $i); 39092a62512bSSteven Rostedt} 39102a62512bSSteven Rostedt 39112545eb61SSteven Rostedt# First we need to do is the builds 3912a75fececSSteven Rostedtfor (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) { 39132545eb61SSteven Rostedt 39144ab1cce5SSteven Rostedt # Do not reboot on failing test options 39154ab1cce5SSteven Rostedt $no_reboot = 1; 3916759a3cc6SSteven Rostedt $reboot_success = 0; 39174ab1cce5SSteven Rostedt 3918683a3e64SSteven Rostedt $have_version = 0; 3919683a3e64SSteven Rostedt 3920576f627cSSteven Rostedt $iteration = $i; 3921576f627cSSteven Rostedt 3922c1434dccSSteven Rostedt undef %force_config; 3923c1434dccSSteven Rostedt 3924a75fececSSteven Rostedt my $makecmd = set_test_option("MAKE_CMD", $i); 3925a75fececSSteven Rostedt 3926*8e80bf05SSteven Rostedt (Red Hat) $outputdir = set_test_option("OUTPUT_DIR", $i); 3927*8e80bf05SSteven Rostedt (Red Hat) $builddir = set_test_option("BUILD_DIR", $i); 3928*8e80bf05SSteven Rostedt (Red Hat) 3929*8e80bf05SSteven Rostedt (Red Hat) chdir $builddir || die "can't change directory to $builddir"; 3930*8e80bf05SSteven Rostedt (Red Hat) 3931*8e80bf05SSteven Rostedt (Red Hat) if (!-d $outputdir) { 3932*8e80bf05SSteven Rostedt (Red Hat) mkpath($outputdir) or 3933*8e80bf05SSteven Rostedt (Red Hat) die "can't create $outputdir"; 3934*8e80bf05SSteven Rostedt (Red Hat) } 3935*8e80bf05SSteven Rostedt (Red Hat) 3936*8e80bf05SSteven Rostedt (Red Hat) $make = "$makecmd O=$outputdir"; 3937*8e80bf05SSteven Rostedt (Red Hat) 39389cc9e091SSteven Rostedt # Load all the options into their mapped variable names 39399cc9e091SSteven Rostedt foreach my $opt (keys %option_map) { 39409cc9e091SSteven Rostedt ${$option_map{$opt}} = set_test_option($opt, $i); 39419cc9e091SSteven Rostedt } 3942b5f4aea6SSteven Rostedt 394335ce5952SSteven Rostedt $start_minconfig_defined = 1; 394435ce5952SSteven Rostedt 3945921ed4c7SSteven Rostedt # The first test may override the PRE_KTEST option 3946921ed4c7SSteven Rostedt if (defined($pre_ktest) && $i == 1) { 3947921ed4c7SSteven Rostedt doprint "\n"; 3948921ed4c7SSteven Rostedt run_command $pre_ktest; 3949921ed4c7SSteven Rostedt } 3950921ed4c7SSteven Rostedt 3951921ed4c7SSteven Rostedt # Any test can override the POST_KTEST option 3952921ed4c7SSteven Rostedt # The last test takes precedence. 3953921ed4c7SSteven Rostedt if (defined($post_ktest)) { 3954921ed4c7SSteven Rostedt $final_post_ktest = $post_ktest; 3955921ed4c7SSteven Rostedt } 3956921ed4c7SSteven Rostedt 39574c4ab120SSteven Rostedt if (!defined($start_minconfig)) { 395835ce5952SSteven Rostedt $start_minconfig_defined = 0; 39594c4ab120SSteven Rostedt $start_minconfig = $minconfig; 39604c4ab120SSteven Rostedt } 39614c4ab120SSteven Rostedt 3962*8e80bf05SSteven Rostedt (Red Hat) if (!-d $tmpdir) { 3963*8e80bf05SSteven Rostedt (Red Hat) mkpath($tmpdir) or 3964*8e80bf05SSteven Rostedt (Red Hat) die "can't create $tmpdir"; 3965a75fececSSteven Rostedt } 3966a75fececSSteven Rostedt 3967e48c5293SSteven Rostedt $ENV{"SSH_USER"} = $ssh_user; 3968e48c5293SSteven Rostedt $ENV{"MACHINE"} = $machine; 3969e48c5293SSteven Rostedt 3970a75fececSSteven Rostedt $buildlog = "$tmpdir/buildlog-$machine"; 3971a9dd5d63SRabin Vincent $testlog = "$tmpdir/testlog-$machine"; 3972a75fececSSteven Rostedt $dmesg = "$tmpdir/dmesg-$machine"; 397351ad1dd1SSteven Rostedt $output_config = "$outputdir/.config"; 3974a75fececSSteven Rostedt 3975bb8474b1SSteven Rostedt if (!$buildonly) { 3976bb8474b1SSteven Rostedt $target = "$ssh_user\@$machine"; 3977a75fececSSteven Rostedt if ($reboot_type eq "grub") { 3978576f627cSSteven Rostedt dodie "GRUB_MENU not defined" if (!defined($grub_menu)); 3979a15ba913SSteven Rostedt } elsif ($reboot_type eq "grub2") { 3980a15ba913SSteven Rostedt dodie "GRUB_MENU not defined" if (!defined($grub_menu)); 3981a15ba913SSteven Rostedt dodie "GRUB_FILE not defined" if (!defined($grub_file)); 39827786954cSSteven Rostedt } elsif ($reboot_type eq "syslinux") { 39837786954cSSteven Rostedt dodie "SYSLINUX_LABEL not defined" if (!defined($syslinux_label)); 3984a75fececSSteven Rostedt } 3985bb8474b1SSteven Rostedt } 3986a75fececSSteven Rostedt 3987a75fececSSteven Rostedt my $run_type = $build_type; 3988a75fececSSteven Rostedt if ($test_type eq "patchcheck") { 3989b5f4aea6SSteven Rostedt $run_type = $patchcheck_type; 3990a75fececSSteven Rostedt } elsif ($test_type eq "bisect") { 3991b5f4aea6SSteven Rostedt $run_type = $bisect_type; 39920a05c769SSteven Rostedt } elsif ($test_type eq "config_bisect") { 3993b5f4aea6SSteven Rostedt $run_type = $config_bisect_type; 39944283b169SSteven Rostedt (Red Hat) } elsif ($test_type eq "make_min_config") { 39954283b169SSteven Rostedt (Red Hat) $run_type = ""; 39964283b169SSteven Rostedt (Red Hat) } elsif ($test_type eq "make_warnings_file") { 39974c4ab120SSteven Rostedt $run_type = ""; 39984c4ab120SSteven Rostedt } 39994c4ab120SSteven Rostedt 4000a75fececSSteven Rostedt # mistake in config file? 4001a75fececSSteven Rostedt if (!defined($run_type)) { 4002a75fececSSteven Rostedt $run_type = "ERROR"; 4003a75fececSSteven Rostedt } 40042545eb61SSteven Rostedt 4005e0a8742eSSteven Rostedt my $installme = ""; 4006e0a8742eSSteven Rostedt $installme = " no_install" if ($no_install); 4007e0a8742eSSteven Rostedt 40082545eb61SSteven Rostedt doprint "\n\n"; 4009e0a8742eSSteven Rostedt doprint "RUNNING TEST $i of $opt{NUM_TESTS} with option $test_type $run_type$installme\n\n"; 40107faafbd6SSteven Rostedt 4011921ed4c7SSteven Rostedt if (defined($pre_test)) { 4012921ed4c7SSteven Rostedt run_command $pre_test; 4013921ed4c7SSteven Rostedt } 4014921ed4c7SSteven Rostedt 40157faafbd6SSteven Rostedt unlink $dmesg; 40167faafbd6SSteven Rostedt unlink $buildlog; 4017a9dd5d63SRabin Vincent unlink $testlog; 40182545eb61SSteven Rostedt 4019250bae8bSSteven Rostedt if (defined($addconfig)) { 4020250bae8bSSteven Rostedt my $min = $minconfig; 40212b7d9b21SSteven Rostedt if (!defined($minconfig)) { 4022250bae8bSSteven Rostedt $min = ""; 4023250bae8bSSteven Rostedt } 4024250bae8bSSteven Rostedt run_command "cat $addconfig $min > $tmpdir/add_config" or 40252b7d9b21SSteven Rostedt dodie "Failed to create temp config"; 40269be2e6b5SSteven Rostedt $minconfig = "$tmpdir/add_config"; 40272b7d9b21SSteven Rostedt } 40282b7d9b21SSteven Rostedt 40296c5ee0beSSteven Rostedt if (defined($checkout)) { 40306c5ee0beSSteven Rostedt run_command "git checkout $checkout" or 40316c5ee0beSSteven Rostedt die "failed to checkout $checkout"; 40326c5ee0beSSteven Rostedt } 40336c5ee0beSSteven Rostedt 4034759a3cc6SSteven Rostedt $no_reboot = 0; 4035759a3cc6SSteven Rostedt 4036648a182cSSteven Rostedt # A test may opt to not reboot the box 4037648a182cSSteven Rostedt if ($reboot_on_success) { 4038759a3cc6SSteven Rostedt $reboot_success = 1; 4039648a182cSSteven Rostedt } 40404ab1cce5SSteven Rostedt 4041a75fececSSteven Rostedt if ($test_type eq "bisect") { 40425f9b6cedSSteven Rostedt bisect $i; 40435f9b6cedSSteven Rostedt next; 40440a05c769SSteven Rostedt } elsif ($test_type eq "config_bisect") { 40450a05c769SSteven Rostedt config_bisect $i; 40460a05c769SSteven Rostedt next; 4047a75fececSSteven Rostedt } elsif ($test_type eq "patchcheck") { 40486c5ee0beSSteven Rostedt patchcheck $i; 40496c5ee0beSSteven Rostedt next; 40504c4ab120SSteven Rostedt } elsif ($test_type eq "make_min_config") { 40514c4ab120SSteven Rostedt make_min_config $i; 40524c4ab120SSteven Rostedt next; 40534283b169SSteven Rostedt (Red Hat) } elsif ($test_type eq "make_warnings_file") { 40544283b169SSteven Rostedt (Red Hat) $no_reboot = 1; 40554283b169SSteven Rostedt (Red Hat) make_warnings_file $i; 40564283b169SSteven Rostedt (Red Hat) next; 40575f9b6cedSSteven Rostedt } 40585f9b6cedSSteven Rostedt 40597faafbd6SSteven Rostedt if ($build_type ne "nobuild") { 40607faafbd6SSteven Rostedt build $build_type or next; 40614283b169SSteven Rostedt (Red Hat) check_buildlog or next; 40622545eb61SSteven Rostedt } 40632545eb61SSteven Rostedt 4064cd8e368fSSteven Rostedt if ($test_type eq "install") { 4065cd8e368fSSteven Rostedt get_version; 4066cd8e368fSSteven Rostedt install; 4067cd8e368fSSteven Rostedt success $i; 4068cd8e368fSSteven Rostedt next; 4069cd8e368fSSteven Rostedt } 4070cd8e368fSSteven Rostedt 4071a75fececSSteven Rostedt if ($test_type ne "build") { 40727faafbd6SSteven Rostedt my $failed = 0; 4073ddf607e5SSteven Rostedt start_monitor_and_boot or $failed = 1; 4074a75fececSSteven Rostedt 4075a75fececSSteven Rostedt if (!$failed && $test_type ne "boot" && defined($run_test)) { 40767faafbd6SSteven Rostedt do_run_test or $failed = 1; 40775a391fbfSSteven Rostedt } 40787faafbd6SSteven Rostedt end_monitor; 40797faafbd6SSteven Rostedt next if ($failed); 4080a75fececSSteven Rostedt } 40815a391fbfSSteven Rostedt 40825f9b6cedSSteven Rostedt success $i; 408375c3fda7SSteven Rostedt} 40842545eb61SSteven Rostedt 4085921ed4c7SSteven Rostedtif (defined($final_post_ktest)) { 4086921ed4c7SSteven Rostedt run_command $final_post_ktest; 4087921ed4c7SSteven Rostedt} 4088921ed4c7SSteven Rostedt 40895c42fc5bSSteven Rostedtif ($opt{"POWEROFF_ON_SUCCESS"}) { 409075c3fda7SSteven Rostedt halt; 4091759a3cc6SSteven Rostedt} elsif ($opt{"REBOOT_ON_SUCCESS"} && !do_not_reboot && $reboot_success) { 4092bc7c5803SSteven Rostedt reboot_to_good; 4093648a182cSSteven Rostedt} elsif (defined($switch_to_good)) { 4094648a182cSSteven Rostedt # still need to get to the good kernel 4095648a182cSSteven Rostedt run_command $switch_to_good; 40965c42fc5bSSteven Rostedt} 409775c3fda7SSteven Rostedt 4098648a182cSSteven Rostedt 4099e48c5293SSteven Rostedtdoprint "\n $successes of $opt{NUM_TESTS} tests were successful\n\n"; 4100e48c5293SSteven Rostedt 41012545eb61SSteven Rostedtexit 0; 4102