xref: /openbmc/linux/tools/testing/ktest/ktest.pl (revision a15ba91361d46b4cc71d76d5712fb6420b517d8a)
12545eb61SSteven Rostedt#!/usr/bin/perl -w
2d6ce2a0bSSteven Rostedt#
3cce1dac8SUwe Kleine-König# Copyright 2010 - Steven Rostedt <srostedt@redhat.com>, Red Hat Inc.
4d6ce2a0bSSteven Rostedt# Licensed under the terms of the GNU GPL License version 2
5d6ce2a0bSSteven Rostedt#
62545eb61SSteven Rostedt
72545eb61SSteven Rostedtuse strict;
82545eb61SSteven Rostedtuse IPC::Open2;
92545eb61SSteven Rostedtuse Fcntl qw(F_GETFL F_SETFL O_NONBLOCK);
107faafbd6SSteven Rostedtuse File::Path qw(mkpath);
117faafbd6SSteven Rostedtuse File::Copy qw(cp);
122545eb61SSteven Rostedtuse FileHandle;
132545eb61SSteven Rostedt
14e48c5293SSteven Rostedtmy $VERSION = "0.2";
15e48c5293SSteven Rostedt
162545eb61SSteven Rostedt$| = 1;
172545eb61SSteven Rostedt
182545eb61SSteven Rostedtmy %opt;
19a57419b3SSteven Rostedtmy %repeat_tests;
20a57419b3SSteven Rostedtmy %repeats;
212545eb61SSteven Rostedt
222545eb61SSteven Rostedt#default opts
234f43e0dcSSteven Rostedtmy %default = (
244f43e0dcSSteven Rostedt    "NUM_TESTS"			=> 1,
254f43e0dcSSteven Rostedt    "TEST_TYPE"			=> "build",
264f43e0dcSSteven Rostedt    "BUILD_TYPE"		=> "randconfig",
274f43e0dcSSteven Rostedt    "MAKE_CMD"			=> "make",
284f43e0dcSSteven Rostedt    "TIMEOUT"			=> 120,
294f43e0dcSSteven Rostedt    "TMP_DIR"			=> "/tmp/ktest/\${MACHINE}",
304f43e0dcSSteven Rostedt    "SLEEP_TIME"		=> 60,	# sleep time between tests
314f43e0dcSSteven Rostedt    "BUILD_NOCLEAN"		=> 0,
324f43e0dcSSteven Rostedt    "REBOOT_ON_ERROR"		=> 0,
334f43e0dcSSteven Rostedt    "POWEROFF_ON_ERROR"		=> 0,
344f43e0dcSSteven Rostedt    "REBOOT_ON_SUCCESS"		=> 1,
354f43e0dcSSteven Rostedt    "POWEROFF_ON_SUCCESS"	=> 0,
364f43e0dcSSteven Rostedt    "BUILD_OPTIONS"		=> "",
374f43e0dcSSteven Rostedt    "BISECT_SLEEP_TIME"		=> 60,   # sleep time between bisects
384f43e0dcSSteven Rostedt    "PATCHCHECK_SLEEP_TIME"	=> 60, # sleep time between patch checks
394f43e0dcSSteven Rostedt    "CLEAR_LOG"			=> 0,
404f43e0dcSSteven Rostedt    "BISECT_MANUAL"		=> 0,
414f43e0dcSSteven Rostedt    "BISECT_SKIP"		=> 1,
42ccc513b6SSteven Rostedt    "MIN_CONFIG_TYPE"		=> "boot",
434f43e0dcSSteven Rostedt    "SUCCESS_LINE"		=> "login:",
444f43e0dcSSteven Rostedt    "DETECT_TRIPLE_FAULT"	=> 1,
454f43e0dcSSteven Rostedt    "NO_INSTALL"		=> 0,
464f43e0dcSSteven Rostedt    "BOOTED_TIMEOUT"		=> 1,
474f43e0dcSSteven Rostedt    "DIE_ON_FAILURE"		=> 1,
484f43e0dcSSteven Rostedt    "SSH_EXEC"			=> "ssh \$SSH_USER\@\$MACHINE \$SSH_COMMAND",
494f43e0dcSSteven Rostedt    "SCP_TO_TARGET"		=> "scp \$SRC_FILE \$SSH_USER\@\$MACHINE:\$DST_FILE",
5002ad2617SSteven Rostedt    "SCP_TO_TARGET_INSTALL"	=> "\${SCP_TO_TARGET}",
514f43e0dcSSteven Rostedt    "REBOOT"			=> "ssh \$SSH_USER\@\$MACHINE reboot",
524f43e0dcSSteven Rostedt    "STOP_AFTER_SUCCESS"	=> 10,
534f43e0dcSSteven Rostedt    "STOP_AFTER_FAILURE"	=> 60,
544f43e0dcSSteven Rostedt    "STOP_TEST_AFTER"		=> 600,
55407b95b7SSteven Rostedt    "MAX_MONITOR_WAIT"		=> 1800,
56*a15ba913SSteven Rostedt    "GRUB_REBOOT"		=> "grub2-reboot",
57600bbf0aSSteven Rostedt
58600bbf0aSSteven Rostedt# required, and we will ask users if they don't have them but we keep the default
59600bbf0aSSteven Rostedt# value something that is common.
604f43e0dcSSteven Rostedt    "REBOOT_TYPE"		=> "grub",
614f43e0dcSSteven Rostedt    "LOCALVERSION"		=> "-test",
624f43e0dcSSteven Rostedt    "SSH_USER"			=> "root",
634f43e0dcSSteven Rostedt    "BUILD_TARGET"	 	=> "arch/x86/boot/bzImage",
644f43e0dcSSteven Rostedt    "TARGET_IMAGE"		=> "/boot/vmlinuz-test",
659cc9e091SSteven Rostedt
669cc9e091SSteven Rostedt    "LOG_FILE"			=> undef,
679cc9e091SSteven Rostedt    "IGNORE_UNUSED"		=> 0,
684f43e0dcSSteven Rostedt);
692545eb61SSteven Rostedt
708d1491baSSteven Rostedtmy $ktest_config;
712545eb61SSteven Rostedtmy $version;
72683a3e64SSteven Rostedtmy $have_version = 0;
73a75fececSSteven Rostedtmy $machine;
74e48c5293SSteven Rostedtmy $ssh_user;
75a75fececSSteven Rostedtmy $tmpdir;
76a75fececSSteven Rostedtmy $builddir;
77a75fececSSteven Rostedtmy $outputdir;
7851ad1dd1SSteven Rostedtmy $output_config;
79a75fececSSteven Rostedtmy $test_type;
807faafbd6SSteven Rostedtmy $build_type;
81a75fececSSteven Rostedtmy $build_options;
82921ed4c7SSteven Rostedtmy $final_post_ktest;
83921ed4c7SSteven Rostedtmy $pre_ktest;
84921ed4c7SSteven Rostedtmy $post_ktest;
85921ed4c7SSteven Rostedtmy $pre_test;
86921ed4c7SSteven Rostedtmy $post_test;
870bd6c1a3SSteven Rostedtmy $pre_build;
880bd6c1a3SSteven Rostedtmy $post_build;
890bd6c1a3SSteven Rostedtmy $pre_build_die;
900bd6c1a3SSteven Rostedtmy $post_build_die;
91a75fececSSteven Rostedtmy $reboot_type;
92a75fececSSteven Rostedtmy $reboot_script;
93a75fececSSteven Rostedtmy $power_cycle;
94e48c5293SSteven Rostedtmy $reboot;
95a75fececSSteven Rostedtmy $reboot_on_error;
96bc7c5803SSteven Rostedtmy $switch_to_good;
97bc7c5803SSteven Rostedtmy $switch_to_test;
98a75fececSSteven Rostedtmy $poweroff_on_error;
99648a182cSSteven Rostedtmy $reboot_on_success;
100a75fececSSteven Rostedtmy $die_on_failure;
101576f627cSSteven Rostedtmy $powercycle_after_reboot;
102576f627cSSteven Rostedtmy $poweroff_after_halt;
103407b95b7SSteven Rostedtmy $max_monitor_wait;
104e48c5293SSteven Rostedtmy $ssh_exec;
105e48c5293SSteven Rostedtmy $scp_to_target;
10602ad2617SSteven Rostedtmy $scp_to_target_install;
107a75fececSSteven Rostedtmy $power_off;
108a75fececSSteven Rostedtmy $grub_menu;
109*a15ba913SSteven Rostedtmy $grub_file;
1102545eb61SSteven Rostedtmy $grub_number;
111*a15ba913SSteven Rostedtmy $grub_reboot;
1122545eb61SSteven Rostedtmy $target;
1132545eb61SSteven Rostedtmy $make;
114e5c2ec11SSteven Rostedtmy $pre_install;
1158b37ca8cSSteven Rostedtmy $post_install;
116e0a8742eSSteven Rostedtmy $no_install;
1175c42fc5bSSteven Rostedtmy $noclean;
1185f9b6cedSSteven Rostedtmy $minconfig;
1194c4ab120SSteven Rostedtmy $start_minconfig;
12035ce5952SSteven Rostedtmy $start_minconfig_defined;
1214c4ab120SSteven Rostedtmy $output_minconfig;
122ccc513b6SSteven Rostedtmy $minconfig_type;
12343de3316SSteven Rostedtmy $use_output_minconfig;
1244c4ab120SSteven Rostedtmy $ignore_config;
125be405f95SSteven Rostedtmy $ignore_errors;
1262b7d9b21SSteven Rostedtmy $addconfig;
1275f9b6cedSSteven Rostedtmy $in_bisect = 0;
128b5f4aea6SSteven Rostedtmy $bisect_bad_commit = "";
129d6ce2a0bSSteven Rostedtmy $reverse_bisect;
130c960bb9fSSteven Rostedtmy $bisect_manual;
131c23dca7cSSteven Rostedtmy $bisect_skip;
13230f75da5SSteven Rostedtmy $config_bisect_good;
133c5dacb88SSteven Rostedtmy $bisect_ret_good;
134c5dacb88SSteven Rostedtmy $bisect_ret_bad;
135c5dacb88SSteven Rostedtmy $bisect_ret_skip;
136c5dacb88SSteven Rostedtmy $bisect_ret_abort;
137c5dacb88SSteven Rostedtmy $bisect_ret_default;
1386c5ee0beSSteven Rostedtmy $in_patchcheck = 0;
1395a391fbfSSteven Rostedtmy $run_test;
1406c5ee0beSSteven Rostedtmy $redirect;
1417faafbd6SSteven Rostedtmy $buildlog;
142a9dd5d63SRabin Vincentmy $testlog;
1437faafbd6SSteven Rostedtmy $dmesg;
1447faafbd6SSteven Rostedtmy $monitor_fp;
1457faafbd6SSteven Rostedtmy $monitor_pid;
1467faafbd6SSteven Rostedtmy $monitor_cnt = 0;
147a75fececSSteven Rostedtmy $sleep_time;
148a75fececSSteven Rostedtmy $bisect_sleep_time;
14927d934b2SSteven Rostedtmy $patchcheck_sleep_time;
1501990207dSSteven Rostedtmy $ignore_warnings;
151a75fececSSteven Rostedtmy $store_failures;
152de5b6e3bSRabin Vincentmy $store_successes;
1539064af52SSteven Rostedtmy $test_name;
154a75fececSSteven Rostedtmy $timeout;
155a75fececSSteven Rostedtmy $booted_timeout;
156f1a5b962SSteven Rostedtmy $detect_triplefault;
157a75fececSSteven Rostedtmy $console;
1582b803365SSteven Rostedtmy $reboot_success_line;
159a75fececSSteven Rostedtmy $success_line;
1601c8a617aSSteven Rostedtmy $stop_after_success;
1611c8a617aSSteven Rostedtmy $stop_after_failure;
1622d01b26aSSteven Rostedtmy $stop_test_after;
163a75fececSSteven Rostedtmy $build_target;
164a75fececSSteven Rostedtmy $target_image;
165b5f4aea6SSteven Rostedtmy $checkout;
166a75fececSSteven Rostedtmy $localversion;
167576f627cSSteven Rostedtmy $iteration = 0;
168e48c5293SSteven Rostedtmy $successes = 0;
1692545eb61SSteven Rostedt
170b5f4aea6SSteven Rostedtmy $bisect_good;
171b5f4aea6SSteven Rostedtmy $bisect_bad;
172b5f4aea6SSteven Rostedtmy $bisect_type;
173b5f4aea6SSteven Rostedtmy $bisect_start;
174b5f4aea6SSteven Rostedtmy $bisect_replay;
175b5f4aea6SSteven Rostedtmy $bisect_files;
176b5f4aea6SSteven Rostedtmy $bisect_reverse;
177b5f4aea6SSteven Rostedtmy $bisect_check;
178b5f4aea6SSteven Rostedt
179b5f4aea6SSteven Rostedtmy $config_bisect;
180b5f4aea6SSteven Rostedtmy $config_bisect_type;
181b0918612SSteven Rostedtmy $config_bisect_check;
182b5f4aea6SSteven Rostedt
183b5f4aea6SSteven Rostedtmy $patchcheck_type;
184b5f4aea6SSteven Rostedtmy $patchcheck_start;
185b5f4aea6SSteven Rostedtmy $patchcheck_end;
186b5f4aea6SSteven Rostedt
187165708b2SSteven Rostedt# set when a test is something other that just building or install
188bb8474b1SSteven Rostedt# which would require more options.
189bb8474b1SSteven Rostedtmy $buildonly = 1;
190bb8474b1SSteven Rostedt
191dbd3783bSSteven Rostedt# set when creating a new config
192dbd3783bSSteven Rostedtmy $newconfig = 0;
193dbd3783bSSteven Rostedt
1948d1491baSSteven Rostedtmy %entered_configs;
1958d1491baSSteven Rostedtmy %config_help;
19677d942ceSSteven Rostedtmy %variable;
197cf79fab6SSteven Rostedt
198cf79fab6SSteven Rostedt# force_config is the list of configs that we force enabled (or disabled)
199cf79fab6SSteven Rostedt# in a .config file. The MIN_CONFIG and ADD_CONFIG configs.
200fcb3f16aSSteven Rostedtmy %force_config;
2018d1491baSSteven Rostedt
2024ab1cce5SSteven Rostedt# do not force reboots on config problems
2034ab1cce5SSteven Rostedtmy $no_reboot = 1;
2044ab1cce5SSteven Rostedt
205759a3cc6SSteven Rostedt# reboot on success
206759a3cc6SSteven Rostedtmy $reboot_success = 0;
207759a3cc6SSteven Rostedt
2089cc9e091SSteven Rostedtmy %option_map = (
2099cc9e091SSteven Rostedt    "MACHINE"			=> \$machine,
2109cc9e091SSteven Rostedt    "SSH_USER"			=> \$ssh_user,
2119cc9e091SSteven Rostedt    "TMP_DIR"			=> \$tmpdir,
2129cc9e091SSteven Rostedt    "OUTPUT_DIR"		=> \$outputdir,
2139cc9e091SSteven Rostedt    "BUILD_DIR"			=> \$builddir,
2149cc9e091SSteven Rostedt    "TEST_TYPE"			=> \$test_type,
215921ed4c7SSteven Rostedt    "PRE_KTEST"			=> \$pre_ktest,
216921ed4c7SSteven Rostedt    "POST_KTEST"		=> \$post_ktest,
217921ed4c7SSteven Rostedt    "PRE_TEST"			=> \$pre_test,
218921ed4c7SSteven Rostedt    "POST_TEST"			=> \$post_test,
2199cc9e091SSteven Rostedt    "BUILD_TYPE"		=> \$build_type,
2209cc9e091SSteven Rostedt    "BUILD_OPTIONS"		=> \$build_options,
2219cc9e091SSteven Rostedt    "PRE_BUILD"			=> \$pre_build,
2229cc9e091SSteven Rostedt    "POST_BUILD"		=> \$post_build,
2239cc9e091SSteven Rostedt    "PRE_BUILD_DIE"		=> \$pre_build_die,
2249cc9e091SSteven Rostedt    "POST_BUILD_DIE"		=> \$post_build_die,
2259cc9e091SSteven Rostedt    "POWER_CYCLE"		=> \$power_cycle,
2269cc9e091SSteven Rostedt    "REBOOT"			=> \$reboot,
2279cc9e091SSteven Rostedt    "BUILD_NOCLEAN"		=> \$noclean,
2289cc9e091SSteven Rostedt    "MIN_CONFIG"		=> \$minconfig,
2299cc9e091SSteven Rostedt    "OUTPUT_MIN_CONFIG"		=> \$output_minconfig,
2309cc9e091SSteven Rostedt    "START_MIN_CONFIG"		=> \$start_minconfig,
231ccc513b6SSteven Rostedt    "MIN_CONFIG_TYPE"		=> \$minconfig_type,
23243de3316SSteven Rostedt    "USE_OUTPUT_MIN_CONFIG"	=> \$use_output_minconfig,
2339cc9e091SSteven Rostedt    "IGNORE_CONFIG"		=> \$ignore_config,
2349cc9e091SSteven Rostedt    "TEST"			=> \$run_test,
2359cc9e091SSteven Rostedt    "ADD_CONFIG"		=> \$addconfig,
2369cc9e091SSteven Rostedt    "REBOOT_TYPE"		=> \$reboot_type,
2379cc9e091SSteven Rostedt    "GRUB_MENU"			=> \$grub_menu,
238*a15ba913SSteven Rostedt    "GRUB_FILE"			=> \$grub_file,
239*a15ba913SSteven Rostedt    "GRUB_REBOOT"		=> \$grub_reboot,
240e5c2ec11SSteven Rostedt    "PRE_INSTALL"		=> \$pre_install,
2419cc9e091SSteven Rostedt    "POST_INSTALL"		=> \$post_install,
2429cc9e091SSteven Rostedt    "NO_INSTALL"		=> \$no_install,
2439cc9e091SSteven Rostedt    "REBOOT_SCRIPT"		=> \$reboot_script,
2449cc9e091SSteven Rostedt    "REBOOT_ON_ERROR"		=> \$reboot_on_error,
2459cc9e091SSteven Rostedt    "SWITCH_TO_GOOD"		=> \$switch_to_good,
2469cc9e091SSteven Rostedt    "SWITCH_TO_TEST"		=> \$switch_to_test,
2479cc9e091SSteven Rostedt    "POWEROFF_ON_ERROR"		=> \$poweroff_on_error,
248648a182cSSteven Rostedt    "REBOOT_ON_SUCCESS"		=> \$reboot_on_success,
2499cc9e091SSteven Rostedt    "DIE_ON_FAILURE"		=> \$die_on_failure,
2509cc9e091SSteven Rostedt    "POWER_OFF"			=> \$power_off,
2519cc9e091SSteven Rostedt    "POWERCYCLE_AFTER_REBOOT"	=> \$powercycle_after_reboot,
2529cc9e091SSteven Rostedt    "POWEROFF_AFTER_HALT"	=> \$poweroff_after_halt,
253407b95b7SSteven Rostedt    "MAX_MONITOR_WAIT"		=> \$max_monitor_wait,
2549cc9e091SSteven Rostedt    "SLEEP_TIME"		=> \$sleep_time,
2559cc9e091SSteven Rostedt    "BISECT_SLEEP_TIME"		=> \$bisect_sleep_time,
2569cc9e091SSteven Rostedt    "PATCHCHECK_SLEEP_TIME"	=> \$patchcheck_sleep_time,
2579cc9e091SSteven Rostedt    "IGNORE_WARNINGS"		=> \$ignore_warnings,
258be405f95SSteven Rostedt    "IGNORE_ERRORS"		=> \$ignore_errors,
2599cc9e091SSteven Rostedt    "BISECT_MANUAL"		=> \$bisect_manual,
2609cc9e091SSteven Rostedt    "BISECT_SKIP"		=> \$bisect_skip,
2619cc9e091SSteven Rostedt    "CONFIG_BISECT_GOOD"	=> \$config_bisect_good,
2629cc9e091SSteven Rostedt    "BISECT_RET_GOOD"		=> \$bisect_ret_good,
2639cc9e091SSteven Rostedt    "BISECT_RET_BAD"		=> \$bisect_ret_bad,
2649cc9e091SSteven Rostedt    "BISECT_RET_SKIP"		=> \$bisect_ret_skip,
2659cc9e091SSteven Rostedt    "BISECT_RET_ABORT"		=> \$bisect_ret_abort,
2669cc9e091SSteven Rostedt    "BISECT_RET_DEFAULT"	=> \$bisect_ret_default,
2679cc9e091SSteven Rostedt    "STORE_FAILURES"		=> \$store_failures,
2689cc9e091SSteven Rostedt    "STORE_SUCCESSES"		=> \$store_successes,
2699cc9e091SSteven Rostedt    "TEST_NAME"			=> \$test_name,
2709cc9e091SSteven Rostedt    "TIMEOUT"			=> \$timeout,
2719cc9e091SSteven Rostedt    "BOOTED_TIMEOUT"		=> \$booted_timeout,
2729cc9e091SSteven Rostedt    "CONSOLE"			=> \$console,
2739cc9e091SSteven Rostedt    "DETECT_TRIPLE_FAULT"	=> \$detect_triplefault,
2749cc9e091SSteven Rostedt    "SUCCESS_LINE"		=> \$success_line,
2759cc9e091SSteven Rostedt    "REBOOT_SUCCESS_LINE"	=> \$reboot_success_line,
2769cc9e091SSteven Rostedt    "STOP_AFTER_SUCCESS"	=> \$stop_after_success,
2779cc9e091SSteven Rostedt    "STOP_AFTER_FAILURE"	=> \$stop_after_failure,
2789cc9e091SSteven Rostedt    "STOP_TEST_AFTER"		=> \$stop_test_after,
2799cc9e091SSteven Rostedt    "BUILD_TARGET"		=> \$build_target,
2809cc9e091SSteven Rostedt    "SSH_EXEC"			=> \$ssh_exec,
2819cc9e091SSteven Rostedt    "SCP_TO_TARGET"		=> \$scp_to_target,
28202ad2617SSteven Rostedt    "SCP_TO_TARGET_INSTALL"	=> \$scp_to_target_install,
2839cc9e091SSteven Rostedt    "CHECKOUT"			=> \$checkout,
2849cc9e091SSteven Rostedt    "TARGET_IMAGE"		=> \$target_image,
2859cc9e091SSteven Rostedt    "LOCALVERSION"		=> \$localversion,
2869cc9e091SSteven Rostedt
2879cc9e091SSteven Rostedt    "BISECT_GOOD"		=> \$bisect_good,
2889cc9e091SSteven Rostedt    "BISECT_BAD"		=> \$bisect_bad,
2899cc9e091SSteven Rostedt    "BISECT_TYPE"		=> \$bisect_type,
2909cc9e091SSteven Rostedt    "BISECT_START"		=> \$bisect_start,
2919cc9e091SSteven Rostedt    "BISECT_REPLAY"		=> \$bisect_replay,
2929cc9e091SSteven Rostedt    "BISECT_FILES"		=> \$bisect_files,
2939cc9e091SSteven Rostedt    "BISECT_REVERSE"		=> \$bisect_reverse,
2949cc9e091SSteven Rostedt    "BISECT_CHECK"		=> \$bisect_check,
2959cc9e091SSteven Rostedt
2969cc9e091SSteven Rostedt    "CONFIG_BISECT"		=> \$config_bisect,
2979cc9e091SSteven Rostedt    "CONFIG_BISECT_TYPE"	=> \$config_bisect_type,
298b0918612SSteven Rostedt    "CONFIG_BISECT_CHECK"	=> \$config_bisect_check,
2999cc9e091SSteven Rostedt
3009cc9e091SSteven Rostedt    "PATCHCHECK_TYPE"		=> \$patchcheck_type,
3019cc9e091SSteven Rostedt    "PATCHCHECK_START"		=> \$patchcheck_start,
3029cc9e091SSteven Rostedt    "PATCHCHECK_END"		=> \$patchcheck_end,
3039cc9e091SSteven Rostedt);
3049cc9e091SSteven Rostedt
3059cc9e091SSteven Rostedt# Options may be used by other options, record them.
3069cc9e091SSteven Rostedtmy %used_options;
3079cc9e091SSteven Rostedt
3087bf51073SSteven Rostedt# default variables that can be used
3097bf51073SSteven Rostedtchomp ($variable{"PWD"} = `pwd`);
3107bf51073SSteven Rostedt
3118d1491baSSteven Rostedt$config_help{"MACHINE"} = << "EOF"
3128d1491baSSteven Rostedt The machine hostname that you will test.
313bb8474b1SSteven Rostedt For build only tests, it is still needed to differentiate log files.
3148d1491baSSteven RostedtEOF
3158d1491baSSteven Rostedt    ;
3168d1491baSSteven Rostedt$config_help{"SSH_USER"} = << "EOF"
3178d1491baSSteven Rostedt The box is expected to have ssh on normal bootup, provide the user
3188d1491baSSteven Rostedt  (most likely root, since you need privileged operations)
3198d1491baSSteven RostedtEOF
3208d1491baSSteven Rostedt    ;
3218d1491baSSteven Rostedt$config_help{"BUILD_DIR"} = << "EOF"
3228d1491baSSteven Rostedt The directory that contains the Linux source code (full path).
3230e7a22deSSteven Rostedt You can use \${PWD} that will be the path where ktest.pl is run, or use
3240e7a22deSSteven Rostedt \${THIS_DIR} which is assigned \${PWD} but may be changed later.
3258d1491baSSteven RostedtEOF
3268d1491baSSteven Rostedt    ;
3278d1491baSSteven Rostedt$config_help{"OUTPUT_DIR"} = << "EOF"
3288d1491baSSteven Rostedt The directory that the objects will be built (full path).
3298d1491baSSteven Rostedt (can not be same as BUILD_DIR)
3300e7a22deSSteven Rostedt You can use \${PWD} that will be the path where ktest.pl is run, or use
3310e7a22deSSteven Rostedt \${THIS_DIR} which is assigned \${PWD} but may be changed later.
3328d1491baSSteven RostedtEOF
3338d1491baSSteven Rostedt    ;
3348d1491baSSteven Rostedt$config_help{"BUILD_TARGET"} = << "EOF"
3358d1491baSSteven Rostedt The location of the compiled file to copy to the target.
3368d1491baSSteven Rostedt (relative to OUTPUT_DIR)
3378d1491baSSteven RostedtEOF
3388d1491baSSteven Rostedt    ;
339dbd3783bSSteven Rostedt$config_help{"BUILD_OPTIONS"} = << "EOF"
340dbd3783bSSteven Rostedt Options to add to \"make\" when building.
341dbd3783bSSteven Rostedt i.e.  -j20
342dbd3783bSSteven RostedtEOF
343dbd3783bSSteven Rostedt    ;
3448d1491baSSteven Rostedt$config_help{"TARGET_IMAGE"} = << "EOF"
3458d1491baSSteven Rostedt The place to put your image on the test machine.
3468d1491baSSteven RostedtEOF
3478d1491baSSteven Rostedt    ;
3488d1491baSSteven Rostedt$config_help{"POWER_CYCLE"} = << "EOF"
3498d1491baSSteven Rostedt A script or command to reboot the box.
3508d1491baSSteven Rostedt
3518d1491baSSteven Rostedt Here is a digital loggers power switch example
3528d1491baSSteven Rostedt POWER_CYCLE = wget --no-proxy -O /dev/null -q  --auth-no-challenge 'http://admin:admin\@power/outlet?5=CCL'
3538d1491baSSteven Rostedt
3548d1491baSSteven Rostedt Here is an example to reboot a virtual box on the current host
3558d1491baSSteven Rostedt with the name "Guest".
3568d1491baSSteven Rostedt POWER_CYCLE = virsh destroy Guest; sleep 5; virsh start Guest
3578d1491baSSteven RostedtEOF
3588d1491baSSteven Rostedt    ;
3598d1491baSSteven Rostedt$config_help{"CONSOLE"} = << "EOF"
3608d1491baSSteven Rostedt The script or command that reads the console
3618d1491baSSteven Rostedt
3628d1491baSSteven Rostedt  If you use ttywatch server, something like the following would work.
3638d1491baSSteven RostedtCONSOLE = nc -d localhost 3001
3648d1491baSSteven Rostedt
3658d1491baSSteven Rostedt For a virtual machine with guest name "Guest".
3668d1491baSSteven RostedtCONSOLE =  virsh console Guest
3678d1491baSSteven RostedtEOF
3688d1491baSSteven Rostedt    ;
3698d1491baSSteven Rostedt$config_help{"LOCALVERSION"} = << "EOF"
3708d1491baSSteven Rostedt Required version ending to differentiate the test
3718d1491baSSteven Rostedt from other linux builds on the system.
3728d1491baSSteven RostedtEOF
3738d1491baSSteven Rostedt    ;
3748d1491baSSteven Rostedt$config_help{"REBOOT_TYPE"} = << "EOF"
3758d1491baSSteven Rostedt Way to reboot the box to the test kernel.
376*a15ba913SSteven Rostedt Only valid options so far are "grub", "grub2", and "script".
3778d1491baSSteven Rostedt
3788d1491baSSteven Rostedt If you specify grub, it will assume grub version 1
3798d1491baSSteven Rostedt and will search in /boot/grub/menu.lst for the title \$GRUB_MENU
3808d1491baSSteven Rostedt and select that target to reboot to the kernel. If this is not
3818d1491baSSteven Rostedt your setup, then specify "script" and have a command or script
3828d1491baSSteven Rostedt specified in REBOOT_SCRIPT to boot to the target.
3838d1491baSSteven Rostedt
3848d1491baSSteven Rostedt The entry in /boot/grub/menu.lst must be entered in manually.
3858d1491baSSteven Rostedt The test will not modify that file.
386*a15ba913SSteven Rostedt
387*a15ba913SSteven Rostedt If you specify grub2, then you also need to specify both \$GRUB_MENU
388*a15ba913SSteven Rostedt and \$GRUB_FILE.
3898d1491baSSteven RostedtEOF
3908d1491baSSteven Rostedt    ;
3918d1491baSSteven Rostedt$config_help{"GRUB_MENU"} = << "EOF"
3928d1491baSSteven Rostedt The grub title name for the test kernel to boot
393*a15ba913SSteven Rostedt (Only mandatory if REBOOT_TYPE = grub or grub2)
3948d1491baSSteven Rostedt
3958d1491baSSteven Rostedt Note, ktest.pl will not update the grub menu.lst, you need to
3968d1491baSSteven Rostedt manually add an option for the test. ktest.pl will search
3978d1491baSSteven Rostedt the grub menu.lst for this option to find what kernel to
3988d1491baSSteven Rostedt reboot into.
3998d1491baSSteven Rostedt
4008d1491baSSteven Rostedt For example, if in the /boot/grub/menu.lst the test kernel title has:
4018d1491baSSteven Rostedt title Test Kernel
4028d1491baSSteven Rostedt kernel vmlinuz-test
4038d1491baSSteven Rostedt GRUB_MENU = Test Kernel
404*a15ba913SSteven Rostedt
405*a15ba913SSteven Rostedt For grub2, a search of \$GRUB_FILE is performed for the lines
406*a15ba913SSteven Rostedt that begin with "menuentry". It will not detect submenus. The
407*a15ba913SSteven Rostedt menu must be a non-nested menu. Add the quotes used in the menu
408*a15ba913SSteven Rostedt to guarantee your selection, as the first menuentry with the content
409*a15ba913SSteven Rostedt of \$GRUB_MENU that is found will be used.
410*a15ba913SSteven RostedtEOF
411*a15ba913SSteven Rostedt    ;
412*a15ba913SSteven Rostedt$config_help{"GRUB_FILE"} = << "EOF"
413*a15ba913SSteven Rostedt If grub2 is used, the full path for the grub.cfg file is placed
414*a15ba913SSteven Rostedt here. Use something like /boot/grub2/grub.cfg to search.
4158d1491baSSteven RostedtEOF
4168d1491baSSteven Rostedt    ;
4178d1491baSSteven Rostedt$config_help{"REBOOT_SCRIPT"} = << "EOF"
4188d1491baSSteven Rostedt A script to reboot the target into the test kernel
4198d1491baSSteven Rostedt (Only mandatory if REBOOT_TYPE = script)
4208d1491baSSteven RostedtEOF
4218d1491baSSteven Rostedt    ;
4228d1491baSSteven Rostedt
423dad98754SSteven Rostedtsub read_prompt {
424dad98754SSteven Rostedt    my ($cancel, $prompt) = @_;
42535ce5952SSteven Rostedt
42635ce5952SSteven Rostedt    my $ans;
42735ce5952SSteven Rostedt
42835ce5952SSteven Rostedt    for (;;) {
429dad98754SSteven Rostedt	if ($cancel) {
430dad98754SSteven Rostedt	    print "$prompt [y/n/C] ";
431dad98754SSteven Rostedt	} else {
43235ce5952SSteven Rostedt	    print "$prompt [Y/n] ";
433dad98754SSteven Rostedt	}
43435ce5952SSteven Rostedt	$ans = <STDIN>;
43535ce5952SSteven Rostedt	chomp $ans;
43635ce5952SSteven Rostedt	if ($ans =~ /^\s*$/) {
437dad98754SSteven Rostedt	    if ($cancel) {
438dad98754SSteven Rostedt		$ans = "c";
439dad98754SSteven Rostedt	    } else {
44035ce5952SSteven Rostedt		$ans = "y";
44135ce5952SSteven Rostedt	    }
442dad98754SSteven Rostedt	}
44335ce5952SSteven Rostedt	last if ($ans =~ /^y$/i || $ans =~ /^n$/i);
444dad98754SSteven Rostedt	if ($cancel) {
445dad98754SSteven Rostedt	    last if ($ans =~ /^c$/i);
446dad98754SSteven Rostedt	    print "Please answer either 'y', 'n' or 'c'.\n";
447dad98754SSteven Rostedt	} else {
44835ce5952SSteven Rostedt	    print "Please answer either 'y' or 'n'.\n";
44935ce5952SSteven Rostedt	}
450dad98754SSteven Rostedt    }
451dad98754SSteven Rostedt    if ($ans =~ /^c/i) {
452dad98754SSteven Rostedt	exit;
453dad98754SSteven Rostedt    }
45435ce5952SSteven Rostedt    if ($ans !~ /^y$/i) {
45535ce5952SSteven Rostedt	return 0;
45635ce5952SSteven Rostedt    }
45735ce5952SSteven Rostedt    return 1;
45835ce5952SSteven Rostedt}
4598d1491baSSteven Rostedt
460dad98754SSteven Rostedtsub read_yn {
461dad98754SSteven Rostedt    my ($prompt) = @_;
462dad98754SSteven Rostedt
463dad98754SSteven Rostedt    return read_prompt 0, $prompt;
464dad98754SSteven Rostedt}
465dad98754SSteven Rostedt
466dad98754SSteven Rostedtsub read_ync {
467dad98754SSteven Rostedt    my ($prompt) = @_;
468dad98754SSteven Rostedt
469dad98754SSteven Rostedt    return read_prompt 1, $prompt;
470dad98754SSteven Rostedt}
471dad98754SSteven Rostedt
4728d1491baSSteven Rostedtsub get_ktest_config {
4738d1491baSSteven Rostedt    my ($config) = @_;
474815e2bd7SSteven Rostedt    my $ans;
4758d1491baSSteven Rostedt
4768d1491baSSteven Rostedt    return if (defined($opt{$config}));
4778d1491baSSteven Rostedt
4788d1491baSSteven Rostedt    if (defined($config_help{$config})) {
4798d1491baSSteven Rostedt	print "\n";
4808d1491baSSteven Rostedt	print $config_help{$config};
4818d1491baSSteven Rostedt    }
4828d1491baSSteven Rostedt
4838d1491baSSteven Rostedt    for (;;) {
4848d1491baSSteven Rostedt	print "$config = ";
485dbd3783bSSteven Rostedt	if (defined($default{$config}) && length($default{$config})) {
4868d1491baSSteven Rostedt	    print "\[$default{$config}\] ";
4878d1491baSSteven Rostedt	}
488815e2bd7SSteven Rostedt	$ans = <STDIN>;
489815e2bd7SSteven Rostedt	$ans =~ s/^\s*(.*\S)\s*$/$1/;
490815e2bd7SSteven Rostedt	if ($ans =~ /^\s*$/) {
4918d1491baSSteven Rostedt	    if ($default{$config}) {
492815e2bd7SSteven Rostedt		$ans = $default{$config};
4938d1491baSSteven Rostedt	    } else {
4948d1491baSSteven Rostedt		print "Your answer can not be blank\n";
4958d1491baSSteven Rostedt		next;
4968d1491baSSteven Rostedt	    }
4978d1491baSSteven Rostedt	}
4980e7a22deSSteven Rostedt	$entered_configs{$config} = ${ans};
4998d1491baSSteven Rostedt	last;
5008d1491baSSteven Rostedt    }
5018d1491baSSteven Rostedt}
5028d1491baSSteven Rostedt
5038d1491baSSteven Rostedtsub get_ktest_configs {
5048d1491baSSteven Rostedt    get_ktest_config("MACHINE");
5058d1491baSSteven Rostedt    get_ktest_config("BUILD_DIR");
5068d1491baSSteven Rostedt    get_ktest_config("OUTPUT_DIR");
507bb8474b1SSteven Rostedt
508dbd3783bSSteven Rostedt    if ($newconfig) {
509dbd3783bSSteven Rostedt	get_ktest_config("BUILD_OPTIONS");
510dbd3783bSSteven Rostedt    }
511dbd3783bSSteven Rostedt
512bb8474b1SSteven Rostedt    # options required for other than just building a kernel
513bb8474b1SSteven Rostedt    if (!$buildonly) {
514165708b2SSteven Rostedt	get_ktest_config("POWER_CYCLE");
515165708b2SSteven Rostedt	get_ktest_config("CONSOLE");
516165708b2SSteven Rostedt    }
517165708b2SSteven Rostedt
518165708b2SSteven Rostedt    # options required for install and more
519165708b2SSteven Rostedt    if ($buildonly != 1) {
520bb8474b1SSteven Rostedt	get_ktest_config("SSH_USER");
5218d1491baSSteven Rostedt	get_ktest_config("BUILD_TARGET");
5228d1491baSSteven Rostedt	get_ktest_config("TARGET_IMAGE");
523bb8474b1SSteven Rostedt    }
524bb8474b1SSteven Rostedt
5258d1491baSSteven Rostedt    get_ktest_config("LOCALVERSION");
5268d1491baSSteven Rostedt
527bb8474b1SSteven Rostedt    return if ($buildonly);
528bb8474b1SSteven Rostedt
5298d1491baSSteven Rostedt    my $rtype = $opt{"REBOOT_TYPE"};
5308d1491baSSteven Rostedt
5318d1491baSSteven Rostedt    if (!defined($rtype)) {
5328d1491baSSteven Rostedt	if (!defined($opt{"GRUB_MENU"})) {
5338d1491baSSteven Rostedt	    get_ktest_config("REBOOT_TYPE");
5348d1491baSSteven Rostedt	    $rtype = $entered_configs{"REBOOT_TYPE"};
5358d1491baSSteven Rostedt	} else {
5368d1491baSSteven Rostedt	    $rtype = "grub";
5378d1491baSSteven Rostedt	}
5388d1491baSSteven Rostedt    }
5398d1491baSSteven Rostedt
5408d1491baSSteven Rostedt    if ($rtype eq "grub") {
5418d1491baSSteven Rostedt	get_ktest_config("GRUB_MENU");
5428d1491baSSteven Rostedt    }
543*a15ba913SSteven Rostedt
544*a15ba913SSteven Rostedt    if ($rtype eq "grub2") {
545*a15ba913SSteven Rostedt	get_ktest_config("GRUB_MENU");
546*a15ba913SSteven Rostedt	get_ktest_config("GRUB_FILE");
547*a15ba913SSteven Rostedt    }
5488d1491baSSteven Rostedt}
5498d1491baSSteven Rostedt
55077d942ceSSteven Rostedtsub process_variables {
5518d735212SSteven Rostedt    my ($value, $remove_undef) = @_;
55277d942ceSSteven Rostedt    my $retval = "";
55377d942ceSSteven Rostedt
55477d942ceSSteven Rostedt    # We want to check for '\', and it is just easier
55577d942ceSSteven Rostedt    # to check the previous characet of '$' and not need
55677d942ceSSteven Rostedt    # to worry if '$' is the first character. By adding
55777d942ceSSteven Rostedt    # a space to $value, we can just check [^\\]\$ and
55877d942ceSSteven Rostedt    # it will still work.
55977d942ceSSteven Rostedt    $value = " $value";
56077d942ceSSteven Rostedt
56177d942ceSSteven Rostedt    while ($value =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) {
56277d942ceSSteven Rostedt	my $begin = $1;
56377d942ceSSteven Rostedt	my $var = $2;
56477d942ceSSteven Rostedt	my $end = $3;
56577d942ceSSteven Rostedt	# append beginning of value to retval
56677d942ceSSteven Rostedt	$retval = "$retval$begin";
56777d942ceSSteven Rostedt	if (defined($variable{$var})) {
56877d942ceSSteven Rostedt	    $retval = "$retval$variable{$var}";
5698d735212SSteven Rostedt	} elsif (defined($remove_undef) && $remove_undef) {
5708d735212SSteven Rostedt	    # for if statements, any variable that is not defined,
5718d735212SSteven Rostedt	    # we simple convert to 0
5728d735212SSteven Rostedt	    $retval = "${retval}0";
57377d942ceSSteven Rostedt	} else {
57477d942ceSSteven Rostedt	    # put back the origin piece.
57577d942ceSSteven Rostedt	    $retval = "$retval\$\{$var\}";
5769cc9e091SSteven Rostedt	    # This could be an option that is used later, save
5779cc9e091SSteven Rostedt	    # it so we don't warn if this option is not one of
5789cc9e091SSteven Rostedt	    # ktests options.
5799cc9e091SSteven Rostedt	    $used_options{$var} = 1;
58077d942ceSSteven Rostedt	}
58177d942ceSSteven Rostedt	$value = $end;
58277d942ceSSteven Rostedt    }
58377d942ceSSteven Rostedt    $retval = "$retval$value";
58477d942ceSSteven Rostedt
58577d942ceSSteven Rostedt    # remove the space added in the beginning
58677d942ceSSteven Rostedt    $retval =~ s/ //;
58777d942ceSSteven Rostedt
58877d942ceSSteven Rostedt    return "$retval"
58977d942ceSSteven Rostedt}
59077d942ceSSteven Rostedt
591a57419b3SSteven Rostedtsub set_value {
5923d1cc414SSteven Rostedt    my ($lvalue, $rvalue, $override, $overrides, $name) = @_;
5932545eb61SSteven Rostedt
594cad96669SSteven Rostedt    my $prvalue = process_variables($rvalue);
595cad96669SSteven Rostedt
596cad96669SSteven Rostedt    if ($buildonly && $lvalue =~ /^TEST_TYPE(\[.*\])?$/ && $prvalue ne "build") {
597bb8474b1SSteven Rostedt	# Note if a test is something other than build, then we
598bb8474b1SSteven Rostedt	# will need other manditory options.
599cad96669SSteven Rostedt	if ($prvalue ne "install") {
600bb8474b1SSteven Rostedt	    $buildonly = 0;
601165708b2SSteven Rostedt	} else {
602165708b2SSteven Rostedt	    # install still limits some manditory options.
603165708b2SSteven Rostedt	    $buildonly = 2;
604165708b2SSteven Rostedt	}
605bb8474b1SSteven Rostedt    }
606bb8474b1SSteven Rostedt
607a75fececSSteven Rostedt    if (defined($opt{$lvalue})) {
6083d1cc414SSteven Rostedt	if (!$override || defined(${$overrides}{$lvalue})) {
6093d1cc414SSteven Rostedt	    my $extra = "";
6103d1cc414SSteven Rostedt	    if ($override) {
6113d1cc414SSteven Rostedt		$extra = "In the same override section!\n";
6123d1cc414SSteven Rostedt	    }
6133d1cc414SSteven Rostedt	    die "$name: $.: Option $lvalue defined more than once!\n$extra";
6143d1cc414SSteven Rostedt	}
615cad96669SSteven Rostedt	${$overrides}{$lvalue} = $prvalue;
616a75fececSSteven Rostedt    }
61721a9679fSSteven Rostedt    if ($rvalue =~ /^\s*$/) {
61821a9679fSSteven Rostedt	delete $opt{$lvalue};
61921a9679fSSteven Rostedt    } else {
620cad96669SSteven Rostedt	$opt{$lvalue} = $prvalue;
62121a9679fSSteven Rostedt    }
6222545eb61SSteven Rostedt}
623a57419b3SSteven Rostedt
62477d942ceSSteven Rostedtsub set_variable {
62577d942ceSSteven Rostedt    my ($lvalue, $rvalue) = @_;
62677d942ceSSteven Rostedt
62777d942ceSSteven Rostedt    if ($rvalue =~ /^\s*$/) {
62877d942ceSSteven Rostedt	delete $variable{$lvalue};
62977d942ceSSteven Rostedt    } else {
63077d942ceSSteven Rostedt	$rvalue = process_variables($rvalue);
63177d942ceSSteven Rostedt	$variable{$lvalue} = $rvalue;
63277d942ceSSteven Rostedt    }
63377d942ceSSteven Rostedt}
63477d942ceSSteven Rostedt
635ab7a3f52SSteven Rostedtsub process_compare {
636ab7a3f52SSteven Rostedt    my ($lval, $cmp, $rval) = @_;
637ab7a3f52SSteven Rostedt
638ab7a3f52SSteven Rostedt    # remove whitespace
639ab7a3f52SSteven Rostedt
640ab7a3f52SSteven Rostedt    $lval =~ s/^\s*//;
641ab7a3f52SSteven Rostedt    $lval =~ s/\s*$//;
642ab7a3f52SSteven Rostedt
643ab7a3f52SSteven Rostedt    $rval =~ s/^\s*//;
644ab7a3f52SSteven Rostedt    $rval =~ s/\s*$//;
645ab7a3f52SSteven Rostedt
646ab7a3f52SSteven Rostedt    if ($cmp eq "==") {
647ab7a3f52SSteven Rostedt	return $lval eq $rval;
648ab7a3f52SSteven Rostedt    } elsif ($cmp eq "!=") {
649ab7a3f52SSteven Rostedt	return $lval ne $rval;
6508fddbe9bSSteven Rostedt    } elsif ($cmp eq "=~") {
6518fddbe9bSSteven Rostedt	return $lval =~ m/$rval/;
6528fddbe9bSSteven Rostedt    } elsif ($cmp eq "!~") {
6538fddbe9bSSteven Rostedt	return $lval !~ m/$rval/;
654ab7a3f52SSteven Rostedt    }
655ab7a3f52SSteven Rostedt
656ab7a3f52SSteven Rostedt    my $statement = "$lval $cmp $rval";
657ab7a3f52SSteven Rostedt    my $ret = eval $statement;
658ab7a3f52SSteven Rostedt
659ab7a3f52SSteven Rostedt    # $@ stores error of eval
660ab7a3f52SSteven Rostedt    if ($@) {
661ab7a3f52SSteven Rostedt	return -1;
662ab7a3f52SSteven Rostedt    }
663ab7a3f52SSteven Rostedt
664ab7a3f52SSteven Rostedt    return $ret;
665ab7a3f52SSteven Rostedt}
666ab7a3f52SSteven Rostedt
6679900b5dcSSteven Rostedtsub value_defined {
6689900b5dcSSteven Rostedt    my ($val) = @_;
6699900b5dcSSteven Rostedt
6709900b5dcSSteven Rostedt    return defined($variable{$2}) ||
6719900b5dcSSteven Rostedt	defined($opt{$2});
6729900b5dcSSteven Rostedt}
6739900b5dcSSteven Rostedt
6748d735212SSteven Rostedtmy $d = 0;
6758d735212SSteven Rostedtsub process_expression {
6768d735212SSteven Rostedt    my ($name, $val) = @_;
67745d73a5dSSteven Rostedt
6788d735212SSteven Rostedt    my $c = $d++;
6798d735212SSteven Rostedt
6808d735212SSteven Rostedt    while ($val =~ s/\(([^\(]*?)\)/\&\&\&\&VAL\&\&\&\&/) {
6818d735212SSteven Rostedt	my $express = $1;
6828d735212SSteven Rostedt
6838d735212SSteven Rostedt	if (process_expression($name, $express)) {
6848d735212SSteven Rostedt	    $val =~ s/\&\&\&\&VAL\&\&\&\&/ 1 /;
6858d735212SSteven Rostedt	} else {
6868d735212SSteven Rostedt	    $val =~ s/\&\&\&\&VAL\&\&\&\&/ 0 /;
6878d735212SSteven Rostedt	}
6888d735212SSteven Rostedt    }
6898d735212SSteven Rostedt
6908d735212SSteven Rostedt    $d--;
6918d735212SSteven Rostedt    my $OR = "\\|\\|";
6928d735212SSteven Rostedt    my $AND = "\\&\\&";
6938d735212SSteven Rostedt
6948d735212SSteven Rostedt    while ($val =~ s/^(.*?)($OR|$AND)//) {
6958d735212SSteven Rostedt	my $express = $1;
6968d735212SSteven Rostedt	my $op = $2;
6978d735212SSteven Rostedt
6988d735212SSteven Rostedt	if (process_expression($name, $express)) {
6998d735212SSteven Rostedt	    if ($op eq "||") {
7008d735212SSteven Rostedt		return 1;
7018d735212SSteven Rostedt	    }
7028d735212SSteven Rostedt	} else {
7038d735212SSteven Rostedt	    if ($op eq "&&") {
7048d735212SSteven Rostedt		return 0;
7058d735212SSteven Rostedt	    }
7068d735212SSteven Rostedt	}
7078d735212SSteven Rostedt    }
70845d73a5dSSteven Rostedt
7098fddbe9bSSteven Rostedt    if ($val =~ /(.*)(==|\!=|>=|<=|>|<|=~|\!~)(.*)/) {
710ab7a3f52SSteven Rostedt	my $ret = process_compare($1, $2, $3);
711ab7a3f52SSteven Rostedt	if ($ret < 0) {
712ab7a3f52SSteven Rostedt	    die "$name: $.: Unable to process comparison\n";
713ab7a3f52SSteven Rostedt	}
714ab7a3f52SSteven Rostedt	return $ret;
715ab7a3f52SSteven Rostedt    }
716ab7a3f52SSteven Rostedt
7179900b5dcSSteven Rostedt    if ($val =~ /^\s*(NOT\s*)?DEFINED\s+(\S+)\s*$/) {
7189900b5dcSSteven Rostedt	if (defined $1) {
7199900b5dcSSteven Rostedt	    return !value_defined($2);
7209900b5dcSSteven Rostedt	} else {
7219900b5dcSSteven Rostedt	    return value_defined($2);
7229900b5dcSSteven Rostedt	}
7239900b5dcSSteven Rostedt    }
7249900b5dcSSteven Rostedt
72545d73a5dSSteven Rostedt    if ($val =~ /^\s*0\s*$/) {
72645d73a5dSSteven Rostedt	return 0;
72745d73a5dSSteven Rostedt    } elsif ($val =~ /^\s*\d+\s*$/) {
72845d73a5dSSteven Rostedt	return 1;
72945d73a5dSSteven Rostedt    }
73045d73a5dSSteven Rostedt
7319900b5dcSSteven Rostedt    die ("$name: $.: Undefined content $val in if statement\n");
7328d735212SSteven Rostedt}
7338d735212SSteven Rostedt
7348d735212SSteven Rostedtsub process_if {
7358d735212SSteven Rostedt    my ($name, $value) = @_;
7368d735212SSteven Rostedt
7378d735212SSteven Rostedt    # Convert variables and replace undefined ones with 0
7388d735212SSteven Rostedt    my $val = process_variables($value, 1);
7398d735212SSteven Rostedt    my $ret = process_expression $name, $val;
7408d735212SSteven Rostedt
7418d735212SSteven Rostedt    return $ret;
74245d73a5dSSteven Rostedt}
74345d73a5dSSteven Rostedt
7442ed3b161SSteven Rostedtsub __read_config {
7452ed3b161SSteven Rostedt    my ($config, $current_test_num) = @_;
746a57419b3SSteven Rostedt
7472ed3b161SSteven Rostedt    my $in;
7482ed3b161SSteven Rostedt    open($in, $config) || die "can't read file $config";
749a57419b3SSteven Rostedt
750a57419b3SSteven Rostedt    my $name = $config;
751a57419b3SSteven Rostedt    $name =~ s,.*/(.*),$1,;
752a57419b3SSteven Rostedt
7532ed3b161SSteven Rostedt    my $test_num = $$current_test_num;
754a57419b3SSteven Rostedt    my $default = 1;
755a57419b3SSteven Rostedt    my $repeat = 1;
756a57419b3SSteven Rostedt    my $num_tests_set = 0;
757a57419b3SSteven Rostedt    my $skip = 0;
758a57419b3SSteven Rostedt    my $rest;
759a9f84424SSteven Rostedt    my $line;
7600df213caSSteven Rostedt    my $test_case = 0;
76145d73a5dSSteven Rostedt    my $if = 0;
76245d73a5dSSteven Rostedt    my $if_set = 0;
7633d1cc414SSteven Rostedt    my $override = 0;
7643d1cc414SSteven Rostedt
7653d1cc414SSteven Rostedt    my %overrides;
766a57419b3SSteven Rostedt
7672ed3b161SSteven Rostedt    while (<$in>) {
768a57419b3SSteven Rostedt
769a57419b3SSteven Rostedt	# ignore blank lines and comments
770a57419b3SSteven Rostedt	next if (/^\s*$/ || /\s*\#/);
771a57419b3SSteven Rostedt
7720050b6bbSSteven Rostedt	if (/^\s*(TEST_START|DEFAULTS)\b(.*)/) {
773a57419b3SSteven Rostedt
7740050b6bbSSteven Rostedt	    my $type = $1;
7750050b6bbSSteven Rostedt	    $rest = $2;
776a9f84424SSteven Rostedt	    $line = $2;
7770050b6bbSSteven Rostedt
7780050b6bbSSteven Rostedt	    my $old_test_num;
7790050b6bbSSteven Rostedt	    my $old_repeat;
7803d1cc414SSteven Rostedt	    $override = 0;
7810050b6bbSSteven Rostedt
7820050b6bbSSteven Rostedt	    if ($type eq "TEST_START") {
783a57419b3SSteven Rostedt
784a57419b3SSteven Rostedt		if ($num_tests_set) {
785a57419b3SSteven Rostedt		    die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
786a57419b3SSteven Rostedt		}
787a57419b3SSteven Rostedt
7880050b6bbSSteven Rostedt		$old_test_num = $test_num;
7890050b6bbSSteven Rostedt		$old_repeat = $repeat;
790a57419b3SSteven Rostedt
791a57419b3SSteven Rostedt		$test_num += $repeat;
792a57419b3SSteven Rostedt		$default = 0;
793a57419b3SSteven Rostedt		$repeat = 1;
7940050b6bbSSteven Rostedt	    } else {
7950050b6bbSSteven Rostedt		$default = 1;
7960050b6bbSSteven Rostedt	    }
797a57419b3SSteven Rostedt
798a9f84424SSteven Rostedt	    # If SKIP is anywhere in the line, the command will be skipped
799a9f84424SSteven Rostedt	    if ($rest =~ s/\s+SKIP\b//) {
800a57419b3SSteven Rostedt		$skip = 1;
801a57419b3SSteven Rostedt	    } else {
8020df213caSSteven Rostedt		$test_case = 1;
803a57419b3SSteven Rostedt		$skip = 0;
804a57419b3SSteven Rostedt	    }
805a57419b3SSteven Rostedt
806a9f84424SSteven Rostedt	    if ($rest =~ s/\sELSE\b//) {
807a9f84424SSteven Rostedt		if (!$if) {
808a9f84424SSteven Rostedt		    die "$name: $.: ELSE found with out matching IF section\n$_";
809a57419b3SSteven Rostedt		}
810a9f84424SSteven Rostedt		$if = 0;
811a9f84424SSteven Rostedt
812a9f84424SSteven Rostedt		if ($if_set) {
813a9f84424SSteven Rostedt		    $skip = 1;
814a9f84424SSteven Rostedt		} else {
815a9f84424SSteven Rostedt		    $skip = 0;
8163d1cc414SSteven Rostedt		}
8173d1cc414SSteven Rostedt	    }
818a57419b3SSteven Rostedt
819a9f84424SSteven Rostedt	    if ($rest =~ s/\sIF\s+(.*)//) {
82045d73a5dSSteven Rostedt		if (process_if($name, $1)) {
82145d73a5dSSteven Rostedt		    $if_set = 1;
82245d73a5dSSteven Rostedt		} else {
823a57419b3SSteven Rostedt		    $skip = 1;
824a57419b3SSteven Rostedt		}
82545d73a5dSSteven Rostedt		$if = 1;
82645d73a5dSSteven Rostedt	    } else {
82745d73a5dSSteven Rostedt		$if = 0;
828a9f84424SSteven Rostedt		$if_set = 0;
82945d73a5dSSteven Rostedt	    }
830a57419b3SSteven Rostedt
831a9f84424SSteven Rostedt	    if (!$skip) {
832a9f84424SSteven Rostedt		if ($type eq "TEST_START") {
833a9f84424SSteven Rostedt		    if ($rest =~ s/\s+ITERATE\s+(\d+)//) {
834a9f84424SSteven Rostedt			$repeat = $1;
835a9f84424SSteven Rostedt			$repeat_tests{"$test_num"} = $repeat;
836a9f84424SSteven Rostedt		    }
837a9f84424SSteven Rostedt		} elsif ($rest =~ s/\sOVERRIDE\b//) {
838a9f84424SSteven Rostedt		    # DEFAULT only
839a9f84424SSteven Rostedt		    $override = 1;
840a9f84424SSteven Rostedt		    # Clear previous overrides
841a9f84424SSteven Rostedt		    %overrides = ();
842a9f84424SSteven Rostedt		}
843a9f84424SSteven Rostedt	    }
844a9f84424SSteven Rostedt
845a9f84424SSteven Rostedt	    if (!$skip && $rest !~ /^\s*$/) {
8460050b6bbSSteven Rostedt		die "$name: $.: Gargbage found after $type\n$_";
847a57419b3SSteven Rostedt	    }
848a57419b3SSteven Rostedt
8490050b6bbSSteven Rostedt	    if ($skip && $type eq "TEST_START") {
850a57419b3SSteven Rostedt		$test_num = $old_test_num;
851e48c5293SSteven Rostedt		$repeat = $old_repeat;
852a57419b3SSteven Rostedt	    }
853a57419b3SSteven Rostedt
854ab7a3f52SSteven Rostedt	} elsif (/^\s*ELSE\b(.*)$/) {
85545d73a5dSSteven Rostedt	    if (!$if) {
85645d73a5dSSteven Rostedt		die "$name: $.: ELSE found with out matching IF section\n$_";
85745d73a5dSSteven Rostedt	    }
85845d73a5dSSteven Rostedt	    $rest = $1;
85945d73a5dSSteven Rostedt	    if ($if_set) {
86045d73a5dSSteven Rostedt		$skip = 1;
861ab7a3f52SSteven Rostedt		$rest = "";
86245d73a5dSSteven Rostedt	    } else {
86345d73a5dSSteven Rostedt		$skip = 0;
86445d73a5dSSteven Rostedt
865ab7a3f52SSteven Rostedt		if ($rest =~ /\sIF\s+(.*)/) {
86645d73a5dSSteven Rostedt		    # May be a ELSE IF section.
86795f57838SSteven Rostedt		    if (process_if($name, $1)) {
86895f57838SSteven Rostedt			$if_set = 1;
86995f57838SSteven Rostedt		    } else {
87045d73a5dSSteven Rostedt			$skip = 1;
87145d73a5dSSteven Rostedt		    }
872ab7a3f52SSteven Rostedt		    $rest = "";
87345d73a5dSSteven Rostedt		} else {
87445d73a5dSSteven Rostedt		    $if = 0;
87545d73a5dSSteven Rostedt		}
87645d73a5dSSteven Rostedt	    }
87745d73a5dSSteven Rostedt
878ab7a3f52SSteven Rostedt	    if ($rest !~ /^\s*$/) {
879ab7a3f52SSteven Rostedt		die "$name: $.: Gargbage found after DEFAULTS\n$_";
880ab7a3f52SSteven Rostedt	    }
881ab7a3f52SSteven Rostedt
8822ed3b161SSteven Rostedt	} elsif (/^\s*INCLUDE\s+(\S+)/) {
8832ed3b161SSteven Rostedt
8842ed3b161SSteven Rostedt	    next if ($skip);
8852ed3b161SSteven Rostedt
8862ed3b161SSteven Rostedt	    if (!$default) {
8872ed3b161SSteven Rostedt		die "$name: $.: INCLUDE can only be done in default sections\n$_";
8882ed3b161SSteven Rostedt	    }
8892ed3b161SSteven Rostedt
8902ed3b161SSteven Rostedt	    my $file = process_variables($1);
8912ed3b161SSteven Rostedt
8922ed3b161SSteven Rostedt	    if ($file !~ m,^/,) {
8932ed3b161SSteven Rostedt		# check the path of the config file first
8942ed3b161SSteven Rostedt		if ($config =~ m,(.*)/,) {
8952ed3b161SSteven Rostedt		    if (-f "$1/$file") {
8962ed3b161SSteven Rostedt			$file = "$1/$file";
8972ed3b161SSteven Rostedt		    }
8982ed3b161SSteven Rostedt		}
8992ed3b161SSteven Rostedt	    }
9002ed3b161SSteven Rostedt
9012ed3b161SSteven Rostedt	    if ( ! -r $file ) {
9022ed3b161SSteven Rostedt		die "$name: $.: Can't read file $file\n$_";
9032ed3b161SSteven Rostedt	    }
9042ed3b161SSteven Rostedt
9052ed3b161SSteven Rostedt	    if (__read_config($file, \$test_num)) {
9062ed3b161SSteven Rostedt		$test_case = 1;
9072ed3b161SSteven Rostedt	    }
9082ed3b161SSteven Rostedt
909a57419b3SSteven Rostedt	} elsif (/^\s*([A-Z_\[\]\d]+)\s*=\s*(.*?)\s*$/) {
910a57419b3SSteven Rostedt
911a57419b3SSteven Rostedt	    next if ($skip);
912a57419b3SSteven Rostedt
913a57419b3SSteven Rostedt	    my $lvalue = $1;
914a57419b3SSteven Rostedt	    my $rvalue = $2;
915a57419b3SSteven Rostedt
916a57419b3SSteven Rostedt	    if (!$default &&
917a57419b3SSteven Rostedt		($lvalue eq "NUM_TESTS" ||
918a57419b3SSteven Rostedt		 $lvalue eq "LOG_FILE" ||
919a57419b3SSteven Rostedt		 $lvalue eq "CLEAR_LOG")) {
920a57419b3SSteven Rostedt		die "$name: $.: $lvalue must be set in DEFAULTS section\n";
921a57419b3SSteven Rostedt	    }
922a57419b3SSteven Rostedt
923a57419b3SSteven Rostedt	    if ($lvalue eq "NUM_TESTS") {
924a57419b3SSteven Rostedt		if ($test_num) {
925a57419b3SSteven Rostedt		    die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
926a57419b3SSteven Rostedt		}
927a57419b3SSteven Rostedt		if (!$default) {
928a57419b3SSteven Rostedt		    die "$name: $.: NUM_TESTS must be set in default section\n";
929a57419b3SSteven Rostedt		}
930a57419b3SSteven Rostedt		$num_tests_set = 1;
931a57419b3SSteven Rostedt	    }
932a57419b3SSteven Rostedt
933a57419b3SSteven Rostedt	    if ($default || $lvalue =~ /\[\d+\]$/) {
9343d1cc414SSteven Rostedt		set_value($lvalue, $rvalue, $override, \%overrides, $name);
935a57419b3SSteven Rostedt	    } else {
936a57419b3SSteven Rostedt		my $val = "$lvalue\[$test_num\]";
9373d1cc414SSteven Rostedt		set_value($val, $rvalue, $override, \%overrides, $name);
938a57419b3SSteven Rostedt
939a57419b3SSteven Rostedt		if ($repeat > 1) {
940a57419b3SSteven Rostedt		    $repeats{$val} = $repeat;
941a57419b3SSteven Rostedt		}
942a57419b3SSteven Rostedt	    }
94377d942ceSSteven Rostedt	} elsif (/^\s*([A-Z_\[\]\d]+)\s*:=\s*(.*?)\s*$/) {
94477d942ceSSteven Rostedt	    next if ($skip);
94577d942ceSSteven Rostedt
94677d942ceSSteven Rostedt	    my $lvalue = $1;
94777d942ceSSteven Rostedt	    my $rvalue = $2;
94877d942ceSSteven Rostedt
94977d942ceSSteven Rostedt	    # process config variables.
95077d942ceSSteven Rostedt	    # Config variables are only active while reading the
95177d942ceSSteven Rostedt	    # config and can be defined anywhere. They also ignore
95277d942ceSSteven Rostedt	    # TEST_START and DEFAULTS, but are skipped if they are in
95377d942ceSSteven Rostedt	    # on of these sections that have SKIP defined.
95477d942ceSSteven Rostedt	    # The save variable can be
95577d942ceSSteven Rostedt	    # defined multiple times and the new one simply overrides
95677d942ceSSteven Rostedt	    # the prevous one.
95777d942ceSSteven Rostedt	    set_variable($lvalue, $rvalue);
95877d942ceSSteven Rostedt
959a57419b3SSteven Rostedt	} else {
960a57419b3SSteven Rostedt	    die "$name: $.: Garbage found in config\n$_";
961a57419b3SSteven Rostedt	}
9622545eb61SSteven Rostedt    }
9632545eb61SSteven Rostedt
964a57419b3SSteven Rostedt    if ($test_num) {
965a57419b3SSteven Rostedt	$test_num += $repeat - 1;
966a57419b3SSteven Rostedt	$opt{"NUM_TESTS"} = $test_num;
967a57419b3SSteven Rostedt    }
968a57419b3SSteven Rostedt
9692ed3b161SSteven Rostedt    close($in);
9702ed3b161SSteven Rostedt
9712ed3b161SSteven Rostedt    $$current_test_num = $test_num;
9722ed3b161SSteven Rostedt
9732ed3b161SSteven Rostedt    return $test_case;
9742ed3b161SSteven Rostedt}
9752ed3b161SSteven Rostedt
976c4261d0fSSteven Rostedtsub get_test_case {
977c4261d0fSSteven Rostedt	print "What test case would you like to run?\n";
978c4261d0fSSteven Rostedt	print " (build, install or boot)\n";
979c4261d0fSSteven Rostedt	print " Other tests are available but require editing the config file\n";
980c4261d0fSSteven Rostedt	my $ans = <STDIN>;
981c4261d0fSSteven Rostedt	chomp $ans;
982c4261d0fSSteven Rostedt	$default{"TEST_TYPE"} = $ans;
983c4261d0fSSteven Rostedt}
984c4261d0fSSteven Rostedt
9852ed3b161SSteven Rostedtsub read_config {
9862ed3b161SSteven Rostedt    my ($config) = @_;
9872ed3b161SSteven Rostedt
9882ed3b161SSteven Rostedt    my $test_case;
9892ed3b161SSteven Rostedt    my $test_num = 0;
9902ed3b161SSteven Rostedt
9912ed3b161SSteven Rostedt    $test_case = __read_config $config, \$test_num;
9922ed3b161SSteven Rostedt
9938d1491baSSteven Rostedt    # make sure we have all mandatory configs
9948d1491baSSteven Rostedt    get_ktest_configs;
9958d1491baSSteven Rostedt
9960df213caSSteven Rostedt    # was a test specified?
9970df213caSSteven Rostedt    if (!$test_case) {
9980df213caSSteven Rostedt	print "No test case specified.\n";
999c4261d0fSSteven Rostedt	get_test_case;
10000df213caSSteven Rostedt    }
10010df213caSSteven Rostedt
1002a75fececSSteven Rostedt    # set any defaults
1003a75fececSSteven Rostedt
1004a75fececSSteven Rostedt    foreach my $default (keys %default) {
1005a75fececSSteven Rostedt	if (!defined($opt{$default})) {
1006a75fececSSteven Rostedt	    $opt{$default} = $default{$default};
1007a75fececSSteven Rostedt	}
1008a75fececSSteven Rostedt    }
10099cc9e091SSteven Rostedt
10109cc9e091SSteven Rostedt    if ($opt{"IGNORE_UNUSED"} == 1) {
10119cc9e091SSteven Rostedt	return;
10129cc9e091SSteven Rostedt    }
10139cc9e091SSteven Rostedt
10149cc9e091SSteven Rostedt    my %not_used;
10159cc9e091SSteven Rostedt
10169cc9e091SSteven Rostedt    # check if there are any stragglers (typos?)
10179cc9e091SSteven Rostedt    foreach my $option (keys %opt) {
10189cc9e091SSteven Rostedt	my $op = $option;
10199cc9e091SSteven Rostedt	# remove per test labels.
10209cc9e091SSteven Rostedt	$op =~ s/\[.*\]//;
10219cc9e091SSteven Rostedt	if (!exists($option_map{$op}) &&
10229cc9e091SSteven Rostedt	    !exists($default{$op}) &&
10239cc9e091SSteven Rostedt	    !exists($used_options{$op})) {
10249cc9e091SSteven Rostedt	    $not_used{$op} = 1;
10259cc9e091SSteven Rostedt	}
10269cc9e091SSteven Rostedt    }
10279cc9e091SSteven Rostedt
10289cc9e091SSteven Rostedt    if (%not_used) {
10299cc9e091SSteven Rostedt	my $s = "s are";
10309cc9e091SSteven Rostedt	$s = " is" if (keys %not_used == 1);
10319cc9e091SSteven Rostedt	print "The following option$s not used; could be a typo:\n";
10329cc9e091SSteven Rostedt	foreach my $option (keys %not_used) {
10339cc9e091SSteven Rostedt	    print "$option\n";
10349cc9e091SSteven Rostedt	}
10359cc9e091SSteven Rostedt	print "Set IGRNORE_UNUSED = 1 to have ktest ignore unused variables\n";
10369cc9e091SSteven Rostedt	if (!read_yn "Do you want to continue?") {
10379cc9e091SSteven Rostedt	    exit -1;
10389cc9e091SSteven Rostedt	}
10399cc9e091SSteven Rostedt    }
10402545eb61SSteven Rostedt}
10412545eb61SSteven Rostedt
104223715c3cSSteven Rostedtsub __eval_option {
104323715c3cSSteven Rostedt    my ($option, $i) = @_;
104423715c3cSSteven Rostedt
104523715c3cSSteven Rostedt    # Add space to evaluate the character before $
104623715c3cSSteven Rostedt    $option = " $option";
104723715c3cSSteven Rostedt    my $retval = "";
1048f9dfb65bSRabin Vincent    my $repeated = 0;
1049f9dfb65bSRabin Vincent    my $parent = 0;
1050f9dfb65bSRabin Vincent
1051f9dfb65bSRabin Vincent    foreach my $test (keys %repeat_tests) {
1052f9dfb65bSRabin Vincent	if ($i >= $test &&
1053f9dfb65bSRabin Vincent	    $i < $test + $repeat_tests{$test}) {
1054f9dfb65bSRabin Vincent
1055f9dfb65bSRabin Vincent	    $repeated = 1;
1056f9dfb65bSRabin Vincent	    $parent = $test;
1057f9dfb65bSRabin Vincent	    last;
1058f9dfb65bSRabin Vincent	}
1059f9dfb65bSRabin Vincent    }
106023715c3cSSteven Rostedt
106123715c3cSSteven Rostedt    while ($option =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) {
106223715c3cSSteven Rostedt	my $start = $1;
106323715c3cSSteven Rostedt	my $var = $2;
106423715c3cSSteven Rostedt	my $end = $3;
106523715c3cSSteven Rostedt
106623715c3cSSteven Rostedt	# Append beginning of line
106723715c3cSSteven Rostedt	$retval = "$retval$start";
106823715c3cSSteven Rostedt
106923715c3cSSteven Rostedt	# If the iteration option OPT[$i] exists, then use that.
107023715c3cSSteven Rostedt	# otherwise see if the default OPT (without [$i]) exists.
107123715c3cSSteven Rostedt
107223715c3cSSteven Rostedt	my $o = "$var\[$i\]";
1073f9dfb65bSRabin Vincent	my $parento = "$var\[$parent\]";
107423715c3cSSteven Rostedt
107523715c3cSSteven Rostedt	if (defined($opt{$o})) {
107623715c3cSSteven Rostedt	    $o = $opt{$o};
107723715c3cSSteven Rostedt	    $retval = "$retval$o";
1078f9dfb65bSRabin Vincent	} elsif ($repeated && defined($opt{$parento})) {
1079f9dfb65bSRabin Vincent	    $o = $opt{$parento};
1080f9dfb65bSRabin Vincent	    $retval = "$retval$o";
108123715c3cSSteven Rostedt	} elsif (defined($opt{$var})) {
108223715c3cSSteven Rostedt	    $o = $opt{$var};
108323715c3cSSteven Rostedt	    $retval = "$retval$o";
108423715c3cSSteven Rostedt	} else {
108523715c3cSSteven Rostedt	    $retval = "$retval\$\{$var\}";
108623715c3cSSteven Rostedt	}
108723715c3cSSteven Rostedt
108823715c3cSSteven Rostedt	$option = $end;
108923715c3cSSteven Rostedt    }
109023715c3cSSteven Rostedt
109123715c3cSSteven Rostedt    $retval = "$retval$option";
109223715c3cSSteven Rostedt
109323715c3cSSteven Rostedt    $retval =~ s/^ //;
109423715c3cSSteven Rostedt
109523715c3cSSteven Rostedt    return $retval;
109623715c3cSSteven Rostedt}
109723715c3cSSteven Rostedt
109823715c3cSSteven Rostedtsub eval_option {
109923715c3cSSteven Rostedt    my ($option, $i) = @_;
110023715c3cSSteven Rostedt
110123715c3cSSteven Rostedt    my $prev = "";
110223715c3cSSteven Rostedt
110323715c3cSSteven Rostedt    # Since an option can evaluate to another option,
110423715c3cSSteven Rostedt    # keep iterating until we do not evaluate any more
110523715c3cSSteven Rostedt    # options.
110623715c3cSSteven Rostedt    my $r = 0;
110723715c3cSSteven Rostedt    while ($prev ne $option) {
110823715c3cSSteven Rostedt	# Check for recursive evaluations.
110923715c3cSSteven Rostedt	# 100 deep should be more than enough.
111023715c3cSSteven Rostedt	if ($r++ > 100) {
111123715c3cSSteven Rostedt	    die "Over 100 evaluations accurred with $option\n" .
111223715c3cSSteven Rostedt		"Check for recursive variables\n";
111323715c3cSSteven Rostedt	}
111423715c3cSSteven Rostedt	$prev = $option;
111523715c3cSSteven Rostedt	$option = __eval_option($option, $i);
111623715c3cSSteven Rostedt    }
111723715c3cSSteven Rostedt
111823715c3cSSteven Rostedt    return $option;
111923715c3cSSteven Rostedt}
112023715c3cSSteven Rostedt
1121d1e2f22aSSteven Rostedtsub _logit {
11222545eb61SSteven Rostedt    if (defined($opt{"LOG_FILE"})) {
11232545eb61SSteven Rostedt	open(OUT, ">> $opt{LOG_FILE}") or die "Can't write to $opt{LOG_FILE}";
11242545eb61SSteven Rostedt	print OUT @_;
11252545eb61SSteven Rostedt	close(OUT);
11262545eb61SSteven Rostedt    }
11272545eb61SSteven Rostedt}
11282545eb61SSteven Rostedt
1129d1e2f22aSSteven Rostedtsub logit {
1130d1e2f22aSSteven Rostedt    if (defined($opt{"LOG_FILE"})) {
1131d1e2f22aSSteven Rostedt	_logit @_;
1132d1e2f22aSSteven Rostedt    } else {
1133d1e2f22aSSteven Rostedt	print @_;
1134d1e2f22aSSteven Rostedt    }
1135d1e2f22aSSteven Rostedt}
1136d1e2f22aSSteven Rostedt
11375f9b6cedSSteven Rostedtsub doprint {
11385f9b6cedSSteven Rostedt    print @_;
1139d1e2f22aSSteven Rostedt    _logit @_;
11405f9b6cedSSteven Rostedt}
11415f9b6cedSSteven Rostedt
11427faafbd6SSteven Rostedtsub run_command;
11432728be41SAndrew Jonessub start_monitor;
11442728be41SAndrew Jonessub end_monitor;
11452728be41SAndrew Jonessub wait_for_monitor;
11467faafbd6SSteven Rostedt
11477faafbd6SSteven Rostedtsub reboot {
11482728be41SAndrew Jones    my ($time) = @_;
11492728be41SAndrew Jones
11502b803365SSteven Rostedt    if (defined($time)) {
11512b803365SSteven Rostedt	start_monitor;
11522b803365SSteven Rostedt	# flush out current monitor
11532b803365SSteven Rostedt	# May contain the reboot success line
11542b803365SSteven Rostedt	wait_for_monitor 1;
11552b803365SSteven Rostedt    }
11562b803365SSteven Rostedt
11577faafbd6SSteven Rostedt    # try to reboot normally
1158e48c5293SSteven Rostedt    if (run_command $reboot) {
1159576f627cSSteven Rostedt	if (defined($powercycle_after_reboot)) {
1160576f627cSSteven Rostedt	    sleep $powercycle_after_reboot;
1161576f627cSSteven Rostedt	    run_command "$power_cycle";
1162576f627cSSteven Rostedt	}
1163576f627cSSteven Rostedt    } else {
11647faafbd6SSteven Rostedt	# nope? power cycle it.
1165a75fececSSteven Rostedt	run_command "$power_cycle";
11667faafbd6SSteven Rostedt    }
11672728be41SAndrew Jones
11682728be41SAndrew Jones    if (defined($time)) {
1169407b95b7SSteven Rostedt	if (wait_for_monitor($time, $reboot_success_line)) {
1170407b95b7SSteven Rostedt	    # reboot got stuck?
11718a80c727SSteven Rostedt	    doprint "Reboot did not finish. Forcing power cycle\n";
1172407b95b7SSteven Rostedt	    run_command "$power_cycle";
1173407b95b7SSteven Rostedt	}
11742728be41SAndrew Jones	end_monitor;
11752728be41SAndrew Jones    }
11767faafbd6SSteven Rostedt}
11777faafbd6SSteven Rostedt
1178bc7c5803SSteven Rostedtsub reboot_to_good {
1179bc7c5803SSteven Rostedt    my ($time) = @_;
1180bc7c5803SSteven Rostedt
1181bc7c5803SSteven Rostedt    if (defined($switch_to_good)) {
1182bc7c5803SSteven Rostedt	run_command $switch_to_good;
1183bc7c5803SSteven Rostedt    }
1184bc7c5803SSteven Rostedt
1185bc7c5803SSteven Rostedt    reboot $time;
1186bc7c5803SSteven Rostedt}
1187bc7c5803SSteven Rostedt
1188576f627cSSteven Rostedtsub do_not_reboot {
1189576f627cSSteven Rostedt    my $i = $iteration;
1190576f627cSSteven Rostedt
11914ab1cce5SSteven Rostedt    return $test_type eq "build" || $no_reboot ||
1192576f627cSSteven Rostedt	($test_type eq "patchcheck" && $opt{"PATCHCHECK_TYPE[$i]"} eq "build") ||
1193576f627cSSteven Rostedt	($test_type eq "bisect" && $opt{"BISECT_TYPE[$i]"} eq "build");
1194576f627cSSteven Rostedt}
1195576f627cSSteven Rostedt
11965c42fc5bSSteven Rostedtsub dodie {
11975a391fbfSSteven Rostedt    doprint "CRITICAL FAILURE... ", @_, "\n";
11985c42fc5bSSteven Rostedt
1199576f627cSSteven Rostedt    my $i = $iteration;
1200576f627cSSteven Rostedt
1201576f627cSSteven Rostedt    if ($reboot_on_error && !do_not_reboot) {
1202576f627cSSteven Rostedt
120375c3fda7SSteven Rostedt	doprint "REBOOTING\n";
1204bc7c5803SSteven Rostedt	reboot_to_good;
120575c3fda7SSteven Rostedt
1206a75fececSSteven Rostedt    } elsif ($poweroff_on_error && defined($power_off)) {
12075c42fc5bSSteven Rostedt	doprint "POWERING OFF\n";
1208a75fececSSteven Rostedt	`$power_off`;
12095c42fc5bSSteven Rostedt    }
121075c3fda7SSteven Rostedt
1211f80802cbSSteven Rostedt    if (defined($opt{"LOG_FILE"})) {
1212f80802cbSSteven Rostedt	print " See $opt{LOG_FILE} for more info.\n";
1213f80802cbSSteven Rostedt    }
1214f80802cbSSteven Rostedt
1215576f627cSSteven Rostedt    die @_, "\n";
12165c42fc5bSSteven Rostedt}
12175c42fc5bSSteven Rostedt
12187faafbd6SSteven Rostedtsub open_console {
12197faafbd6SSteven Rostedt    my ($fp) = @_;
12207faafbd6SSteven Rostedt
12217faafbd6SSteven Rostedt    my $flags;
12227faafbd6SSteven Rostedt
1223a75fececSSteven Rostedt    my $pid = open($fp, "$console|") or
1224a75fececSSteven Rostedt	dodie "Can't open console $console";
12257faafbd6SSteven Rostedt
12267faafbd6SSteven Rostedt    $flags = fcntl($fp, F_GETFL, 0) or
1227576f627cSSteven Rostedt	dodie "Can't get flags for the socket: $!";
12287faafbd6SSteven Rostedt    $flags = fcntl($fp, F_SETFL, $flags | O_NONBLOCK) or
1229576f627cSSteven Rostedt	dodie "Can't set flags for the socket: $!";
12307faafbd6SSteven Rostedt
12317faafbd6SSteven Rostedt    return $pid;
12327faafbd6SSteven Rostedt}
12337faafbd6SSteven Rostedt
12347faafbd6SSteven Rostedtsub close_console {
12357faafbd6SSteven Rostedt    my ($fp, $pid) = @_;
12367faafbd6SSteven Rostedt
12377faafbd6SSteven Rostedt    doprint "kill child process $pid\n";
12387faafbd6SSteven Rostedt    kill 2, $pid;
12397faafbd6SSteven Rostedt
12407faafbd6SSteven Rostedt    print "closing!\n";
12417faafbd6SSteven Rostedt    close($fp);
12427faafbd6SSteven Rostedt}
12437faafbd6SSteven Rostedt
12447faafbd6SSteven Rostedtsub start_monitor {
12457faafbd6SSteven Rostedt    if ($monitor_cnt++) {
12467faafbd6SSteven Rostedt	return;
12477faafbd6SSteven Rostedt    }
12487faafbd6SSteven Rostedt    $monitor_fp = \*MONFD;
12497faafbd6SSteven Rostedt    $monitor_pid = open_console $monitor_fp;
1250a75fececSSteven Rostedt
1251a75fececSSteven Rostedt    return;
1252a75fececSSteven Rostedt
1253a75fececSSteven Rostedt    open(MONFD, "Stop perl from warning about single use of MONFD");
12547faafbd6SSteven Rostedt}
12557faafbd6SSteven Rostedt
12567faafbd6SSteven Rostedtsub end_monitor {
12577faafbd6SSteven Rostedt    if (--$monitor_cnt) {
12587faafbd6SSteven Rostedt	return;
12597faafbd6SSteven Rostedt    }
12607faafbd6SSteven Rostedt    close_console($monitor_fp, $monitor_pid);
12617faafbd6SSteven Rostedt}
12627faafbd6SSteven Rostedt
12637faafbd6SSteven Rostedtsub wait_for_monitor {
12642b803365SSteven Rostedt    my ($time, $stop) = @_;
12652b803365SSteven Rostedt    my $full_line = "";
12667faafbd6SSteven Rostedt    my $line;
12672b803365SSteven Rostedt    my $booted = 0;
1268407b95b7SSteven Rostedt    my $start_time = time;
12698a80c727SSteven Rostedt    my $skip_call_trace = 0;
12708a80c727SSteven Rostedt    my $bug = 0;
12718a80c727SSteven Rostedt    my $bug_ignored = 0;
1272407b95b7SSteven Rostedt    my $now;
12737faafbd6SSteven Rostedt
1274a75fececSSteven Rostedt    doprint "** Wait for monitor to settle down **\n";
12757faafbd6SSteven Rostedt
12767faafbd6SSteven Rostedt    # read the monitor and wait for the system to calm down
12772b803365SSteven Rostedt    while (!$booted) {
12787faafbd6SSteven Rostedt	$line = wait_for_input($monitor_fp, $time);
12792b803365SSteven Rostedt	last if (!defined($line));
12802b803365SSteven Rostedt	print "$line";
12812b803365SSteven Rostedt	$full_line .= $line;
12822b803365SSteven Rostedt
12832b803365SSteven Rostedt	if (defined($stop) && $full_line =~ /$stop/) {
12842b803365SSteven Rostedt	    doprint "wait for monitor detected $stop\n";
12852b803365SSteven Rostedt	    $booted = 1;
12862b803365SSteven Rostedt	}
12872b803365SSteven Rostedt
12888a80c727SSteven Rostedt	if ($full_line =~ /\[ backtrace testing \]/) {
12898a80c727SSteven Rostedt	    $skip_call_trace = 1;
12908a80c727SSteven Rostedt	}
12918a80c727SSteven Rostedt
12928a80c727SSteven Rostedt	if ($full_line =~ /call trace:/i) {
12938a80c727SSteven Rostedt	    if (!$bug && !$skip_call_trace) {
12948a80c727SSteven Rostedt		if ($ignore_errors) {
12958a80c727SSteven Rostedt		    $bug_ignored = 1;
12968a80c727SSteven Rostedt		} else {
12978a80c727SSteven Rostedt		    $bug = 1;
12988a80c727SSteven Rostedt		}
12998a80c727SSteven Rostedt	    }
13008a80c727SSteven Rostedt	}
13018a80c727SSteven Rostedt
13028a80c727SSteven Rostedt	if ($full_line =~ /\[ end of backtrace testing \]/) {
13038a80c727SSteven Rostedt	    $skip_call_trace = 0;
13048a80c727SSteven Rostedt	}
13058a80c727SSteven Rostedt
13068a80c727SSteven Rostedt	if ($full_line =~ /Kernel panic -/) {
13078a80c727SSteven Rostedt	    $bug = 1;
13088a80c727SSteven Rostedt	}
13098a80c727SSteven Rostedt
13102b803365SSteven Rostedt	if ($line =~ /\n/) {
13112b803365SSteven Rostedt	    $full_line = "";
13122b803365SSteven Rostedt	}
1313407b95b7SSteven Rostedt	$now = time;
1314407b95b7SSteven Rostedt	if ($now - $start_time >= $max_monitor_wait) {
1315407b95b7SSteven Rostedt	    doprint "Exiting monitor flush due to hitting MAX_MONITOR_WAIT\n";
1316407b95b7SSteven Rostedt	    return 1;
1317407b95b7SSteven Rostedt	}
13182b803365SSteven Rostedt    }
1319a75fececSSteven Rostedt    print "** Monitor flushed **\n";
13208a80c727SSteven Rostedt    return $bug;
13217faafbd6SSteven Rostedt}
13227faafbd6SSteven Rostedt
1323de5b6e3bSRabin Vincentsub save_logs {
1324de5b6e3bSRabin Vincent	my ($result, $basedir) = @_;
1325de5b6e3bSRabin Vincent	my @t = localtime;
1326de5b6e3bSRabin Vincent	my $date = sprintf "%04d%02d%02d%02d%02d%02d",
1327de5b6e3bSRabin Vincent		1900+$t[5],$t[4],$t[3],$t[2],$t[1],$t[0];
1328de5b6e3bSRabin Vincent
1329de5b6e3bSRabin Vincent	my $type = $build_type;
1330de5b6e3bSRabin Vincent	if ($type =~ /useconfig/) {
1331de5b6e3bSRabin Vincent	    $type = "useconfig";
1332de5b6e3bSRabin Vincent	}
1333de5b6e3bSRabin Vincent
1334de5b6e3bSRabin Vincent	my $dir = "$machine-$test_type-$type-$result-$date";
1335de5b6e3bSRabin Vincent
1336de5b6e3bSRabin Vincent	$dir = "$basedir/$dir";
1337de5b6e3bSRabin Vincent
1338de5b6e3bSRabin Vincent	if (!-d $dir) {
1339de5b6e3bSRabin Vincent	    mkpath($dir) or
1340de5b6e3bSRabin Vincent		die "can't create $dir";
1341de5b6e3bSRabin Vincent	}
1342de5b6e3bSRabin Vincent
1343de5b6e3bSRabin Vincent	my %files = (
1344de5b6e3bSRabin Vincent		"config" => $output_config,
1345de5b6e3bSRabin Vincent		"buildlog" => $buildlog,
1346de5b6e3bSRabin Vincent		"dmesg" => $dmesg,
1347de5b6e3bSRabin Vincent		"testlog" => $testlog,
1348de5b6e3bSRabin Vincent	);
1349de5b6e3bSRabin Vincent
1350de5b6e3bSRabin Vincent	while (my ($name, $source) = each(%files)) {
1351de5b6e3bSRabin Vincent		if (-f "$source") {
1352de5b6e3bSRabin Vincent			cp "$source", "$dir/$name" or
1353de5b6e3bSRabin Vincent				die "failed to copy $source";
1354de5b6e3bSRabin Vincent		}
1355de5b6e3bSRabin Vincent	}
1356de5b6e3bSRabin Vincent
1357de5b6e3bSRabin Vincent	doprint "*** Saved info to $dir ***\n";
1358de5b6e3bSRabin Vincent}
1359de5b6e3bSRabin Vincent
13602b7d9b21SSteven Rostedtsub fail {
13612b7d9b21SSteven Rostedt
1362921ed4c7SSteven Rostedt	if (defined($post_test)) {
1363921ed4c7SSteven Rostedt		run_command $post_test;
1364921ed4c7SSteven Rostedt	}
1365921ed4c7SSteven Rostedt
1366a75fececSSteven Rostedt	if ($die_on_failure) {
13672b7d9b21SSteven Rostedt		dodie @_;
13682b7d9b21SSteven Rostedt	}
13692b7d9b21SSteven Rostedt
1370a75fececSSteven Rostedt	doprint "FAILED\n";
13717faafbd6SSteven Rostedt
1372576f627cSSteven Rostedt	my $i = $iteration;
1373576f627cSSteven Rostedt
1374a75fececSSteven Rostedt	# no need to reboot for just building.
1375576f627cSSteven Rostedt	if (!do_not_reboot) {
13767faafbd6SSteven Rostedt	    doprint "REBOOTING\n";
1377bc7c5803SSteven Rostedt	    reboot_to_good $sleep_time;
1378a75fececSSteven Rostedt	}
13797faafbd6SSteven Rostedt
13809064af52SSteven Rostedt	my $name = "";
13819064af52SSteven Rostedt
13829064af52SSteven Rostedt	if (defined($test_name)) {
13839064af52SSteven Rostedt	    $name = " ($test_name)";
13849064af52SSteven Rostedt	}
13859064af52SSteven Rostedt
1386576f627cSSteven Rostedt	doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
1387576f627cSSteven Rostedt	doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
13889064af52SSteven Rostedt	doprint "KTEST RESULT: TEST $i$name Failed: ", @_, "\n";
1389576f627cSSteven Rostedt	doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
1390576f627cSSteven Rostedt	doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
1391a75fececSSteven Rostedt
1392de5b6e3bSRabin Vincent	if (defined($store_failures)) {
1393de5b6e3bSRabin Vincent	    save_logs "fail", $store_failures;
1394cccae1a6SSteven Rostedt        }
1395cccae1a6SSteven Rostedt
13962b7d9b21SSteven Rostedt	return 1;
13972b7d9b21SSteven Rostedt}
13982b7d9b21SSteven Rostedt
13992545eb61SSteven Rostedtsub run_command {
14002545eb61SSteven Rostedt    my ($command) = @_;
1401d6ce2a0bSSteven Rostedt    my $dolog = 0;
1402d6ce2a0bSSteven Rostedt    my $dord = 0;
1403d6ce2a0bSSteven Rostedt    my $pid;
1404d6ce2a0bSSteven Rostedt
1405e48c5293SSteven Rostedt    $command =~ s/\$SSH_USER/$ssh_user/g;
1406e48c5293SSteven Rostedt    $command =~ s/\$MACHINE/$machine/g;
1407e48c5293SSteven Rostedt
1408d6ce2a0bSSteven Rostedt    doprint("$command ... ");
1409d6ce2a0bSSteven Rostedt
1410d6ce2a0bSSteven Rostedt    $pid = open(CMD, "$command 2>&1 |") or
14112b7d9b21SSteven Rostedt	(fail "unable to exec $command" and return 0);
14122545eb61SSteven Rostedt
14132545eb61SSteven Rostedt    if (defined($opt{"LOG_FILE"})) {
1414d6ce2a0bSSteven Rostedt	open(LOG, ">>$opt{LOG_FILE}") or
1415d6ce2a0bSSteven Rostedt	    dodie "failed to write to log";
1416d6ce2a0bSSteven Rostedt	$dolog = 1;
14176c5ee0beSSteven Rostedt    }
14186c5ee0beSSteven Rostedt
14196c5ee0beSSteven Rostedt    if (defined($redirect)) {
1420d6ce2a0bSSteven Rostedt	open (RD, ">$redirect") or
1421d6ce2a0bSSteven Rostedt	    dodie "failed to write to redirect $redirect";
1422d6ce2a0bSSteven Rostedt	$dord = 1;
14232545eb61SSteven Rostedt    }
14242545eb61SSteven Rostedt
1425d6ce2a0bSSteven Rostedt    while (<CMD>) {
1426d6ce2a0bSSteven Rostedt	print LOG if ($dolog);
1427d6ce2a0bSSteven Rostedt	print RD  if ($dord);
1428d6ce2a0bSSteven Rostedt    }
14292545eb61SSteven Rostedt
1430d6ce2a0bSSteven Rostedt    waitpid($pid, 0);
14312545eb61SSteven Rostedt    my $failed = $?;
14322545eb61SSteven Rostedt
1433d6ce2a0bSSteven Rostedt    close(CMD);
1434d6ce2a0bSSteven Rostedt    close(LOG) if ($dolog);
1435d6ce2a0bSSteven Rostedt    close(RD)  if ($dord);
1436d6ce2a0bSSteven Rostedt
14372545eb61SSteven Rostedt    if ($failed) {
14382545eb61SSteven Rostedt	doprint "FAILED!\n";
14392545eb61SSteven Rostedt    } else {
14402545eb61SSteven Rostedt	doprint "SUCCESS\n";
14412545eb61SSteven Rostedt    }
14422545eb61SSteven Rostedt
14435f9b6cedSSteven Rostedt    return !$failed;
14445f9b6cedSSteven Rostedt}
14455f9b6cedSSteven Rostedt
1446e48c5293SSteven Rostedtsub run_ssh {
1447e48c5293SSteven Rostedt    my ($cmd) = @_;
1448e48c5293SSteven Rostedt    my $cp_exec = $ssh_exec;
1449e48c5293SSteven Rostedt
1450e48c5293SSteven Rostedt    $cp_exec =~ s/\$SSH_COMMAND/$cmd/g;
1451e48c5293SSteven Rostedt    return run_command "$cp_exec";
1452e48c5293SSteven Rostedt}
1453e48c5293SSteven Rostedt
1454e48c5293SSteven Rostedtsub run_scp {
145502ad2617SSteven Rostedt    my ($src, $dst, $cp_scp) = @_;
1456e48c5293SSteven Rostedt
1457e48c5293SSteven Rostedt    $cp_scp =~ s/\$SRC_FILE/$src/g;
1458e48c5293SSteven Rostedt    $cp_scp =~ s/\$DST_FILE/$dst/g;
1459e48c5293SSteven Rostedt
1460e48c5293SSteven Rostedt    return run_command "$cp_scp";
1461e48c5293SSteven Rostedt}
1462e48c5293SSteven Rostedt
146302ad2617SSteven Rostedtsub run_scp_install {
146402ad2617SSteven Rostedt    my ($src, $dst) = @_;
146502ad2617SSteven Rostedt
146602ad2617SSteven Rostedt    my $cp_scp = $scp_to_target_install;
146702ad2617SSteven Rostedt
146802ad2617SSteven Rostedt    return run_scp($src, $dst, $cp_scp);
146902ad2617SSteven Rostedt}
147002ad2617SSteven Rostedt
147102ad2617SSteven Rostedtsub run_scp_mod {
147202ad2617SSteven Rostedt    my ($src, $dst) = @_;
147302ad2617SSteven Rostedt
147402ad2617SSteven Rostedt    my $cp_scp = $scp_to_target;
147502ad2617SSteven Rostedt
147602ad2617SSteven Rostedt    return run_scp($src, $dst, $cp_scp);
147702ad2617SSteven Rostedt}
147802ad2617SSteven Rostedt
1479*a15ba913SSteven Rostedtsub get_grub2_index {
1480*a15ba913SSteven Rostedt
1481*a15ba913SSteven Rostedt    return if (defined($grub_number));
1482*a15ba913SSteven Rostedt
1483*a15ba913SSteven Rostedt    doprint "Find grub2 menu ... ";
1484*a15ba913SSteven Rostedt    $grub_number = -1;
1485*a15ba913SSteven Rostedt
1486*a15ba913SSteven Rostedt    my $ssh_grub = $ssh_exec;
1487*a15ba913SSteven Rostedt    $ssh_grub =~ s,\$SSH_COMMAND,cat $grub_file,g;
1488*a15ba913SSteven Rostedt
1489*a15ba913SSteven Rostedt    open(IN, "$ssh_grub |")
1490*a15ba913SSteven Rostedt	or die "unable to get $grub_file";
1491*a15ba913SSteven Rostedt
1492*a15ba913SSteven Rostedt    my $found = 0;
1493*a15ba913SSteven Rostedt
1494*a15ba913SSteven Rostedt    while (<IN>) {
1495*a15ba913SSteven Rostedt	if (/^menuentry.*$grub_menu/) {
1496*a15ba913SSteven Rostedt	    $grub_number++;
1497*a15ba913SSteven Rostedt	    $found = 1;
1498*a15ba913SSteven Rostedt	    last;
1499*a15ba913SSteven Rostedt	} elsif (/^menuentry\s/) {
1500*a15ba913SSteven Rostedt	    $grub_number++;
1501*a15ba913SSteven Rostedt	}
1502*a15ba913SSteven Rostedt    }
1503*a15ba913SSteven Rostedt    close(IN);
1504*a15ba913SSteven Rostedt
1505*a15ba913SSteven Rostedt    die "Could not find '$grub_menu' in $grub_file on $machine"
1506*a15ba913SSteven Rostedt	if (!$found);
1507*a15ba913SSteven Rostedt    doprint "$grub_number\n";
1508*a15ba913SSteven Rostedt}
1509*a15ba913SSteven Rostedt
15105f9b6cedSSteven Rostedtsub get_grub_index {
15115f9b6cedSSteven Rostedt
1512*a15ba913SSteven Rostedt    if ($reboot_type eq "grub2") {
1513*a15ba913SSteven Rostedt	get_grub2_index;
1514*a15ba913SSteven Rostedt	return;
1515*a15ba913SSteven Rostedt    }
1516*a15ba913SSteven Rostedt
1517a75fececSSteven Rostedt    if ($reboot_type ne "grub") {
1518a75fececSSteven Rostedt	return;
1519a75fececSSteven Rostedt    }
15205a391fbfSSteven Rostedt    return if (defined($grub_number));
15215f9b6cedSSteven Rostedt
15225f9b6cedSSteven Rostedt    doprint "Find grub menu ... ";
15235f9b6cedSSteven Rostedt    $grub_number = -1;
1524e48c5293SSteven Rostedt
1525e48c5293SSteven Rostedt    my $ssh_grub = $ssh_exec;
1526e48c5293SSteven Rostedt    $ssh_grub =~ s,\$SSH_COMMAND,cat /boot/grub/menu.lst,g;
1527e48c5293SSteven Rostedt
1528e48c5293SSteven Rostedt    open(IN, "$ssh_grub |")
15295f9b6cedSSteven Rostedt	or die "unable to get menu.lst";
1530e48c5293SSteven Rostedt
1531eaa1fe25SSteven Rostedt    my $found = 0;
1532eaa1fe25SSteven Rostedt
15335f9b6cedSSteven Rostedt    while (<IN>) {
1534a75fececSSteven Rostedt	if (/^\s*title\s+$grub_menu\s*$/) {
15355f9b6cedSSteven Rostedt	    $grub_number++;
1536eaa1fe25SSteven Rostedt	    $found = 1;
15375f9b6cedSSteven Rostedt	    last;
15385f9b6cedSSteven Rostedt	} elsif (/^\s*title\s/) {
15395f9b6cedSSteven Rostedt	    $grub_number++;
15405f9b6cedSSteven Rostedt	}
15415f9b6cedSSteven Rostedt    }
15425f9b6cedSSteven Rostedt    close(IN);
15435f9b6cedSSteven Rostedt
1544a75fececSSteven Rostedt    die "Could not find '$grub_menu' in /boot/grub/menu on $machine"
1545eaa1fe25SSteven Rostedt	if (!$found);
15465f9b6cedSSteven Rostedt    doprint "$grub_number\n";
15472545eb61SSteven Rostedt}
15482545eb61SSteven Rostedt
15492545eb61SSteven Rostedtsub wait_for_input
15502545eb61SSteven Rostedt{
15512545eb61SSteven Rostedt    my ($fp, $time) = @_;
15522545eb61SSteven Rostedt    my $rin;
15532545eb61SSteven Rostedt    my $ready;
15542545eb61SSteven Rostedt    my $line;
15552545eb61SSteven Rostedt    my $ch;
15562545eb61SSteven Rostedt
15572545eb61SSteven Rostedt    if (!defined($time)) {
15582545eb61SSteven Rostedt	$time = $timeout;
15592545eb61SSteven Rostedt    }
15602545eb61SSteven Rostedt
15612545eb61SSteven Rostedt    $rin = '';
15622545eb61SSteven Rostedt    vec($rin, fileno($fp), 1) = 1;
15632545eb61SSteven Rostedt    $ready = select($rin, undef, undef, $time);
15642545eb61SSteven Rostedt
15652545eb61SSteven Rostedt    $line = "";
15662545eb61SSteven Rostedt
15672545eb61SSteven Rostedt    # try to read one char at a time
15682545eb61SSteven Rostedt    while (sysread $fp, $ch, 1) {
15692545eb61SSteven Rostedt	$line .= $ch;
15702545eb61SSteven Rostedt	last if ($ch eq "\n");
15712545eb61SSteven Rostedt    }
15722545eb61SSteven Rostedt
15732545eb61SSteven Rostedt    if (!length($line)) {
15742545eb61SSteven Rostedt	return undef;
15752545eb61SSteven Rostedt    }
15762545eb61SSteven Rostedt
15772545eb61SSteven Rostedt    return $line;
15782545eb61SSteven Rostedt}
15792545eb61SSteven Rostedt
158075c3fda7SSteven Rostedtsub reboot_to {
1581bc7c5803SSteven Rostedt    if (defined($switch_to_test)) {
1582bc7c5803SSteven Rostedt	run_command $switch_to_test;
1583bc7c5803SSteven Rostedt    }
1584bc7c5803SSteven Rostedt
1585a75fececSSteven Rostedt    if ($reboot_type eq "grub") {
1586c54367f9SSteven Rostedt	run_ssh "'(echo \"savedefault --default=$grub_number --once\" | grub --batch)'";
1587*a15ba913SSteven Rostedt    } elsif ($reboot_type eq "grub2") {
1588*a15ba913SSteven Rostedt	run_ssh "$grub_reboot $grub_number";
158996f6a0dfSSteven Rostedt    } elsif (defined $reboot_script) {
1590a75fececSSteven Rostedt	run_command "$reboot_script";
15912545eb61SSteven Rostedt    }
159296f6a0dfSSteven Rostedt    reboot;
159396f6a0dfSSteven Rostedt}
15942545eb61SSteven Rostedt
1595a57419b3SSteven Rostedtsub get_sha1 {
1596a57419b3SSteven Rostedt    my ($commit) = @_;
1597a57419b3SSteven Rostedt
1598a57419b3SSteven Rostedt    doprint "git rev-list --max-count=1 $commit ... ";
1599a57419b3SSteven Rostedt    my $sha1 = `git rev-list --max-count=1 $commit`;
1600a57419b3SSteven Rostedt    my $ret = $?;
1601a57419b3SSteven Rostedt
1602a57419b3SSteven Rostedt    logit $sha1;
1603a57419b3SSteven Rostedt
1604a57419b3SSteven Rostedt    if ($ret) {
1605a57419b3SSteven Rostedt	doprint "FAILED\n";
1606a57419b3SSteven Rostedt	dodie "Failed to get git $commit";
1607a57419b3SSteven Rostedt    }
1608a57419b3SSteven Rostedt
1609a57419b3SSteven Rostedt    print "SUCCESS\n";
1610a57419b3SSteven Rostedt
1611a57419b3SSteven Rostedt    chomp $sha1;
1612a57419b3SSteven Rostedt
1613a57419b3SSteven Rostedt    return $sha1;
1614a57419b3SSteven Rostedt}
1615a57419b3SSteven Rostedt
16165a391fbfSSteven Rostedtsub monitor {
16172545eb61SSteven Rostedt    my $booted = 0;
16182545eb61SSteven Rostedt    my $bug = 0;
16196ca996ccSSteven Rostedt    my $bug_ignored = 0;
16205c42fc5bSSteven Rostedt    my $skip_call_trace = 0;
16212b7d9b21SSteven Rostedt    my $loops;
16222545eb61SSteven Rostedt
16237faafbd6SSteven Rostedt    wait_for_monitor 5;
16242545eb61SSteven Rostedt
16252545eb61SSteven Rostedt    my $line;
16262545eb61SSteven Rostedt    my $full_line = "";
16272545eb61SSteven Rostedt
16287faafbd6SSteven Rostedt    open(DMESG, "> $dmesg") or
16297faafbd6SSteven Rostedt	die "unable to write to $dmesg";
16302545eb61SSteven Rostedt
163175c3fda7SSteven Rostedt    reboot_to;
16322545eb61SSteven Rostedt
16331c8a617aSSteven Rostedt    my $success_start;
16341c8a617aSSteven Rostedt    my $failure_start;
16352d01b26aSSteven Rostedt    my $monitor_start = time;
16362d01b26aSSteven Rostedt    my $done = 0;
1637f1a5b962SSteven Rostedt    my $version_found = 0;
16381c8a617aSSteven Rostedt
16392d01b26aSSteven Rostedt    while (!$done) {
16402545eb61SSteven Rostedt
1641ecaf8e52SSteven Rostedt	if ($bug && defined($stop_after_failure) &&
1642ecaf8e52SSteven Rostedt	    $stop_after_failure >= 0) {
1643ecaf8e52SSteven Rostedt	    my $time = $stop_after_failure - (time - $failure_start);
1644ecaf8e52SSteven Rostedt	    $line = wait_for_input($monitor_fp, $time);
1645ecaf8e52SSteven Rostedt	    if (!defined($line)) {
1646ecaf8e52SSteven Rostedt		doprint "bug timed out after $booted_timeout seconds\n";
1647ecaf8e52SSteven Rostedt		doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
1648ecaf8e52SSteven Rostedt		last;
1649ecaf8e52SSteven Rostedt	    }
1650ecaf8e52SSteven Rostedt	} elsif ($booted) {
1651a75fececSSteven Rostedt	    $line = wait_for_input($monitor_fp, $booted_timeout);
1652cd4f1d53SSteven Rostedt	    if (!defined($line)) {
1653cd4f1d53SSteven Rostedt		my $s = $booted_timeout == 1 ? "" : "s";
1654cd4f1d53SSteven Rostedt		doprint "Successful boot found: break after $booted_timeout second$s\n";
1655cd4f1d53SSteven Rostedt		last;
1656cd4f1d53SSteven Rostedt	    }
16572b7d9b21SSteven Rostedt	} else {
16587faafbd6SSteven Rostedt	    $line = wait_for_input($monitor_fp);
1659cd4f1d53SSteven Rostedt	    if (!defined($line)) {
1660cd4f1d53SSteven Rostedt		my $s = $timeout == 1 ? "" : "s";
1661cd4f1d53SSteven Rostedt		doprint "Timed out after $timeout second$s\n";
1662cd4f1d53SSteven Rostedt		last;
16632b7d9b21SSteven Rostedt	    }
1664cd4f1d53SSteven Rostedt	}
16652545eb61SSteven Rostedt
16662545eb61SSteven Rostedt	doprint $line;
16677faafbd6SSteven Rostedt	print DMESG $line;
16682545eb61SSteven Rostedt
16692545eb61SSteven Rostedt	# we are not guaranteed to get a full line
16702545eb61SSteven Rostedt	$full_line .= $line;
16712545eb61SSteven Rostedt
1672a75fececSSteven Rostedt	if ($full_line =~ /$success_line/) {
16732545eb61SSteven Rostedt	    $booted = 1;
16741c8a617aSSteven Rostedt	    $success_start = time;
16751c8a617aSSteven Rostedt	}
16761c8a617aSSteven Rostedt
16771c8a617aSSteven Rostedt	if ($booted && defined($stop_after_success) &&
16781c8a617aSSteven Rostedt	    $stop_after_success >= 0) {
16791c8a617aSSteven Rostedt	    my $now = time;
16801c8a617aSSteven Rostedt	    if ($now - $success_start >= $stop_after_success) {
16811c8a617aSSteven Rostedt		doprint "Test forced to stop after $stop_after_success seconds after success\n";
16821c8a617aSSteven Rostedt		last;
16831c8a617aSSteven Rostedt	    }
16842545eb61SSteven Rostedt	}
16852545eb61SSteven Rostedt
16865c42fc5bSSteven Rostedt	if ($full_line =~ /\[ backtrace testing \]/) {
16875c42fc5bSSteven Rostedt	    $skip_call_trace = 1;
16885c42fc5bSSteven Rostedt	}
16895c42fc5bSSteven Rostedt
16902545eb61SSteven Rostedt	if ($full_line =~ /call trace:/i) {
16916ca996ccSSteven Rostedt	    if (!$bug && !$skip_call_trace) {
16926ca996ccSSteven Rostedt		if ($ignore_errors) {
16936ca996ccSSteven Rostedt		    $bug_ignored = 1;
16946ca996ccSSteven Rostedt		} else {
16951c8a617aSSteven Rostedt		    $bug = 1;
16961c8a617aSSteven Rostedt		    $failure_start = time;
16971c8a617aSSteven Rostedt		}
16981c8a617aSSteven Rostedt	    }
16996ca996ccSSteven Rostedt	}
17001c8a617aSSteven Rostedt
17011c8a617aSSteven Rostedt	if ($bug && defined($stop_after_failure) &&
17021c8a617aSSteven Rostedt	    $stop_after_failure >= 0) {
17031c8a617aSSteven Rostedt	    my $now = time;
17041c8a617aSSteven Rostedt	    if ($now - $failure_start >= $stop_after_failure) {
17051c8a617aSSteven Rostedt		doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
17061c8a617aSSteven Rostedt		last;
17071c8a617aSSteven Rostedt	    }
17085c42fc5bSSteven Rostedt	}
17095c42fc5bSSteven Rostedt
17105c42fc5bSSteven Rostedt	if ($full_line =~ /\[ end of backtrace testing \]/) {
17115c42fc5bSSteven Rostedt	    $skip_call_trace = 0;
17125c42fc5bSSteven Rostedt	}
17135c42fc5bSSteven Rostedt
17145c42fc5bSSteven Rostedt	if ($full_line =~ /Kernel panic -/) {
171510abf118SSteven Rostedt	    $failure_start = time;
17162545eb61SSteven Rostedt	    $bug = 1;
17172545eb61SSteven Rostedt	}
17182545eb61SSteven Rostedt
1719f1a5b962SSteven Rostedt	# Detect triple faults by testing the banner
1720f1a5b962SSteven Rostedt	if ($full_line =~ /\bLinux version (\S+).*\n/) {
1721f1a5b962SSteven Rostedt	    if ($1 eq $version) {
1722f1a5b962SSteven Rostedt		$version_found = 1;
1723f1a5b962SSteven Rostedt	    } elsif ($version_found && $detect_triplefault) {
1724f1a5b962SSteven Rostedt		# We already booted into the kernel we are testing,
1725f1a5b962SSteven Rostedt		# but now we booted into another kernel?
1726f1a5b962SSteven Rostedt		# Consider this a triple fault.
1727f1a5b962SSteven Rostedt		doprint "Aleady booted in Linux kernel $version, but now\n";
1728f1a5b962SSteven Rostedt		doprint "we booted into Linux kernel $1.\n";
1729f1a5b962SSteven Rostedt		doprint "Assuming that this is a triple fault.\n";
1730f1a5b962SSteven Rostedt		doprint "To disable this: set DETECT_TRIPLE_FAULT to 0\n";
1731f1a5b962SSteven Rostedt		last;
1732f1a5b962SSteven Rostedt	    }
1733f1a5b962SSteven Rostedt	}
1734f1a5b962SSteven Rostedt
17352545eb61SSteven Rostedt	if ($line =~ /\n/) {
17362545eb61SSteven Rostedt	    $full_line = "";
17372545eb61SSteven Rostedt	}
17382d01b26aSSteven Rostedt
17392d01b26aSSteven Rostedt	if ($stop_test_after > 0 && !$booted && !$bug) {
17402d01b26aSSteven Rostedt	    if (time - $monitor_start > $stop_test_after) {
17414d62bf51SSteven Rostedt		doprint "STOP_TEST_AFTER ($stop_test_after seconds) timed out\n";
17422d01b26aSSteven Rostedt		$done = 1;
17432d01b26aSSteven Rostedt	    }
17442d01b26aSSteven Rostedt	}
17452545eb61SSteven Rostedt    }
17462545eb61SSteven Rostedt
17477faafbd6SSteven Rostedt    close(DMESG);
17482545eb61SSteven Rostedt
17492545eb61SSteven Rostedt    if ($bug) {
17502b7d9b21SSteven Rostedt	return 0 if ($in_bisect);
1751576f627cSSteven Rostedt	fail "failed - got a bug report" and return 0;
17522545eb61SSteven Rostedt    }
17535f9b6cedSSteven Rostedt
1754a75fececSSteven Rostedt    if (!$booted) {
1755a75fececSSteven Rostedt	return 0 if ($in_bisect);
1756576f627cSSteven Rostedt	fail "failed - never got a boot prompt." and return 0;
1757a75fececSSteven Rostedt    }
1758a75fececSSteven Rostedt
17596ca996ccSSteven Rostedt    if ($bug_ignored) {
17606ca996ccSSteven Rostedt	doprint "WARNING: Call Trace detected but ignored due to IGNORE_ERRORS=1\n";
17616ca996ccSSteven Rostedt    }
17626ca996ccSSteven Rostedt
17632b7d9b21SSteven Rostedt    return 1;
17642545eb61SSteven Rostedt}
17652545eb61SSteven Rostedt
17662b29b2f8SSteven Rostedtsub eval_kernel_version {
17672b29b2f8SSteven Rostedt    my ($option) = @_;
17682b29b2f8SSteven Rostedt
17692b29b2f8SSteven Rostedt    $option =~ s/\$KERNEL_VERSION/$version/g;
17702b29b2f8SSteven Rostedt
17712b29b2f8SSteven Rostedt    return $option;
17722b29b2f8SSteven Rostedt}
17732b29b2f8SSteven Rostedt
1774db05cfefSSteven Rostedtsub do_post_install {
1775db05cfefSSteven Rostedt
1776db05cfefSSteven Rostedt    return if (!defined($post_install));
1777db05cfefSSteven Rostedt
17782b29b2f8SSteven Rostedt    my $cp_post_install = eval_kernel_version $post_install;
1779db05cfefSSteven Rostedt    run_command "$cp_post_install" or
1780db05cfefSSteven Rostedt	dodie "Failed to run post install";
1781db05cfefSSteven Rostedt}
1782db05cfefSSteven Rostedt
17832545eb61SSteven Rostedtsub install {
17842545eb61SSteven Rostedt
1785e0a8742eSSteven Rostedt    return if ($no_install);
1786e0a8742eSSteven Rostedt
1787e5c2ec11SSteven Rostedt    if (defined($pre_install)) {
1788e5c2ec11SSteven Rostedt	my $cp_pre_install = eval_kernel_version $pre_install;
1789e5c2ec11SSteven Rostedt	run_command "$cp_pre_install" or
1790e5c2ec11SSteven Rostedt	    dodie "Failed to run pre install";
1791e5c2ec11SSteven Rostedt    }
1792e5c2ec11SSteven Rostedt
17932b29b2f8SSteven Rostedt    my $cp_target = eval_kernel_version $target_image;
17942b29b2f8SSteven Rostedt
179502ad2617SSteven Rostedt    run_scp_install "$outputdir/$build_target", "$cp_target" or
17965c42fc5bSSteven Rostedt	dodie "failed to copy image";
17975f9b6cedSSteven Rostedt
17985f9b6cedSSteven Rostedt    my $install_mods = 0;
17995f9b6cedSSteven Rostedt
18005f9b6cedSSteven Rostedt    # should we process modules?
18015f9b6cedSSteven Rostedt    $install_mods = 0;
180251ad1dd1SSteven Rostedt    open(IN, "$output_config") or dodie("Can't read config file");
18035f9b6cedSSteven Rostedt    while (<IN>) {
18045f9b6cedSSteven Rostedt	if (/CONFIG_MODULES(=y)?/) {
18058bc5e4eaSSteven Rostedt	    if (defined($1)) {
18068bc5e4eaSSteven Rostedt		$install_mods = 1;
18075f9b6cedSSteven Rostedt		last;
18085f9b6cedSSteven Rostedt	    }
18095f9b6cedSSteven Rostedt	}
18108bc5e4eaSSteven Rostedt    }
18115f9b6cedSSteven Rostedt    close(IN);
18125f9b6cedSSteven Rostedt
18135f9b6cedSSteven Rostedt    if (!$install_mods) {
1814db05cfefSSteven Rostedt	do_post_install;
18155f9b6cedSSteven Rostedt	doprint "No modules needed\n";
18165f9b6cedSSteven Rostedt	return;
18172545eb61SSteven Rostedt    }
18182545eb61SSteven Rostedt
1819627977d8SSteven Rostedt    run_command "$make INSTALL_MOD_STRIP=1 INSTALL_MOD_PATH=$tmpdir modules_install" or
18205f9b6cedSSteven Rostedt	dodie "Failed to install modules";
18215f9b6cedSSteven Rostedt
18222545eb61SSteven Rostedt    my $modlib = "/lib/modules/$version";
1823a57419b3SSteven Rostedt    my $modtar = "ktest-mods.tar.bz2";
18242545eb61SSteven Rostedt
1825e48c5293SSteven Rostedt    run_ssh "rm -rf $modlib" or
18265c42fc5bSSteven Rostedt	dodie "failed to remove old mods: $modlib";
18272545eb61SSteven Rostedt
18285c42fc5bSSteven Rostedt    # would be nice if scp -r did not follow symbolic links
1829a75fececSSteven Rostedt    run_command "cd $tmpdir && tar -cjf $modtar lib/modules/$version" or
18305c42fc5bSSteven Rostedt	dodie "making tarball";
18315c42fc5bSSteven Rostedt
183202ad2617SSteven Rostedt    run_scp_mod "$tmpdir/$modtar", "/tmp" or
18335c42fc5bSSteven Rostedt	dodie "failed to copy modules";
18345c42fc5bSSteven Rostedt
1835a75fececSSteven Rostedt    unlink "$tmpdir/$modtar";
18365c42fc5bSSteven Rostedt
1837e7b13441SSteven Rostedt    run_ssh "'(cd / && tar xjf /tmp/$modtar)'" or
18385c42fc5bSSteven Rostedt	dodie "failed to tar modules";
18395c42fc5bSSteven Rostedt
1840e48c5293SSteven Rostedt    run_ssh "rm -f /tmp/$modtar";
18418b37ca8cSSteven Rostedt
1842db05cfefSSteven Rostedt    do_post_install;
18432545eb61SSteven Rostedt}
18442545eb61SSteven Rostedt
1845ddf607e5SSteven Rostedtsub get_version {
1846ddf607e5SSteven Rostedt    # get the release name
1847683a3e64SSteven Rostedt    return if ($have_version);
1848ddf607e5SSteven Rostedt    doprint "$make kernelrelease ... ";
1849ddf607e5SSteven Rostedt    $version = `$make kernelrelease | tail -1`;
1850ddf607e5SSteven Rostedt    chomp($version);
1851ddf607e5SSteven Rostedt    doprint "$version\n";
1852683a3e64SSteven Rostedt    $have_version = 1;
1853ddf607e5SSteven Rostedt}
1854ddf607e5SSteven Rostedt
1855ddf607e5SSteven Rostedtsub start_monitor_and_boot {
18569f7424ccSSteven Rostedt    # Make sure the stable kernel has finished booting
18579f7424ccSSteven Rostedt    start_monitor;
18589f7424ccSSteven Rostedt    wait_for_monitor 5;
18599f7424ccSSteven Rostedt    end_monitor;
18609f7424ccSSteven Rostedt
1861ddf607e5SSteven Rostedt    get_grub_index;
1862ddf607e5SSteven Rostedt    get_version;
1863ddf607e5SSteven Rostedt    install;
1864ddf607e5SSteven Rostedt
1865ddf607e5SSteven Rostedt    start_monitor;
1866ddf607e5SSteven Rostedt    return monitor;
1867ddf607e5SSteven Rostedt}
1868ddf607e5SSteven Rostedt
18696c5ee0beSSteven Rostedtsub check_buildlog {
18706c5ee0beSSteven Rostedt    my ($patch) = @_;
18716c5ee0beSSteven Rostedt
18726c5ee0beSSteven Rostedt    my @files = `git show $patch | diffstat -l`;
18736c5ee0beSSteven Rostedt
18746c5ee0beSSteven Rostedt    open(IN, "git show $patch |") or
18756c5ee0beSSteven Rostedt	dodie "failed to show $patch";
18766c5ee0beSSteven Rostedt    while (<IN>) {
18776c5ee0beSSteven Rostedt	if (m,^--- a/(.*),) {
18786c5ee0beSSteven Rostedt	    chomp $1;
18796c5ee0beSSteven Rostedt	    $files[$#files] = $1;
18806c5ee0beSSteven Rostedt	}
18816c5ee0beSSteven Rostedt    }
18826c5ee0beSSteven Rostedt    close(IN);
18836c5ee0beSSteven Rostedt
18846c5ee0beSSteven Rostedt    open(IN, $buildlog) or dodie "Can't open $buildlog";
18856c5ee0beSSteven Rostedt    while (<IN>) {
18866c5ee0beSSteven Rostedt	if (/^\s*(.*?):.*(warning|error)/) {
18876c5ee0beSSteven Rostedt	    my $err = $1;
18886c5ee0beSSteven Rostedt	    foreach my $file (@files) {
1889a75fececSSteven Rostedt		my $fullpath = "$builddir/$file";
18906c5ee0beSSteven Rostedt		if ($file eq $err || $fullpath eq $err) {
18912b7d9b21SSteven Rostedt		    fail "$file built with warnings" and return 0;
18926c5ee0beSSteven Rostedt		}
18936c5ee0beSSteven Rostedt	    }
18946c5ee0beSSteven Rostedt	}
18956c5ee0beSSteven Rostedt    }
18966c5ee0beSSteven Rostedt    close(IN);
18972b7d9b21SSteven Rostedt
18982b7d9b21SSteven Rostedt    return 1;
18996c5ee0beSSteven Rostedt}
19006c5ee0beSSteven Rostedt
1901fcb3f16aSSteven Rostedtsub apply_min_config {
1902fcb3f16aSSteven Rostedt    my $outconfig = "$output_config.new";
1903612b9e9bSSteven Rostedt
1904fcb3f16aSSteven Rostedt    # Read the config file and remove anything that
1905fcb3f16aSSteven Rostedt    # is in the force_config hash (from minconfig and others)
1906fcb3f16aSSteven Rostedt    # then add the force config back.
1907fcb3f16aSSteven Rostedt
1908fcb3f16aSSteven Rostedt    doprint "Applying minimum configurations into $output_config.new\n";
1909fcb3f16aSSteven Rostedt
1910fcb3f16aSSteven Rostedt    open (OUT, ">$outconfig") or
1911fcb3f16aSSteven Rostedt	dodie "Can't create $outconfig";
1912fcb3f16aSSteven Rostedt
1913fcb3f16aSSteven Rostedt    if (-f $output_config) {
1914fcb3f16aSSteven Rostedt	open (IN, $output_config) or
1915fcb3f16aSSteven Rostedt	    dodie "Failed to open $output_config";
1916fcb3f16aSSteven Rostedt	while (<IN>) {
1917fcb3f16aSSteven Rostedt	    if (/^(# )?(CONFIG_[^\s=]*)/) {
1918fcb3f16aSSteven Rostedt		next if (defined($force_config{$2}));
1919fcb3f16aSSteven Rostedt	    }
1920fcb3f16aSSteven Rostedt	    print OUT;
1921fcb3f16aSSteven Rostedt	}
1922fcb3f16aSSteven Rostedt	close IN;
1923fcb3f16aSSteven Rostedt    }
1924fcb3f16aSSteven Rostedt    foreach my $config (keys %force_config) {
1925fcb3f16aSSteven Rostedt	print OUT "$force_config{$config}\n";
1926fcb3f16aSSteven Rostedt    }
1927fcb3f16aSSteven Rostedt    close OUT;
1928fcb3f16aSSteven Rostedt
1929fcb3f16aSSteven Rostedt    run_command "mv $outconfig $output_config";
1930fcb3f16aSSteven Rostedt}
1931fcb3f16aSSteven Rostedt
1932fcb3f16aSSteven Rostedtsub make_oldconfig {
1933fcb3f16aSSteven Rostedt
19344c4ab120SSteven Rostedt    my @force_list = keys %force_config;
19354c4ab120SSteven Rostedt
19364c4ab120SSteven Rostedt    if ($#force_list >= 0) {
1937fcb3f16aSSteven Rostedt	apply_min_config;
19384c4ab120SSteven Rostedt    }
1939fcb3f16aSSteven Rostedt
1940fb16d891SAdam Lee    if (!run_command "$make olddefconfig") {
1941fb16d891SAdam Lee	# Perhaps olddefconfig doesn't exist in this version of the kernel
1942612b9e9bSSteven Rostedt	# try a yes '' | oldconfig
1943fb16d891SAdam Lee	doprint "olddefconfig failed, trying yes '' | make oldconfig\n";
1944fcb3f16aSSteven Rostedt	run_command "yes '' | $make oldconfig" or
1945612b9e9bSSteven Rostedt	    dodie "failed make config oldconfig";
1946612b9e9bSSteven Rostedt    }
1947612b9e9bSSteven Rostedt}
1948612b9e9bSSteven Rostedt
1949fcb3f16aSSteven Rostedt# read a config file and use this to force new configs.
1950fcb3f16aSSteven Rostedtsub load_force_config {
1951fcb3f16aSSteven Rostedt    my ($config) = @_;
1952fcb3f16aSSteven Rostedt
1953cf79fab6SSteven Rostedt    doprint "Loading force configs from $config\n";
1954fcb3f16aSSteven Rostedt    open(IN, $config) or
1955fcb3f16aSSteven Rostedt	dodie "failed to read $config";
1956fcb3f16aSSteven Rostedt    while (<IN>) {
1957fcb3f16aSSteven Rostedt	chomp;
1958fcb3f16aSSteven Rostedt	if (/^(CONFIG[^\s=]*)(\s*=.*)/) {
1959fcb3f16aSSteven Rostedt	    $force_config{$1} = $_;
1960fcb3f16aSSteven Rostedt	} elsif (/^# (CONFIG_\S*) is not set/) {
1961fcb3f16aSSteven Rostedt	    $force_config{$1} = $_;
1962fcb3f16aSSteven Rostedt	}
1963fcb3f16aSSteven Rostedt    }
1964fcb3f16aSSteven Rostedt    close IN;
1965fcb3f16aSSteven Rostedt}
1966fcb3f16aSSteven Rostedt
19672545eb61SSteven Rostedtsub build {
19682545eb61SSteven Rostedt    my ($type) = @_;
19692545eb61SSteven Rostedt
19707faafbd6SSteven Rostedt    unlink $buildlog;
19717faafbd6SSteven Rostedt
19724ab1cce5SSteven Rostedt    # Failed builds should not reboot the target
19734ab1cce5SSteven Rostedt    my $save_no_reboot = $no_reboot;
19744ab1cce5SSteven Rostedt    $no_reboot = 1;
19754ab1cce5SSteven Rostedt
1976683a3e64SSteven Rostedt    # Calculate a new version from here.
1977683a3e64SSteven Rostedt    $have_version = 0;
1978683a3e64SSteven Rostedt
19790bd6c1a3SSteven Rostedt    if (defined($pre_build)) {
19800bd6c1a3SSteven Rostedt	my $ret = run_command $pre_build;
19810bd6c1a3SSteven Rostedt	if (!$ret && defined($pre_build_die) &&
19820bd6c1a3SSteven Rostedt	    $pre_build_die) {
19830bd6c1a3SSteven Rostedt	    dodie "failed to pre_build\n";
19840bd6c1a3SSteven Rostedt	}
19850bd6c1a3SSteven Rostedt    }
19860bd6c1a3SSteven Rostedt
198775c3fda7SSteven Rostedt    if ($type =~ /^useconfig:(.*)/) {
198851ad1dd1SSteven Rostedt	run_command "cp $1 $output_config" or
198975c3fda7SSteven Rostedt	    dodie "could not copy $1 to .config";
19905f9b6cedSSteven Rostedt
199175c3fda7SSteven Rostedt	$type = "oldconfig";
199275c3fda7SSteven Rostedt    }
199375c3fda7SSteven Rostedt
19945c42fc5bSSteven Rostedt    # old config can ask questions
19955c42fc5bSSteven Rostedt    if ($type eq "oldconfig") {
1996fb16d891SAdam Lee	$type = "olddefconfig";
199775c3fda7SSteven Rostedt
199875c3fda7SSteven Rostedt	# allow for empty configs
199951ad1dd1SSteven Rostedt	run_command "touch $output_config";
200075c3fda7SSteven Rostedt
200113488231SAndrew Jones	if (!$noclean) {
200251ad1dd1SSteven Rostedt	    run_command "mv $output_config $outputdir/config_temp" or
20035c42fc5bSSteven Rostedt		dodie "moving .config";
20045c42fc5bSSteven Rostedt
200513488231SAndrew Jones	    run_command "$make mrproper" or dodie "make mrproper";
20065c42fc5bSSteven Rostedt
200751ad1dd1SSteven Rostedt	    run_command "mv $outputdir/config_temp $output_config" or
20085c42fc5bSSteven Rostedt		dodie "moving config_temp";
200913488231SAndrew Jones	}
20105c42fc5bSSteven Rostedt
20115c42fc5bSSteven Rostedt    } elsif (!$noclean) {
201251ad1dd1SSteven Rostedt	unlink "$output_config";
20135f9b6cedSSteven Rostedt	run_command "$make mrproper" or
20145c42fc5bSSteven Rostedt	    dodie "make mrproper";
20155c42fc5bSSteven Rostedt    }
20162545eb61SSteven Rostedt
20172545eb61SSteven Rostedt    # add something to distinguish this build
2018a75fececSSteven Rostedt    open(OUT, "> $outputdir/localversion") or dodie("Can't make localversion file");
2019a75fececSSteven Rostedt    print OUT "$localversion\n";
20202545eb61SSteven Rostedt    close(OUT);
20212545eb61SSteven Rostedt
20225f9b6cedSSteven Rostedt    if (defined($minconfig)) {
2023fcb3f16aSSteven Rostedt	load_force_config($minconfig);
20242545eb61SSteven Rostedt    }
20252545eb61SSteven Rostedt
2026fb16d891SAdam Lee    if ($type ne "olddefconfig") {
2027fcb3f16aSSteven Rostedt	run_command "$make $type" or
20285c42fc5bSSteven Rostedt	    dodie "failed make config";
2029612b9e9bSSteven Rostedt    }
2030fcb3f16aSSteven Rostedt    # Run old config regardless, to enforce min configurations
2031fcb3f16aSSteven Rostedt    make_oldconfig;
20322545eb61SSteven Rostedt
2033a75fececSSteven Rostedt    $redirect = "$buildlog";
20340bd6c1a3SSteven Rostedt    my $build_ret = run_command "$make $build_options";
20356c5ee0beSSteven Rostedt    undef $redirect;
20360bd6c1a3SSteven Rostedt
20370bd6c1a3SSteven Rostedt    if (defined($post_build)) {
2038683a3e64SSteven Rostedt	# Because a post build may change the kernel version
2039683a3e64SSteven Rostedt	# do it now.
2040683a3e64SSteven Rostedt	get_version;
20410bd6c1a3SSteven Rostedt	my $ret = run_command $post_build;
20420bd6c1a3SSteven Rostedt	if (!$ret && defined($post_build_die) &&
20430bd6c1a3SSteven Rostedt	    $post_build_die) {
20440bd6c1a3SSteven Rostedt	    dodie "failed to post_build\n";
20450bd6c1a3SSteven Rostedt	}
20460bd6c1a3SSteven Rostedt    }
20470bd6c1a3SSteven Rostedt
20480bd6c1a3SSteven Rostedt    if (!$build_ret) {
20495f9b6cedSSteven Rostedt	# bisect may need this to pass
20504ab1cce5SSteven Rostedt	if ($in_bisect) {
20514ab1cce5SSteven Rostedt	    $no_reboot = $save_no_reboot;
20524ab1cce5SSteven Rostedt	    return 0;
20534ab1cce5SSteven Rostedt	}
20542b7d9b21SSteven Rostedt	fail "failed build" and return 0;
20552545eb61SSteven Rostedt    }
20565f9b6cedSSteven Rostedt
20574ab1cce5SSteven Rostedt    $no_reboot = $save_no_reboot;
20584ab1cce5SSteven Rostedt
20592b7d9b21SSteven Rostedt    return 1;
20602545eb61SSteven Rostedt}
20612545eb61SSteven Rostedt
206275c3fda7SSteven Rostedtsub halt {
2063e48c5293SSteven Rostedt    if (!run_ssh "halt" or defined($power_off)) {
2064576f627cSSteven Rostedt	if (defined($poweroff_after_halt)) {
2065576f627cSSteven Rostedt	    sleep $poweroff_after_halt;
2066576f627cSSteven Rostedt	    run_command "$power_off";
2067576f627cSSteven Rostedt	}
2068576f627cSSteven Rostedt    } else {
206975c3fda7SSteven Rostedt	# nope? the zap it!
2070a75fececSSteven Rostedt	run_command "$power_off";
207175c3fda7SSteven Rostedt    }
207275c3fda7SSteven Rostedt}
207375c3fda7SSteven Rostedt
20745f9b6cedSSteven Rostedtsub success {
20755f9b6cedSSteven Rostedt    my ($i) = @_;
20765f9b6cedSSteven Rostedt
2077921ed4c7SSteven Rostedt    if (defined($post_test)) {
2078921ed4c7SSteven Rostedt	run_command $post_test;
2079921ed4c7SSteven Rostedt    }
2080921ed4c7SSteven Rostedt
2081e48c5293SSteven Rostedt    $successes++;
2082e48c5293SSteven Rostedt
20839064af52SSteven Rostedt    my $name = "";
20849064af52SSteven Rostedt
20859064af52SSteven Rostedt    if (defined($test_name)) {
20869064af52SSteven Rostedt	$name = " ($test_name)";
20879064af52SSteven Rostedt    }
20889064af52SSteven Rostedt
20895f9b6cedSSteven Rostedt    doprint "\n\n*******************************************\n";
20905f9b6cedSSteven Rostedt    doprint     "*******************************************\n";
20919064af52SSteven Rostedt    doprint     "KTEST RESULT: TEST $i$name SUCCESS!!!!         **\n";
20925f9b6cedSSteven Rostedt    doprint     "*******************************************\n";
20935f9b6cedSSteven Rostedt    doprint     "*******************************************\n";
20945f9b6cedSSteven Rostedt
2095de5b6e3bSRabin Vincent    if (defined($store_successes)) {
2096de5b6e3bSRabin Vincent        save_logs "success", $store_successes;
2097de5b6e3bSRabin Vincent    }
2098de5b6e3bSRabin Vincent
2099576f627cSSteven Rostedt    if ($i != $opt{"NUM_TESTS"} && !do_not_reboot) {
2100a75fececSSteven Rostedt	doprint "Reboot and wait $sleep_time seconds\n";
2101bc7c5803SSteven Rostedt	reboot_to_good $sleep_time;
21025f9b6cedSSteven Rostedt    }
21035f9b6cedSSteven Rostedt}
21045f9b6cedSSteven Rostedt
2105c960bb9fSSteven Rostedtsub answer_bisect {
2106c960bb9fSSteven Rostedt    for (;;) {
2107c960bb9fSSteven Rostedt	doprint "Pass or fail? [p/f]";
2108c960bb9fSSteven Rostedt	my $ans = <STDIN>;
2109c960bb9fSSteven Rostedt	chomp $ans;
2110c960bb9fSSteven Rostedt	if ($ans eq "p" || $ans eq "P") {
2111c960bb9fSSteven Rostedt	    return 1;
2112c960bb9fSSteven Rostedt	} elsif ($ans eq "f" || $ans eq "F") {
2113c960bb9fSSteven Rostedt	    return 0;
2114c960bb9fSSteven Rostedt	} else {
2115c960bb9fSSteven Rostedt	    print "Please answer 'P' or 'F'\n";
2116c960bb9fSSteven Rostedt	}
2117c960bb9fSSteven Rostedt    }
2118c960bb9fSSteven Rostedt}
2119c960bb9fSSteven Rostedt
21205a391fbfSSteven Rostedtsub child_run_test {
21217faafbd6SSteven Rostedt    my $failed = 0;
21225a391fbfSSteven Rostedt
21237faafbd6SSteven Rostedt    # child should have no power
2124a75fececSSteven Rostedt    $reboot_on_error = 0;
2125a75fececSSteven Rostedt    $poweroff_on_error = 0;
2126a75fececSSteven Rostedt    $die_on_failure = 1;
21277faafbd6SSteven Rostedt
2128a9dd5d63SRabin Vincent    $redirect = "$testlog";
21297faafbd6SSteven Rostedt    run_command $run_test or $failed = 1;
2130a9dd5d63SRabin Vincent    undef $redirect;
2131a9dd5d63SRabin Vincent
21325a391fbfSSteven Rostedt    exit $failed;
21335a391fbfSSteven Rostedt}
21345a391fbfSSteven Rostedt
21355a391fbfSSteven Rostedtmy $child_done;
21365a391fbfSSteven Rostedt
21375a391fbfSSteven Rostedtsub child_finished {
21385a391fbfSSteven Rostedt    $child_done = 1;
21395a391fbfSSteven Rostedt}
21405a391fbfSSteven Rostedt
21415a391fbfSSteven Rostedtsub do_run_test {
21425a391fbfSSteven Rostedt    my $child_pid;
21435a391fbfSSteven Rostedt    my $child_exit;
21445a391fbfSSteven Rostedt    my $line;
21455a391fbfSSteven Rostedt    my $full_line;
21465a391fbfSSteven Rostedt    my $bug = 0;
21479b1d367dSSteven Rostedt    my $bug_ignored = 0;
21485a391fbfSSteven Rostedt
21497faafbd6SSteven Rostedt    wait_for_monitor 1;
21505a391fbfSSteven Rostedt
21517faafbd6SSteven Rostedt    doprint "run test $run_test\n";
21525a391fbfSSteven Rostedt
21535a391fbfSSteven Rostedt    $child_done = 0;
21545a391fbfSSteven Rostedt
21555a391fbfSSteven Rostedt    $SIG{CHLD} = qw(child_finished);
21565a391fbfSSteven Rostedt
21575a391fbfSSteven Rostedt    $child_pid = fork;
21585a391fbfSSteven Rostedt
21595a391fbfSSteven Rostedt    child_run_test if (!$child_pid);
21605a391fbfSSteven Rostedt
21615a391fbfSSteven Rostedt    $full_line = "";
21625a391fbfSSteven Rostedt
21635a391fbfSSteven Rostedt    do {
21647faafbd6SSteven Rostedt	$line = wait_for_input($monitor_fp, 1);
21655a391fbfSSteven Rostedt	if (defined($line)) {
21665a391fbfSSteven Rostedt
21675a391fbfSSteven Rostedt	    # we are not guaranteed to get a full line
21685a391fbfSSteven Rostedt	    $full_line .= $line;
21698ea0e063SSteven Rostedt	    doprint $line;
21705a391fbfSSteven Rostedt
21715a391fbfSSteven Rostedt	    if ($full_line =~ /call trace:/i) {
21729b1d367dSSteven Rostedt		if ($ignore_errors) {
21739b1d367dSSteven Rostedt		    $bug_ignored = 1;
21749b1d367dSSteven Rostedt		} else {
21755a391fbfSSteven Rostedt		    $bug = 1;
21765a391fbfSSteven Rostedt		}
21779b1d367dSSteven Rostedt	    }
21785a391fbfSSteven Rostedt
21795a391fbfSSteven Rostedt	    if ($full_line =~ /Kernel panic -/) {
21805a391fbfSSteven Rostedt		$bug = 1;
21815a391fbfSSteven Rostedt	    }
21825a391fbfSSteven Rostedt
21835a391fbfSSteven Rostedt	    if ($line =~ /\n/) {
21845a391fbfSSteven Rostedt		$full_line = "";
21855a391fbfSSteven Rostedt	    }
21865a391fbfSSteven Rostedt	}
21875a391fbfSSteven Rostedt    } while (!$child_done && !$bug);
21885a391fbfSSteven Rostedt
21899b1d367dSSteven Rostedt    if (!$bug && $bug_ignored) {
21909b1d367dSSteven Rostedt	doprint "WARNING: Call Trace detected but ignored due to IGNORE_ERRORS=1\n";
21919b1d367dSSteven Rostedt    }
21929b1d367dSSteven Rostedt
21935a391fbfSSteven Rostedt    if ($bug) {
21948ea0e063SSteven Rostedt	my $failure_start = time;
21958ea0e063SSteven Rostedt	my $now;
21968ea0e063SSteven Rostedt	do {
21978ea0e063SSteven Rostedt	    $line = wait_for_input($monitor_fp, 1);
21988ea0e063SSteven Rostedt	    if (defined($line)) {
21998ea0e063SSteven Rostedt		doprint $line;
22008ea0e063SSteven Rostedt	    }
22018ea0e063SSteven Rostedt	    $now = time;
22028ea0e063SSteven Rostedt	    if ($now - $failure_start >= $stop_after_failure) {
22038ea0e063SSteven Rostedt		last;
22048ea0e063SSteven Rostedt	    }
22058ea0e063SSteven Rostedt	} while (defined($line));
22068ea0e063SSteven Rostedt
22075a391fbfSSteven Rostedt	doprint "Detected kernel crash!\n";
22085a391fbfSSteven Rostedt	# kill the child with extreme prejudice
22095a391fbfSSteven Rostedt	kill 9, $child_pid;
22105a391fbfSSteven Rostedt    }
22115a391fbfSSteven Rostedt
22125a391fbfSSteven Rostedt    waitpid $child_pid, 0;
22135a391fbfSSteven Rostedt    $child_exit = $?;
22145a391fbfSSteven Rostedt
2215c5dacb88SSteven Rostedt    if (!$bug && $in_bisect) {
2216c5dacb88SSteven Rostedt	if (defined($bisect_ret_good)) {
2217c5dacb88SSteven Rostedt	    if ($child_exit == $bisect_ret_good) {
2218c5dacb88SSteven Rostedt		return 1;
2219c5dacb88SSteven Rostedt	    }
2220c5dacb88SSteven Rostedt	}
2221c5dacb88SSteven Rostedt	if (defined($bisect_ret_skip)) {
2222c5dacb88SSteven Rostedt	    if ($child_exit == $bisect_ret_skip) {
2223c5dacb88SSteven Rostedt		return -1;
2224c5dacb88SSteven Rostedt	    }
2225c5dacb88SSteven Rostedt	}
2226c5dacb88SSteven Rostedt	if (defined($bisect_ret_abort)) {
2227c5dacb88SSteven Rostedt	    if ($child_exit == $bisect_ret_abort) {
2228c5dacb88SSteven Rostedt		fail "test abort" and return -2;
2229c5dacb88SSteven Rostedt	    }
2230c5dacb88SSteven Rostedt	}
2231c5dacb88SSteven Rostedt	if (defined($bisect_ret_bad)) {
2232c5dacb88SSteven Rostedt	    if ($child_exit == $bisect_ret_skip) {
2233c5dacb88SSteven Rostedt		return 0;
2234c5dacb88SSteven Rostedt	    }
2235c5dacb88SSteven Rostedt	}
2236c5dacb88SSteven Rostedt	if (defined($bisect_ret_default)) {
2237c5dacb88SSteven Rostedt	    if ($bisect_ret_default eq "good") {
2238c5dacb88SSteven Rostedt		return 1;
2239c5dacb88SSteven Rostedt	    } elsif ($bisect_ret_default eq "bad") {
2240c5dacb88SSteven Rostedt		return 0;
2241c5dacb88SSteven Rostedt	    } elsif ($bisect_ret_default eq "skip") {
2242c5dacb88SSteven Rostedt		return -1;
2243c5dacb88SSteven Rostedt	    } elsif ($bisect_ret_default eq "abort") {
2244c5dacb88SSteven Rostedt		return -2;
2245c5dacb88SSteven Rostedt	    } else {
2246c5dacb88SSteven Rostedt		fail "unknown default action: $bisect_ret_default"
2247c5dacb88SSteven Rostedt		    and return -2;
2248c5dacb88SSteven Rostedt	    }
2249c5dacb88SSteven Rostedt	}
2250c5dacb88SSteven Rostedt    }
2251c5dacb88SSteven Rostedt
22525a391fbfSSteven Rostedt    if ($bug || $child_exit) {
22532b7d9b21SSteven Rostedt	return 0 if $in_bisect;
22542b7d9b21SSteven Rostedt	fail "test failed" and return 0;
22555a391fbfSSteven Rostedt    }
22562b7d9b21SSteven Rostedt    return 1;
22575a391fbfSSteven Rostedt}
22585a391fbfSSteven Rostedt
2259a75fececSSteven Rostedtsub run_git_bisect {
2260a75fececSSteven Rostedt    my ($command) = @_;
2261a75fececSSteven Rostedt
2262a75fececSSteven Rostedt    doprint "$command ... ";
2263a75fececSSteven Rostedt
2264a75fececSSteven Rostedt    my $output = `$command 2>&1`;
2265a75fececSSteven Rostedt    my $ret = $?;
2266a75fececSSteven Rostedt
2267a75fececSSteven Rostedt    logit $output;
2268a75fececSSteven Rostedt
2269a75fececSSteven Rostedt    if ($ret) {
2270a75fececSSteven Rostedt	doprint "FAILED\n";
2271a75fececSSteven Rostedt	dodie "Failed to git bisect";
2272a75fececSSteven Rostedt    }
2273a75fececSSteven Rostedt
2274a75fececSSteven Rostedt    doprint "SUCCESS\n";
2275a75fececSSteven Rostedt    if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\))\s+\[([[:xdigit:]]+)\]/) {
2276a75fececSSteven Rostedt	doprint "$1 [$2]\n";
2277a75fececSSteven Rostedt    } elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) {
2278b5f4aea6SSteven Rostedt	$bisect_bad_commit = $1;
2279a75fececSSteven Rostedt	doprint "Found bad commit... $1\n";
2280a75fececSSteven Rostedt	return 0;
2281a75fececSSteven Rostedt    } else {
2282a75fececSSteven Rostedt	# we already logged it, just print it now.
2283a75fececSSteven Rostedt	print $output;
2284a75fececSSteven Rostedt    }
2285a75fececSSteven Rostedt
2286a75fececSSteven Rostedt    return 1;
2287a75fececSSteven Rostedt}
2288a75fececSSteven Rostedt
2289c23dca7cSSteven Rostedtsub bisect_reboot {
2290c23dca7cSSteven Rostedt    doprint "Reboot and sleep $bisect_sleep_time seconds\n";
2291bc7c5803SSteven Rostedt    reboot_to_good $bisect_sleep_time;
2292c23dca7cSSteven Rostedt}
2293c23dca7cSSteven Rostedt
2294c23dca7cSSteven Rostedt# returns 1 on success, 0 on failure, -1 on skip
22950a05c769SSteven Rostedtsub run_bisect_test {
22960a05c769SSteven Rostedt    my ($type, $buildtype) = @_;
22975f9b6cedSSteven Rostedt
22982b7d9b21SSteven Rostedt    my $failed = 0;
22995f9b6cedSSteven Rostedt    my $result;
23005f9b6cedSSteven Rostedt    my $output;
23015f9b6cedSSteven Rostedt    my $ret;
23025f9b6cedSSteven Rostedt
23030a05c769SSteven Rostedt    $in_bisect = 1;
23040a05c769SSteven Rostedt
23050a05c769SSteven Rostedt    build $buildtype or $failed = 1;
23065f9b6cedSSteven Rostedt
23075f9b6cedSSteven Rostedt    if ($type ne "build") {
2308c23dca7cSSteven Rostedt	if ($failed && $bisect_skip) {
2309c23dca7cSSteven Rostedt	    $in_bisect = 0;
2310c23dca7cSSteven Rostedt	    return -1;
2311c23dca7cSSteven Rostedt	}
23127faafbd6SSteven Rostedt	dodie "Failed on build" if $failed;
23135f9b6cedSSteven Rostedt
23145f9b6cedSSteven Rostedt	# Now boot the box
2315ddf607e5SSteven Rostedt	start_monitor_and_boot or $failed = 1;
23165f9b6cedSSteven Rostedt
23175f9b6cedSSteven Rostedt	if ($type ne "boot") {
2318c23dca7cSSteven Rostedt	    if ($failed && $bisect_skip) {
2319c23dca7cSSteven Rostedt		end_monitor;
2320c23dca7cSSteven Rostedt		bisect_reboot;
2321c23dca7cSSteven Rostedt		$in_bisect = 0;
2322c23dca7cSSteven Rostedt		return -1;
2323c23dca7cSSteven Rostedt	    }
23247faafbd6SSteven Rostedt	    dodie "Failed on boot" if $failed;
23255a391fbfSSteven Rostedt
23262b7d9b21SSteven Rostedt	    do_run_test or $failed = 1;
23275f9b6cedSSteven Rostedt	}
23287faafbd6SSteven Rostedt	end_monitor;
23295f9b6cedSSteven Rostedt    }
23305f9b6cedSSteven Rostedt
23315f9b6cedSSteven Rostedt    if ($failed) {
23320a05c769SSteven Rostedt	$result = 0;
23335f9b6cedSSteven Rostedt    } else {
23340a05c769SSteven Rostedt	$result = 1;
23355f9b6cedSSteven Rostedt    }
23364025bc62SSteven Rostedt
23374025bc62SSteven Rostedt    # reboot the box to a kernel we can ssh to
23384025bc62SSteven Rostedt    if ($type ne "build") {
23394025bc62SSteven Rostedt	bisect_reboot;
23404025bc62SSteven Rostedt    }
23410a05c769SSteven Rostedt    $in_bisect = 0;
23420a05c769SSteven Rostedt
23430a05c769SSteven Rostedt    return $result;
23440a05c769SSteven Rostedt}
23450a05c769SSteven Rostedt
23460a05c769SSteven Rostedtsub run_bisect {
23470a05c769SSteven Rostedt    my ($type) = @_;
23480a05c769SSteven Rostedt    my $buildtype = "oldconfig";
23490a05c769SSteven Rostedt
23500a05c769SSteven Rostedt    # We should have a minconfig to use?
23510a05c769SSteven Rostedt    if (defined($minconfig)) {
23520a05c769SSteven Rostedt	$buildtype = "useconfig:$minconfig";
23530a05c769SSteven Rostedt    }
23540a05c769SSteven Rostedt
23550a05c769SSteven Rostedt    my $ret = run_bisect_test $type, $buildtype;
23560a05c769SSteven Rostedt
2357c960bb9fSSteven Rostedt    if ($bisect_manual) {
2358c960bb9fSSteven Rostedt	$ret = answer_bisect;
2359c960bb9fSSteven Rostedt    }
23605f9b6cedSSteven Rostedt
2361d6ce2a0bSSteven Rostedt    # Are we looking for where it worked, not failed?
23625158ba3eSRuss Dill    if ($reverse_bisect && $ret >= 0) {
23630a05c769SSteven Rostedt	$ret = !$ret;
2364d6ce2a0bSSteven Rostedt    }
2365d6ce2a0bSSteven Rostedt
2366c23dca7cSSteven Rostedt    if ($ret > 0) {
23670a05c769SSteven Rostedt	return "good";
2368c23dca7cSSteven Rostedt    } elsif ($ret == 0) {
23690a05c769SSteven Rostedt	return  "bad";
2370c23dca7cSSteven Rostedt    } elsif ($bisect_skip) {
2371c23dca7cSSteven Rostedt	doprint "HIT A BAD COMMIT ... SKIPPING\n";
2372c23dca7cSSteven Rostedt	return "skip";
23730a05c769SSteven Rostedt    }
23745f9b6cedSSteven Rostedt}
23755f9b6cedSSteven Rostedt
2376dad98754SSteven Rostedtsub update_bisect_replay {
2377dad98754SSteven Rostedt    my $tmp_log = "$tmpdir/ktest_bisect_log";
2378dad98754SSteven Rostedt    run_command "git bisect log > $tmp_log" or
2379dad98754SSteven Rostedt	die "can't create bisect log";
2380dad98754SSteven Rostedt    return $tmp_log;
2381dad98754SSteven Rostedt}
2382dad98754SSteven Rostedt
23835f9b6cedSSteven Rostedtsub bisect {
23845f9b6cedSSteven Rostedt    my ($i) = @_;
23855f9b6cedSSteven Rostedt
23865f9b6cedSSteven Rostedt    my $result;
23875f9b6cedSSteven Rostedt
2388b5f4aea6SSteven Rostedt    die "BISECT_GOOD[$i] not defined\n"	if (!defined($bisect_good));
2389b5f4aea6SSteven Rostedt    die "BISECT_BAD[$i] not defined\n"	if (!defined($bisect_bad));
2390b5f4aea6SSteven Rostedt    die "BISECT_TYPE[$i] not defined\n"	if (!defined($bisect_type));
23915f9b6cedSSteven Rostedt
2392b5f4aea6SSteven Rostedt    my $good = $bisect_good;
2393b5f4aea6SSteven Rostedt    my $bad = $bisect_bad;
2394b5f4aea6SSteven Rostedt    my $type = $bisect_type;
2395b5f4aea6SSteven Rostedt    my $start = $bisect_start;
2396b5f4aea6SSteven Rostedt    my $replay = $bisect_replay;
2397b5f4aea6SSteven Rostedt    my $start_files = $bisect_files;
23983410f6fdSSteven Rostedt
23993410f6fdSSteven Rostedt    if (defined($start_files)) {
24003410f6fdSSteven Rostedt	$start_files = " -- " . $start_files;
24013410f6fdSSteven Rostedt    } else {
24023410f6fdSSteven Rostedt	$start_files = "";
24033410f6fdSSteven Rostedt    }
24045f9b6cedSSteven Rostedt
2405a57419b3SSteven Rostedt    # convert to true sha1's
2406a57419b3SSteven Rostedt    $good = get_sha1($good);
2407a57419b3SSteven Rostedt    $bad = get_sha1($bad);
2408a57419b3SSteven Rostedt
2409b5f4aea6SSteven Rostedt    if (defined($bisect_reverse) && $bisect_reverse == 1) {
2410d6ce2a0bSSteven Rostedt	doprint "Performing a reverse bisect (bad is good, good is bad!)\n";
2411d6ce2a0bSSteven Rostedt	$reverse_bisect = 1;
2412d6ce2a0bSSteven Rostedt    } else {
2413d6ce2a0bSSteven Rostedt	$reverse_bisect = 0;
2414d6ce2a0bSSteven Rostedt    }
2415d6ce2a0bSSteven Rostedt
24165a391fbfSSteven Rostedt    # Can't have a test without having a test to run
24175a391fbfSSteven Rostedt    if ($type eq "test" && !defined($run_test)) {
24185a391fbfSSteven Rostedt	$type = "boot";
24195a391fbfSSteven Rostedt    }
24205a391fbfSSteven Rostedt
2421dad98754SSteven Rostedt    # Check if a bisect was running
2422dad98754SSteven Rostedt    my $bisect_start_file = "$builddir/.git/BISECT_START";
2423dad98754SSteven Rostedt
2424b5f4aea6SSteven Rostedt    my $check = $bisect_check;
2425dad98754SSteven Rostedt    my $do_check = defined($check) && $check ne "0";
2426dad98754SSteven Rostedt
2427dad98754SSteven Rostedt    if ( -f $bisect_start_file ) {
2428dad98754SSteven Rostedt	print "Bisect in progress found\n";
2429dad98754SSteven Rostedt	if ($do_check) {
2430dad98754SSteven Rostedt	    print " If you say yes, then no checks of good or bad will be done\n";
2431dad98754SSteven Rostedt	}
2432dad98754SSteven Rostedt	if (defined($replay)) {
2433dad98754SSteven Rostedt	    print "** BISECT_REPLAY is defined in config file **";
2434dad98754SSteven Rostedt	    print " Ignore config option and perform new git bisect log?\n";
2435dad98754SSteven Rostedt	    if (read_ync " (yes, no, or cancel) ") {
2436dad98754SSteven Rostedt		$replay = update_bisect_replay;
2437dad98754SSteven Rostedt		$do_check = 0;
2438dad98754SSteven Rostedt	    }
2439dad98754SSteven Rostedt	} elsif (read_yn "read git log and continue?") {
2440dad98754SSteven Rostedt	    $replay = update_bisect_replay;
2441dad98754SSteven Rostedt	    $do_check = 0;
2442dad98754SSteven Rostedt	}
2443dad98754SSteven Rostedt    }
2444dad98754SSteven Rostedt
2445dad98754SSteven Rostedt    if ($do_check) {
2446a75fececSSteven Rostedt
2447a75fececSSteven Rostedt	# get current HEAD
2448a57419b3SSteven Rostedt	my $head = get_sha1("HEAD");
2449a75fececSSteven Rostedt
2450a75fececSSteven Rostedt	if ($check ne "good") {
2451a75fececSSteven Rostedt	    doprint "TESTING BISECT BAD [$bad]\n";
2452a75fececSSteven Rostedt	    run_command "git checkout $bad" or
2453a75fececSSteven Rostedt		die "Failed to checkout $bad";
2454a75fececSSteven Rostedt
2455a75fececSSteven Rostedt	    $result = run_bisect $type;
2456a75fececSSteven Rostedt
2457a75fececSSteven Rostedt	    if ($result ne "bad") {
2458a75fececSSteven Rostedt		fail "Tested BISECT_BAD [$bad] and it succeeded" and return 0;
2459a75fececSSteven Rostedt	    }
2460a75fececSSteven Rostedt	}
2461a75fececSSteven Rostedt
2462a75fececSSteven Rostedt	if ($check ne "bad") {
2463a75fececSSteven Rostedt	    doprint "TESTING BISECT GOOD [$good]\n";
2464a75fececSSteven Rostedt	    run_command "git checkout $good" or
2465a75fececSSteven Rostedt		die "Failed to checkout $good";
2466a75fececSSteven Rostedt
2467a75fececSSteven Rostedt	    $result = run_bisect $type;
2468a75fececSSteven Rostedt
2469a75fececSSteven Rostedt	    if ($result ne "good") {
2470a75fececSSteven Rostedt		fail "Tested BISECT_GOOD [$good] and it failed" and return 0;
2471a75fececSSteven Rostedt	    }
2472a75fececSSteven Rostedt	}
2473a75fececSSteven Rostedt
2474a75fececSSteven Rostedt	# checkout where we started
2475a75fececSSteven Rostedt	run_command "git checkout $head" or
2476a75fececSSteven Rostedt	    die "Failed to checkout $head";
2477a75fececSSteven Rostedt    }
2478a75fececSSteven Rostedt
24793410f6fdSSteven Rostedt    run_command "git bisect start$start_files" or
2480a75fececSSteven Rostedt	dodie "could not start bisect";
2481a75fececSSteven Rostedt
2482a75fececSSteven Rostedt    run_command "git bisect good $good" or
2483a75fececSSteven Rostedt	dodie "could not set bisect good to $good";
2484a75fececSSteven Rostedt
2485a75fececSSteven Rostedt    run_git_bisect "git bisect bad $bad" or
2486a75fececSSteven Rostedt	dodie "could not set bisect bad to $bad";
2487a75fececSSteven Rostedt
2488a75fececSSteven Rostedt    if (defined($replay)) {
2489a75fececSSteven Rostedt	run_command "git bisect replay $replay" or
2490a75fececSSteven Rostedt	    dodie "failed to run replay";
2491a75fececSSteven Rostedt    }
2492a75fececSSteven Rostedt
2493a75fececSSteven Rostedt    if (defined($start)) {
2494a75fececSSteven Rostedt	run_command "git checkout $start" or
2495a75fececSSteven Rostedt	    dodie "failed to checkout $start";
2496a75fececSSteven Rostedt    }
2497a75fececSSteven Rostedt
2498a75fececSSteven Rostedt    my $test;
24995f9b6cedSSteven Rostedt    do {
25005f9b6cedSSteven Rostedt	$result = run_bisect $type;
2501a75fececSSteven Rostedt	$test = run_git_bisect "git bisect $result";
2502a75fececSSteven Rostedt    } while ($test);
25035f9b6cedSSteven Rostedt
25045f9b6cedSSteven Rostedt    run_command "git bisect log" or
25055f9b6cedSSteven Rostedt	dodie "could not capture git bisect log";
25065f9b6cedSSteven Rostedt
25075f9b6cedSSteven Rostedt    run_command "git bisect reset" or
25085f9b6cedSSteven Rostedt	dodie "could not reset git bisect";
25095f9b6cedSSteven Rostedt
2510b5f4aea6SSteven Rostedt    doprint "Bad commit was [$bisect_bad_commit]\n";
25115f9b6cedSSteven Rostedt
25120a05c769SSteven Rostedt    success $i;
25130a05c769SSteven Rostedt}
25140a05c769SSteven Rostedt
2515cf79fab6SSteven Rostedt# config_ignore holds the configs that were set (or unset) for
2516cf79fab6SSteven Rostedt# a good config and we will ignore these configs for the rest
2517cf79fab6SSteven Rostedt# of a config bisect. These configs stay as they were.
25180a05c769SSteven Rostedtmy %config_ignore;
2519cf79fab6SSteven Rostedt
2520cf79fab6SSteven Rostedt# config_set holds what all configs were set as.
25210a05c769SSteven Rostedtmy %config_set;
25220a05c769SSteven Rostedt
2523cf79fab6SSteven Rostedt# config_off holds the set of configs that the bad config had disabled.
2524cf79fab6SSteven Rostedt# We need to record them and set them in the .config when running
2525fb16d891SAdam Lee# olddefconfig, because olddefconfig keeps the defaults.
2526cf79fab6SSteven Rostedtmy %config_off;
2527cf79fab6SSteven Rostedt
2528cf79fab6SSteven Rostedt# config_off_tmp holds a set of configs to turn off for now
2529cf79fab6SSteven Rostedtmy @config_off_tmp;
2530cf79fab6SSteven Rostedt
2531cf79fab6SSteven Rostedt# config_list is the set of configs that are being tested
25320a05c769SSteven Rostedtmy %config_list;
25330a05c769SSteven Rostedtmy %null_config;
25340a05c769SSteven Rostedt
25350a05c769SSteven Rostedtmy %dependency;
25360a05c769SSteven Rostedt
25374c4ab120SSteven Rostedtsub assign_configs {
25384c4ab120SSteven Rostedt    my ($hash, $config) = @_;
25390a05c769SSteven Rostedt
25400a05c769SSteven Rostedt    open (IN, $config)
25410a05c769SSteven Rostedt	or dodie "Failed to read $config";
25420a05c769SSteven Rostedt
25430a05c769SSteven Rostedt    while (<IN>) {
25449bf71749SSteven Rostedt	if (/^((CONFIG\S*)=.*)/) {
25454c4ab120SSteven Rostedt	    ${$hash}{$2} = $1;
25460a05c769SSteven Rostedt	}
25470a05c769SSteven Rostedt    }
25480a05c769SSteven Rostedt
25490a05c769SSteven Rostedt    close(IN);
25500a05c769SSteven Rostedt}
25510a05c769SSteven Rostedt
25524c4ab120SSteven Rostedtsub process_config_ignore {
25534c4ab120SSteven Rostedt    my ($config) = @_;
25544c4ab120SSteven Rostedt
25554c4ab120SSteven Rostedt    assign_configs \%config_ignore, $config;
25564c4ab120SSteven Rostedt}
25574c4ab120SSteven Rostedt
25580a05c769SSteven Rostedtsub read_current_config {
25590a05c769SSteven Rostedt    my ($config_ref) = @_;
25600a05c769SSteven Rostedt
25610a05c769SSteven Rostedt    %{$config_ref} = ();
25620a05c769SSteven Rostedt    undef %{$config_ref};
25630a05c769SSteven Rostedt
25640a05c769SSteven Rostedt    my @key = keys %{$config_ref};
25650a05c769SSteven Rostedt    if ($#key >= 0) {
25660a05c769SSteven Rostedt	print "did not delete!\n";
25670a05c769SSteven Rostedt	exit;
25680a05c769SSteven Rostedt    }
25690a05c769SSteven Rostedt    open (IN, "$output_config");
25700a05c769SSteven Rostedt
25710a05c769SSteven Rostedt    while (<IN>) {
25720a05c769SSteven Rostedt	if (/^(CONFIG\S+)=(.*)/) {
25730a05c769SSteven Rostedt	    ${$config_ref}{$1} = $2;
25740a05c769SSteven Rostedt	}
25750a05c769SSteven Rostedt    }
25760a05c769SSteven Rostedt    close(IN);
25770a05c769SSteven Rostedt}
25780a05c769SSteven Rostedt
25790a05c769SSteven Rostedtsub get_dependencies {
25800a05c769SSteven Rostedt    my ($config) = @_;
25810a05c769SSteven Rostedt
25820a05c769SSteven Rostedt    my $arr = $dependency{$config};
25830a05c769SSteven Rostedt    if (!defined($arr)) {
25840a05c769SSteven Rostedt	return ();
25850a05c769SSteven Rostedt    }
25860a05c769SSteven Rostedt
25870a05c769SSteven Rostedt    my @deps = @{$arr};
25880a05c769SSteven Rostedt
25890a05c769SSteven Rostedt    foreach my $dep (@{$arr}) {
25900a05c769SSteven Rostedt	print "ADD DEP $dep\n";
25910a05c769SSteven Rostedt	@deps = (@deps, get_dependencies $dep);
25920a05c769SSteven Rostedt    }
25930a05c769SSteven Rostedt
25940a05c769SSteven Rostedt    return @deps;
25950a05c769SSteven Rostedt}
25960a05c769SSteven Rostedt
25970a05c769SSteven Rostedtsub create_config {
25980a05c769SSteven Rostedt    my @configs = @_;
25990a05c769SSteven Rostedt
26000a05c769SSteven Rostedt    open(OUT, ">$output_config") or dodie "Can not write to $output_config";
26010a05c769SSteven Rostedt
26020a05c769SSteven Rostedt    foreach my $config (@configs) {
26030a05c769SSteven Rostedt	print OUT "$config_set{$config}\n";
26040a05c769SSteven Rostedt	my @deps = get_dependencies $config;
26050a05c769SSteven Rostedt	foreach my $dep (@deps) {
26060a05c769SSteven Rostedt	    print OUT "$config_set{$dep}\n";
26070a05c769SSteven Rostedt	}
26080a05c769SSteven Rostedt    }
26090a05c769SSteven Rostedt
2610cf79fab6SSteven Rostedt    # turn off configs to keep off
2611cf79fab6SSteven Rostedt    foreach my $config (keys %config_off) {
2612cf79fab6SSteven Rostedt	print OUT "# $config is not set\n";
2613cf79fab6SSteven Rostedt    }
2614cf79fab6SSteven Rostedt
2615cf79fab6SSteven Rostedt    # turn off configs that should be off for now
2616cf79fab6SSteven Rostedt    foreach my $config (@config_off_tmp) {
2617cf79fab6SSteven Rostedt	print OUT "# $config is not set\n";
2618cf79fab6SSteven Rostedt    }
2619cf79fab6SSteven Rostedt
26200a05c769SSteven Rostedt    foreach my $config (keys %config_ignore) {
26210a05c769SSteven Rostedt	print OUT "$config_ignore{$config}\n";
26220a05c769SSteven Rostedt    }
26230a05c769SSteven Rostedt    close(OUT);
26240a05c769SSteven Rostedt
2625fcb3f16aSSteven Rostedt    make_oldconfig;
26260a05c769SSteven Rostedt}
26270a05c769SSteven Rostedt
26280a05c769SSteven Rostedtsub compare_configs {
26290a05c769SSteven Rostedt    my (%a, %b) = @_;
26300a05c769SSteven Rostedt
26310a05c769SSteven Rostedt    foreach my $item (keys %a) {
26320a05c769SSteven Rostedt	if (!defined($b{$item})) {
26330a05c769SSteven Rostedt	    print "diff $item\n";
26340a05c769SSteven Rostedt	    return 1;
26350a05c769SSteven Rostedt	}
26360a05c769SSteven Rostedt	delete $b{$item};
26370a05c769SSteven Rostedt    }
26380a05c769SSteven Rostedt
26390a05c769SSteven Rostedt    my @keys = keys %b;
26400a05c769SSteven Rostedt    if ($#keys) {
26410a05c769SSteven Rostedt	print "diff2 $keys[0]\n";
26420a05c769SSteven Rostedt    }
26430a05c769SSteven Rostedt    return -1 if ($#keys >= 0);
26440a05c769SSteven Rostedt
26450a05c769SSteven Rostedt    return 0;
26460a05c769SSteven Rostedt}
26470a05c769SSteven Rostedt
26480a05c769SSteven Rostedtsub run_config_bisect_test {
26490a05c769SSteven Rostedt    my ($type) = @_;
26500a05c769SSteven Rostedt
26510a05c769SSteven Rostedt    return run_bisect_test $type, "oldconfig";
26520a05c769SSteven Rostedt}
26530a05c769SSteven Rostedt
26540a05c769SSteven Rostedtsub process_passed {
26550a05c769SSteven Rostedt    my (%configs) = @_;
26560a05c769SSteven Rostedt
26570a05c769SSteven Rostedt    doprint "These configs had no failure: (Enabling them for further compiles)\n";
26580a05c769SSteven Rostedt    # Passed! All these configs are part of a good compile.
26590a05c769SSteven Rostedt    # Add them to the min options.
26600a05c769SSteven Rostedt    foreach my $config (keys %configs) {
26610a05c769SSteven Rostedt	if (defined($config_list{$config})) {
26620a05c769SSteven Rostedt	    doprint " removing $config\n";
26630a05c769SSteven Rostedt	    $config_ignore{$config} = $config_list{$config};
26640a05c769SSteven Rostedt	    delete $config_list{$config};
26650a05c769SSteven Rostedt	}
26660a05c769SSteven Rostedt    }
2667f1a27850SSteven Rostedt    doprint "config copied to $outputdir/config_good\n";
2668f1a27850SSteven Rostedt    run_command "cp -f $output_config $outputdir/config_good";
26690a05c769SSteven Rostedt}
26700a05c769SSteven Rostedt
26710a05c769SSteven Rostedtsub process_failed {
26720a05c769SSteven Rostedt    my ($config) = @_;
26730a05c769SSteven Rostedt
26740a05c769SSteven Rostedt    doprint "\n\n***************************************\n";
26750a05c769SSteven Rostedt    doprint "Found bad config: $config\n";
26760a05c769SSteven Rostedt    doprint "***************************************\n\n";
26770a05c769SSteven Rostedt}
26780a05c769SSteven Rostedt
26790a05c769SSteven Rostedtsub run_config_bisect {
26800a05c769SSteven Rostedt
26810a05c769SSteven Rostedt    my @start_list = keys %config_list;
26820a05c769SSteven Rostedt
26830a05c769SSteven Rostedt    if ($#start_list < 0) {
26840a05c769SSteven Rostedt	doprint "No more configs to test!!!\n";
26850a05c769SSteven Rostedt	return -1;
26860a05c769SSteven Rostedt    }
26870a05c769SSteven Rostedt
26880a05c769SSteven Rostedt    doprint "***** RUN TEST ***\n";
2689b5f4aea6SSteven Rostedt    my $type = $config_bisect_type;
26900a05c769SSteven Rostedt    my $ret;
26910a05c769SSteven Rostedt    my %current_config;
26920a05c769SSteven Rostedt
26930a05c769SSteven Rostedt    my $count = $#start_list + 1;
26940a05c769SSteven Rostedt    doprint "  $count configs to test\n";
26950a05c769SSteven Rostedt
26960a05c769SSteven Rostedt    my $half = int($#start_list / 2);
26970a05c769SSteven Rostedt
26980a05c769SSteven Rostedt    do {
26990a05c769SSteven Rostedt	my @tophalf = @start_list[0 .. $half];
27000a05c769SSteven Rostedt
2701cf79fab6SSteven Rostedt	# keep the bottom half off
2702cf79fab6SSteven Rostedt	if ($half < $#start_list) {
2703cf79fab6SSteven Rostedt	    @config_off_tmp = @start_list[$half + 1 .. $#start_list];
2704cf79fab6SSteven Rostedt	} else {
2705cf79fab6SSteven Rostedt	    @config_off_tmp = ();
2706cf79fab6SSteven Rostedt	}
2707cf79fab6SSteven Rostedt
27080a05c769SSteven Rostedt	create_config @tophalf;
27090a05c769SSteven Rostedt	read_current_config \%current_config;
27100a05c769SSteven Rostedt
27110a05c769SSteven Rostedt	$count = $#tophalf + 1;
27120a05c769SSteven Rostedt	doprint "Testing $count configs\n";
27130a05c769SSteven Rostedt	my $found = 0;
27140a05c769SSteven Rostedt	# make sure we test something
27150a05c769SSteven Rostedt	foreach my $config (@tophalf) {
27160a05c769SSteven Rostedt	    if (defined($current_config{$config})) {
27170a05c769SSteven Rostedt		logit " $config\n";
27180a05c769SSteven Rostedt		$found = 1;
27190a05c769SSteven Rostedt	    }
27200a05c769SSteven Rostedt	}
27210a05c769SSteven Rostedt	if (!$found) {
27220a05c769SSteven Rostedt	    # try the other half
27230a05c769SSteven Rostedt	    doprint "Top half produced no set configs, trying bottom half\n";
2724cf79fab6SSteven Rostedt
2725cf79fab6SSteven Rostedt	    # keep the top half off
2726cf79fab6SSteven Rostedt	    @config_off_tmp = @tophalf;
27274c8cc55bSSteven Rostedt	    @tophalf = @start_list[$half + 1 .. $#start_list];
2728cf79fab6SSteven Rostedt
27290a05c769SSteven Rostedt	    create_config @tophalf;
27300a05c769SSteven Rostedt	    read_current_config \%current_config;
27310a05c769SSteven Rostedt	    foreach my $config (@tophalf) {
27320a05c769SSteven Rostedt		if (defined($current_config{$config})) {
27330a05c769SSteven Rostedt		    logit " $config\n";
27340a05c769SSteven Rostedt		    $found = 1;
27350a05c769SSteven Rostedt		}
27360a05c769SSteven Rostedt	    }
27370a05c769SSteven Rostedt	    if (!$found) {
27380a05c769SSteven Rostedt		doprint "Failed: Can't make new config with current configs\n";
27390a05c769SSteven Rostedt		foreach my $config (@start_list) {
27400a05c769SSteven Rostedt		    doprint "  CONFIG: $config\n";
27410a05c769SSteven Rostedt		}
27420a05c769SSteven Rostedt		return -1;
27430a05c769SSteven Rostedt	    }
27440a05c769SSteven Rostedt	    $count = $#tophalf + 1;
27450a05c769SSteven Rostedt	    doprint "Testing $count configs\n";
27460a05c769SSteven Rostedt	}
27470a05c769SSteven Rostedt
27480a05c769SSteven Rostedt	$ret = run_config_bisect_test $type;
2749c960bb9fSSteven Rostedt	if ($bisect_manual) {
2750c960bb9fSSteven Rostedt	    $ret = answer_bisect;
2751c960bb9fSSteven Rostedt	}
27520a05c769SSteven Rostedt	if ($ret) {
27530a05c769SSteven Rostedt	    process_passed %current_config;
27540a05c769SSteven Rostedt	    return 0;
27550a05c769SSteven Rostedt	}
27560a05c769SSteven Rostedt
27570a05c769SSteven Rostedt	doprint "This config had a failure.\n";
27580a05c769SSteven Rostedt	doprint "Removing these configs that were not set in this config:\n";
2759f1a27850SSteven Rostedt	doprint "config copied to $outputdir/config_bad\n";
2760f1a27850SSteven Rostedt	run_command "cp -f $output_config $outputdir/config_bad";
27610a05c769SSteven Rostedt
27620a05c769SSteven Rostedt	# A config exists in this group that was bad.
27630a05c769SSteven Rostedt	foreach my $config (keys %config_list) {
27640a05c769SSteven Rostedt	    if (!defined($current_config{$config})) {
27650a05c769SSteven Rostedt		doprint " removing $config\n";
27660a05c769SSteven Rostedt		delete $config_list{$config};
27670a05c769SSteven Rostedt	    }
27680a05c769SSteven Rostedt	}
27690a05c769SSteven Rostedt
27700a05c769SSteven Rostedt	@start_list = @tophalf;
27710a05c769SSteven Rostedt
27720a05c769SSteven Rostedt	if ($#start_list == 0) {
27730a05c769SSteven Rostedt	    process_failed $start_list[0];
27740a05c769SSteven Rostedt	    return 1;
27750a05c769SSteven Rostedt	}
27760a05c769SSteven Rostedt
27770a05c769SSteven Rostedt	# remove half the configs we are looking at and see if
27780a05c769SSteven Rostedt	# they are good.
27790a05c769SSteven Rostedt	$half = int($#start_list / 2);
27804c8cc55bSSteven Rostedt    } while ($#start_list > 0);
27810a05c769SSteven Rostedt
2782c960bb9fSSteven Rostedt    # we found a single config, try it again unless we are running manually
2783c960bb9fSSteven Rostedt
2784c960bb9fSSteven Rostedt    if ($bisect_manual) {
2785c960bb9fSSteven Rostedt	process_failed $start_list[0];
2786c960bb9fSSteven Rostedt	return 1;
2787c960bb9fSSteven Rostedt    }
2788c960bb9fSSteven Rostedt
27890a05c769SSteven Rostedt    my @tophalf = @start_list[0 .. 0];
27900a05c769SSteven Rostedt
27910a05c769SSteven Rostedt    $ret = run_config_bisect_test $type;
27920a05c769SSteven Rostedt    if ($ret) {
27930a05c769SSteven Rostedt	process_passed %current_config;
27940a05c769SSteven Rostedt	return 0;
27950a05c769SSteven Rostedt    }
27960a05c769SSteven Rostedt
27970a05c769SSteven Rostedt    process_failed $start_list[0];
27980a05c769SSteven Rostedt    return 1;
27990a05c769SSteven Rostedt}
28000a05c769SSteven Rostedt
28010a05c769SSteven Rostedtsub config_bisect {
28020a05c769SSteven Rostedt    my ($i) = @_;
28030a05c769SSteven Rostedt
2804b5f4aea6SSteven Rostedt    my $start_config = $config_bisect;
28050a05c769SSteven Rostedt
28060a05c769SSteven Rostedt    my $tmpconfig = "$tmpdir/use_config";
28070a05c769SSteven Rostedt
280830f75da5SSteven Rostedt    if (defined($config_bisect_good)) {
280930f75da5SSteven Rostedt	process_config_ignore $config_bisect_good;
281030f75da5SSteven Rostedt    }
281130f75da5SSteven Rostedt
28120a05c769SSteven Rostedt    # Make the file with the bad config and the min config
28130a05c769SSteven Rostedt    if (defined($minconfig)) {
28140a05c769SSteven Rostedt	# read the min config for things to ignore
28150a05c769SSteven Rostedt	run_command "cp $minconfig $tmpconfig" or
28160a05c769SSteven Rostedt	    dodie "failed to copy $minconfig to $tmpconfig";
28170a05c769SSteven Rostedt    } else {
28180a05c769SSteven Rostedt	unlink $tmpconfig;
28190a05c769SSteven Rostedt    }
28200a05c769SSteven Rostedt
28210a05c769SSteven Rostedt    if (-f $tmpconfig) {
2822fcb3f16aSSteven Rostedt	load_force_config($tmpconfig);
28230a05c769SSteven Rostedt	process_config_ignore $tmpconfig;
28240a05c769SSteven Rostedt    }
28250a05c769SSteven Rostedt
28260a05c769SSteven Rostedt    # now process the start config
28270a05c769SSteven Rostedt    run_command "cp $start_config $output_config" or
28280a05c769SSteven Rostedt	dodie "failed to copy $start_config to $output_config";
28290a05c769SSteven Rostedt
28300a05c769SSteven Rostedt    # read directly what we want to check
28310a05c769SSteven Rostedt    my %config_check;
28320a05c769SSteven Rostedt    open (IN, $output_config)
2833f9dee311SMasanari Iida	or dodie "failed to open $output_config";
28340a05c769SSteven Rostedt
28350a05c769SSteven Rostedt    while (<IN>) {
28360a05c769SSteven Rostedt	if (/^((CONFIG\S*)=.*)/) {
28370a05c769SSteven Rostedt	    $config_check{$2} = $1;
28380a05c769SSteven Rostedt	}
28390a05c769SSteven Rostedt    }
28400a05c769SSteven Rostedt    close(IN);
28410a05c769SSteven Rostedt
2842250bae8bSSteven Rostedt    # Now run oldconfig with the minconfig
2843fcb3f16aSSteven Rostedt    make_oldconfig;
28440a05c769SSteven Rostedt
28450a05c769SSteven Rostedt    # check to see what we lost (or gained)
28460a05c769SSteven Rostedt    open (IN, $output_config)
28470a05c769SSteven Rostedt	or dodie "Failed to read $start_config";
28480a05c769SSteven Rostedt
28490a05c769SSteven Rostedt    my %removed_configs;
28500a05c769SSteven Rostedt    my %added_configs;
28510a05c769SSteven Rostedt
28520a05c769SSteven Rostedt    while (<IN>) {
28530a05c769SSteven Rostedt	if (/^((CONFIG\S*)=.*)/) {
28540a05c769SSteven Rostedt	    # save off all options
28550a05c769SSteven Rostedt	    $config_set{$2} = $1;
28560a05c769SSteven Rostedt	    if (defined($config_check{$2})) {
28570a05c769SSteven Rostedt		if (defined($config_ignore{$2})) {
28580a05c769SSteven Rostedt		    $removed_configs{$2} = $1;
28590a05c769SSteven Rostedt		} else {
28600a05c769SSteven Rostedt		    $config_list{$2} = $1;
28610a05c769SSteven Rostedt		}
28620a05c769SSteven Rostedt	    } elsif (!defined($config_ignore{$2})) {
28630a05c769SSteven Rostedt		$added_configs{$2} = $1;
28640a05c769SSteven Rostedt		$config_list{$2} = $1;
28650a05c769SSteven Rostedt	    }
2866cf79fab6SSteven Rostedt	} elsif (/^# ((CONFIG\S*).*)/) {
2867cf79fab6SSteven Rostedt	    # Keep these configs disabled
2868cf79fab6SSteven Rostedt	    $config_set{$2} = $1;
2869cf79fab6SSteven Rostedt	    $config_off{$2} = $1;
28700a05c769SSteven Rostedt	}
28710a05c769SSteven Rostedt    }
28720a05c769SSteven Rostedt    close(IN);
28730a05c769SSteven Rostedt
28740a05c769SSteven Rostedt    my @confs = keys %removed_configs;
28750a05c769SSteven Rostedt    if ($#confs >= 0) {
28760a05c769SSteven Rostedt	doprint "Configs overridden by default configs and removed from check:\n";
28770a05c769SSteven Rostedt	foreach my $config (@confs) {
28780a05c769SSteven Rostedt	    doprint " $config\n";
28790a05c769SSteven Rostedt	}
28800a05c769SSteven Rostedt    }
28810a05c769SSteven Rostedt    @confs = keys %added_configs;
28820a05c769SSteven Rostedt    if ($#confs >= 0) {
28830a05c769SSteven Rostedt	doprint "Configs appearing in make oldconfig and added:\n";
28840a05c769SSteven Rostedt	foreach my $config (@confs) {
28850a05c769SSteven Rostedt	    doprint " $config\n";
28860a05c769SSteven Rostedt	}
28870a05c769SSteven Rostedt    }
28880a05c769SSteven Rostedt
28890a05c769SSteven Rostedt    my %config_test;
28900a05c769SSteven Rostedt    my $once = 0;
28910a05c769SSteven Rostedt
2892cf79fab6SSteven Rostedt    @config_off_tmp = ();
2893cf79fab6SSteven Rostedt
28940a05c769SSteven Rostedt    # Sometimes kconfig does weird things. We must make sure
28950a05c769SSteven Rostedt    # that the config we autocreate has everything we need
28960a05c769SSteven Rostedt    # to test, otherwise we may miss testing configs, or
28970a05c769SSteven Rostedt    # may not be able to create a new config.
28980a05c769SSteven Rostedt    # Here we create a config with everything set.
28990a05c769SSteven Rostedt    create_config (keys %config_list);
29000a05c769SSteven Rostedt    read_current_config \%config_test;
29010a05c769SSteven Rostedt    foreach my $config (keys %config_list) {
29020a05c769SSteven Rostedt	if (!defined($config_test{$config})) {
29030a05c769SSteven Rostedt	    if (!$once) {
29040a05c769SSteven Rostedt		$once = 1;
29050a05c769SSteven Rostedt		doprint "Configs not produced by kconfig (will not be checked):\n";
29060a05c769SSteven Rostedt	    }
29070a05c769SSteven Rostedt	    doprint "  $config\n";
29080a05c769SSteven Rostedt	    delete $config_list{$config};
29090a05c769SSteven Rostedt	}
29100a05c769SSteven Rostedt    }
29110a05c769SSteven Rostedt    my $ret;
2912b0918612SSteven Rostedt
2913b0918612SSteven Rostedt    if (defined($config_bisect_check) && $config_bisect_check) {
2914b0918612SSteven Rostedt	doprint " Checking to make sure bad config with min config fails\n";
2915b0918612SSteven Rostedt	create_config keys %config_list;
2916b0918612SSteven Rostedt	$ret = run_config_bisect_test $config_bisect_type;
2917b0918612SSteven Rostedt	if ($ret) {
2918b0918612SSteven Rostedt	    doprint " FAILED! Bad config with min config boots fine\n";
2919b0918612SSteven Rostedt	    return -1;
2920b0918612SSteven Rostedt	}
2921b0918612SSteven Rostedt	doprint " Bad config with min config fails as expected\n";
2922b0918612SSteven Rostedt    }
2923b0918612SSteven Rostedt
29240a05c769SSteven Rostedt    do {
29250a05c769SSteven Rostedt	$ret = run_config_bisect;
29260a05c769SSteven Rostedt    } while (!$ret);
29270a05c769SSteven Rostedt
29280a05c769SSteven Rostedt    return $ret if ($ret < 0);
29295f9b6cedSSteven Rostedt
29305f9b6cedSSteven Rostedt    success $i;
29315f9b6cedSSteven Rostedt}
29325f9b6cedSSteven Rostedt
293327d934b2SSteven Rostedtsub patchcheck_reboot {
293427d934b2SSteven Rostedt    doprint "Reboot and sleep $patchcheck_sleep_time seconds\n";
2935bc7c5803SSteven Rostedt    reboot_to_good $patchcheck_sleep_time;
293627d934b2SSteven Rostedt}
293727d934b2SSteven Rostedt
29386c5ee0beSSteven Rostedtsub patchcheck {
29396c5ee0beSSteven Rostedt    my ($i) = @_;
29406c5ee0beSSteven Rostedt
29416c5ee0beSSteven Rostedt    die "PATCHCHECK_START[$i] not defined\n"
2942b5f4aea6SSteven Rostedt	if (!defined($patchcheck_start));
29436c5ee0beSSteven Rostedt    die "PATCHCHECK_TYPE[$i] not defined\n"
2944b5f4aea6SSteven Rostedt	if (!defined($patchcheck_type));
29456c5ee0beSSteven Rostedt
2946b5f4aea6SSteven Rostedt    my $start = $patchcheck_start;
29476c5ee0beSSteven Rostedt
29486c5ee0beSSteven Rostedt    my $end = "HEAD";
2949b5f4aea6SSteven Rostedt    if (defined($patchcheck_end)) {
2950b5f4aea6SSteven Rostedt	$end = $patchcheck_end;
29516c5ee0beSSteven Rostedt    }
29526c5ee0beSSteven Rostedt
2953a57419b3SSteven Rostedt    # Get the true sha1's since we can use things like HEAD~3
2954a57419b3SSteven Rostedt    $start = get_sha1($start);
2955a57419b3SSteven Rostedt    $end = get_sha1($end);
2956a57419b3SSteven Rostedt
2957b5f4aea6SSteven Rostedt    my $type = $patchcheck_type;
29586c5ee0beSSteven Rostedt
29596c5ee0beSSteven Rostedt    # Can't have a test without having a test to run
29606c5ee0beSSteven Rostedt    if ($type eq "test" && !defined($run_test)) {
29616c5ee0beSSteven Rostedt	$type = "boot";
29626c5ee0beSSteven Rostedt    }
29636c5ee0beSSteven Rostedt
29646c5ee0beSSteven Rostedt    open (IN, "git log --pretty=oneline $end|") or
29656c5ee0beSSteven Rostedt	dodie "could not get git list";
29666c5ee0beSSteven Rostedt
29676c5ee0beSSteven Rostedt    my @list;
29686c5ee0beSSteven Rostedt
29696c5ee0beSSteven Rostedt    while (<IN>) {
29706c5ee0beSSteven Rostedt	chomp;
29716c5ee0beSSteven Rostedt	$list[$#list+1] = $_;
29726c5ee0beSSteven Rostedt	last if (/^$start/);
29736c5ee0beSSteven Rostedt    }
29746c5ee0beSSteven Rostedt    close(IN);
29756c5ee0beSSteven Rostedt
29766c5ee0beSSteven Rostedt    if ($list[$#list] !~ /^$start/) {
29772b7d9b21SSteven Rostedt	fail "SHA1 $start not found";
29786c5ee0beSSteven Rostedt    }
29796c5ee0beSSteven Rostedt
29806c5ee0beSSteven Rostedt    # go backwards in the list
29816c5ee0beSSteven Rostedt    @list = reverse @list;
29826c5ee0beSSteven Rostedt
29836c5ee0beSSteven Rostedt    my $save_clean = $noclean;
29841990207dSSteven Rostedt    my %ignored_warnings;
29851990207dSSteven Rostedt
29861990207dSSteven Rostedt    if (defined($ignore_warnings)) {
29871990207dSSteven Rostedt	foreach my $sha1 (split /\s+/, $ignore_warnings) {
29881990207dSSteven Rostedt	    $ignored_warnings{$sha1} = 1;
29891990207dSSteven Rostedt	}
29901990207dSSteven Rostedt    }
29916c5ee0beSSteven Rostedt
29926c5ee0beSSteven Rostedt    $in_patchcheck = 1;
29936c5ee0beSSteven Rostedt    foreach my $item (@list) {
29946c5ee0beSSteven Rostedt	my $sha1 = $item;
29956c5ee0beSSteven Rostedt	$sha1 =~ s/^([[:xdigit:]]+).*/$1/;
29966c5ee0beSSteven Rostedt
29976c5ee0beSSteven Rostedt	doprint "\nProcessing commit $item\n\n";
29986c5ee0beSSteven Rostedt
29996c5ee0beSSteven Rostedt	run_command "git checkout $sha1" or
30006c5ee0beSSteven Rostedt	    die "Failed to checkout $sha1";
30016c5ee0beSSteven Rostedt
30026c5ee0beSSteven Rostedt	# only clean on the first and last patch
30036c5ee0beSSteven Rostedt	if ($item eq $list[0] ||
30046c5ee0beSSteven Rostedt	    $item eq $list[$#list]) {
30056c5ee0beSSteven Rostedt	    $noclean = $save_clean;
30066c5ee0beSSteven Rostedt	} else {
30076c5ee0beSSteven Rostedt	    $noclean = 1;
30086c5ee0beSSteven Rostedt	}
30096c5ee0beSSteven Rostedt
30106c5ee0beSSteven Rostedt	if (defined($minconfig)) {
30112b7d9b21SSteven Rostedt	    build "useconfig:$minconfig" or return 0;
30126c5ee0beSSteven Rostedt	} else {
30136c5ee0beSSteven Rostedt	    # ?? no config to use?
30142b7d9b21SSteven Rostedt	    build "oldconfig" or return 0;
30156c5ee0beSSteven Rostedt	}
30166c5ee0beSSteven Rostedt
30171990207dSSteven Rostedt
30181990207dSSteven Rostedt	if (!defined($ignored_warnings{$sha1})) {
30192b7d9b21SSteven Rostedt	    check_buildlog $sha1 or return 0;
30201990207dSSteven Rostedt	}
30216c5ee0beSSteven Rostedt
30226c5ee0beSSteven Rostedt	next if ($type eq "build");
30236c5ee0beSSteven Rostedt
30247faafbd6SSteven Rostedt	my $failed = 0;
30257faafbd6SSteven Rostedt
3026ddf607e5SSteven Rostedt	start_monitor_and_boot or $failed = 1;
30277faafbd6SSteven Rostedt
30287faafbd6SSteven Rostedt	if (!$failed && $type ne "boot"){
30297faafbd6SSteven Rostedt	    do_run_test or $failed = 1;
30307faafbd6SSteven Rostedt	}
30317faafbd6SSteven Rostedt	end_monitor;
30327faafbd6SSteven Rostedt	return 0 if ($failed);
30337faafbd6SSteven Rostedt
303427d934b2SSteven Rostedt	patchcheck_reboot;
303527d934b2SSteven Rostedt
30366c5ee0beSSteven Rostedt    }
30376c5ee0beSSteven Rostedt    $in_patchcheck = 0;
30386c5ee0beSSteven Rostedt    success $i;
30392b7d9b21SSteven Rostedt
30402b7d9b21SSteven Rostedt    return 1;
30416c5ee0beSSteven Rostedt}
30426c5ee0beSSteven Rostedt
3043b9066f6cSSteven Rostedtmy %depends;
3044ac6974c7SSteven Rostedtmy %depcount;
3045b9066f6cSSteven Rostedtmy $iflevel = 0;
3046b9066f6cSSteven Rostedtmy @ifdeps;
3047b9066f6cSSteven Rostedt
3048b9066f6cSSteven Rostedt# prevent recursion
3049b9066f6cSSteven Rostedtmy %read_kconfigs;
3050b9066f6cSSteven Rostedt
3051ac6974c7SSteven Rostedtsub add_dep {
3052ac6974c7SSteven Rostedt    # $config depends on $dep
3053ac6974c7SSteven Rostedt    my ($config, $dep) = @_;
3054ac6974c7SSteven Rostedt
3055ac6974c7SSteven Rostedt    if (defined($depends{$config})) {
3056ac6974c7SSteven Rostedt	$depends{$config} .= " " . $dep;
3057ac6974c7SSteven Rostedt    } else {
3058ac6974c7SSteven Rostedt	$depends{$config} = $dep;
3059ac6974c7SSteven Rostedt    }
3060ac6974c7SSteven Rostedt
3061ac6974c7SSteven Rostedt    # record the number of configs depending on $dep
3062ac6974c7SSteven Rostedt    if (defined $depcount{$dep}) {
3063ac6974c7SSteven Rostedt	$depcount{$dep}++;
3064ac6974c7SSteven Rostedt    } else {
3065ac6974c7SSteven Rostedt	$depcount{$dep} = 1;
3066ac6974c7SSteven Rostedt    }
3067ac6974c7SSteven Rostedt}
3068ac6974c7SSteven Rostedt
3069b9066f6cSSteven Rostedt# taken from streamline_config.pl
3070b9066f6cSSteven Rostedtsub read_kconfig {
3071b9066f6cSSteven Rostedt    my ($kconfig) = @_;
3072b9066f6cSSteven Rostedt
3073b9066f6cSSteven Rostedt    my $state = "NONE";
3074b9066f6cSSteven Rostedt    my $config;
3075b9066f6cSSteven Rostedt    my @kconfigs;
3076b9066f6cSSteven Rostedt
3077b9066f6cSSteven Rostedt    my $cont = 0;
3078b9066f6cSSteven Rostedt    my $line;
3079b9066f6cSSteven Rostedt
3080b9066f6cSSteven Rostedt
3081b9066f6cSSteven Rostedt    if (! -f $kconfig) {
3082b9066f6cSSteven Rostedt	doprint "file $kconfig does not exist, skipping\n";
3083b9066f6cSSteven Rostedt	return;
3084b9066f6cSSteven Rostedt    }
3085b9066f6cSSteven Rostedt
3086b9066f6cSSteven Rostedt    open(KIN, "$kconfig")
3087b9066f6cSSteven Rostedt	or die "Can't open $kconfig";
3088b9066f6cSSteven Rostedt    while (<KIN>) {
3089b9066f6cSSteven Rostedt	chomp;
3090b9066f6cSSteven Rostedt
3091b9066f6cSSteven Rostedt	# Make sure that lines ending with \ continue
3092b9066f6cSSteven Rostedt	if ($cont) {
3093b9066f6cSSteven Rostedt	    $_ = $line . " " . $_;
3094b9066f6cSSteven Rostedt	}
3095b9066f6cSSteven Rostedt
3096b9066f6cSSteven Rostedt	if (s/\\$//) {
3097b9066f6cSSteven Rostedt	    $cont = 1;
3098b9066f6cSSteven Rostedt	    $line = $_;
3099b9066f6cSSteven Rostedt	    next;
3100b9066f6cSSteven Rostedt	}
3101b9066f6cSSteven Rostedt
3102b9066f6cSSteven Rostedt	$cont = 0;
3103b9066f6cSSteven Rostedt
3104b9066f6cSSteven Rostedt	# collect any Kconfig sources
3105b9066f6cSSteven Rostedt	if (/^source\s*"(.*)"/) {
3106b9066f6cSSteven Rostedt	    $kconfigs[$#kconfigs+1] = $1;
3107b9066f6cSSteven Rostedt	}
3108b9066f6cSSteven Rostedt
3109b9066f6cSSteven Rostedt	# configs found
3110b9066f6cSSteven Rostedt	if (/^\s*(menu)?config\s+(\S+)\s*$/) {
3111b9066f6cSSteven Rostedt	    $state = "NEW";
3112b9066f6cSSteven Rostedt	    $config = $2;
3113b9066f6cSSteven Rostedt
3114b9066f6cSSteven Rostedt	    for (my $i = 0; $i < $iflevel; $i++) {
3115ac6974c7SSteven Rostedt		add_dep $config, $ifdeps[$i];
3116b9066f6cSSteven Rostedt	    }
3117b9066f6cSSteven Rostedt
3118b9066f6cSSteven Rostedt	# collect the depends for the config
3119b9066f6cSSteven Rostedt	} elsif ($state eq "NEW" && /^\s*depends\s+on\s+(.*)$/) {
3120b9066f6cSSteven Rostedt
3121ac6974c7SSteven Rostedt	    add_dep $config, $1;
3122b9066f6cSSteven Rostedt
3123b9066f6cSSteven Rostedt	# Get the configs that select this config
3124ac6974c7SSteven Rostedt	} elsif ($state eq "NEW" && /^\s*select\s+(\S+)/) {
3125ac6974c7SSteven Rostedt
3126ac6974c7SSteven Rostedt	    # selected by depends on config
3127ac6974c7SSteven Rostedt	    add_dep $1, $config;
3128b9066f6cSSteven Rostedt
3129b9066f6cSSteven Rostedt	# Check for if statements
3130b9066f6cSSteven Rostedt	} elsif (/^if\s+(.*\S)\s*$/) {
3131b9066f6cSSteven Rostedt	    my $deps = $1;
3132b9066f6cSSteven Rostedt	    # remove beginning and ending non text
3133b9066f6cSSteven Rostedt	    $deps =~ s/^[^a-zA-Z0-9_]*//;
3134b9066f6cSSteven Rostedt	    $deps =~ s/[^a-zA-Z0-9_]*$//;
3135b9066f6cSSteven Rostedt
3136b9066f6cSSteven Rostedt	    my @deps = split /[^a-zA-Z0-9_]+/, $deps;
3137b9066f6cSSteven Rostedt
3138b9066f6cSSteven Rostedt	    $ifdeps[$iflevel++] = join ':', @deps;
3139b9066f6cSSteven Rostedt
3140b9066f6cSSteven Rostedt	} elsif (/^endif/) {
3141b9066f6cSSteven Rostedt
3142b9066f6cSSteven Rostedt	    $iflevel-- if ($iflevel);
3143b9066f6cSSteven Rostedt
3144b9066f6cSSteven Rostedt	# stop on "help"
3145b9066f6cSSteven Rostedt	} elsif (/^\s*help\s*$/) {
3146b9066f6cSSteven Rostedt	    $state = "NONE";
3147b9066f6cSSteven Rostedt	}
3148b9066f6cSSteven Rostedt    }
3149b9066f6cSSteven Rostedt    close(KIN);
3150b9066f6cSSteven Rostedt
3151b9066f6cSSteven Rostedt    # read in any configs that were found.
3152b9066f6cSSteven Rostedt    foreach $kconfig (@kconfigs) {
3153b9066f6cSSteven Rostedt	if (!defined($read_kconfigs{$kconfig})) {
3154b9066f6cSSteven Rostedt	    $read_kconfigs{$kconfig} = 1;
3155b9066f6cSSteven Rostedt	    read_kconfig("$builddir/$kconfig");
3156b9066f6cSSteven Rostedt	}
3157b9066f6cSSteven Rostedt    }
3158b9066f6cSSteven Rostedt}
3159b9066f6cSSteven Rostedt
3160b9066f6cSSteven Rostedtsub read_depends {
3161b9066f6cSSteven Rostedt    # find out which arch this is by the kconfig file
3162b9066f6cSSteven Rostedt    open (IN, $output_config)
3163b9066f6cSSteven Rostedt	or dodie "Failed to read $output_config";
3164b9066f6cSSteven Rostedt    my $arch;
3165b9066f6cSSteven Rostedt    while (<IN>) {
3166b9066f6cSSteven Rostedt	if (m,Linux/(\S+)\s+\S+\s+Kernel Configuration,) {
3167b9066f6cSSteven Rostedt	    $arch = $1;
3168b9066f6cSSteven Rostedt	    last;
3169b9066f6cSSteven Rostedt	}
3170b9066f6cSSteven Rostedt    }
3171b9066f6cSSteven Rostedt    close IN;
3172b9066f6cSSteven Rostedt
3173b9066f6cSSteven Rostedt    if (!defined($arch)) {
3174b9066f6cSSteven Rostedt	doprint "Could not find arch from config file\n";
3175b9066f6cSSteven Rostedt	doprint "no dependencies used\n";
3176b9066f6cSSteven Rostedt	return;
3177b9066f6cSSteven Rostedt    }
3178b9066f6cSSteven Rostedt
3179b9066f6cSSteven Rostedt    # arch is really the subarch, we need to know
3180b9066f6cSSteven Rostedt    # what directory to look at.
3181b9066f6cSSteven Rostedt    if ($arch eq "i386" || $arch eq "x86_64") {
3182b9066f6cSSteven Rostedt	$arch = "x86";
3183b9066f6cSSteven Rostedt    } elsif ($arch =~ /^tile/) {
3184b9066f6cSSteven Rostedt	$arch = "tile";
3185b9066f6cSSteven Rostedt    }
3186b9066f6cSSteven Rostedt
3187b9066f6cSSteven Rostedt    my $kconfig = "$builddir/arch/$arch/Kconfig";
3188b9066f6cSSteven Rostedt
3189b9066f6cSSteven Rostedt    if (! -f $kconfig && $arch =~ /\d$/) {
3190b9066f6cSSteven Rostedt	my $orig = $arch;
3191b9066f6cSSteven Rostedt 	# some subarchs have numbers, truncate them
3192b9066f6cSSteven Rostedt	$arch =~ s/\d*$//;
3193b9066f6cSSteven Rostedt	$kconfig = "$builddir/arch/$arch/Kconfig";
3194b9066f6cSSteven Rostedt	if (! -f $kconfig) {
3195b9066f6cSSteven Rostedt	    doprint "No idea what arch dir $orig is for\n";
3196b9066f6cSSteven Rostedt	    doprint "no dependencies used\n";
3197b9066f6cSSteven Rostedt	    return;
3198b9066f6cSSteven Rostedt	}
3199b9066f6cSSteven Rostedt    }
3200b9066f6cSSteven Rostedt
3201b9066f6cSSteven Rostedt    read_kconfig($kconfig);
3202b9066f6cSSteven Rostedt}
3203b9066f6cSSteven Rostedt
32044c4ab120SSteven Rostedtsub read_config_list {
32054c4ab120SSteven Rostedt    my ($config) = @_;
32064c4ab120SSteven Rostedt
32074c4ab120SSteven Rostedt    open (IN, $config)
32084c4ab120SSteven Rostedt	or dodie "Failed to read $config";
32094c4ab120SSteven Rostedt
32104c4ab120SSteven Rostedt    while (<IN>) {
32114c4ab120SSteven Rostedt	if (/^((CONFIG\S*)=.*)/) {
32124c4ab120SSteven Rostedt	    if (!defined($config_ignore{$2})) {
32134c4ab120SSteven Rostedt		$config_list{$2} = $1;
32144c4ab120SSteven Rostedt	    }
32154c4ab120SSteven Rostedt	}
32164c4ab120SSteven Rostedt    }
32174c4ab120SSteven Rostedt
32184c4ab120SSteven Rostedt    close(IN);
32194c4ab120SSteven Rostedt}
32204c4ab120SSteven Rostedt
32214c4ab120SSteven Rostedtsub read_output_config {
32224c4ab120SSteven Rostedt    my ($config) = @_;
32234c4ab120SSteven Rostedt
32244c4ab120SSteven Rostedt    assign_configs \%config_ignore, $config;
32254c4ab120SSteven Rostedt}
32264c4ab120SSteven Rostedt
32274c4ab120SSteven Rostedtsub make_new_config {
32284c4ab120SSteven Rostedt    my @configs = @_;
32294c4ab120SSteven Rostedt
32304c4ab120SSteven Rostedt    open (OUT, ">$output_config")
32314c4ab120SSteven Rostedt	or dodie "Failed to write $output_config";
32324c4ab120SSteven Rostedt
32334c4ab120SSteven Rostedt    foreach my $config (@configs) {
32344c4ab120SSteven Rostedt	print OUT "$config\n";
32354c4ab120SSteven Rostedt    }
32364c4ab120SSteven Rostedt    close OUT;
32374c4ab120SSteven Rostedt}
32384c4ab120SSteven Rostedt
3239ac6974c7SSteven Rostedtsub chomp_config {
3240ac6974c7SSteven Rostedt    my ($config) = @_;
3241ac6974c7SSteven Rostedt
3242ac6974c7SSteven Rostedt    $config =~ s/CONFIG_//;
3243ac6974c7SSteven Rostedt
3244ac6974c7SSteven Rostedt    return $config;
3245ac6974c7SSteven Rostedt}
3246ac6974c7SSteven Rostedt
3247b9066f6cSSteven Rostedtsub get_depends {
3248b9066f6cSSteven Rostedt    my ($dep) = @_;
3249b9066f6cSSteven Rostedt
3250ac6974c7SSteven Rostedt    my $kconfig = chomp_config $dep;
3251b9066f6cSSteven Rostedt
3252b9066f6cSSteven Rostedt    $dep = $depends{"$kconfig"};
3253b9066f6cSSteven Rostedt
3254b9066f6cSSteven Rostedt    # the dep string we have saves the dependencies as they
3255b9066f6cSSteven Rostedt    # were found, including expressions like ! && ||. We
3256b9066f6cSSteven Rostedt    # want to split this out into just an array of configs.
3257b9066f6cSSteven Rostedt
3258b9066f6cSSteven Rostedt    my $valid = "A-Za-z_0-9";
3259b9066f6cSSteven Rostedt
3260b9066f6cSSteven Rostedt    my @configs;
3261b9066f6cSSteven Rostedt
3262b9066f6cSSteven Rostedt    while ($dep =~ /[$valid]/) {
3263b9066f6cSSteven Rostedt
3264b9066f6cSSteven Rostedt	if ($dep =~ /^[^$valid]*([$valid]+)/) {
3265b9066f6cSSteven Rostedt	    my $conf = "CONFIG_" . $1;
3266b9066f6cSSteven Rostedt
3267b9066f6cSSteven Rostedt	    $configs[$#configs + 1] = $conf;
3268b9066f6cSSteven Rostedt
3269b9066f6cSSteven Rostedt	    $dep =~ s/^[^$valid]*[$valid]+//;
3270b9066f6cSSteven Rostedt	} else {
3271b9066f6cSSteven Rostedt	    die "this should never happen";
3272b9066f6cSSteven Rostedt	}
3273b9066f6cSSteven Rostedt    }
3274b9066f6cSSteven Rostedt
3275b9066f6cSSteven Rostedt    return @configs;
3276b9066f6cSSteven Rostedt}
3277b9066f6cSSteven Rostedt
3278b9066f6cSSteven Rostedtmy %min_configs;
3279b9066f6cSSteven Rostedtmy %keep_configs;
328043d1b651SSteven Rostedtmy %save_configs;
3281b9066f6cSSteven Rostedtmy %processed_configs;
3282b9066f6cSSteven Rostedtmy %nochange_config;
3283b9066f6cSSteven Rostedt
3284b9066f6cSSteven Rostedtsub test_this_config {
3285b9066f6cSSteven Rostedt    my ($config) = @_;
3286b9066f6cSSteven Rostedt
3287b9066f6cSSteven Rostedt    my $found;
3288b9066f6cSSteven Rostedt
3289b9066f6cSSteven Rostedt    # if we already processed this config, skip it
3290b9066f6cSSteven Rostedt    if (defined($processed_configs{$config})) {
3291b9066f6cSSteven Rostedt	return undef;
3292b9066f6cSSteven Rostedt    }
3293b9066f6cSSteven Rostedt    $processed_configs{$config} = 1;
3294b9066f6cSSteven Rostedt
3295b9066f6cSSteven Rostedt    # if this config failed during this round, skip it
3296b9066f6cSSteven Rostedt    if (defined($nochange_config{$config})) {
3297b9066f6cSSteven Rostedt	return undef;
3298b9066f6cSSteven Rostedt    }
3299b9066f6cSSteven Rostedt
3300ac6974c7SSteven Rostedt    my $kconfig = chomp_config $config;
3301b9066f6cSSteven Rostedt
3302b9066f6cSSteven Rostedt    # Test dependencies first
3303b9066f6cSSteven Rostedt    if (defined($depends{"$kconfig"})) {
3304b9066f6cSSteven Rostedt	my @parents = get_depends $config;
3305b9066f6cSSteven Rostedt	foreach my $parent (@parents) {
3306b9066f6cSSteven Rostedt	    # if the parent is in the min config, check it first
3307b9066f6cSSteven Rostedt	    next if (!defined($min_configs{$parent}));
3308b9066f6cSSteven Rostedt	    $found = test_this_config($parent);
3309b9066f6cSSteven Rostedt	    if (defined($found)) {
3310b9066f6cSSteven Rostedt		return $found;
3311b9066f6cSSteven Rostedt	    }
3312b9066f6cSSteven Rostedt	}
3313b9066f6cSSteven Rostedt    }
3314b9066f6cSSteven Rostedt
3315b9066f6cSSteven Rostedt    # Remove this config from the list of configs
3316fb16d891SAdam Lee    # do a make olddefconfig and then read the resulting
3317b9066f6cSSteven Rostedt    # .config to make sure it is missing the config that
3318b9066f6cSSteven Rostedt    # we had before
3319b9066f6cSSteven Rostedt    my %configs = %min_configs;
3320b9066f6cSSteven Rostedt    delete $configs{$config};
3321b9066f6cSSteven Rostedt    make_new_config ((values %configs), (values %keep_configs));
3322b9066f6cSSteven Rostedt    make_oldconfig;
3323b9066f6cSSteven Rostedt    undef %configs;
3324b9066f6cSSteven Rostedt    assign_configs \%configs, $output_config;
3325b9066f6cSSteven Rostedt
3326b9066f6cSSteven Rostedt    return $config if (!defined($configs{$config}));
3327b9066f6cSSteven Rostedt
3328b9066f6cSSteven Rostedt    doprint "disabling config $config did not change .config\n";
3329b9066f6cSSteven Rostedt
3330b9066f6cSSteven Rostedt    $nochange_config{$config} = 1;
3331b9066f6cSSteven Rostedt
3332b9066f6cSSteven Rostedt    return undef;
3333b9066f6cSSteven Rostedt}
3334b9066f6cSSteven Rostedt
33354c4ab120SSteven Rostedtsub make_min_config {
33364c4ab120SSteven Rostedt    my ($i) = @_;
33374c4ab120SSteven Rostedt
3338ccc513b6SSteven Rostedt    my $type = $minconfig_type;
3339ccc513b6SSteven Rostedt    if ($type ne "boot" && $type ne "test") {
3340ccc513b6SSteven Rostedt	fail "Invalid MIN_CONFIG_TYPE '$minconfig_type'\n" .
3341ccc513b6SSteven Rostedt	    " make_min_config works only with 'boot' and 'test'\n" and return;
3342ccc513b6SSteven Rostedt    }
3343ccc513b6SSteven Rostedt
33444c4ab120SSteven Rostedt    if (!defined($output_minconfig)) {
33454c4ab120SSteven Rostedt	fail "OUTPUT_MIN_CONFIG not defined" and return;
33464c4ab120SSteven Rostedt    }
334735ce5952SSteven Rostedt
334835ce5952SSteven Rostedt    # If output_minconfig exists, and the start_minconfig
334935ce5952SSteven Rostedt    # came from min_config, than ask if we should use
335035ce5952SSteven Rostedt    # that instead.
335135ce5952SSteven Rostedt    if (-f $output_minconfig && !$start_minconfig_defined) {
335235ce5952SSteven Rostedt	print "$output_minconfig exists\n";
335343de3316SSteven Rostedt	if (!defined($use_output_minconfig)) {
335435ce5952SSteven Rostedt	    if (read_yn " Use it as minconfig?") {
335535ce5952SSteven Rostedt		$start_minconfig = $output_minconfig;
335635ce5952SSteven Rostedt	    }
335743de3316SSteven Rostedt	} elsif ($use_output_minconfig > 0) {
335843de3316SSteven Rostedt	    doprint "Using $output_minconfig as MIN_CONFIG\n";
335943de3316SSteven Rostedt	    $start_minconfig = $output_minconfig;
336043de3316SSteven Rostedt	} else {
336143de3316SSteven Rostedt	    doprint "Set to still use MIN_CONFIG as starting point\n";
336243de3316SSteven Rostedt	}
336335ce5952SSteven Rostedt    }
336435ce5952SSteven Rostedt
33654c4ab120SSteven Rostedt    if (!defined($start_minconfig)) {
33664c4ab120SSteven Rostedt	fail "START_MIN_CONFIG or MIN_CONFIG not defined" and return;
33674c4ab120SSteven Rostedt    }
33684c4ab120SSteven Rostedt
336935ce5952SSteven Rostedt    my $temp_config = "$tmpdir/temp_config";
337035ce5952SSteven Rostedt
33714c4ab120SSteven Rostedt    # First things first. We build an allnoconfig to find
33724c4ab120SSteven Rostedt    # out what the defaults are that we can't touch.
33734c4ab120SSteven Rostedt    # Some are selections, but we really can't handle selections.
33744c4ab120SSteven Rostedt
33754c4ab120SSteven Rostedt    my $save_minconfig = $minconfig;
33764c4ab120SSteven Rostedt    undef $minconfig;
33774c4ab120SSteven Rostedt
33784c4ab120SSteven Rostedt    run_command "$make allnoconfig" or return 0;
33794c4ab120SSteven Rostedt
3380b9066f6cSSteven Rostedt    read_depends;
3381b9066f6cSSteven Rostedt
33824c4ab120SSteven Rostedt    process_config_ignore $output_config;
3383b9066f6cSSteven Rostedt
338443d1b651SSteven Rostedt    undef %save_configs;
3385b9066f6cSSteven Rostedt    undef %min_configs;
33864c4ab120SSteven Rostedt
33874c4ab120SSteven Rostedt    if (defined($ignore_config)) {
33884c4ab120SSteven Rostedt	# make sure the file exists
33894c4ab120SSteven Rostedt	`touch $ignore_config`;
339043d1b651SSteven Rostedt	assign_configs \%save_configs, $ignore_config;
33914c4ab120SSteven Rostedt    }
33924c4ab120SSteven Rostedt
339343d1b651SSteven Rostedt    %keep_configs = %save_configs;
339443d1b651SSteven Rostedt
33954c4ab120SSteven Rostedt    doprint "Load initial configs from $start_minconfig\n";
33964c4ab120SSteven Rostedt
33974c4ab120SSteven Rostedt    # Look at the current min configs, and save off all the
33984c4ab120SSteven Rostedt    # ones that were set via the allnoconfig
33994c4ab120SSteven Rostedt    assign_configs \%min_configs, $start_minconfig;
34004c4ab120SSteven Rostedt
34014c4ab120SSteven Rostedt    my @config_keys = keys %min_configs;
34024c4ab120SSteven Rostedt
3403ac6974c7SSteven Rostedt    # All configs need a depcount
3404ac6974c7SSteven Rostedt    foreach my $config (@config_keys) {
3405ac6974c7SSteven Rostedt	my $kconfig = chomp_config $config;
3406ac6974c7SSteven Rostedt	if (!defined $depcount{$kconfig}) {
3407ac6974c7SSteven Rostedt		$depcount{$kconfig} = 0;
3408ac6974c7SSteven Rostedt	}
3409ac6974c7SSteven Rostedt    }
3410ac6974c7SSteven Rostedt
34114c4ab120SSteven Rostedt    # Remove anything that was set by the make allnoconfig
34124c4ab120SSteven Rostedt    # we shouldn't need them as they get set for us anyway.
34134c4ab120SSteven Rostedt    foreach my $config (@config_keys) {
34144c4ab120SSteven Rostedt	# Remove anything in the ignore_config
34154c4ab120SSteven Rostedt	if (defined($keep_configs{$config})) {
34164c4ab120SSteven Rostedt	    my $file = $ignore_config;
34174c4ab120SSteven Rostedt	    $file =~ s,.*/(.*?)$,$1,;
34184c4ab120SSteven Rostedt	    doprint "$config set by $file ... ignored\n";
34194c4ab120SSteven Rostedt	    delete $min_configs{$config};
34204c4ab120SSteven Rostedt	    next;
34214c4ab120SSteven Rostedt	}
34224c4ab120SSteven Rostedt	# But make sure the settings are the same. If a min config
34234c4ab120SSteven Rostedt	# sets a selection, we do not want to get rid of it if
34244c4ab120SSteven Rostedt	# it is not the same as what we have. Just move it into
34254c4ab120SSteven Rostedt	# the keep configs.
34264c4ab120SSteven Rostedt	if (defined($config_ignore{$config})) {
34274c4ab120SSteven Rostedt	    if ($config_ignore{$config} ne $min_configs{$config}) {
34284c4ab120SSteven Rostedt		doprint "$config is in allnoconfig as '$config_ignore{$config}'";
34294c4ab120SSteven Rostedt		doprint " but it is '$min_configs{$config}' in minconfig .. keeping\n";
34304c4ab120SSteven Rostedt		$keep_configs{$config} = $min_configs{$config};
34314c4ab120SSteven Rostedt	    } else {
34324c4ab120SSteven Rostedt		doprint "$config set by allnoconfig ... ignored\n";
34334c4ab120SSteven Rostedt	    }
34344c4ab120SSteven Rostedt	    delete $min_configs{$config};
34354c4ab120SSteven Rostedt	}
34364c4ab120SSteven Rostedt    }
34374c4ab120SSteven Rostedt
34384c4ab120SSteven Rostedt    my $done = 0;
3439b9066f6cSSteven Rostedt    my $take_two = 0;
34404c4ab120SSteven Rostedt
34414c4ab120SSteven Rostedt    while (!$done) {
34424c4ab120SSteven Rostedt
34434c4ab120SSteven Rostedt	my $config;
34444c4ab120SSteven Rostedt	my $found;
34454c4ab120SSteven Rostedt
34464c4ab120SSteven Rostedt	# Now disable each config one by one and do a make oldconfig
34474c4ab120SSteven Rostedt	# till we find a config that changes our list.
34484c4ab120SSteven Rostedt
34494c4ab120SSteven Rostedt	my @test_configs = keys %min_configs;
3450ac6974c7SSteven Rostedt
3451ac6974c7SSteven Rostedt	# Sort keys by who is most dependent on
3452ac6974c7SSteven Rostedt	@test_configs = sort  { $depcount{chomp_config($b)} <=> $depcount{chomp_config($a)} }
3453ac6974c7SSteven Rostedt			  @test_configs ;
3454ac6974c7SSteven Rostedt
3455ac6974c7SSteven Rostedt	# Put configs that did not modify the config at the end.
34564c4ab120SSteven Rostedt	my $reset = 1;
34574c4ab120SSteven Rostedt	for (my $i = 0; $i < $#test_configs; $i++) {
34584c4ab120SSteven Rostedt	    if (!defined($nochange_config{$test_configs[0]})) {
34594c4ab120SSteven Rostedt		$reset = 0;
34604c4ab120SSteven Rostedt		last;
34614c4ab120SSteven Rostedt	    }
34624c4ab120SSteven Rostedt	    # This config didn't change the .config last time.
34634c4ab120SSteven Rostedt	    # Place it at the end
34644c4ab120SSteven Rostedt	    my $config = shift @test_configs;
34654c4ab120SSteven Rostedt	    push @test_configs, $config;
34664c4ab120SSteven Rostedt	}
34674c4ab120SSteven Rostedt
34684c4ab120SSteven Rostedt	# if every test config has failed to modify the .config file
34694c4ab120SSteven Rostedt	# in the past, then reset and start over.
34704c4ab120SSteven Rostedt	if ($reset) {
34714c4ab120SSteven Rostedt	    undef %nochange_config;
34724c4ab120SSteven Rostedt	}
34734c4ab120SSteven Rostedt
3474b9066f6cSSteven Rostedt	undef %processed_configs;
3475b9066f6cSSteven Rostedt
34764c4ab120SSteven Rostedt	foreach my $config (@test_configs) {
34774c4ab120SSteven Rostedt
3478b9066f6cSSteven Rostedt	    $found = test_this_config $config;
34794c4ab120SSteven Rostedt
3480b9066f6cSSteven Rostedt	    last if (defined($found));
34814c4ab120SSteven Rostedt
34824c4ab120SSteven Rostedt	    # oh well, try another config
34834c4ab120SSteven Rostedt	}
34844c4ab120SSteven Rostedt
34854c4ab120SSteven Rostedt	if (!defined($found)) {
3486b9066f6cSSteven Rostedt	    # we could have failed due to the nochange_config hash
3487b9066f6cSSteven Rostedt	    # reset and try again
3488b9066f6cSSteven Rostedt	    if (!$take_two) {
3489b9066f6cSSteven Rostedt		undef %nochange_config;
3490b9066f6cSSteven Rostedt		$take_two = 1;
3491b9066f6cSSteven Rostedt		next;
3492b9066f6cSSteven Rostedt	    }
34934c4ab120SSteven Rostedt	    doprint "No more configs found that we can disable\n";
34944c4ab120SSteven Rostedt	    $done = 1;
34954c4ab120SSteven Rostedt	    last;
34964c4ab120SSteven Rostedt	}
3497b9066f6cSSteven Rostedt	$take_two = 0;
34984c4ab120SSteven Rostedt
34994c4ab120SSteven Rostedt	$config = $found;
35004c4ab120SSteven Rostedt
35014c4ab120SSteven Rostedt	doprint "Test with $config disabled\n";
35024c4ab120SSteven Rostedt
35034c4ab120SSteven Rostedt	# set in_bisect to keep build and monitor from dieing
35044c4ab120SSteven Rostedt	$in_bisect = 1;
35054c4ab120SSteven Rostedt
35064c4ab120SSteven Rostedt	my $failed = 0;
3507bf1c95abSSteven Rostedt	build "oldconfig" or $failed = 1;
3508bf1c95abSSteven Rostedt	if (!$failed) {
35094c4ab120SSteven Rostedt		start_monitor_and_boot or $failed = 1;
3510ccc513b6SSteven Rostedt
3511ccc513b6SSteven Rostedt		if ($type eq "test" && !$failed) {
3512ccc513b6SSteven Rostedt		    do_run_test or $failed = 1;
3513ccc513b6SSteven Rostedt		}
3514ccc513b6SSteven Rostedt
35154c4ab120SSteven Rostedt		end_monitor;
3516bf1c95abSSteven Rostedt	}
35174c4ab120SSteven Rostedt
35184c4ab120SSteven Rostedt	$in_bisect = 0;
35194c4ab120SSteven Rostedt
35204c4ab120SSteven Rostedt	if ($failed) {
3521b9066f6cSSteven Rostedt	    doprint "$min_configs{$config} is needed to boot the box... keeping\n";
35224c4ab120SSteven Rostedt	    # this config is needed, add it to the ignore list.
35234c4ab120SSteven Rostedt	    $keep_configs{$config} = $min_configs{$config};
352443d1b651SSteven Rostedt	    $save_configs{$config} = $min_configs{$config};
35254c4ab120SSteven Rostedt	    delete $min_configs{$config};
352635ce5952SSteven Rostedt
352735ce5952SSteven Rostedt	    # update new ignore configs
352835ce5952SSteven Rostedt	    if (defined($ignore_config)) {
352935ce5952SSteven Rostedt		open (OUT, ">$temp_config")
353035ce5952SSteven Rostedt		    or die "Can't write to $temp_config";
353143d1b651SSteven Rostedt		foreach my $config (keys %save_configs) {
353243d1b651SSteven Rostedt		    print OUT "$save_configs{$config}\n";
353335ce5952SSteven Rostedt		}
353435ce5952SSteven Rostedt		close OUT;
353535ce5952SSteven Rostedt		run_command "mv $temp_config $ignore_config" or
353635ce5952SSteven Rostedt		    dodie "failed to copy update to $ignore_config";
353735ce5952SSteven Rostedt	    }
353835ce5952SSteven Rostedt
35394c4ab120SSteven Rostedt	} else {
35404c4ab120SSteven Rostedt	    # We booted without this config, remove it from the minconfigs.
35414c4ab120SSteven Rostedt	    doprint "$config is not needed, disabling\n";
35424c4ab120SSteven Rostedt
35434c4ab120SSteven Rostedt	    delete $min_configs{$config};
35444c4ab120SSteven Rostedt
35454c4ab120SSteven Rostedt	    # Also disable anything that is not enabled in this config
35464c4ab120SSteven Rostedt	    my %configs;
35474c4ab120SSteven Rostedt	    assign_configs \%configs, $output_config;
35484c4ab120SSteven Rostedt	    my @config_keys = keys %min_configs;
35494c4ab120SSteven Rostedt	    foreach my $config (@config_keys) {
35504c4ab120SSteven Rostedt		if (!defined($configs{$config})) {
35514c4ab120SSteven Rostedt		    doprint "$config is not set, disabling\n";
35524c4ab120SSteven Rostedt		    delete $min_configs{$config};
35534c4ab120SSteven Rostedt		}
35544c4ab120SSteven Rostedt	    }
35554c4ab120SSteven Rostedt
35564c4ab120SSteven Rostedt	    # Save off all the current mandidory configs
355735ce5952SSteven Rostedt	    open (OUT, ">$temp_config")
355835ce5952SSteven Rostedt		or die "Can't write to $temp_config";
35594c4ab120SSteven Rostedt	    foreach my $config (keys %keep_configs) {
35604c4ab120SSteven Rostedt		print OUT "$keep_configs{$config}\n";
35614c4ab120SSteven Rostedt	    }
35624c4ab120SSteven Rostedt	    foreach my $config (keys %min_configs) {
35634c4ab120SSteven Rostedt		print OUT "$min_configs{$config}\n";
35644c4ab120SSteven Rostedt	    }
35654c4ab120SSteven Rostedt	    close OUT;
356635ce5952SSteven Rostedt
356735ce5952SSteven Rostedt	    run_command "mv $temp_config $output_minconfig" or
356835ce5952SSteven Rostedt		dodie "failed to copy update to $output_minconfig";
35694c4ab120SSteven Rostedt	}
35704c4ab120SSteven Rostedt
35714c4ab120SSteven Rostedt	doprint "Reboot and wait $sleep_time seconds\n";
3572bc7c5803SSteven Rostedt	reboot_to_good $sleep_time;
35734c4ab120SSteven Rostedt    }
35744c4ab120SSteven Rostedt
35754c4ab120SSteven Rostedt    success $i;
35764c4ab120SSteven Rostedt    return 1;
35774c4ab120SSteven Rostedt}
35784c4ab120SSteven Rostedt
35798d1491baSSteven Rostedt$#ARGV < 1 or die "ktest.pl version: $VERSION\n   usage: ktest.pl config-file\n";
35802545eb61SSteven Rostedt
35818d1491baSSteven Rostedtif ($#ARGV == 0) {
35828d1491baSSteven Rostedt    $ktest_config = $ARGV[0];
35838d1491baSSteven Rostedt    if (! -f $ktest_config) {
35848d1491baSSteven Rostedt	print "$ktest_config does not exist.\n";
358535ce5952SSteven Rostedt	if (!read_yn "Create it?") {
35868d1491baSSteven Rostedt	    exit 0;
35878d1491baSSteven Rostedt	}
35888d1491baSSteven Rostedt    }
35898d1491baSSteven Rostedt} else {
35908d1491baSSteven Rostedt    $ktest_config = "ktest.conf";
35918d1491baSSteven Rostedt}
35928d1491baSSteven Rostedt
35938d1491baSSteven Rostedtif (! -f $ktest_config) {
3594dbd3783bSSteven Rostedt    $newconfig = 1;
3595c4261d0fSSteven Rostedt    get_test_case;
35968d1491baSSteven Rostedt    open(OUT, ">$ktest_config") or die "Can not create $ktest_config";
35978d1491baSSteven Rostedt    print OUT << "EOF"
35988d1491baSSteven Rostedt# Generated by ktest.pl
35998d1491baSSteven Rostedt#
36000e7a22deSSteven Rostedt
36010e7a22deSSteven Rostedt# PWD is a ktest.pl variable that will result in the process working
36020e7a22deSSteven Rostedt# directory that ktest.pl is executed in.
36030e7a22deSSteven Rostedt
36040e7a22deSSteven Rostedt# THIS_DIR is automatically assigned the PWD of the path that generated
36050e7a22deSSteven Rostedt# the config file. It is best to use this variable when assigning other
36060e7a22deSSteven Rostedt# directory paths within this directory. This allows you to easily
36070e7a22deSSteven Rostedt# move the test cases to other locations or to other machines.
36080e7a22deSSteven Rostedt#
36090e7a22deSSteven RostedtTHIS_DIR := $variable{"PWD"}
36100e7a22deSSteven Rostedt
36118d1491baSSteven Rostedt# Define each test with TEST_START
36128d1491baSSteven Rostedt# The config options below it will override the defaults
36138d1491baSSteven RostedtTEST_START
3614c4261d0fSSteven RostedtTEST_TYPE = $default{"TEST_TYPE"}
36158d1491baSSteven Rostedt
36168d1491baSSteven RostedtDEFAULTS
36178d1491baSSteven RostedtEOF
36188d1491baSSteven Rostedt;
36198d1491baSSteven Rostedt    close(OUT);
36208d1491baSSteven Rostedt}
36218d1491baSSteven Rostedtread_config $ktest_config;
36228d1491baSSteven Rostedt
362323715c3cSSteven Rostedtif (defined($opt{"LOG_FILE"})) {
362423715c3cSSteven Rostedt    $opt{"LOG_FILE"} = eval_option($opt{"LOG_FILE"}, -1);
362523715c3cSSteven Rostedt}
362623715c3cSSteven Rostedt
36278d1491baSSteven Rostedt# Append any configs entered in manually to the config file.
36288d1491baSSteven Rostedtmy @new_configs = keys %entered_configs;
36298d1491baSSteven Rostedtif ($#new_configs >= 0) {
36308d1491baSSteven Rostedt    print "\nAppending entered in configs to $ktest_config\n";
36318d1491baSSteven Rostedt    open(OUT, ">>$ktest_config") or die "Can not append to $ktest_config";
36328d1491baSSteven Rostedt    foreach my $config (@new_configs) {
36338d1491baSSteven Rostedt	print OUT "$config = $entered_configs{$config}\n";
36340e7a22deSSteven Rostedt	$opt{$config} = process_variables($entered_configs{$config});
36358d1491baSSteven Rostedt    }
36368d1491baSSteven Rostedt}
36372545eb61SSteven Rostedt
36382b7d9b21SSteven Rostedtif ($opt{"CLEAR_LOG"} && defined($opt{"LOG_FILE"})) {
36392b7d9b21SSteven Rostedt    unlink $opt{"LOG_FILE"};
36402b7d9b21SSteven Rostedt}
36412545eb61SSteven Rostedt
36422b7d9b21SSteven Rostedtdoprint "\n\nSTARTING AUTOMATED TESTS\n\n";
36432b7d9b21SSteven Rostedt
3644a57419b3SSteven Rostedtfor (my $i = 0, my $repeat = 1; $i <= $opt{"NUM_TESTS"}; $i += $repeat) {
3645a57419b3SSteven Rostedt
3646a57419b3SSteven Rostedt    if (!$i) {
3647a57419b3SSteven Rostedt	doprint "DEFAULT OPTIONS:\n";
3648a57419b3SSteven Rostedt    } else {
3649a57419b3SSteven Rostedt	doprint "\nTEST $i OPTIONS";
3650a57419b3SSteven Rostedt	if (defined($repeat_tests{$i})) {
3651a57419b3SSteven Rostedt	    $repeat = $repeat_tests{$i};
3652a57419b3SSteven Rostedt	    doprint " ITERATE $repeat";
3653a57419b3SSteven Rostedt	}
3654a57419b3SSteven Rostedt	doprint "\n";
3655a57419b3SSteven Rostedt    }
3656a57419b3SSteven Rostedt
36572b7d9b21SSteven Rostedt    foreach my $option (sort keys %opt) {
3658a57419b3SSteven Rostedt
3659a57419b3SSteven Rostedt	if ($option =~ /\[(\d+)\]$/) {
3660a57419b3SSteven Rostedt	    next if ($i != $1);
3661a57419b3SSteven Rostedt	} else {
3662a57419b3SSteven Rostedt	    next if ($i);
3663a57419b3SSteven Rostedt	}
3664a57419b3SSteven Rostedt
36652b7d9b21SSteven Rostedt	doprint "$option = $opt{$option}\n";
36662b7d9b21SSteven Rostedt    }
3667a57419b3SSteven Rostedt}
36682545eb61SSteven Rostedt
36692a62512bSSteven Rostedtsub __set_test_option {
36705a391fbfSSteven Rostedt    my ($name, $i) = @_;
36715a391fbfSSteven Rostedt
36725a391fbfSSteven Rostedt    my $option = "$name\[$i\]";
36735a391fbfSSteven Rostedt
36745a391fbfSSteven Rostedt    if (defined($opt{$option})) {
36755a391fbfSSteven Rostedt	return $opt{$option};
36765a391fbfSSteven Rostedt    }
36775a391fbfSSteven Rostedt
3678a57419b3SSteven Rostedt    foreach my $test (keys %repeat_tests) {
3679a57419b3SSteven Rostedt	if ($i >= $test &&
3680a57419b3SSteven Rostedt	    $i < $test + $repeat_tests{$test}) {
3681a57419b3SSteven Rostedt	    $option = "$name\[$test\]";
3682a57419b3SSteven Rostedt	    if (defined($opt{$option})) {
3683a57419b3SSteven Rostedt		return $opt{$option};
3684a57419b3SSteven Rostedt	    }
3685a57419b3SSteven Rostedt	}
3686a57419b3SSteven Rostedt    }
3687a57419b3SSteven Rostedt
36885a391fbfSSteven Rostedt    if (defined($opt{$name})) {
36895a391fbfSSteven Rostedt	return $opt{$name};
36905a391fbfSSteven Rostedt    }
36915a391fbfSSteven Rostedt
36925a391fbfSSteven Rostedt    return undef;
36935a391fbfSSteven Rostedt}
36945a391fbfSSteven Rostedt
36952a62512bSSteven Rostedtsub set_test_option {
36962a62512bSSteven Rostedt    my ($name, $i) = @_;
36972a62512bSSteven Rostedt
36982a62512bSSteven Rostedt    my $option = __set_test_option($name, $i);
36992a62512bSSteven Rostedt    return $option if (!defined($option));
37002a62512bSSteven Rostedt
370123715c3cSSteven Rostedt    return eval_option($option, $i);
37022a62512bSSteven Rostedt}
37032a62512bSSteven Rostedt
37042545eb61SSteven Rostedt# First we need to do is the builds
3705a75fececSSteven Rostedtfor (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
37062545eb61SSteven Rostedt
37074ab1cce5SSteven Rostedt    # Do not reboot on failing test options
37084ab1cce5SSteven Rostedt    $no_reboot = 1;
3709759a3cc6SSteven Rostedt    $reboot_success = 0;
37104ab1cce5SSteven Rostedt
3711683a3e64SSteven Rostedt    $have_version = 0;
3712683a3e64SSteven Rostedt
3713576f627cSSteven Rostedt    $iteration = $i;
3714576f627cSSteven Rostedt
3715c1434dccSSteven Rostedt    undef %force_config;
3716c1434dccSSteven Rostedt
3717a75fececSSteven Rostedt    my $makecmd = set_test_option("MAKE_CMD", $i);
3718a75fececSSteven Rostedt
37199cc9e091SSteven Rostedt    # Load all the options into their mapped variable names
37209cc9e091SSteven Rostedt    foreach my $opt (keys %option_map) {
37219cc9e091SSteven Rostedt	${$option_map{$opt}} = set_test_option($opt, $i);
37229cc9e091SSteven Rostedt    }
3723b5f4aea6SSteven Rostedt
372435ce5952SSteven Rostedt    $start_minconfig_defined = 1;
372535ce5952SSteven Rostedt
3726921ed4c7SSteven Rostedt    # The first test may override the PRE_KTEST option
3727921ed4c7SSteven Rostedt    if (defined($pre_ktest) && $i == 1) {
3728921ed4c7SSteven Rostedt	doprint "\n";
3729921ed4c7SSteven Rostedt	run_command $pre_ktest;
3730921ed4c7SSteven Rostedt    }
3731921ed4c7SSteven Rostedt
3732921ed4c7SSteven Rostedt    # Any test can override the POST_KTEST option
3733921ed4c7SSteven Rostedt    # The last test takes precedence.
3734921ed4c7SSteven Rostedt    if (defined($post_ktest)) {
3735921ed4c7SSteven Rostedt	$final_post_ktest = $post_ktest;
3736921ed4c7SSteven Rostedt    }
3737921ed4c7SSteven Rostedt
37384c4ab120SSteven Rostedt    if (!defined($start_minconfig)) {
373935ce5952SSteven Rostedt	$start_minconfig_defined = 0;
37404c4ab120SSteven Rostedt	$start_minconfig = $minconfig;
37414c4ab120SSteven Rostedt    }
37424c4ab120SSteven Rostedt
3743a75fececSSteven Rostedt    chdir $builddir || die "can't change directory to $builddir";
3744a75fececSSteven Rostedt
3745a908a665SAndrew Jones    foreach my $dir ($tmpdir, $outputdir) {
3746a908a665SAndrew Jones	if (!-d $dir) {
3747a908a665SAndrew Jones	    mkpath($dir) or
3748a908a665SAndrew Jones		die "can't create $dir";
3749a908a665SAndrew Jones	}
3750a75fececSSteven Rostedt    }
3751a75fececSSteven Rostedt
3752e48c5293SSteven Rostedt    $ENV{"SSH_USER"} = $ssh_user;
3753e48c5293SSteven Rostedt    $ENV{"MACHINE"} = $machine;
3754e48c5293SSteven Rostedt
3755a75fececSSteven Rostedt    $buildlog = "$tmpdir/buildlog-$machine";
3756a9dd5d63SRabin Vincent    $testlog = "$tmpdir/testlog-$machine";
3757a75fececSSteven Rostedt    $dmesg = "$tmpdir/dmesg-$machine";
3758a75fececSSteven Rostedt    $make = "$makecmd O=$outputdir";
375951ad1dd1SSteven Rostedt    $output_config = "$outputdir/.config";
3760a75fececSSteven Rostedt
3761bb8474b1SSteven Rostedt    if (!$buildonly) {
3762bb8474b1SSteven Rostedt	$target = "$ssh_user\@$machine";
3763a75fececSSteven Rostedt	if ($reboot_type eq "grub") {
3764576f627cSSteven Rostedt	    dodie "GRUB_MENU not defined" if (!defined($grub_menu));
3765*a15ba913SSteven Rostedt	} elsif ($reboot_type eq "grub2") {
3766*a15ba913SSteven Rostedt	    dodie "GRUB_MENU not defined" if (!defined($grub_menu));
3767*a15ba913SSteven Rostedt	    dodie "GRUB_FILE not defined" if (!defined($grub_file));
3768a75fececSSteven Rostedt	}
3769bb8474b1SSteven Rostedt    }
3770a75fececSSteven Rostedt
3771a75fececSSteven Rostedt    my $run_type = $build_type;
3772a75fececSSteven Rostedt    if ($test_type eq "patchcheck") {
3773b5f4aea6SSteven Rostedt	$run_type = $patchcheck_type;
3774a75fececSSteven Rostedt    } elsif ($test_type eq "bisect") {
3775b5f4aea6SSteven Rostedt	$run_type = $bisect_type;
37760a05c769SSteven Rostedt    } elsif ($test_type eq "config_bisect") {
3777b5f4aea6SSteven Rostedt	$run_type = $config_bisect_type;
3778a75fececSSteven Rostedt    }
3779a75fececSSteven Rostedt
37804c4ab120SSteven Rostedt    if ($test_type eq "make_min_config") {
37814c4ab120SSteven Rostedt	$run_type = "";
37824c4ab120SSteven Rostedt    }
37834c4ab120SSteven Rostedt
3784a75fececSSteven Rostedt    # mistake in config file?
3785a75fececSSteven Rostedt    if (!defined($run_type)) {
3786a75fececSSteven Rostedt	$run_type = "ERROR";
3787a75fececSSteven Rostedt    }
37882545eb61SSteven Rostedt
3789e0a8742eSSteven Rostedt    my $installme = "";
3790e0a8742eSSteven Rostedt    $installme = " no_install" if ($no_install);
3791e0a8742eSSteven Rostedt
37922545eb61SSteven Rostedt    doprint "\n\n";
3793e0a8742eSSteven Rostedt    doprint "RUNNING TEST $i of $opt{NUM_TESTS} with option $test_type $run_type$installme\n\n";
37947faafbd6SSteven Rostedt
3795921ed4c7SSteven Rostedt    if (defined($pre_test)) {
3796921ed4c7SSteven Rostedt	run_command $pre_test;
3797921ed4c7SSteven Rostedt    }
3798921ed4c7SSteven Rostedt
37997faafbd6SSteven Rostedt    unlink $dmesg;
38007faafbd6SSteven Rostedt    unlink $buildlog;
3801a9dd5d63SRabin Vincent    unlink $testlog;
38022545eb61SSteven Rostedt
3803250bae8bSSteven Rostedt    if (defined($addconfig)) {
3804250bae8bSSteven Rostedt	my $min = $minconfig;
38052b7d9b21SSteven Rostedt	if (!defined($minconfig)) {
3806250bae8bSSteven Rostedt	    $min = "";
3807250bae8bSSteven Rostedt	}
3808250bae8bSSteven Rostedt	run_command "cat $addconfig $min > $tmpdir/add_config" or
38092b7d9b21SSteven Rostedt	    dodie "Failed to create temp config";
38109be2e6b5SSteven Rostedt	$minconfig = "$tmpdir/add_config";
38112b7d9b21SSteven Rostedt    }
38122b7d9b21SSteven Rostedt
38136c5ee0beSSteven Rostedt    if (defined($checkout)) {
38146c5ee0beSSteven Rostedt	run_command "git checkout $checkout" or
38156c5ee0beSSteven Rostedt	    die "failed to checkout $checkout";
38166c5ee0beSSteven Rostedt    }
38176c5ee0beSSteven Rostedt
3818759a3cc6SSteven Rostedt    $no_reboot = 0;
3819759a3cc6SSteven Rostedt
3820648a182cSSteven Rostedt    # A test may opt to not reboot the box
3821648a182cSSteven Rostedt    if ($reboot_on_success) {
3822759a3cc6SSteven Rostedt	$reboot_success = 1;
3823648a182cSSteven Rostedt    }
38244ab1cce5SSteven Rostedt
3825a75fececSSteven Rostedt    if ($test_type eq "bisect") {
38265f9b6cedSSteven Rostedt	bisect $i;
38275f9b6cedSSteven Rostedt	next;
38280a05c769SSteven Rostedt    } elsif ($test_type eq "config_bisect") {
38290a05c769SSteven Rostedt	config_bisect $i;
38300a05c769SSteven Rostedt	next;
3831a75fececSSteven Rostedt    } elsif ($test_type eq "patchcheck") {
38326c5ee0beSSteven Rostedt	patchcheck $i;
38336c5ee0beSSteven Rostedt	next;
38344c4ab120SSteven Rostedt    } elsif ($test_type eq "make_min_config") {
38354c4ab120SSteven Rostedt	make_min_config $i;
38364c4ab120SSteven Rostedt	next;
38375f9b6cedSSteven Rostedt    }
38385f9b6cedSSteven Rostedt
38397faafbd6SSteven Rostedt    if ($build_type ne "nobuild") {
38407faafbd6SSteven Rostedt	build $build_type or next;
38412545eb61SSteven Rostedt    }
38422545eb61SSteven Rostedt
3843cd8e368fSSteven Rostedt    if ($test_type eq "install") {
3844cd8e368fSSteven Rostedt	get_version;
3845cd8e368fSSteven Rostedt	install;
3846cd8e368fSSteven Rostedt	success $i;
3847cd8e368fSSteven Rostedt	next;
3848cd8e368fSSteven Rostedt    }
3849cd8e368fSSteven Rostedt
3850a75fececSSteven Rostedt    if ($test_type ne "build") {
38517faafbd6SSteven Rostedt	my $failed = 0;
3852ddf607e5SSteven Rostedt	start_monitor_and_boot or $failed = 1;
3853a75fececSSteven Rostedt
3854a75fececSSteven Rostedt	if (!$failed && $test_type ne "boot" && defined($run_test)) {
38557faafbd6SSteven Rostedt	    do_run_test or $failed = 1;
38565a391fbfSSteven Rostedt	}
38577faafbd6SSteven Rostedt	end_monitor;
38587faafbd6SSteven Rostedt	next if ($failed);
3859a75fececSSteven Rostedt    }
38605a391fbfSSteven Rostedt
38615f9b6cedSSteven Rostedt    success $i;
386275c3fda7SSteven Rostedt}
38632545eb61SSteven Rostedt
3864921ed4c7SSteven Rostedtif (defined($final_post_ktest)) {
3865921ed4c7SSteven Rostedt    run_command $final_post_ktest;
3866921ed4c7SSteven Rostedt}
3867921ed4c7SSteven Rostedt
38685c42fc5bSSteven Rostedtif ($opt{"POWEROFF_ON_SUCCESS"}) {
386975c3fda7SSteven Rostedt    halt;
3870759a3cc6SSteven Rostedt} elsif ($opt{"REBOOT_ON_SUCCESS"} && !do_not_reboot && $reboot_success) {
3871bc7c5803SSteven Rostedt    reboot_to_good;
3872648a182cSSteven Rostedt} elsif (defined($switch_to_good)) {
3873648a182cSSteven Rostedt    # still need to get to the good kernel
3874648a182cSSteven Rostedt    run_command $switch_to_good;
38755c42fc5bSSteven Rostedt}
387675c3fda7SSteven Rostedt
3877648a182cSSteven Rostedt
3878e48c5293SSteven Rostedtdoprint "\n    $successes of $opt{NUM_TESTS} tests were successful\n\n";
3879e48c5293SSteven Rostedt
38802545eb61SSteven Rostedtexit 0;
3881