xref: /openbmc/linux/tools/testing/ktest/ktest.pl (revision e1a6c3d748ef0ee093e764af3fdd0c1a5cd2b664)
12545eb61SSteven Rostedt#!/usr/bin/perl -w
2d6ce2a0bSSteven Rostedt#
3cce1dac8SUwe Kleine-König# Copyright 2010 - Steven Rostedt <srostedt@redhat.com>, Red Hat Inc.
4d6ce2a0bSSteven Rostedt# Licensed under the terms of the GNU GPL License version 2
5d6ce2a0bSSteven Rostedt#
62545eb61SSteven Rostedt
72545eb61SSteven Rostedtuse strict;
82545eb61SSteven Rostedtuse IPC::Open2;
92545eb61SSteven Rostedtuse Fcntl qw(F_GETFL F_SETFL O_NONBLOCK);
107faafbd6SSteven Rostedtuse File::Path qw(mkpath);
117faafbd6SSteven Rostedtuse File::Copy qw(cp);
122545eb61SSteven Rostedtuse FileHandle;
132545eb61SSteven Rostedt
14e48c5293SSteven Rostedtmy $VERSION = "0.2";
15e48c5293SSteven Rostedt
162545eb61SSteven Rostedt$| = 1;
172545eb61SSteven Rostedt
182545eb61SSteven Rostedtmy %opt;
19a57419b3SSteven Rostedtmy %repeat_tests;
20a57419b3SSteven Rostedtmy %repeats;
212545eb61SSteven Rostedt
222545eb61SSteven Rostedt#default opts
234f43e0dcSSteven Rostedtmy %default = (
244f43e0dcSSteven Rostedt    "NUM_TESTS"			=> 1,
254f43e0dcSSteven Rostedt    "TEST_TYPE"			=> "build",
264f43e0dcSSteven Rostedt    "BUILD_TYPE"		=> "randconfig",
274f43e0dcSSteven Rostedt    "MAKE_CMD"			=> "make",
284f43e0dcSSteven Rostedt    "TIMEOUT"			=> 120,
294f43e0dcSSteven Rostedt    "TMP_DIR"			=> "/tmp/ktest/\${MACHINE}",
304f43e0dcSSteven Rostedt    "SLEEP_TIME"		=> 60,	# sleep time between tests
314f43e0dcSSteven Rostedt    "BUILD_NOCLEAN"		=> 0,
324f43e0dcSSteven Rostedt    "REBOOT_ON_ERROR"		=> 0,
334f43e0dcSSteven Rostedt    "POWEROFF_ON_ERROR"		=> 0,
344f43e0dcSSteven Rostedt    "REBOOT_ON_SUCCESS"		=> 1,
354f43e0dcSSteven Rostedt    "POWEROFF_ON_SUCCESS"	=> 0,
364f43e0dcSSteven Rostedt    "BUILD_OPTIONS"		=> "",
374f43e0dcSSteven Rostedt    "BISECT_SLEEP_TIME"		=> 60,   # sleep time between bisects
384f43e0dcSSteven Rostedt    "PATCHCHECK_SLEEP_TIME"	=> 60, # sleep time between patch checks
394f43e0dcSSteven Rostedt    "CLEAR_LOG"			=> 0,
404f43e0dcSSteven Rostedt    "BISECT_MANUAL"		=> 0,
414f43e0dcSSteven Rostedt    "BISECT_SKIP"		=> 1,
42ccc513b6SSteven Rostedt    "MIN_CONFIG_TYPE"		=> "boot",
434f43e0dcSSteven Rostedt    "SUCCESS_LINE"		=> "login:",
444f43e0dcSSteven Rostedt    "DETECT_TRIPLE_FAULT"	=> 1,
454f43e0dcSSteven Rostedt    "NO_INSTALL"		=> 0,
464f43e0dcSSteven Rostedt    "BOOTED_TIMEOUT"		=> 1,
474f43e0dcSSteven Rostedt    "DIE_ON_FAILURE"		=> 1,
484f43e0dcSSteven Rostedt    "SSH_EXEC"			=> "ssh \$SSH_USER\@\$MACHINE \$SSH_COMMAND",
494f43e0dcSSteven Rostedt    "SCP_TO_TARGET"		=> "scp \$SRC_FILE \$SSH_USER\@\$MACHINE:\$DST_FILE",
5002ad2617SSteven Rostedt    "SCP_TO_TARGET_INSTALL"	=> "\${SCP_TO_TARGET}",
514f43e0dcSSteven Rostedt    "REBOOT"			=> "ssh \$SSH_USER\@\$MACHINE reboot",
524f43e0dcSSteven Rostedt    "STOP_AFTER_SUCCESS"	=> 10,
534f43e0dcSSteven Rostedt    "STOP_AFTER_FAILURE"	=> 60,
544f43e0dcSSteven Rostedt    "STOP_TEST_AFTER"		=> 600,
55407b95b7SSteven Rostedt    "MAX_MONITOR_WAIT"		=> 1800,
56a15ba913SSteven Rostedt    "GRUB_REBOOT"		=> "grub2-reboot",
577786954cSSteven Rostedt    "SYSLINUX"			=> "extlinux",
587786954cSSteven Rostedt    "SYSLINUX_PATH"		=> "/boot/extlinux",
59600bbf0aSSteven Rostedt
60600bbf0aSSteven Rostedt# required, and we will ask users if they don't have them but we keep the default
61600bbf0aSSteven Rostedt# value something that is common.
624f43e0dcSSteven Rostedt    "REBOOT_TYPE"		=> "grub",
634f43e0dcSSteven Rostedt    "LOCALVERSION"		=> "-test",
644f43e0dcSSteven Rostedt    "SSH_USER"			=> "root",
654f43e0dcSSteven Rostedt    "BUILD_TARGET"	 	=> "arch/x86/boot/bzImage",
664f43e0dcSSteven Rostedt    "TARGET_IMAGE"		=> "/boot/vmlinuz-test",
679cc9e091SSteven Rostedt
689cc9e091SSteven Rostedt    "LOG_FILE"			=> undef,
699cc9e091SSteven Rostedt    "IGNORE_UNUSED"		=> 0,
704f43e0dcSSteven Rostedt);
712545eb61SSteven Rostedt
728d1491baSSteven Rostedtmy $ktest_config;
732545eb61SSteven Rostedtmy $version;
74683a3e64SSteven Rostedtmy $have_version = 0;
75a75fececSSteven Rostedtmy $machine;
76e48c5293SSteven Rostedtmy $ssh_user;
77a75fececSSteven Rostedtmy $tmpdir;
78a75fececSSteven Rostedtmy $builddir;
79a75fececSSteven Rostedtmy $outputdir;
8051ad1dd1SSteven Rostedtmy $output_config;
81a75fececSSteven Rostedtmy $test_type;
827faafbd6SSteven Rostedtmy $build_type;
83a75fececSSteven Rostedtmy $build_options;
84921ed4c7SSteven Rostedtmy $final_post_ktest;
85921ed4c7SSteven Rostedtmy $pre_ktest;
86921ed4c7SSteven Rostedtmy $post_ktest;
87921ed4c7SSteven Rostedtmy $pre_test;
88921ed4c7SSteven Rostedtmy $post_test;
890bd6c1a3SSteven Rostedtmy $pre_build;
900bd6c1a3SSteven Rostedtmy $post_build;
910bd6c1a3SSteven Rostedtmy $pre_build_die;
920bd6c1a3SSteven Rostedtmy $post_build_die;
93a75fececSSteven Rostedtmy $reboot_type;
94a75fececSSteven Rostedtmy $reboot_script;
95a75fececSSteven Rostedtmy $power_cycle;
96e48c5293SSteven Rostedtmy $reboot;
97a75fececSSteven Rostedtmy $reboot_on_error;
98bc7c5803SSteven Rostedtmy $switch_to_good;
99bc7c5803SSteven Rostedtmy $switch_to_test;
100a75fececSSteven Rostedtmy $poweroff_on_error;
101648a182cSSteven Rostedtmy $reboot_on_success;
102a75fececSSteven Rostedtmy $die_on_failure;
103576f627cSSteven Rostedtmy $powercycle_after_reboot;
104576f627cSSteven Rostedtmy $poweroff_after_halt;
105407b95b7SSteven Rostedtmy $max_monitor_wait;
106e48c5293SSteven Rostedtmy $ssh_exec;
107e48c5293SSteven Rostedtmy $scp_to_target;
10802ad2617SSteven Rostedtmy $scp_to_target_install;
109a75fececSSteven Rostedtmy $power_off;
110a75fececSSteven Rostedtmy $grub_menu;
111a15ba913SSteven Rostedtmy $grub_file;
1122545eb61SSteven Rostedtmy $grub_number;
113a15ba913SSteven Rostedtmy $grub_reboot;
1147786954cSSteven Rostedtmy $syslinux;
1157786954cSSteven Rostedtmy $syslinux_path;
1167786954cSSteven Rostedtmy $syslinux_label;
1172545eb61SSteven Rostedtmy $target;
1182545eb61SSteven Rostedtmy $make;
119e5c2ec11SSteven Rostedtmy $pre_install;
1208b37ca8cSSteven Rostedtmy $post_install;
121e0a8742eSSteven Rostedtmy $no_install;
1225c42fc5bSSteven Rostedtmy $noclean;
1235f9b6cedSSteven Rostedtmy $minconfig;
1244c4ab120SSteven Rostedtmy $start_minconfig;
12535ce5952SSteven Rostedtmy $start_minconfig_defined;
1264c4ab120SSteven Rostedtmy $output_minconfig;
127ccc513b6SSteven Rostedtmy $minconfig_type;
12843de3316SSteven Rostedtmy $use_output_minconfig;
1294c4ab120SSteven Rostedtmy $ignore_config;
130be405f95SSteven Rostedtmy $ignore_errors;
1312b7d9b21SSteven Rostedtmy $addconfig;
1325f9b6cedSSteven Rostedtmy $in_bisect = 0;
133b5f4aea6SSteven Rostedtmy $bisect_bad_commit = "";
134d6ce2a0bSSteven Rostedtmy $reverse_bisect;
135c960bb9fSSteven Rostedtmy $bisect_manual;
136c23dca7cSSteven Rostedtmy $bisect_skip;
13730f75da5SSteven Rostedtmy $config_bisect_good;
138c5dacb88SSteven Rostedtmy $bisect_ret_good;
139c5dacb88SSteven Rostedtmy $bisect_ret_bad;
140c5dacb88SSteven Rostedtmy $bisect_ret_skip;
141c5dacb88SSteven Rostedtmy $bisect_ret_abort;
142c5dacb88SSteven Rostedtmy $bisect_ret_default;
1436c5ee0beSSteven Rostedtmy $in_patchcheck = 0;
1445a391fbfSSteven Rostedtmy $run_test;
1456c5ee0beSSteven Rostedtmy $redirect;
1467faafbd6SSteven Rostedtmy $buildlog;
147a9dd5d63SRabin Vincentmy $testlog;
1487faafbd6SSteven Rostedtmy $dmesg;
1497faafbd6SSteven Rostedtmy $monitor_fp;
1507faafbd6SSteven Rostedtmy $monitor_pid;
1517faafbd6SSteven Rostedtmy $monitor_cnt = 0;
152a75fececSSteven Rostedtmy $sleep_time;
153a75fececSSteven Rostedtmy $bisect_sleep_time;
15427d934b2SSteven Rostedtmy $patchcheck_sleep_time;
1551990207dSSteven Rostedtmy $ignore_warnings;
156a75fececSSteven Rostedtmy $store_failures;
157de5b6e3bSRabin Vincentmy $store_successes;
1589064af52SSteven Rostedtmy $test_name;
159a75fececSSteven Rostedtmy $timeout;
160a75fececSSteven Rostedtmy $booted_timeout;
161f1a5b962SSteven Rostedtmy $detect_triplefault;
162a75fececSSteven Rostedtmy $console;
1632b803365SSteven Rostedtmy $reboot_success_line;
164a75fececSSteven Rostedtmy $success_line;
1651c8a617aSSteven Rostedtmy $stop_after_success;
1661c8a617aSSteven Rostedtmy $stop_after_failure;
1672d01b26aSSteven Rostedtmy $stop_test_after;
168a75fececSSteven Rostedtmy $build_target;
169a75fececSSteven Rostedtmy $target_image;
170b5f4aea6SSteven Rostedtmy $checkout;
171a75fececSSteven Rostedtmy $localversion;
172576f627cSSteven Rostedtmy $iteration = 0;
173e48c5293SSteven Rostedtmy $successes = 0;
1742545eb61SSteven Rostedt
175b5f4aea6SSteven Rostedtmy $bisect_good;
176b5f4aea6SSteven Rostedtmy $bisect_bad;
177b5f4aea6SSteven Rostedtmy $bisect_type;
178b5f4aea6SSteven Rostedtmy $bisect_start;
179b5f4aea6SSteven Rostedtmy $bisect_replay;
180b5f4aea6SSteven Rostedtmy $bisect_files;
181b5f4aea6SSteven Rostedtmy $bisect_reverse;
182b5f4aea6SSteven Rostedtmy $bisect_check;
183b5f4aea6SSteven Rostedt
184b5f4aea6SSteven Rostedtmy $config_bisect;
185b5f4aea6SSteven Rostedtmy $config_bisect_type;
186b0918612SSteven Rostedtmy $config_bisect_check;
187b5f4aea6SSteven Rostedt
188b5f4aea6SSteven Rostedtmy $patchcheck_type;
189b5f4aea6SSteven Rostedtmy $patchcheck_start;
190b5f4aea6SSteven Rostedtmy $patchcheck_end;
191b5f4aea6SSteven Rostedt
192165708b2SSteven Rostedt# set when a test is something other that just building or install
193bb8474b1SSteven Rostedt# which would require more options.
194bb8474b1SSteven Rostedtmy $buildonly = 1;
195bb8474b1SSteven Rostedt
196dbd3783bSSteven Rostedt# set when creating a new config
197dbd3783bSSteven Rostedtmy $newconfig = 0;
198dbd3783bSSteven Rostedt
1998d1491baSSteven Rostedtmy %entered_configs;
2008d1491baSSteven Rostedtmy %config_help;
20177d942ceSSteven Rostedtmy %variable;
202cf79fab6SSteven Rostedt
203cf79fab6SSteven Rostedt# force_config is the list of configs that we force enabled (or disabled)
204cf79fab6SSteven Rostedt# in a .config file. The MIN_CONFIG and ADD_CONFIG configs.
205fcb3f16aSSteven Rostedtmy %force_config;
2068d1491baSSteven Rostedt
2074ab1cce5SSteven Rostedt# do not force reboots on config problems
2084ab1cce5SSteven Rostedtmy $no_reboot = 1;
2094ab1cce5SSteven Rostedt
210759a3cc6SSteven Rostedt# reboot on success
211759a3cc6SSteven Rostedtmy $reboot_success = 0;
212759a3cc6SSteven Rostedt
2139cc9e091SSteven Rostedtmy %option_map = (
2149cc9e091SSteven Rostedt    "MACHINE"			=> \$machine,
2159cc9e091SSteven Rostedt    "SSH_USER"			=> \$ssh_user,
2169cc9e091SSteven Rostedt    "TMP_DIR"			=> \$tmpdir,
2179cc9e091SSteven Rostedt    "OUTPUT_DIR"		=> \$outputdir,
2189cc9e091SSteven Rostedt    "BUILD_DIR"			=> \$builddir,
2199cc9e091SSteven Rostedt    "TEST_TYPE"			=> \$test_type,
220921ed4c7SSteven Rostedt    "PRE_KTEST"			=> \$pre_ktest,
221921ed4c7SSteven Rostedt    "POST_KTEST"		=> \$post_ktest,
222921ed4c7SSteven Rostedt    "PRE_TEST"			=> \$pre_test,
223921ed4c7SSteven Rostedt    "POST_TEST"			=> \$post_test,
2249cc9e091SSteven Rostedt    "BUILD_TYPE"		=> \$build_type,
2259cc9e091SSteven Rostedt    "BUILD_OPTIONS"		=> \$build_options,
2269cc9e091SSteven Rostedt    "PRE_BUILD"			=> \$pre_build,
2279cc9e091SSteven Rostedt    "POST_BUILD"		=> \$post_build,
2289cc9e091SSteven Rostedt    "PRE_BUILD_DIE"		=> \$pre_build_die,
2299cc9e091SSteven Rostedt    "POST_BUILD_DIE"		=> \$post_build_die,
2309cc9e091SSteven Rostedt    "POWER_CYCLE"		=> \$power_cycle,
2319cc9e091SSteven Rostedt    "REBOOT"			=> \$reboot,
2329cc9e091SSteven Rostedt    "BUILD_NOCLEAN"		=> \$noclean,
2339cc9e091SSteven Rostedt    "MIN_CONFIG"		=> \$minconfig,
2349cc9e091SSteven Rostedt    "OUTPUT_MIN_CONFIG"		=> \$output_minconfig,
2359cc9e091SSteven Rostedt    "START_MIN_CONFIG"		=> \$start_minconfig,
236ccc513b6SSteven Rostedt    "MIN_CONFIG_TYPE"		=> \$minconfig_type,
23743de3316SSteven Rostedt    "USE_OUTPUT_MIN_CONFIG"	=> \$use_output_minconfig,
2389cc9e091SSteven Rostedt    "IGNORE_CONFIG"		=> \$ignore_config,
2399cc9e091SSteven Rostedt    "TEST"			=> \$run_test,
2409cc9e091SSteven Rostedt    "ADD_CONFIG"		=> \$addconfig,
2419cc9e091SSteven Rostedt    "REBOOT_TYPE"		=> \$reboot_type,
2429cc9e091SSteven Rostedt    "GRUB_MENU"			=> \$grub_menu,
243a15ba913SSteven Rostedt    "GRUB_FILE"			=> \$grub_file,
244a15ba913SSteven Rostedt    "GRUB_REBOOT"		=> \$grub_reboot,
2457786954cSSteven Rostedt    "SYSLINUX"			=> \$syslinux,
2467786954cSSteven Rostedt    "SYSLINUX_PATH"		=> \$syslinux_path,
2477786954cSSteven Rostedt    "SYSLINUX_LABEL"		=> \$syslinux_label,
248e5c2ec11SSteven Rostedt    "PRE_INSTALL"		=> \$pre_install,
2499cc9e091SSteven Rostedt    "POST_INSTALL"		=> \$post_install,
2509cc9e091SSteven Rostedt    "NO_INSTALL"		=> \$no_install,
2519cc9e091SSteven Rostedt    "REBOOT_SCRIPT"		=> \$reboot_script,
2529cc9e091SSteven Rostedt    "REBOOT_ON_ERROR"		=> \$reboot_on_error,
2539cc9e091SSteven Rostedt    "SWITCH_TO_GOOD"		=> \$switch_to_good,
2549cc9e091SSteven Rostedt    "SWITCH_TO_TEST"		=> \$switch_to_test,
2559cc9e091SSteven Rostedt    "POWEROFF_ON_ERROR"		=> \$poweroff_on_error,
256648a182cSSteven Rostedt    "REBOOT_ON_SUCCESS"		=> \$reboot_on_success,
2579cc9e091SSteven Rostedt    "DIE_ON_FAILURE"		=> \$die_on_failure,
2589cc9e091SSteven Rostedt    "POWER_OFF"			=> \$power_off,
2599cc9e091SSteven Rostedt    "POWERCYCLE_AFTER_REBOOT"	=> \$powercycle_after_reboot,
2609cc9e091SSteven Rostedt    "POWEROFF_AFTER_HALT"	=> \$poweroff_after_halt,
261407b95b7SSteven Rostedt    "MAX_MONITOR_WAIT"		=> \$max_monitor_wait,
2629cc9e091SSteven Rostedt    "SLEEP_TIME"		=> \$sleep_time,
2639cc9e091SSteven Rostedt    "BISECT_SLEEP_TIME"		=> \$bisect_sleep_time,
2649cc9e091SSteven Rostedt    "PATCHCHECK_SLEEP_TIME"	=> \$patchcheck_sleep_time,
2659cc9e091SSteven Rostedt    "IGNORE_WARNINGS"		=> \$ignore_warnings,
266be405f95SSteven Rostedt    "IGNORE_ERRORS"		=> \$ignore_errors,
2679cc9e091SSteven Rostedt    "BISECT_MANUAL"		=> \$bisect_manual,
2689cc9e091SSteven Rostedt    "BISECT_SKIP"		=> \$bisect_skip,
2699cc9e091SSteven Rostedt    "CONFIG_BISECT_GOOD"	=> \$config_bisect_good,
2709cc9e091SSteven Rostedt    "BISECT_RET_GOOD"		=> \$bisect_ret_good,
2719cc9e091SSteven Rostedt    "BISECT_RET_BAD"		=> \$bisect_ret_bad,
2729cc9e091SSteven Rostedt    "BISECT_RET_SKIP"		=> \$bisect_ret_skip,
2739cc9e091SSteven Rostedt    "BISECT_RET_ABORT"		=> \$bisect_ret_abort,
2749cc9e091SSteven Rostedt    "BISECT_RET_DEFAULT"	=> \$bisect_ret_default,
2759cc9e091SSteven Rostedt    "STORE_FAILURES"		=> \$store_failures,
2769cc9e091SSteven Rostedt    "STORE_SUCCESSES"		=> \$store_successes,
2779cc9e091SSteven Rostedt    "TEST_NAME"			=> \$test_name,
2789cc9e091SSteven Rostedt    "TIMEOUT"			=> \$timeout,
2799cc9e091SSteven Rostedt    "BOOTED_TIMEOUT"		=> \$booted_timeout,
2809cc9e091SSteven Rostedt    "CONSOLE"			=> \$console,
2819cc9e091SSteven Rostedt    "DETECT_TRIPLE_FAULT"	=> \$detect_triplefault,
2829cc9e091SSteven Rostedt    "SUCCESS_LINE"		=> \$success_line,
2839cc9e091SSteven Rostedt    "REBOOT_SUCCESS_LINE"	=> \$reboot_success_line,
2849cc9e091SSteven Rostedt    "STOP_AFTER_SUCCESS"	=> \$stop_after_success,
2859cc9e091SSteven Rostedt    "STOP_AFTER_FAILURE"	=> \$stop_after_failure,
2869cc9e091SSteven Rostedt    "STOP_TEST_AFTER"		=> \$stop_test_after,
2879cc9e091SSteven Rostedt    "BUILD_TARGET"		=> \$build_target,
2889cc9e091SSteven Rostedt    "SSH_EXEC"			=> \$ssh_exec,
2899cc9e091SSteven Rostedt    "SCP_TO_TARGET"		=> \$scp_to_target,
29002ad2617SSteven Rostedt    "SCP_TO_TARGET_INSTALL"	=> \$scp_to_target_install,
2919cc9e091SSteven Rostedt    "CHECKOUT"			=> \$checkout,
2929cc9e091SSteven Rostedt    "TARGET_IMAGE"		=> \$target_image,
2939cc9e091SSteven Rostedt    "LOCALVERSION"		=> \$localversion,
2949cc9e091SSteven Rostedt
2959cc9e091SSteven Rostedt    "BISECT_GOOD"		=> \$bisect_good,
2969cc9e091SSteven Rostedt    "BISECT_BAD"		=> \$bisect_bad,
2979cc9e091SSteven Rostedt    "BISECT_TYPE"		=> \$bisect_type,
2989cc9e091SSteven Rostedt    "BISECT_START"		=> \$bisect_start,
2999cc9e091SSteven Rostedt    "BISECT_REPLAY"		=> \$bisect_replay,
3009cc9e091SSteven Rostedt    "BISECT_FILES"		=> \$bisect_files,
3019cc9e091SSteven Rostedt    "BISECT_REVERSE"		=> \$bisect_reverse,
3029cc9e091SSteven Rostedt    "BISECT_CHECK"		=> \$bisect_check,
3039cc9e091SSteven Rostedt
3049cc9e091SSteven Rostedt    "CONFIG_BISECT"		=> \$config_bisect,
3059cc9e091SSteven Rostedt    "CONFIG_BISECT_TYPE"	=> \$config_bisect_type,
306b0918612SSteven Rostedt    "CONFIG_BISECT_CHECK"	=> \$config_bisect_check,
3079cc9e091SSteven Rostedt
3089cc9e091SSteven Rostedt    "PATCHCHECK_TYPE"		=> \$patchcheck_type,
3099cc9e091SSteven Rostedt    "PATCHCHECK_START"		=> \$patchcheck_start,
3109cc9e091SSteven Rostedt    "PATCHCHECK_END"		=> \$patchcheck_end,
3119cc9e091SSteven Rostedt);
3129cc9e091SSteven Rostedt
3139cc9e091SSteven Rostedt# Options may be used by other options, record them.
3149cc9e091SSteven Rostedtmy %used_options;
3159cc9e091SSteven Rostedt
3167bf51073SSteven Rostedt# default variables that can be used
3177bf51073SSteven Rostedtchomp ($variable{"PWD"} = `pwd`);
3187bf51073SSteven Rostedt
3198d1491baSSteven Rostedt$config_help{"MACHINE"} = << "EOF"
3208d1491baSSteven Rostedt The machine hostname that you will test.
321bb8474b1SSteven Rostedt For build only tests, it is still needed to differentiate log files.
3228d1491baSSteven RostedtEOF
3238d1491baSSteven Rostedt    ;
3248d1491baSSteven Rostedt$config_help{"SSH_USER"} = << "EOF"
3258d1491baSSteven Rostedt The box is expected to have ssh on normal bootup, provide the user
3268d1491baSSteven Rostedt  (most likely root, since you need privileged operations)
3278d1491baSSteven RostedtEOF
3288d1491baSSteven Rostedt    ;
3298d1491baSSteven Rostedt$config_help{"BUILD_DIR"} = << "EOF"
3308d1491baSSteven Rostedt The directory that contains the Linux source code (full path).
3310e7a22deSSteven Rostedt You can use \${PWD} that will be the path where ktest.pl is run, or use
3320e7a22deSSteven Rostedt \${THIS_DIR} which is assigned \${PWD} but may be changed later.
3338d1491baSSteven RostedtEOF
3348d1491baSSteven Rostedt    ;
3358d1491baSSteven Rostedt$config_help{"OUTPUT_DIR"} = << "EOF"
3368d1491baSSteven Rostedt The directory that the objects will be built (full path).
3378d1491baSSteven Rostedt (can not be same as BUILD_DIR)
3380e7a22deSSteven Rostedt You can use \${PWD} that will be the path where ktest.pl is run, or use
3390e7a22deSSteven Rostedt \${THIS_DIR} which is assigned \${PWD} but may be changed later.
3408d1491baSSteven RostedtEOF
3418d1491baSSteven Rostedt    ;
3428d1491baSSteven Rostedt$config_help{"BUILD_TARGET"} = << "EOF"
3438d1491baSSteven Rostedt The location of the compiled file to copy to the target.
3448d1491baSSteven Rostedt (relative to OUTPUT_DIR)
3458d1491baSSteven RostedtEOF
3468d1491baSSteven Rostedt    ;
347dbd3783bSSteven Rostedt$config_help{"BUILD_OPTIONS"} = << "EOF"
348dbd3783bSSteven Rostedt Options to add to \"make\" when building.
349dbd3783bSSteven Rostedt i.e.  -j20
350dbd3783bSSteven RostedtEOF
351dbd3783bSSteven Rostedt    ;
3528d1491baSSteven Rostedt$config_help{"TARGET_IMAGE"} = << "EOF"
3538d1491baSSteven Rostedt The place to put your image on the test machine.
3548d1491baSSteven RostedtEOF
3558d1491baSSteven Rostedt    ;
3568d1491baSSteven Rostedt$config_help{"POWER_CYCLE"} = << "EOF"
3578d1491baSSteven Rostedt A script or command to reboot the box.
3588d1491baSSteven Rostedt
3598d1491baSSteven Rostedt Here is a digital loggers power switch example
3608d1491baSSteven Rostedt POWER_CYCLE = wget --no-proxy -O /dev/null -q  --auth-no-challenge 'http://admin:admin\@power/outlet?5=CCL'
3618d1491baSSteven Rostedt
3628d1491baSSteven Rostedt Here is an example to reboot a virtual box on the current host
3638d1491baSSteven Rostedt with the name "Guest".
3648d1491baSSteven Rostedt POWER_CYCLE = virsh destroy Guest; sleep 5; virsh start Guest
3658d1491baSSteven RostedtEOF
3668d1491baSSteven Rostedt    ;
3678d1491baSSteven Rostedt$config_help{"CONSOLE"} = << "EOF"
3688d1491baSSteven Rostedt The script or command that reads the console
3698d1491baSSteven Rostedt
3708d1491baSSteven Rostedt  If you use ttywatch server, something like the following would work.
3718d1491baSSteven RostedtCONSOLE = nc -d localhost 3001
3728d1491baSSteven Rostedt
3738d1491baSSteven Rostedt For a virtual machine with guest name "Guest".
3748d1491baSSteven RostedtCONSOLE =  virsh console Guest
3758d1491baSSteven RostedtEOF
3768d1491baSSteven Rostedt    ;
3778d1491baSSteven Rostedt$config_help{"LOCALVERSION"} = << "EOF"
3788d1491baSSteven Rostedt Required version ending to differentiate the test
3798d1491baSSteven Rostedt from other linux builds on the system.
3808d1491baSSteven RostedtEOF
3818d1491baSSteven Rostedt    ;
3828d1491baSSteven Rostedt$config_help{"REBOOT_TYPE"} = << "EOF"
3838d1491baSSteven Rostedt Way to reboot the box to the test kernel.
3847786954cSSteven Rostedt Only valid options so far are "grub", "grub2", "syslinux", and "script".
3858d1491baSSteven Rostedt
3868d1491baSSteven Rostedt If you specify grub, it will assume grub version 1
3878d1491baSSteven Rostedt and will search in /boot/grub/menu.lst for the title \$GRUB_MENU
3888d1491baSSteven Rostedt and select that target to reboot to the kernel. If this is not
3898d1491baSSteven Rostedt your setup, then specify "script" and have a command or script
3908d1491baSSteven Rostedt specified in REBOOT_SCRIPT to boot to the target.
3918d1491baSSteven Rostedt
3928d1491baSSteven Rostedt The entry in /boot/grub/menu.lst must be entered in manually.
3938d1491baSSteven Rostedt The test will not modify that file.
394a15ba913SSteven Rostedt
395a15ba913SSteven Rostedt If you specify grub2, then you also need to specify both \$GRUB_MENU
396a15ba913SSteven Rostedt and \$GRUB_FILE.
3977786954cSSteven Rostedt
3987786954cSSteven Rostedt If you specify syslinux, then you may use SYSLINUX to define the syslinux
3997786954cSSteven Rostedt command (defaults to extlinux), and SYSLINUX_PATH to specify the path to
4007786954cSSteven Rostedt the syslinux install (defaults to /boot/extlinux). But you have to specify
4017786954cSSteven Rostedt SYSLINUX_LABEL to define the label to boot to for the test kernel.
4028d1491baSSteven RostedtEOF
4038d1491baSSteven Rostedt    ;
4048d1491baSSteven Rostedt$config_help{"GRUB_MENU"} = << "EOF"
4058d1491baSSteven Rostedt The grub title name for the test kernel to boot
406a15ba913SSteven Rostedt (Only mandatory if REBOOT_TYPE = grub or grub2)
4078d1491baSSteven Rostedt
4088d1491baSSteven Rostedt Note, ktest.pl will not update the grub menu.lst, you need to
4098d1491baSSteven Rostedt manually add an option for the test. ktest.pl will search
4108d1491baSSteven Rostedt the grub menu.lst for this option to find what kernel to
4118d1491baSSteven Rostedt reboot into.
4128d1491baSSteven Rostedt
4138d1491baSSteven Rostedt For example, if in the /boot/grub/menu.lst the test kernel title has:
4148d1491baSSteven Rostedt title Test Kernel
4158d1491baSSteven Rostedt kernel vmlinuz-test
4168d1491baSSteven Rostedt GRUB_MENU = Test Kernel
417a15ba913SSteven Rostedt
418a15ba913SSteven Rostedt For grub2, a search of \$GRUB_FILE is performed for the lines
419a15ba913SSteven Rostedt that begin with "menuentry". It will not detect submenus. The
420a15ba913SSteven Rostedt menu must be a non-nested menu. Add the quotes used in the menu
421a15ba913SSteven Rostedt to guarantee your selection, as the first menuentry with the content
422a15ba913SSteven Rostedt of \$GRUB_MENU that is found will be used.
423a15ba913SSteven RostedtEOF
424a15ba913SSteven Rostedt    ;
425a15ba913SSteven Rostedt$config_help{"GRUB_FILE"} = << "EOF"
426a15ba913SSteven Rostedt If grub2 is used, the full path for the grub.cfg file is placed
427a15ba913SSteven Rostedt here. Use something like /boot/grub2/grub.cfg to search.
4288d1491baSSteven RostedtEOF
4298d1491baSSteven Rostedt    ;
4307786954cSSteven Rostedt$config_help{"SYSLINUX_LABEL"} = << "EOF"
4317786954cSSteven Rostedt If syslinux is used, the label that boots the target kernel must
4327786954cSSteven Rostedt be specified with SYSLINUX_LABEL.
4337786954cSSteven RostedtEOF
4347786954cSSteven Rostedt    ;
4358d1491baSSteven Rostedt$config_help{"REBOOT_SCRIPT"} = << "EOF"
4368d1491baSSteven Rostedt A script to reboot the target into the test kernel
4378d1491baSSteven Rostedt (Only mandatory if REBOOT_TYPE = script)
4388d1491baSSteven RostedtEOF
4398d1491baSSteven Rostedt    ;
4408d1491baSSteven Rostedt
441dad98754SSteven Rostedtsub read_prompt {
442dad98754SSteven Rostedt    my ($cancel, $prompt) = @_;
44335ce5952SSteven Rostedt
44435ce5952SSteven Rostedt    my $ans;
44535ce5952SSteven Rostedt
44635ce5952SSteven Rostedt    for (;;) {
447dad98754SSteven Rostedt	if ($cancel) {
448dad98754SSteven Rostedt	    print "$prompt [y/n/C] ";
449dad98754SSteven Rostedt	} else {
45035ce5952SSteven Rostedt	    print "$prompt [Y/n] ";
451dad98754SSteven Rostedt	}
45235ce5952SSteven Rostedt	$ans = <STDIN>;
45335ce5952SSteven Rostedt	chomp $ans;
45435ce5952SSteven Rostedt	if ($ans =~ /^\s*$/) {
455dad98754SSteven Rostedt	    if ($cancel) {
456dad98754SSteven Rostedt		$ans = "c";
457dad98754SSteven Rostedt	    } else {
45835ce5952SSteven Rostedt		$ans = "y";
45935ce5952SSteven Rostedt	    }
460dad98754SSteven Rostedt	}
46135ce5952SSteven Rostedt	last if ($ans =~ /^y$/i || $ans =~ /^n$/i);
462dad98754SSteven Rostedt	if ($cancel) {
463dad98754SSteven Rostedt	    last if ($ans =~ /^c$/i);
464dad98754SSteven Rostedt	    print "Please answer either 'y', 'n' or 'c'.\n";
465dad98754SSteven Rostedt	} else {
46635ce5952SSteven Rostedt	    print "Please answer either 'y' or 'n'.\n";
46735ce5952SSteven Rostedt	}
468dad98754SSteven Rostedt    }
469dad98754SSteven Rostedt    if ($ans =~ /^c/i) {
470dad98754SSteven Rostedt	exit;
471dad98754SSteven Rostedt    }
47235ce5952SSteven Rostedt    if ($ans !~ /^y$/i) {
47335ce5952SSteven Rostedt	return 0;
47435ce5952SSteven Rostedt    }
47535ce5952SSteven Rostedt    return 1;
47635ce5952SSteven Rostedt}
4778d1491baSSteven Rostedt
478dad98754SSteven Rostedtsub read_yn {
479dad98754SSteven Rostedt    my ($prompt) = @_;
480dad98754SSteven Rostedt
481dad98754SSteven Rostedt    return read_prompt 0, $prompt;
482dad98754SSteven Rostedt}
483dad98754SSteven Rostedt
484dad98754SSteven Rostedtsub read_ync {
485dad98754SSteven Rostedt    my ($prompt) = @_;
486dad98754SSteven Rostedt
487dad98754SSteven Rostedt    return read_prompt 1, $prompt;
488dad98754SSteven Rostedt}
489dad98754SSteven Rostedt
4908d1491baSSteven Rostedtsub get_ktest_config {
4918d1491baSSteven Rostedt    my ($config) = @_;
492815e2bd7SSteven Rostedt    my $ans;
4938d1491baSSteven Rostedt
4948d1491baSSteven Rostedt    return if (defined($opt{$config}));
4958d1491baSSteven Rostedt
4968d1491baSSteven Rostedt    if (defined($config_help{$config})) {
4978d1491baSSteven Rostedt	print "\n";
4988d1491baSSteven Rostedt	print $config_help{$config};
4998d1491baSSteven Rostedt    }
5008d1491baSSteven Rostedt
5018d1491baSSteven Rostedt    for (;;) {
5028d1491baSSteven Rostedt	print "$config = ";
503dbd3783bSSteven Rostedt	if (defined($default{$config}) && length($default{$config})) {
5048d1491baSSteven Rostedt	    print "\[$default{$config}\] ";
5058d1491baSSteven Rostedt	}
506815e2bd7SSteven Rostedt	$ans = <STDIN>;
507815e2bd7SSteven Rostedt	$ans =~ s/^\s*(.*\S)\s*$/$1/;
508815e2bd7SSteven Rostedt	if ($ans =~ /^\s*$/) {
5098d1491baSSteven Rostedt	    if ($default{$config}) {
510815e2bd7SSteven Rostedt		$ans = $default{$config};
5118d1491baSSteven Rostedt	    } else {
5128d1491baSSteven Rostedt		print "Your answer can not be blank\n";
5138d1491baSSteven Rostedt		next;
5148d1491baSSteven Rostedt	    }
5158d1491baSSteven Rostedt	}
5160e7a22deSSteven Rostedt	$entered_configs{$config} = ${ans};
5178d1491baSSteven Rostedt	last;
5188d1491baSSteven Rostedt    }
5198d1491baSSteven Rostedt}
5208d1491baSSteven Rostedt
5218d1491baSSteven Rostedtsub get_ktest_configs {
5228d1491baSSteven Rostedt    get_ktest_config("MACHINE");
5238d1491baSSteven Rostedt    get_ktest_config("BUILD_DIR");
5248d1491baSSteven Rostedt    get_ktest_config("OUTPUT_DIR");
525bb8474b1SSteven Rostedt
526dbd3783bSSteven Rostedt    if ($newconfig) {
527dbd3783bSSteven Rostedt	get_ktest_config("BUILD_OPTIONS");
528dbd3783bSSteven Rostedt    }
529dbd3783bSSteven Rostedt
530bb8474b1SSteven Rostedt    # options required for other than just building a kernel
531bb8474b1SSteven Rostedt    if (!$buildonly) {
532165708b2SSteven Rostedt	get_ktest_config("POWER_CYCLE");
533165708b2SSteven Rostedt	get_ktest_config("CONSOLE");
534165708b2SSteven Rostedt    }
535165708b2SSteven Rostedt
536165708b2SSteven Rostedt    # options required for install and more
537165708b2SSteven Rostedt    if ($buildonly != 1) {
538bb8474b1SSteven Rostedt	get_ktest_config("SSH_USER");
5398d1491baSSteven Rostedt	get_ktest_config("BUILD_TARGET");
5408d1491baSSteven Rostedt	get_ktest_config("TARGET_IMAGE");
541bb8474b1SSteven Rostedt    }
542bb8474b1SSteven Rostedt
5438d1491baSSteven Rostedt    get_ktest_config("LOCALVERSION");
5448d1491baSSteven Rostedt
545bb8474b1SSteven Rostedt    return if ($buildonly);
546bb8474b1SSteven Rostedt
5478d1491baSSteven Rostedt    my $rtype = $opt{"REBOOT_TYPE"};
5488d1491baSSteven Rostedt
5498d1491baSSteven Rostedt    if (!defined($rtype)) {
5508d1491baSSteven Rostedt	if (!defined($opt{"GRUB_MENU"})) {
5518d1491baSSteven Rostedt	    get_ktest_config("REBOOT_TYPE");
5528d1491baSSteven Rostedt	    $rtype = $entered_configs{"REBOOT_TYPE"};
5538d1491baSSteven Rostedt	} else {
5548d1491baSSteven Rostedt	    $rtype = "grub";
5558d1491baSSteven Rostedt	}
5568d1491baSSteven Rostedt    }
5578d1491baSSteven Rostedt
5588d1491baSSteven Rostedt    if ($rtype eq "grub") {
5598d1491baSSteven Rostedt	get_ktest_config("GRUB_MENU");
5608d1491baSSteven Rostedt    }
561a15ba913SSteven Rostedt
562a15ba913SSteven Rostedt    if ($rtype eq "grub2") {
563a15ba913SSteven Rostedt	get_ktest_config("GRUB_MENU");
564a15ba913SSteven Rostedt	get_ktest_config("GRUB_FILE");
565a15ba913SSteven Rostedt    }
5667786954cSSteven Rostedt
5677786954cSSteven Rostedt    if ($rtype eq "syslinux") {
5687786954cSSteven Rostedt	get_ktest_config("SYSLINUX_LABEL");
5697786954cSSteven Rostedt    }
5708d1491baSSteven Rostedt}
5718d1491baSSteven Rostedt
57277d942ceSSteven Rostedtsub process_variables {
5738d735212SSteven Rostedt    my ($value, $remove_undef) = @_;
57477d942ceSSteven Rostedt    my $retval = "";
57577d942ceSSteven Rostedt
57677d942ceSSteven Rostedt    # We want to check for '\', and it is just easier
57777d942ceSSteven Rostedt    # to check the previous characet of '$' and not need
57877d942ceSSteven Rostedt    # to worry if '$' is the first character. By adding
57977d942ceSSteven Rostedt    # a space to $value, we can just check [^\\]\$ and
58077d942ceSSteven Rostedt    # it will still work.
58177d942ceSSteven Rostedt    $value = " $value";
58277d942ceSSteven Rostedt
58377d942ceSSteven Rostedt    while ($value =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) {
58477d942ceSSteven Rostedt	my $begin = $1;
58577d942ceSSteven Rostedt	my $var = $2;
58677d942ceSSteven Rostedt	my $end = $3;
58777d942ceSSteven Rostedt	# append beginning of value to retval
58877d942ceSSteven Rostedt	$retval = "$retval$begin";
58977d942ceSSteven Rostedt	if (defined($variable{$var})) {
59077d942ceSSteven Rostedt	    $retval = "$retval$variable{$var}";
5918d735212SSteven Rostedt	} elsif (defined($remove_undef) && $remove_undef) {
5928d735212SSteven Rostedt	    # for if statements, any variable that is not defined,
5938d735212SSteven Rostedt	    # we simple convert to 0
5948d735212SSteven Rostedt	    $retval = "${retval}0";
59577d942ceSSteven Rostedt	} else {
59677d942ceSSteven Rostedt	    # put back the origin piece.
59777d942ceSSteven Rostedt	    $retval = "$retval\$\{$var\}";
5989cc9e091SSteven Rostedt	    # This could be an option that is used later, save
5999cc9e091SSteven Rostedt	    # it so we don't warn if this option is not one of
6009cc9e091SSteven Rostedt	    # ktests options.
6019cc9e091SSteven Rostedt	    $used_options{$var} = 1;
60277d942ceSSteven Rostedt	}
60377d942ceSSteven Rostedt	$value = $end;
60477d942ceSSteven Rostedt    }
60577d942ceSSteven Rostedt    $retval = "$retval$value";
60677d942ceSSteven Rostedt
60777d942ceSSteven Rostedt    # remove the space added in the beginning
60877d942ceSSteven Rostedt    $retval =~ s/ //;
60977d942ceSSteven Rostedt
61077d942ceSSteven Rostedt    return "$retval"
61177d942ceSSteven Rostedt}
61277d942ceSSteven Rostedt
613a57419b3SSteven Rostedtsub set_value {
6143d1cc414SSteven Rostedt    my ($lvalue, $rvalue, $override, $overrides, $name) = @_;
6152545eb61SSteven Rostedt
616cad96669SSteven Rostedt    my $prvalue = process_variables($rvalue);
617cad96669SSteven Rostedt
618cad96669SSteven Rostedt    if ($buildonly && $lvalue =~ /^TEST_TYPE(\[.*\])?$/ && $prvalue ne "build") {
619bb8474b1SSteven Rostedt	# Note if a test is something other than build, then we
620bb8474b1SSteven Rostedt	# will need other manditory options.
621cad96669SSteven Rostedt	if ($prvalue ne "install") {
622bb8474b1SSteven Rostedt	    $buildonly = 0;
623165708b2SSteven Rostedt	} else {
624165708b2SSteven Rostedt	    # install still limits some manditory options.
625165708b2SSteven Rostedt	    $buildonly = 2;
626165708b2SSteven Rostedt	}
627bb8474b1SSteven Rostedt    }
628bb8474b1SSteven Rostedt
629a75fececSSteven Rostedt    if (defined($opt{$lvalue})) {
6303d1cc414SSteven Rostedt	if (!$override || defined(${$overrides}{$lvalue})) {
6313d1cc414SSteven Rostedt	    my $extra = "";
6323d1cc414SSteven Rostedt	    if ($override) {
6333d1cc414SSteven Rostedt		$extra = "In the same override section!\n";
6343d1cc414SSteven Rostedt	    }
6353d1cc414SSteven Rostedt	    die "$name: $.: Option $lvalue defined more than once!\n$extra";
6363d1cc414SSteven Rostedt	}
637cad96669SSteven Rostedt	${$overrides}{$lvalue} = $prvalue;
638a75fececSSteven Rostedt    }
63921a9679fSSteven Rostedt    if ($rvalue =~ /^\s*$/) {
64021a9679fSSteven Rostedt	delete $opt{$lvalue};
64121a9679fSSteven Rostedt    } else {
642cad96669SSteven Rostedt	$opt{$lvalue} = $prvalue;
64321a9679fSSteven Rostedt    }
6442545eb61SSteven Rostedt}
645a57419b3SSteven Rostedt
64677d942ceSSteven Rostedtsub set_variable {
64777d942ceSSteven Rostedt    my ($lvalue, $rvalue) = @_;
64877d942ceSSteven Rostedt
64977d942ceSSteven Rostedt    if ($rvalue =~ /^\s*$/) {
65077d942ceSSteven Rostedt	delete $variable{$lvalue};
65177d942ceSSteven Rostedt    } else {
65277d942ceSSteven Rostedt	$rvalue = process_variables($rvalue);
65377d942ceSSteven Rostedt	$variable{$lvalue} = $rvalue;
65477d942ceSSteven Rostedt    }
65577d942ceSSteven Rostedt}
65677d942ceSSteven Rostedt
657ab7a3f52SSteven Rostedtsub process_compare {
658ab7a3f52SSteven Rostedt    my ($lval, $cmp, $rval) = @_;
659ab7a3f52SSteven Rostedt
660ab7a3f52SSteven Rostedt    # remove whitespace
661ab7a3f52SSteven Rostedt
662ab7a3f52SSteven Rostedt    $lval =~ s/^\s*//;
663ab7a3f52SSteven Rostedt    $lval =~ s/\s*$//;
664ab7a3f52SSteven Rostedt
665ab7a3f52SSteven Rostedt    $rval =~ s/^\s*//;
666ab7a3f52SSteven Rostedt    $rval =~ s/\s*$//;
667ab7a3f52SSteven Rostedt
668ab7a3f52SSteven Rostedt    if ($cmp eq "==") {
669ab7a3f52SSteven Rostedt	return $lval eq $rval;
670ab7a3f52SSteven Rostedt    } elsif ($cmp eq "!=") {
671ab7a3f52SSteven Rostedt	return $lval ne $rval;
6728fddbe9bSSteven Rostedt    } elsif ($cmp eq "=~") {
6738fddbe9bSSteven Rostedt	return $lval =~ m/$rval/;
6748fddbe9bSSteven Rostedt    } elsif ($cmp eq "!~") {
6758fddbe9bSSteven Rostedt	return $lval !~ m/$rval/;
676ab7a3f52SSteven Rostedt    }
677ab7a3f52SSteven Rostedt
678ab7a3f52SSteven Rostedt    my $statement = "$lval $cmp $rval";
679ab7a3f52SSteven Rostedt    my $ret = eval $statement;
680ab7a3f52SSteven Rostedt
681ab7a3f52SSteven Rostedt    # $@ stores error of eval
682ab7a3f52SSteven Rostedt    if ($@) {
683ab7a3f52SSteven Rostedt	return -1;
684ab7a3f52SSteven Rostedt    }
685ab7a3f52SSteven Rostedt
686ab7a3f52SSteven Rostedt    return $ret;
687ab7a3f52SSteven Rostedt}
688ab7a3f52SSteven Rostedt
6899900b5dcSSteven Rostedtsub value_defined {
6909900b5dcSSteven Rostedt    my ($val) = @_;
6919900b5dcSSteven Rostedt
6929900b5dcSSteven Rostedt    return defined($variable{$2}) ||
6939900b5dcSSteven Rostedt	defined($opt{$2});
6949900b5dcSSteven Rostedt}
6959900b5dcSSteven Rostedt
6968d735212SSteven Rostedtmy $d = 0;
6978d735212SSteven Rostedtsub process_expression {
6988d735212SSteven Rostedt    my ($name, $val) = @_;
69945d73a5dSSteven Rostedt
7008d735212SSteven Rostedt    my $c = $d++;
7018d735212SSteven Rostedt
7028d735212SSteven Rostedt    while ($val =~ s/\(([^\(]*?)\)/\&\&\&\&VAL\&\&\&\&/) {
7038d735212SSteven Rostedt	my $express = $1;
7048d735212SSteven Rostedt
7058d735212SSteven Rostedt	if (process_expression($name, $express)) {
7068d735212SSteven Rostedt	    $val =~ s/\&\&\&\&VAL\&\&\&\&/ 1 /;
7078d735212SSteven Rostedt	} else {
7088d735212SSteven Rostedt	    $val =~ s/\&\&\&\&VAL\&\&\&\&/ 0 /;
7098d735212SSteven Rostedt	}
7108d735212SSteven Rostedt    }
7118d735212SSteven Rostedt
7128d735212SSteven Rostedt    $d--;
7138d735212SSteven Rostedt    my $OR = "\\|\\|";
7148d735212SSteven Rostedt    my $AND = "\\&\\&";
7158d735212SSteven Rostedt
7168d735212SSteven Rostedt    while ($val =~ s/^(.*?)($OR|$AND)//) {
7178d735212SSteven Rostedt	my $express = $1;
7188d735212SSteven Rostedt	my $op = $2;
7198d735212SSteven Rostedt
7208d735212SSteven Rostedt	if (process_expression($name, $express)) {
7218d735212SSteven Rostedt	    if ($op eq "||") {
7228d735212SSteven Rostedt		return 1;
7238d735212SSteven Rostedt	    }
7248d735212SSteven Rostedt	} else {
7258d735212SSteven Rostedt	    if ($op eq "&&") {
7268d735212SSteven Rostedt		return 0;
7278d735212SSteven Rostedt	    }
7288d735212SSteven Rostedt	}
7298d735212SSteven Rostedt    }
73045d73a5dSSteven Rostedt
7318fddbe9bSSteven Rostedt    if ($val =~ /(.*)(==|\!=|>=|<=|>|<|=~|\!~)(.*)/) {
732ab7a3f52SSteven Rostedt	my $ret = process_compare($1, $2, $3);
733ab7a3f52SSteven Rostedt	if ($ret < 0) {
734ab7a3f52SSteven Rostedt	    die "$name: $.: Unable to process comparison\n";
735ab7a3f52SSteven Rostedt	}
736ab7a3f52SSteven Rostedt	return $ret;
737ab7a3f52SSteven Rostedt    }
738ab7a3f52SSteven Rostedt
7399900b5dcSSteven Rostedt    if ($val =~ /^\s*(NOT\s*)?DEFINED\s+(\S+)\s*$/) {
7409900b5dcSSteven Rostedt	if (defined $1) {
7419900b5dcSSteven Rostedt	    return !value_defined($2);
7429900b5dcSSteven Rostedt	} else {
7439900b5dcSSteven Rostedt	    return value_defined($2);
7449900b5dcSSteven Rostedt	}
7459900b5dcSSteven Rostedt    }
7469900b5dcSSteven Rostedt
74745d73a5dSSteven Rostedt    if ($val =~ /^\s*0\s*$/) {
74845d73a5dSSteven Rostedt	return 0;
74945d73a5dSSteven Rostedt    } elsif ($val =~ /^\s*\d+\s*$/) {
75045d73a5dSSteven Rostedt	return 1;
75145d73a5dSSteven Rostedt    }
75245d73a5dSSteven Rostedt
7539900b5dcSSteven Rostedt    die ("$name: $.: Undefined content $val in if statement\n");
7548d735212SSteven Rostedt}
7558d735212SSteven Rostedt
7568d735212SSteven Rostedtsub process_if {
7578d735212SSteven Rostedt    my ($name, $value) = @_;
7588d735212SSteven Rostedt
7598d735212SSteven Rostedt    # Convert variables and replace undefined ones with 0
7608d735212SSteven Rostedt    my $val = process_variables($value, 1);
7618d735212SSteven Rostedt    my $ret = process_expression $name, $val;
7628d735212SSteven Rostedt
7638d735212SSteven Rostedt    return $ret;
76445d73a5dSSteven Rostedt}
76545d73a5dSSteven Rostedt
7662ed3b161SSteven Rostedtsub __read_config {
7672ed3b161SSteven Rostedt    my ($config, $current_test_num) = @_;
768a57419b3SSteven Rostedt
7692ed3b161SSteven Rostedt    my $in;
7702ed3b161SSteven Rostedt    open($in, $config) || die "can't read file $config";
771a57419b3SSteven Rostedt
772a57419b3SSteven Rostedt    my $name = $config;
773a57419b3SSteven Rostedt    $name =~ s,.*/(.*),$1,;
774a57419b3SSteven Rostedt
7752ed3b161SSteven Rostedt    my $test_num = $$current_test_num;
776a57419b3SSteven Rostedt    my $default = 1;
777a57419b3SSteven Rostedt    my $repeat = 1;
778a57419b3SSteven Rostedt    my $num_tests_set = 0;
779a57419b3SSteven Rostedt    my $skip = 0;
780a57419b3SSteven Rostedt    my $rest;
781a9f84424SSteven Rostedt    my $line;
7820df213caSSteven Rostedt    my $test_case = 0;
78345d73a5dSSteven Rostedt    my $if = 0;
78445d73a5dSSteven Rostedt    my $if_set = 0;
7853d1cc414SSteven Rostedt    my $override = 0;
7863d1cc414SSteven Rostedt
7873d1cc414SSteven Rostedt    my %overrides;
788a57419b3SSteven Rostedt
7892ed3b161SSteven Rostedt    while (<$in>) {
790a57419b3SSteven Rostedt
791a57419b3SSteven Rostedt	# ignore blank lines and comments
792a57419b3SSteven Rostedt	next if (/^\s*$/ || /\s*\#/);
793a57419b3SSteven Rostedt
7940050b6bbSSteven Rostedt	if (/^\s*(TEST_START|DEFAULTS)\b(.*)/) {
795a57419b3SSteven Rostedt
7960050b6bbSSteven Rostedt	    my $type = $1;
7970050b6bbSSteven Rostedt	    $rest = $2;
798a9f84424SSteven Rostedt	    $line = $2;
7990050b6bbSSteven Rostedt
8000050b6bbSSteven Rostedt	    my $old_test_num;
8010050b6bbSSteven Rostedt	    my $old_repeat;
8023d1cc414SSteven Rostedt	    $override = 0;
8030050b6bbSSteven Rostedt
8040050b6bbSSteven Rostedt	    if ($type eq "TEST_START") {
805a57419b3SSteven Rostedt
806a57419b3SSteven Rostedt		if ($num_tests_set) {
807a57419b3SSteven Rostedt		    die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
808a57419b3SSteven Rostedt		}
809a57419b3SSteven Rostedt
8100050b6bbSSteven Rostedt		$old_test_num = $test_num;
8110050b6bbSSteven Rostedt		$old_repeat = $repeat;
812a57419b3SSteven Rostedt
813a57419b3SSteven Rostedt		$test_num += $repeat;
814a57419b3SSteven Rostedt		$default = 0;
815a57419b3SSteven Rostedt		$repeat = 1;
8160050b6bbSSteven Rostedt	    } else {
8170050b6bbSSteven Rostedt		$default = 1;
8180050b6bbSSteven Rostedt	    }
819a57419b3SSteven Rostedt
820a9f84424SSteven Rostedt	    # If SKIP is anywhere in the line, the command will be skipped
821a9f84424SSteven Rostedt	    if ($rest =~ s/\s+SKIP\b//) {
822a57419b3SSteven Rostedt		$skip = 1;
823a57419b3SSteven Rostedt	    } else {
8240df213caSSteven Rostedt		$test_case = 1;
825a57419b3SSteven Rostedt		$skip = 0;
826a57419b3SSteven Rostedt	    }
827a57419b3SSteven Rostedt
828a9f84424SSteven Rostedt	    if ($rest =~ s/\sELSE\b//) {
829a9f84424SSteven Rostedt		if (!$if) {
830a9f84424SSteven Rostedt		    die "$name: $.: ELSE found with out matching IF section\n$_";
831a57419b3SSteven Rostedt		}
832a9f84424SSteven Rostedt		$if = 0;
833a9f84424SSteven Rostedt
834a9f84424SSteven Rostedt		if ($if_set) {
835a9f84424SSteven Rostedt		    $skip = 1;
836a9f84424SSteven Rostedt		} else {
837a9f84424SSteven Rostedt		    $skip = 0;
8383d1cc414SSteven Rostedt		}
8393d1cc414SSteven Rostedt	    }
840a57419b3SSteven Rostedt
841a9f84424SSteven Rostedt	    if ($rest =~ s/\sIF\s+(.*)//) {
84245d73a5dSSteven Rostedt		if (process_if($name, $1)) {
84345d73a5dSSteven Rostedt		    $if_set = 1;
84445d73a5dSSteven Rostedt		} else {
845a57419b3SSteven Rostedt		    $skip = 1;
846a57419b3SSteven Rostedt		}
84745d73a5dSSteven Rostedt		$if = 1;
84845d73a5dSSteven Rostedt	    } else {
84945d73a5dSSteven Rostedt		$if = 0;
850a9f84424SSteven Rostedt		$if_set = 0;
85145d73a5dSSteven Rostedt	    }
852a57419b3SSteven Rostedt
853a9f84424SSteven Rostedt	    if (!$skip) {
854a9f84424SSteven Rostedt		if ($type eq "TEST_START") {
855a9f84424SSteven Rostedt		    if ($rest =~ s/\s+ITERATE\s+(\d+)//) {
856a9f84424SSteven Rostedt			$repeat = $1;
857a9f84424SSteven Rostedt			$repeat_tests{"$test_num"} = $repeat;
858a9f84424SSteven Rostedt		    }
859a9f84424SSteven Rostedt		} elsif ($rest =~ s/\sOVERRIDE\b//) {
860a9f84424SSteven Rostedt		    # DEFAULT only
861a9f84424SSteven Rostedt		    $override = 1;
862a9f84424SSteven Rostedt		    # Clear previous overrides
863a9f84424SSteven Rostedt		    %overrides = ();
864a9f84424SSteven Rostedt		}
865a9f84424SSteven Rostedt	    }
866a9f84424SSteven Rostedt
867a9f84424SSteven Rostedt	    if (!$skip && $rest !~ /^\s*$/) {
8680050b6bbSSteven Rostedt		die "$name: $.: Gargbage found after $type\n$_";
869a57419b3SSteven Rostedt	    }
870a57419b3SSteven Rostedt
8710050b6bbSSteven Rostedt	    if ($skip && $type eq "TEST_START") {
872a57419b3SSteven Rostedt		$test_num = $old_test_num;
873e48c5293SSteven Rostedt		$repeat = $old_repeat;
874a57419b3SSteven Rostedt	    }
875a57419b3SSteven Rostedt
876ab7a3f52SSteven Rostedt	} elsif (/^\s*ELSE\b(.*)$/) {
87745d73a5dSSteven Rostedt	    if (!$if) {
87845d73a5dSSteven Rostedt		die "$name: $.: ELSE found with out matching IF section\n$_";
87945d73a5dSSteven Rostedt	    }
88045d73a5dSSteven Rostedt	    $rest = $1;
88145d73a5dSSteven Rostedt	    if ($if_set) {
88245d73a5dSSteven Rostedt		$skip = 1;
883ab7a3f52SSteven Rostedt		$rest = "";
88445d73a5dSSteven Rostedt	    } else {
88545d73a5dSSteven Rostedt		$skip = 0;
88645d73a5dSSteven Rostedt
887ab7a3f52SSteven Rostedt		if ($rest =~ /\sIF\s+(.*)/) {
88845d73a5dSSteven Rostedt		    # May be a ELSE IF section.
88995f57838SSteven Rostedt		    if (process_if($name, $1)) {
89095f57838SSteven Rostedt			$if_set = 1;
89195f57838SSteven Rostedt		    } else {
89245d73a5dSSteven Rostedt			$skip = 1;
89345d73a5dSSteven Rostedt		    }
894ab7a3f52SSteven Rostedt		    $rest = "";
89545d73a5dSSteven Rostedt		} else {
89645d73a5dSSteven Rostedt		    $if = 0;
89745d73a5dSSteven Rostedt		}
89845d73a5dSSteven Rostedt	    }
89945d73a5dSSteven Rostedt
900ab7a3f52SSteven Rostedt	    if ($rest !~ /^\s*$/) {
901ab7a3f52SSteven Rostedt		die "$name: $.: Gargbage found after DEFAULTS\n$_";
902ab7a3f52SSteven Rostedt	    }
903ab7a3f52SSteven Rostedt
9042ed3b161SSteven Rostedt	} elsif (/^\s*INCLUDE\s+(\S+)/) {
9052ed3b161SSteven Rostedt
9062ed3b161SSteven Rostedt	    next if ($skip);
9072ed3b161SSteven Rostedt
9082ed3b161SSteven Rostedt	    if (!$default) {
9092ed3b161SSteven Rostedt		die "$name: $.: INCLUDE can only be done in default sections\n$_";
9102ed3b161SSteven Rostedt	    }
9112ed3b161SSteven Rostedt
9122ed3b161SSteven Rostedt	    my $file = process_variables($1);
9132ed3b161SSteven Rostedt
9142ed3b161SSteven Rostedt	    if ($file !~ m,^/,) {
9152ed3b161SSteven Rostedt		# check the path of the config file first
9162ed3b161SSteven Rostedt		if ($config =~ m,(.*)/,) {
9172ed3b161SSteven Rostedt		    if (-f "$1/$file") {
9182ed3b161SSteven Rostedt			$file = "$1/$file";
9192ed3b161SSteven Rostedt		    }
9202ed3b161SSteven Rostedt		}
9212ed3b161SSteven Rostedt	    }
9222ed3b161SSteven Rostedt
9232ed3b161SSteven Rostedt	    if ( ! -r $file ) {
9242ed3b161SSteven Rostedt		die "$name: $.: Can't read file $file\n$_";
9252ed3b161SSteven Rostedt	    }
9262ed3b161SSteven Rostedt
9272ed3b161SSteven Rostedt	    if (__read_config($file, \$test_num)) {
9282ed3b161SSteven Rostedt		$test_case = 1;
9292ed3b161SSteven Rostedt	    }
9302ed3b161SSteven Rostedt
931a57419b3SSteven Rostedt	} elsif (/^\s*([A-Z_\[\]\d]+)\s*=\s*(.*?)\s*$/) {
932a57419b3SSteven Rostedt
933a57419b3SSteven Rostedt	    next if ($skip);
934a57419b3SSteven Rostedt
935a57419b3SSteven Rostedt	    my $lvalue = $1;
936a57419b3SSteven Rostedt	    my $rvalue = $2;
937a57419b3SSteven Rostedt
938a57419b3SSteven Rostedt	    if (!$default &&
939a57419b3SSteven Rostedt		($lvalue eq "NUM_TESTS" ||
940a57419b3SSteven Rostedt		 $lvalue eq "LOG_FILE" ||
941a57419b3SSteven Rostedt		 $lvalue eq "CLEAR_LOG")) {
942a57419b3SSteven Rostedt		die "$name: $.: $lvalue must be set in DEFAULTS section\n";
943a57419b3SSteven Rostedt	    }
944a57419b3SSteven Rostedt
945a57419b3SSteven Rostedt	    if ($lvalue eq "NUM_TESTS") {
946a57419b3SSteven Rostedt		if ($test_num) {
947a57419b3SSteven Rostedt		    die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
948a57419b3SSteven Rostedt		}
949a57419b3SSteven Rostedt		if (!$default) {
950a57419b3SSteven Rostedt		    die "$name: $.: NUM_TESTS must be set in default section\n";
951a57419b3SSteven Rostedt		}
952a57419b3SSteven Rostedt		$num_tests_set = 1;
953a57419b3SSteven Rostedt	    }
954a57419b3SSteven Rostedt
955a57419b3SSteven Rostedt	    if ($default || $lvalue =~ /\[\d+\]$/) {
9563d1cc414SSteven Rostedt		set_value($lvalue, $rvalue, $override, \%overrides, $name);
957a57419b3SSteven Rostedt	    } else {
958a57419b3SSteven Rostedt		my $val = "$lvalue\[$test_num\]";
9593d1cc414SSteven Rostedt		set_value($val, $rvalue, $override, \%overrides, $name);
960a57419b3SSteven Rostedt
961a57419b3SSteven Rostedt		if ($repeat > 1) {
962a57419b3SSteven Rostedt		    $repeats{$val} = $repeat;
963a57419b3SSteven Rostedt		}
964a57419b3SSteven Rostedt	    }
96577d942ceSSteven Rostedt	} elsif (/^\s*([A-Z_\[\]\d]+)\s*:=\s*(.*?)\s*$/) {
96677d942ceSSteven Rostedt	    next if ($skip);
96777d942ceSSteven Rostedt
96877d942ceSSteven Rostedt	    my $lvalue = $1;
96977d942ceSSteven Rostedt	    my $rvalue = $2;
97077d942ceSSteven Rostedt
97177d942ceSSteven Rostedt	    # process config variables.
97277d942ceSSteven Rostedt	    # Config variables are only active while reading the
97377d942ceSSteven Rostedt	    # config and can be defined anywhere. They also ignore
97477d942ceSSteven Rostedt	    # TEST_START and DEFAULTS, but are skipped if they are in
97577d942ceSSteven Rostedt	    # on of these sections that have SKIP defined.
97677d942ceSSteven Rostedt	    # The save variable can be
97777d942ceSSteven Rostedt	    # defined multiple times and the new one simply overrides
97877d942ceSSteven Rostedt	    # the prevous one.
97977d942ceSSteven Rostedt	    set_variable($lvalue, $rvalue);
98077d942ceSSteven Rostedt
981a57419b3SSteven Rostedt	} else {
982a57419b3SSteven Rostedt	    die "$name: $.: Garbage found in config\n$_";
983a57419b3SSteven Rostedt	}
9842545eb61SSteven Rostedt    }
9852545eb61SSteven Rostedt
986a57419b3SSteven Rostedt    if ($test_num) {
987a57419b3SSteven Rostedt	$test_num += $repeat - 1;
988a57419b3SSteven Rostedt	$opt{"NUM_TESTS"} = $test_num;
989a57419b3SSteven Rostedt    }
990a57419b3SSteven Rostedt
9912ed3b161SSteven Rostedt    close($in);
9922ed3b161SSteven Rostedt
9932ed3b161SSteven Rostedt    $$current_test_num = $test_num;
9942ed3b161SSteven Rostedt
9952ed3b161SSteven Rostedt    return $test_case;
9962ed3b161SSteven Rostedt}
9972ed3b161SSteven Rostedt
998c4261d0fSSteven Rostedtsub get_test_case {
999c4261d0fSSteven Rostedt	print "What test case would you like to run?\n";
1000c4261d0fSSteven Rostedt	print " (build, install or boot)\n";
1001c4261d0fSSteven Rostedt	print " Other tests are available but require editing the config file\n";
1002c4261d0fSSteven Rostedt	my $ans = <STDIN>;
1003c4261d0fSSteven Rostedt	chomp $ans;
1004c4261d0fSSteven Rostedt	$default{"TEST_TYPE"} = $ans;
1005c4261d0fSSteven Rostedt}
1006c4261d0fSSteven Rostedt
10072ed3b161SSteven Rostedtsub read_config {
10082ed3b161SSteven Rostedt    my ($config) = @_;
10092ed3b161SSteven Rostedt
10102ed3b161SSteven Rostedt    my $test_case;
10112ed3b161SSteven Rostedt    my $test_num = 0;
10122ed3b161SSteven Rostedt
10132ed3b161SSteven Rostedt    $test_case = __read_config $config, \$test_num;
10142ed3b161SSteven Rostedt
10158d1491baSSteven Rostedt    # make sure we have all mandatory configs
10168d1491baSSteven Rostedt    get_ktest_configs;
10178d1491baSSteven Rostedt
10180df213caSSteven Rostedt    # was a test specified?
10190df213caSSteven Rostedt    if (!$test_case) {
10200df213caSSteven Rostedt	print "No test case specified.\n";
1021c4261d0fSSteven Rostedt	get_test_case;
10220df213caSSteven Rostedt    }
10230df213caSSteven Rostedt
1024a75fececSSteven Rostedt    # set any defaults
1025a75fececSSteven Rostedt
1026a75fececSSteven Rostedt    foreach my $default (keys %default) {
1027a75fececSSteven Rostedt	if (!defined($opt{$default})) {
1028a75fececSSteven Rostedt	    $opt{$default} = $default{$default};
1029a75fececSSteven Rostedt	}
1030a75fececSSteven Rostedt    }
10319cc9e091SSteven Rostedt
10329cc9e091SSteven Rostedt    if ($opt{"IGNORE_UNUSED"} == 1) {
10339cc9e091SSteven Rostedt	return;
10349cc9e091SSteven Rostedt    }
10359cc9e091SSteven Rostedt
10369cc9e091SSteven Rostedt    my %not_used;
10379cc9e091SSteven Rostedt
10389cc9e091SSteven Rostedt    # check if there are any stragglers (typos?)
10399cc9e091SSteven Rostedt    foreach my $option (keys %opt) {
10409cc9e091SSteven Rostedt	my $op = $option;
10419cc9e091SSteven Rostedt	# remove per test labels.
10429cc9e091SSteven Rostedt	$op =~ s/\[.*\]//;
10439cc9e091SSteven Rostedt	if (!exists($option_map{$op}) &&
10449cc9e091SSteven Rostedt	    !exists($default{$op}) &&
10459cc9e091SSteven Rostedt	    !exists($used_options{$op})) {
10469cc9e091SSteven Rostedt	    $not_used{$op} = 1;
10479cc9e091SSteven Rostedt	}
10489cc9e091SSteven Rostedt    }
10499cc9e091SSteven Rostedt
10509cc9e091SSteven Rostedt    if (%not_used) {
10519cc9e091SSteven Rostedt	my $s = "s are";
10529cc9e091SSteven Rostedt	$s = " is" if (keys %not_used == 1);
10539cc9e091SSteven Rostedt	print "The following option$s not used; could be a typo:\n";
10549cc9e091SSteven Rostedt	foreach my $option (keys %not_used) {
10559cc9e091SSteven Rostedt	    print "$option\n";
10569cc9e091SSteven Rostedt	}
10579cc9e091SSteven Rostedt	print "Set IGRNORE_UNUSED = 1 to have ktest ignore unused variables\n";
10589cc9e091SSteven Rostedt	if (!read_yn "Do you want to continue?") {
10599cc9e091SSteven Rostedt	    exit -1;
10609cc9e091SSteven Rostedt	}
10619cc9e091SSteven Rostedt    }
10622545eb61SSteven Rostedt}
10632545eb61SSteven Rostedt
106423715c3cSSteven Rostedtsub __eval_option {
106523715c3cSSteven Rostedt    my ($option, $i) = @_;
106623715c3cSSteven Rostedt
106723715c3cSSteven Rostedt    # Add space to evaluate the character before $
106823715c3cSSteven Rostedt    $option = " $option";
106923715c3cSSteven Rostedt    my $retval = "";
1070f9dfb65bSRabin Vincent    my $repeated = 0;
1071f9dfb65bSRabin Vincent    my $parent = 0;
1072f9dfb65bSRabin Vincent
1073f9dfb65bSRabin Vincent    foreach my $test (keys %repeat_tests) {
1074f9dfb65bSRabin Vincent	if ($i >= $test &&
1075f9dfb65bSRabin Vincent	    $i < $test + $repeat_tests{$test}) {
1076f9dfb65bSRabin Vincent
1077f9dfb65bSRabin Vincent	    $repeated = 1;
1078f9dfb65bSRabin Vincent	    $parent = $test;
1079f9dfb65bSRabin Vincent	    last;
1080f9dfb65bSRabin Vincent	}
1081f9dfb65bSRabin Vincent    }
108223715c3cSSteven Rostedt
108323715c3cSSteven Rostedt    while ($option =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) {
108423715c3cSSteven Rostedt	my $start = $1;
108523715c3cSSteven Rostedt	my $var = $2;
108623715c3cSSteven Rostedt	my $end = $3;
108723715c3cSSteven Rostedt
108823715c3cSSteven Rostedt	# Append beginning of line
108923715c3cSSteven Rostedt	$retval = "$retval$start";
109023715c3cSSteven Rostedt
109123715c3cSSteven Rostedt	# If the iteration option OPT[$i] exists, then use that.
109223715c3cSSteven Rostedt	# otherwise see if the default OPT (without [$i]) exists.
109323715c3cSSteven Rostedt
109423715c3cSSteven Rostedt	my $o = "$var\[$i\]";
1095f9dfb65bSRabin Vincent	my $parento = "$var\[$parent\]";
109623715c3cSSteven Rostedt
109723715c3cSSteven Rostedt	if (defined($opt{$o})) {
109823715c3cSSteven Rostedt	    $o = $opt{$o};
109923715c3cSSteven Rostedt	    $retval = "$retval$o";
1100f9dfb65bSRabin Vincent	} elsif ($repeated && defined($opt{$parento})) {
1101f9dfb65bSRabin Vincent	    $o = $opt{$parento};
1102f9dfb65bSRabin Vincent	    $retval = "$retval$o";
110323715c3cSSteven Rostedt	} elsif (defined($opt{$var})) {
110423715c3cSSteven Rostedt	    $o = $opt{$var};
110523715c3cSSteven Rostedt	    $retval = "$retval$o";
110623715c3cSSteven Rostedt	} else {
110723715c3cSSteven Rostedt	    $retval = "$retval\$\{$var\}";
110823715c3cSSteven Rostedt	}
110923715c3cSSteven Rostedt
111023715c3cSSteven Rostedt	$option = $end;
111123715c3cSSteven Rostedt    }
111223715c3cSSteven Rostedt
111323715c3cSSteven Rostedt    $retval = "$retval$option";
111423715c3cSSteven Rostedt
111523715c3cSSteven Rostedt    $retval =~ s/^ //;
111623715c3cSSteven Rostedt
111723715c3cSSteven Rostedt    return $retval;
111823715c3cSSteven Rostedt}
111923715c3cSSteven Rostedt
112023715c3cSSteven Rostedtsub eval_option {
112123715c3cSSteven Rostedt    my ($option, $i) = @_;
112223715c3cSSteven Rostedt
112323715c3cSSteven Rostedt    my $prev = "";
112423715c3cSSteven Rostedt
112523715c3cSSteven Rostedt    # Since an option can evaluate to another option,
112623715c3cSSteven Rostedt    # keep iterating until we do not evaluate any more
112723715c3cSSteven Rostedt    # options.
112823715c3cSSteven Rostedt    my $r = 0;
112923715c3cSSteven Rostedt    while ($prev ne $option) {
113023715c3cSSteven Rostedt	# Check for recursive evaluations.
113123715c3cSSteven Rostedt	# 100 deep should be more than enough.
113223715c3cSSteven Rostedt	if ($r++ > 100) {
113323715c3cSSteven Rostedt	    die "Over 100 evaluations accurred with $option\n" .
113423715c3cSSteven Rostedt		"Check for recursive variables\n";
113523715c3cSSteven Rostedt	}
113623715c3cSSteven Rostedt	$prev = $option;
113723715c3cSSteven Rostedt	$option = __eval_option($option, $i);
113823715c3cSSteven Rostedt    }
113923715c3cSSteven Rostedt
114023715c3cSSteven Rostedt    return $option;
114123715c3cSSteven Rostedt}
114223715c3cSSteven Rostedt
1143d1e2f22aSSteven Rostedtsub _logit {
11442545eb61SSteven Rostedt    if (defined($opt{"LOG_FILE"})) {
11452545eb61SSteven Rostedt	open(OUT, ">> $opt{LOG_FILE}") or die "Can't write to $opt{LOG_FILE}";
11462545eb61SSteven Rostedt	print OUT @_;
11472545eb61SSteven Rostedt	close(OUT);
11482545eb61SSteven Rostedt    }
11492545eb61SSteven Rostedt}
11502545eb61SSteven Rostedt
1151d1e2f22aSSteven Rostedtsub logit {
1152d1e2f22aSSteven Rostedt    if (defined($opt{"LOG_FILE"})) {
1153d1e2f22aSSteven Rostedt	_logit @_;
1154d1e2f22aSSteven Rostedt    } else {
1155d1e2f22aSSteven Rostedt	print @_;
1156d1e2f22aSSteven Rostedt    }
1157d1e2f22aSSteven Rostedt}
1158d1e2f22aSSteven Rostedt
11595f9b6cedSSteven Rostedtsub doprint {
11605f9b6cedSSteven Rostedt    print @_;
1161d1e2f22aSSteven Rostedt    _logit @_;
11625f9b6cedSSteven Rostedt}
11635f9b6cedSSteven Rostedt
11647faafbd6SSteven Rostedtsub run_command;
11652728be41SAndrew Jonessub start_monitor;
11662728be41SAndrew Jonessub end_monitor;
11672728be41SAndrew Jonessub wait_for_monitor;
11687faafbd6SSteven Rostedt
11697faafbd6SSteven Rostedtsub reboot {
11702728be41SAndrew Jones    my ($time) = @_;
11712728be41SAndrew Jones
1172a4968722SSteven Rostedt    # Make sure everything has been written to disk
1173a4968722SSteven Rostedt    run_ssh("sync");
1174a4968722SSteven Rostedt
11752b803365SSteven Rostedt    if (defined($time)) {
11762b803365SSteven Rostedt	start_monitor;
11772b803365SSteven Rostedt	# flush out current monitor
11782b803365SSteven Rostedt	# May contain the reboot success line
11792b803365SSteven Rostedt	wait_for_monitor 1;
11802b803365SSteven Rostedt    }
11812b803365SSteven Rostedt
11827faafbd6SSteven Rostedt    # try to reboot normally
1183e48c5293SSteven Rostedt    if (run_command $reboot) {
1184576f627cSSteven Rostedt	if (defined($powercycle_after_reboot)) {
1185576f627cSSteven Rostedt	    sleep $powercycle_after_reboot;
1186576f627cSSteven Rostedt	    run_command "$power_cycle";
1187576f627cSSteven Rostedt	}
1188576f627cSSteven Rostedt    } else {
11897faafbd6SSteven Rostedt	# nope? power cycle it.
1190a75fececSSteven Rostedt	run_command "$power_cycle";
11917faafbd6SSteven Rostedt    }
11922728be41SAndrew Jones
11932728be41SAndrew Jones    if (defined($time)) {
1194407b95b7SSteven Rostedt	if (wait_for_monitor($time, $reboot_success_line)) {
1195407b95b7SSteven Rostedt	    # reboot got stuck?
11968a80c727SSteven Rostedt	    doprint "Reboot did not finish. Forcing power cycle\n";
1197407b95b7SSteven Rostedt	    run_command "$power_cycle";
1198407b95b7SSteven Rostedt	}
11992728be41SAndrew Jones	end_monitor;
12002728be41SAndrew Jones    }
12017faafbd6SSteven Rostedt}
12027faafbd6SSteven Rostedt
1203bc7c5803SSteven Rostedtsub reboot_to_good {
1204bc7c5803SSteven Rostedt    my ($time) = @_;
1205bc7c5803SSteven Rostedt
1206bc7c5803SSteven Rostedt    if (defined($switch_to_good)) {
1207bc7c5803SSteven Rostedt	run_command $switch_to_good;
1208bc7c5803SSteven Rostedt    }
1209bc7c5803SSteven Rostedt
1210bc7c5803SSteven Rostedt    reboot $time;
1211bc7c5803SSteven Rostedt}
1212bc7c5803SSteven Rostedt
1213576f627cSSteven Rostedtsub do_not_reboot {
1214576f627cSSteven Rostedt    my $i = $iteration;
1215576f627cSSteven Rostedt
12164ab1cce5SSteven Rostedt    return $test_type eq "build" || $no_reboot ||
1217576f627cSSteven Rostedt	($test_type eq "patchcheck" && $opt{"PATCHCHECK_TYPE[$i]"} eq "build") ||
1218576f627cSSteven Rostedt	($test_type eq "bisect" && $opt{"BISECT_TYPE[$i]"} eq "build");
1219576f627cSSteven Rostedt}
1220576f627cSSteven Rostedt
12215c42fc5bSSteven Rostedtsub dodie {
12225a391fbfSSteven Rostedt    doprint "CRITICAL FAILURE... ", @_, "\n";
12235c42fc5bSSteven Rostedt
1224576f627cSSteven Rostedt    my $i = $iteration;
1225576f627cSSteven Rostedt
1226576f627cSSteven Rostedt    if ($reboot_on_error && !do_not_reboot) {
1227576f627cSSteven Rostedt
122875c3fda7SSteven Rostedt	doprint "REBOOTING\n";
1229bc7c5803SSteven Rostedt	reboot_to_good;
123075c3fda7SSteven Rostedt
1231a75fececSSteven Rostedt    } elsif ($poweroff_on_error && defined($power_off)) {
12325c42fc5bSSteven Rostedt	doprint "POWERING OFF\n";
1233a75fececSSteven Rostedt	`$power_off`;
12345c42fc5bSSteven Rostedt    }
123575c3fda7SSteven Rostedt
1236f80802cbSSteven Rostedt    if (defined($opt{"LOG_FILE"})) {
1237f80802cbSSteven Rostedt	print " See $opt{LOG_FILE} for more info.\n";
1238f80802cbSSteven Rostedt    }
1239f80802cbSSteven Rostedt
1240576f627cSSteven Rostedt    die @_, "\n";
12415c42fc5bSSteven Rostedt}
12425c42fc5bSSteven Rostedt
12437faafbd6SSteven Rostedtsub open_console {
12447faafbd6SSteven Rostedt    my ($fp) = @_;
12457faafbd6SSteven Rostedt
12467faafbd6SSteven Rostedt    my $flags;
12477faafbd6SSteven Rostedt
1248a75fececSSteven Rostedt    my $pid = open($fp, "$console|") or
1249a75fececSSteven Rostedt	dodie "Can't open console $console";
12507faafbd6SSteven Rostedt
12517faafbd6SSteven Rostedt    $flags = fcntl($fp, F_GETFL, 0) or
1252576f627cSSteven Rostedt	dodie "Can't get flags for the socket: $!";
12537faafbd6SSteven Rostedt    $flags = fcntl($fp, F_SETFL, $flags | O_NONBLOCK) or
1254576f627cSSteven Rostedt	dodie "Can't set flags for the socket: $!";
12557faafbd6SSteven Rostedt
12567faafbd6SSteven Rostedt    return $pid;
12577faafbd6SSteven Rostedt}
12587faafbd6SSteven Rostedt
12597faafbd6SSteven Rostedtsub close_console {
12607faafbd6SSteven Rostedt    my ($fp, $pid) = @_;
12617faafbd6SSteven Rostedt
12627faafbd6SSteven Rostedt    doprint "kill child process $pid\n";
12637faafbd6SSteven Rostedt    kill 2, $pid;
12647faafbd6SSteven Rostedt
12657faafbd6SSteven Rostedt    print "closing!\n";
12667faafbd6SSteven Rostedt    close($fp);
12677faafbd6SSteven Rostedt}
12687faafbd6SSteven Rostedt
12697faafbd6SSteven Rostedtsub start_monitor {
12707faafbd6SSteven Rostedt    if ($monitor_cnt++) {
12717faafbd6SSteven Rostedt	return;
12727faafbd6SSteven Rostedt    }
12737faafbd6SSteven Rostedt    $monitor_fp = \*MONFD;
12747faafbd6SSteven Rostedt    $monitor_pid = open_console $monitor_fp;
1275a75fececSSteven Rostedt
1276a75fececSSteven Rostedt    return;
1277a75fececSSteven Rostedt
1278a75fececSSteven Rostedt    open(MONFD, "Stop perl from warning about single use of MONFD");
12797faafbd6SSteven Rostedt}
12807faafbd6SSteven Rostedt
12817faafbd6SSteven Rostedtsub end_monitor {
12827faafbd6SSteven Rostedt    if (--$monitor_cnt) {
12837faafbd6SSteven Rostedt	return;
12847faafbd6SSteven Rostedt    }
12857faafbd6SSteven Rostedt    close_console($monitor_fp, $monitor_pid);
12867faafbd6SSteven Rostedt}
12877faafbd6SSteven Rostedt
12887faafbd6SSteven Rostedtsub wait_for_monitor {
12892b803365SSteven Rostedt    my ($time, $stop) = @_;
12902b803365SSteven Rostedt    my $full_line = "";
12917faafbd6SSteven Rostedt    my $line;
12922b803365SSteven Rostedt    my $booted = 0;
1293407b95b7SSteven Rostedt    my $start_time = time;
12948a80c727SSteven Rostedt    my $skip_call_trace = 0;
12958a80c727SSteven Rostedt    my $bug = 0;
12968a80c727SSteven Rostedt    my $bug_ignored = 0;
1297407b95b7SSteven Rostedt    my $now;
12987faafbd6SSteven Rostedt
1299a75fececSSteven Rostedt    doprint "** Wait for monitor to settle down **\n";
13007faafbd6SSteven Rostedt
13017faafbd6SSteven Rostedt    # read the monitor and wait for the system to calm down
13022b803365SSteven Rostedt    while (!$booted) {
13037faafbd6SSteven Rostedt	$line = wait_for_input($monitor_fp, $time);
13042b803365SSteven Rostedt	last if (!defined($line));
13052b803365SSteven Rostedt	print "$line";
13062b803365SSteven Rostedt	$full_line .= $line;
13072b803365SSteven Rostedt
13082b803365SSteven Rostedt	if (defined($stop) && $full_line =~ /$stop/) {
13092b803365SSteven Rostedt	    doprint "wait for monitor detected $stop\n";
13102b803365SSteven Rostedt	    $booted = 1;
13112b803365SSteven Rostedt	}
13122b803365SSteven Rostedt
13138a80c727SSteven Rostedt	if ($full_line =~ /\[ backtrace testing \]/) {
13148a80c727SSteven Rostedt	    $skip_call_trace = 1;
13158a80c727SSteven Rostedt	}
13168a80c727SSteven Rostedt
13178a80c727SSteven Rostedt	if ($full_line =~ /call trace:/i) {
13188a80c727SSteven Rostedt	    if (!$bug && !$skip_call_trace) {
13198a80c727SSteven Rostedt		if ($ignore_errors) {
13208a80c727SSteven Rostedt		    $bug_ignored = 1;
13218a80c727SSteven Rostedt		} else {
13228a80c727SSteven Rostedt		    $bug = 1;
13238a80c727SSteven Rostedt		}
13248a80c727SSteven Rostedt	    }
13258a80c727SSteven Rostedt	}
13268a80c727SSteven Rostedt
13278a80c727SSteven Rostedt	if ($full_line =~ /\[ end of backtrace testing \]/) {
13288a80c727SSteven Rostedt	    $skip_call_trace = 0;
13298a80c727SSteven Rostedt	}
13308a80c727SSteven Rostedt
13318a80c727SSteven Rostedt	if ($full_line =~ /Kernel panic -/) {
13328a80c727SSteven Rostedt	    $bug = 1;
13338a80c727SSteven Rostedt	}
13348a80c727SSteven Rostedt
13352b803365SSteven Rostedt	if ($line =~ /\n/) {
13362b803365SSteven Rostedt	    $full_line = "";
13372b803365SSteven Rostedt	}
1338407b95b7SSteven Rostedt	$now = time;
1339407b95b7SSteven Rostedt	if ($now - $start_time >= $max_monitor_wait) {
1340407b95b7SSteven Rostedt	    doprint "Exiting monitor flush due to hitting MAX_MONITOR_WAIT\n";
1341407b95b7SSteven Rostedt	    return 1;
1342407b95b7SSteven Rostedt	}
13432b803365SSteven Rostedt    }
1344a75fececSSteven Rostedt    print "** Monitor flushed **\n";
13458a80c727SSteven Rostedt    return $bug;
13467faafbd6SSteven Rostedt}
13477faafbd6SSteven Rostedt
1348de5b6e3bSRabin Vincentsub save_logs {
1349de5b6e3bSRabin Vincent	my ($result, $basedir) = @_;
1350de5b6e3bSRabin Vincent	my @t = localtime;
1351de5b6e3bSRabin Vincent	my $date = sprintf "%04d%02d%02d%02d%02d%02d",
1352de5b6e3bSRabin Vincent		1900+$t[5],$t[4],$t[3],$t[2],$t[1],$t[0];
1353de5b6e3bSRabin Vincent
1354de5b6e3bSRabin Vincent	my $type = $build_type;
1355de5b6e3bSRabin Vincent	if ($type =~ /useconfig/) {
1356de5b6e3bSRabin Vincent	    $type = "useconfig";
1357de5b6e3bSRabin Vincent	}
1358de5b6e3bSRabin Vincent
1359de5b6e3bSRabin Vincent	my $dir = "$machine-$test_type-$type-$result-$date";
1360de5b6e3bSRabin Vincent
1361de5b6e3bSRabin Vincent	$dir = "$basedir/$dir";
1362de5b6e3bSRabin Vincent
1363de5b6e3bSRabin Vincent	if (!-d $dir) {
1364de5b6e3bSRabin Vincent	    mkpath($dir) or
1365de5b6e3bSRabin Vincent		die "can't create $dir";
1366de5b6e3bSRabin Vincent	}
1367de5b6e3bSRabin Vincent
1368de5b6e3bSRabin Vincent	my %files = (
1369de5b6e3bSRabin Vincent		"config" => $output_config,
1370de5b6e3bSRabin Vincent		"buildlog" => $buildlog,
1371de5b6e3bSRabin Vincent		"dmesg" => $dmesg,
1372de5b6e3bSRabin Vincent		"testlog" => $testlog,
1373de5b6e3bSRabin Vincent	);
1374de5b6e3bSRabin Vincent
1375de5b6e3bSRabin Vincent	while (my ($name, $source) = each(%files)) {
1376de5b6e3bSRabin Vincent		if (-f "$source") {
1377de5b6e3bSRabin Vincent			cp "$source", "$dir/$name" or
1378de5b6e3bSRabin Vincent				die "failed to copy $source";
1379de5b6e3bSRabin Vincent		}
1380de5b6e3bSRabin Vincent	}
1381de5b6e3bSRabin Vincent
1382de5b6e3bSRabin Vincent	doprint "*** Saved info to $dir ***\n";
1383de5b6e3bSRabin Vincent}
1384de5b6e3bSRabin Vincent
13852b7d9b21SSteven Rostedtsub fail {
13862b7d9b21SSteven Rostedt
1387921ed4c7SSteven Rostedt	if (defined($post_test)) {
1388921ed4c7SSteven Rostedt		run_command $post_test;
1389921ed4c7SSteven Rostedt	}
1390921ed4c7SSteven Rostedt
1391a75fececSSteven Rostedt	if ($die_on_failure) {
13922b7d9b21SSteven Rostedt		dodie @_;
13932b7d9b21SSteven Rostedt	}
13942b7d9b21SSteven Rostedt
1395a75fececSSteven Rostedt	doprint "FAILED\n";
13967faafbd6SSteven Rostedt
1397576f627cSSteven Rostedt	my $i = $iteration;
1398576f627cSSteven Rostedt
1399a75fececSSteven Rostedt	# no need to reboot for just building.
1400576f627cSSteven Rostedt	if (!do_not_reboot) {
14017faafbd6SSteven Rostedt	    doprint "REBOOTING\n";
1402bc7c5803SSteven Rostedt	    reboot_to_good $sleep_time;
1403a75fececSSteven Rostedt	}
14047faafbd6SSteven Rostedt
14059064af52SSteven Rostedt	my $name = "";
14069064af52SSteven Rostedt
14079064af52SSteven Rostedt	if (defined($test_name)) {
14089064af52SSteven Rostedt	    $name = " ($test_name)";
14099064af52SSteven Rostedt	}
14109064af52SSteven Rostedt
1411576f627cSSteven Rostedt	doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
1412576f627cSSteven Rostedt	doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
14139064af52SSteven Rostedt	doprint "KTEST RESULT: TEST $i$name Failed: ", @_, "\n";
1414576f627cSSteven Rostedt	doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
1415576f627cSSteven Rostedt	doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
1416a75fececSSteven Rostedt
1417de5b6e3bSRabin Vincent	if (defined($store_failures)) {
1418de5b6e3bSRabin Vincent	    save_logs "fail", $store_failures;
1419cccae1a6SSteven Rostedt        }
1420cccae1a6SSteven Rostedt
14212b7d9b21SSteven Rostedt	return 1;
14222b7d9b21SSteven Rostedt}
14232b7d9b21SSteven Rostedt
14242545eb61SSteven Rostedtsub run_command {
14252545eb61SSteven Rostedt    my ($command) = @_;
1426d6ce2a0bSSteven Rostedt    my $dolog = 0;
1427d6ce2a0bSSteven Rostedt    my $dord = 0;
1428d6ce2a0bSSteven Rostedt    my $pid;
1429d6ce2a0bSSteven Rostedt
1430e48c5293SSteven Rostedt    $command =~ s/\$SSH_USER/$ssh_user/g;
1431e48c5293SSteven Rostedt    $command =~ s/\$MACHINE/$machine/g;
1432e48c5293SSteven Rostedt
1433d6ce2a0bSSteven Rostedt    doprint("$command ... ");
1434d6ce2a0bSSteven Rostedt
1435d6ce2a0bSSteven Rostedt    $pid = open(CMD, "$command 2>&1 |") or
14362b7d9b21SSteven Rostedt	(fail "unable to exec $command" and return 0);
14372545eb61SSteven Rostedt
14382545eb61SSteven Rostedt    if (defined($opt{"LOG_FILE"})) {
1439d6ce2a0bSSteven Rostedt	open(LOG, ">>$opt{LOG_FILE}") or
1440d6ce2a0bSSteven Rostedt	    dodie "failed to write to log";
1441d6ce2a0bSSteven Rostedt	$dolog = 1;
14426c5ee0beSSteven Rostedt    }
14436c5ee0beSSteven Rostedt
14446c5ee0beSSteven Rostedt    if (defined($redirect)) {
1445d6ce2a0bSSteven Rostedt	open (RD, ">$redirect") or
1446d6ce2a0bSSteven Rostedt	    dodie "failed to write to redirect $redirect";
1447d6ce2a0bSSteven Rostedt	$dord = 1;
14482545eb61SSteven Rostedt    }
14492545eb61SSteven Rostedt
1450d6ce2a0bSSteven Rostedt    while (<CMD>) {
1451d6ce2a0bSSteven Rostedt	print LOG if ($dolog);
1452d6ce2a0bSSteven Rostedt	print RD  if ($dord);
1453d6ce2a0bSSteven Rostedt    }
14542545eb61SSteven Rostedt
1455d6ce2a0bSSteven Rostedt    waitpid($pid, 0);
14562545eb61SSteven Rostedt    my $failed = $?;
14572545eb61SSteven Rostedt
1458d6ce2a0bSSteven Rostedt    close(CMD);
1459d6ce2a0bSSteven Rostedt    close(LOG) if ($dolog);
1460d6ce2a0bSSteven Rostedt    close(RD)  if ($dord);
1461d6ce2a0bSSteven Rostedt
14622545eb61SSteven Rostedt    if ($failed) {
14632545eb61SSteven Rostedt	doprint "FAILED!\n";
14642545eb61SSteven Rostedt    } else {
14652545eb61SSteven Rostedt	doprint "SUCCESS\n";
14662545eb61SSteven Rostedt    }
14672545eb61SSteven Rostedt
14685f9b6cedSSteven Rostedt    return !$failed;
14695f9b6cedSSteven Rostedt}
14705f9b6cedSSteven Rostedt
1471e48c5293SSteven Rostedtsub run_ssh {
1472e48c5293SSteven Rostedt    my ($cmd) = @_;
1473e48c5293SSteven Rostedt    my $cp_exec = $ssh_exec;
1474e48c5293SSteven Rostedt
1475e48c5293SSteven Rostedt    $cp_exec =~ s/\$SSH_COMMAND/$cmd/g;
1476e48c5293SSteven Rostedt    return run_command "$cp_exec";
1477e48c5293SSteven Rostedt}
1478e48c5293SSteven Rostedt
1479e48c5293SSteven Rostedtsub run_scp {
148002ad2617SSteven Rostedt    my ($src, $dst, $cp_scp) = @_;
1481e48c5293SSteven Rostedt
1482e48c5293SSteven Rostedt    $cp_scp =~ s/\$SRC_FILE/$src/g;
1483e48c5293SSteven Rostedt    $cp_scp =~ s/\$DST_FILE/$dst/g;
1484e48c5293SSteven Rostedt
1485e48c5293SSteven Rostedt    return run_command "$cp_scp";
1486e48c5293SSteven Rostedt}
1487e48c5293SSteven Rostedt
148802ad2617SSteven Rostedtsub run_scp_install {
148902ad2617SSteven Rostedt    my ($src, $dst) = @_;
149002ad2617SSteven Rostedt
149102ad2617SSteven Rostedt    my $cp_scp = $scp_to_target_install;
149202ad2617SSteven Rostedt
149302ad2617SSteven Rostedt    return run_scp($src, $dst, $cp_scp);
149402ad2617SSteven Rostedt}
149502ad2617SSteven Rostedt
149602ad2617SSteven Rostedtsub run_scp_mod {
149702ad2617SSteven Rostedt    my ($src, $dst) = @_;
149802ad2617SSteven Rostedt
149902ad2617SSteven Rostedt    my $cp_scp = $scp_to_target;
150002ad2617SSteven Rostedt
150102ad2617SSteven Rostedt    return run_scp($src, $dst, $cp_scp);
150202ad2617SSteven Rostedt}
150302ad2617SSteven Rostedt
1504a15ba913SSteven Rostedtsub get_grub2_index {
1505a15ba913SSteven Rostedt
1506a15ba913SSteven Rostedt    return if (defined($grub_number));
1507a15ba913SSteven Rostedt
1508a15ba913SSteven Rostedt    doprint "Find grub2 menu ... ";
1509a15ba913SSteven Rostedt    $grub_number = -1;
1510a15ba913SSteven Rostedt
1511a15ba913SSteven Rostedt    my $ssh_grub = $ssh_exec;
1512a15ba913SSteven Rostedt    $ssh_grub =~ s,\$SSH_COMMAND,cat $grub_file,g;
1513a15ba913SSteven Rostedt
1514a15ba913SSteven Rostedt    open(IN, "$ssh_grub |")
1515a15ba913SSteven Rostedt	or die "unable to get $grub_file";
1516a15ba913SSteven Rostedt
1517a15ba913SSteven Rostedt    my $found = 0;
1518a15ba913SSteven Rostedt
1519a15ba913SSteven Rostedt    while (<IN>) {
1520a15ba913SSteven Rostedt	if (/^menuentry.*$grub_menu/) {
1521a15ba913SSteven Rostedt	    $grub_number++;
1522a15ba913SSteven Rostedt	    $found = 1;
1523a15ba913SSteven Rostedt	    last;
1524a15ba913SSteven Rostedt	} elsif (/^menuentry\s/) {
1525a15ba913SSteven Rostedt	    $grub_number++;
1526a15ba913SSteven Rostedt	}
1527a15ba913SSteven Rostedt    }
1528a15ba913SSteven Rostedt    close(IN);
1529a15ba913SSteven Rostedt
1530a15ba913SSteven Rostedt    die "Could not find '$grub_menu' in $grub_file on $machine"
1531a15ba913SSteven Rostedt	if (!$found);
1532a15ba913SSteven Rostedt    doprint "$grub_number\n";
1533a15ba913SSteven Rostedt}
1534a15ba913SSteven Rostedt
15355f9b6cedSSteven Rostedtsub get_grub_index {
15365f9b6cedSSteven Rostedt
1537a15ba913SSteven Rostedt    if ($reboot_type eq "grub2") {
1538a15ba913SSteven Rostedt	get_grub2_index;
1539a15ba913SSteven Rostedt	return;
1540a15ba913SSteven Rostedt    }
1541a15ba913SSteven Rostedt
1542a75fececSSteven Rostedt    if ($reboot_type ne "grub") {
1543a75fececSSteven Rostedt	return;
1544a75fececSSteven Rostedt    }
15455a391fbfSSteven Rostedt    return if (defined($grub_number));
15465f9b6cedSSteven Rostedt
15475f9b6cedSSteven Rostedt    doprint "Find grub menu ... ";
15485f9b6cedSSteven Rostedt    $grub_number = -1;
1549e48c5293SSteven Rostedt
1550e48c5293SSteven Rostedt    my $ssh_grub = $ssh_exec;
1551e48c5293SSteven Rostedt    $ssh_grub =~ s,\$SSH_COMMAND,cat /boot/grub/menu.lst,g;
1552e48c5293SSteven Rostedt
1553e48c5293SSteven Rostedt    open(IN, "$ssh_grub |")
15545f9b6cedSSteven Rostedt	or die "unable to get menu.lst";
1555e48c5293SSteven Rostedt
1556eaa1fe25SSteven Rostedt    my $found = 0;
1557eaa1fe25SSteven Rostedt
15585f9b6cedSSteven Rostedt    while (<IN>) {
1559a75fececSSteven Rostedt	if (/^\s*title\s+$grub_menu\s*$/) {
15605f9b6cedSSteven Rostedt	    $grub_number++;
1561eaa1fe25SSteven Rostedt	    $found = 1;
15625f9b6cedSSteven Rostedt	    last;
15635f9b6cedSSteven Rostedt	} elsif (/^\s*title\s/) {
15645f9b6cedSSteven Rostedt	    $grub_number++;
15655f9b6cedSSteven Rostedt	}
15665f9b6cedSSteven Rostedt    }
15675f9b6cedSSteven Rostedt    close(IN);
15685f9b6cedSSteven Rostedt
1569a75fececSSteven Rostedt    die "Could not find '$grub_menu' in /boot/grub/menu on $machine"
1570eaa1fe25SSteven Rostedt	if (!$found);
15715f9b6cedSSteven Rostedt    doprint "$grub_number\n";
15722545eb61SSteven Rostedt}
15732545eb61SSteven Rostedt
15742545eb61SSteven Rostedtsub wait_for_input
15752545eb61SSteven Rostedt{
15762545eb61SSteven Rostedt    my ($fp, $time) = @_;
15772545eb61SSteven Rostedt    my $rin;
15782545eb61SSteven Rostedt    my $ready;
15792545eb61SSteven Rostedt    my $line;
15802545eb61SSteven Rostedt    my $ch;
15812545eb61SSteven Rostedt
15822545eb61SSteven Rostedt    if (!defined($time)) {
15832545eb61SSteven Rostedt	$time = $timeout;
15842545eb61SSteven Rostedt    }
15852545eb61SSteven Rostedt
15862545eb61SSteven Rostedt    $rin = '';
15872545eb61SSteven Rostedt    vec($rin, fileno($fp), 1) = 1;
15882545eb61SSteven Rostedt    $ready = select($rin, undef, undef, $time);
15892545eb61SSteven Rostedt
15902545eb61SSteven Rostedt    $line = "";
15912545eb61SSteven Rostedt
15922545eb61SSteven Rostedt    # try to read one char at a time
15932545eb61SSteven Rostedt    while (sysread $fp, $ch, 1) {
15942545eb61SSteven Rostedt	$line .= $ch;
15952545eb61SSteven Rostedt	last if ($ch eq "\n");
15962545eb61SSteven Rostedt    }
15972545eb61SSteven Rostedt
15982545eb61SSteven Rostedt    if (!length($line)) {
15992545eb61SSteven Rostedt	return undef;
16002545eb61SSteven Rostedt    }
16012545eb61SSteven Rostedt
16022545eb61SSteven Rostedt    return $line;
16032545eb61SSteven Rostedt}
16042545eb61SSteven Rostedt
160575c3fda7SSteven Rostedtsub reboot_to {
1606bc7c5803SSteven Rostedt    if (defined($switch_to_test)) {
1607bc7c5803SSteven Rostedt	run_command $switch_to_test;
1608bc7c5803SSteven Rostedt    }
1609bc7c5803SSteven Rostedt
1610a75fececSSteven Rostedt    if ($reboot_type eq "grub") {
1611c54367f9SSteven Rostedt	run_ssh "'(echo \"savedefault --default=$grub_number --once\" | grub --batch)'";
1612a15ba913SSteven Rostedt    } elsif ($reboot_type eq "grub2") {
1613a15ba913SSteven Rostedt	run_ssh "$grub_reboot $grub_number";
16147786954cSSteven Rostedt    } elsif ($reboot_type eq "syslinux") {
16157786954cSSteven Rostedt	run_ssh "$syslinux --once \\\"$syslinux_label\\\" $syslinux_path";
161696f6a0dfSSteven Rostedt    } elsif (defined $reboot_script) {
1617a75fececSSteven Rostedt	run_command "$reboot_script";
16182545eb61SSteven Rostedt    }
161996f6a0dfSSteven Rostedt    reboot;
162096f6a0dfSSteven Rostedt}
16212545eb61SSteven Rostedt
1622a57419b3SSteven Rostedtsub get_sha1 {
1623a57419b3SSteven Rostedt    my ($commit) = @_;
1624a57419b3SSteven Rostedt
1625a57419b3SSteven Rostedt    doprint "git rev-list --max-count=1 $commit ... ";
1626a57419b3SSteven Rostedt    my $sha1 = `git rev-list --max-count=1 $commit`;
1627a57419b3SSteven Rostedt    my $ret = $?;
1628a57419b3SSteven Rostedt
1629a57419b3SSteven Rostedt    logit $sha1;
1630a57419b3SSteven Rostedt
1631a57419b3SSteven Rostedt    if ($ret) {
1632a57419b3SSteven Rostedt	doprint "FAILED\n";
1633a57419b3SSteven Rostedt	dodie "Failed to get git $commit";
1634a57419b3SSteven Rostedt    }
1635a57419b3SSteven Rostedt
1636a57419b3SSteven Rostedt    print "SUCCESS\n";
1637a57419b3SSteven Rostedt
1638a57419b3SSteven Rostedt    chomp $sha1;
1639a57419b3SSteven Rostedt
1640a57419b3SSteven Rostedt    return $sha1;
1641a57419b3SSteven Rostedt}
1642a57419b3SSteven Rostedt
16435a391fbfSSteven Rostedtsub monitor {
16442545eb61SSteven Rostedt    my $booted = 0;
16452545eb61SSteven Rostedt    my $bug = 0;
16466ca996ccSSteven Rostedt    my $bug_ignored = 0;
16475c42fc5bSSteven Rostedt    my $skip_call_trace = 0;
16482b7d9b21SSteven Rostedt    my $loops;
16492545eb61SSteven Rostedt
16507faafbd6SSteven Rostedt    wait_for_monitor 5;
16512545eb61SSteven Rostedt
16522545eb61SSteven Rostedt    my $line;
16532545eb61SSteven Rostedt    my $full_line = "";
16542545eb61SSteven Rostedt
16557faafbd6SSteven Rostedt    open(DMESG, "> $dmesg") or
16567faafbd6SSteven Rostedt	die "unable to write to $dmesg";
16572545eb61SSteven Rostedt
165875c3fda7SSteven Rostedt    reboot_to;
16592545eb61SSteven Rostedt
16601c8a617aSSteven Rostedt    my $success_start;
16611c8a617aSSteven Rostedt    my $failure_start;
16622d01b26aSSteven Rostedt    my $monitor_start = time;
16632d01b26aSSteven Rostedt    my $done = 0;
1664f1a5b962SSteven Rostedt    my $version_found = 0;
16651c8a617aSSteven Rostedt
16662d01b26aSSteven Rostedt    while (!$done) {
16672545eb61SSteven Rostedt
1668ecaf8e52SSteven Rostedt	if ($bug && defined($stop_after_failure) &&
1669ecaf8e52SSteven Rostedt	    $stop_after_failure >= 0) {
1670ecaf8e52SSteven Rostedt	    my $time = $stop_after_failure - (time - $failure_start);
1671ecaf8e52SSteven Rostedt	    $line = wait_for_input($monitor_fp, $time);
1672ecaf8e52SSteven Rostedt	    if (!defined($line)) {
1673ecaf8e52SSteven Rostedt		doprint "bug timed out after $booted_timeout seconds\n";
1674ecaf8e52SSteven Rostedt		doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
1675ecaf8e52SSteven Rostedt		last;
1676ecaf8e52SSteven Rostedt	    }
1677ecaf8e52SSteven Rostedt	} elsif ($booted) {
1678a75fececSSteven Rostedt	    $line = wait_for_input($monitor_fp, $booted_timeout);
1679cd4f1d53SSteven Rostedt	    if (!defined($line)) {
1680cd4f1d53SSteven Rostedt		my $s = $booted_timeout == 1 ? "" : "s";
1681cd4f1d53SSteven Rostedt		doprint "Successful boot found: break after $booted_timeout second$s\n";
1682cd4f1d53SSteven Rostedt		last;
1683cd4f1d53SSteven Rostedt	    }
16842b7d9b21SSteven Rostedt	} else {
16857faafbd6SSteven Rostedt	    $line = wait_for_input($monitor_fp);
1686cd4f1d53SSteven Rostedt	    if (!defined($line)) {
1687cd4f1d53SSteven Rostedt		my $s = $timeout == 1 ? "" : "s";
1688cd4f1d53SSteven Rostedt		doprint "Timed out after $timeout second$s\n";
1689cd4f1d53SSteven Rostedt		last;
16902b7d9b21SSteven Rostedt	    }
1691cd4f1d53SSteven Rostedt	}
16922545eb61SSteven Rostedt
16932545eb61SSteven Rostedt	doprint $line;
16947faafbd6SSteven Rostedt	print DMESG $line;
16952545eb61SSteven Rostedt
16962545eb61SSteven Rostedt	# we are not guaranteed to get a full line
16972545eb61SSteven Rostedt	$full_line .= $line;
16982545eb61SSteven Rostedt
1699a75fececSSteven Rostedt	if ($full_line =~ /$success_line/) {
17002545eb61SSteven Rostedt	    $booted = 1;
17011c8a617aSSteven Rostedt	    $success_start = time;
17021c8a617aSSteven Rostedt	}
17031c8a617aSSteven Rostedt
17041c8a617aSSteven Rostedt	if ($booted && defined($stop_after_success) &&
17051c8a617aSSteven Rostedt	    $stop_after_success >= 0) {
17061c8a617aSSteven Rostedt	    my $now = time;
17071c8a617aSSteven Rostedt	    if ($now - $success_start >= $stop_after_success) {
17081c8a617aSSteven Rostedt		doprint "Test forced to stop after $stop_after_success seconds after success\n";
17091c8a617aSSteven Rostedt		last;
17101c8a617aSSteven Rostedt	    }
17112545eb61SSteven Rostedt	}
17122545eb61SSteven Rostedt
17135c42fc5bSSteven Rostedt	if ($full_line =~ /\[ backtrace testing \]/) {
17145c42fc5bSSteven Rostedt	    $skip_call_trace = 1;
17155c42fc5bSSteven Rostedt	}
17165c42fc5bSSteven Rostedt
17172545eb61SSteven Rostedt	if ($full_line =~ /call trace:/i) {
17186ca996ccSSteven Rostedt	    if (!$bug && !$skip_call_trace) {
17196ca996ccSSteven Rostedt		if ($ignore_errors) {
17206ca996ccSSteven Rostedt		    $bug_ignored = 1;
17216ca996ccSSteven Rostedt		} else {
17221c8a617aSSteven Rostedt		    $bug = 1;
17231c8a617aSSteven Rostedt		    $failure_start = time;
17241c8a617aSSteven Rostedt		}
17251c8a617aSSteven Rostedt	    }
17266ca996ccSSteven Rostedt	}
17271c8a617aSSteven Rostedt
17281c8a617aSSteven Rostedt	if ($bug && defined($stop_after_failure) &&
17291c8a617aSSteven Rostedt	    $stop_after_failure >= 0) {
17301c8a617aSSteven Rostedt	    my $now = time;
17311c8a617aSSteven Rostedt	    if ($now - $failure_start >= $stop_after_failure) {
17321c8a617aSSteven Rostedt		doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
17331c8a617aSSteven Rostedt		last;
17341c8a617aSSteven Rostedt	    }
17355c42fc5bSSteven Rostedt	}
17365c42fc5bSSteven Rostedt
17375c42fc5bSSteven Rostedt	if ($full_line =~ /\[ end of backtrace testing \]/) {
17385c42fc5bSSteven Rostedt	    $skip_call_trace = 0;
17395c42fc5bSSteven Rostedt	}
17405c42fc5bSSteven Rostedt
17415c42fc5bSSteven Rostedt	if ($full_line =~ /Kernel panic -/) {
174210abf118SSteven Rostedt	    $failure_start = time;
17432545eb61SSteven Rostedt	    $bug = 1;
17442545eb61SSteven Rostedt	}
17452545eb61SSteven Rostedt
1746f1a5b962SSteven Rostedt	# Detect triple faults by testing the banner
1747f1a5b962SSteven Rostedt	if ($full_line =~ /\bLinux version (\S+).*\n/) {
1748f1a5b962SSteven Rostedt	    if ($1 eq $version) {
1749f1a5b962SSteven Rostedt		$version_found = 1;
1750f1a5b962SSteven Rostedt	    } elsif ($version_found && $detect_triplefault) {
1751f1a5b962SSteven Rostedt		# We already booted into the kernel we are testing,
1752f1a5b962SSteven Rostedt		# but now we booted into another kernel?
1753f1a5b962SSteven Rostedt		# Consider this a triple fault.
1754f1a5b962SSteven Rostedt		doprint "Aleady booted in Linux kernel $version, but now\n";
1755f1a5b962SSteven Rostedt		doprint "we booted into Linux kernel $1.\n";
1756f1a5b962SSteven Rostedt		doprint "Assuming that this is a triple fault.\n";
1757f1a5b962SSteven Rostedt		doprint "To disable this: set DETECT_TRIPLE_FAULT to 0\n";
1758f1a5b962SSteven Rostedt		last;
1759f1a5b962SSteven Rostedt	    }
1760f1a5b962SSteven Rostedt	}
1761f1a5b962SSteven Rostedt
17622545eb61SSteven Rostedt	if ($line =~ /\n/) {
17632545eb61SSteven Rostedt	    $full_line = "";
17642545eb61SSteven Rostedt	}
17652d01b26aSSteven Rostedt
17662d01b26aSSteven Rostedt	if ($stop_test_after > 0 && !$booted && !$bug) {
17672d01b26aSSteven Rostedt	    if (time - $monitor_start > $stop_test_after) {
17684d62bf51SSteven Rostedt		doprint "STOP_TEST_AFTER ($stop_test_after seconds) timed out\n";
17692d01b26aSSteven Rostedt		$done = 1;
17702d01b26aSSteven Rostedt	    }
17712d01b26aSSteven Rostedt	}
17722545eb61SSteven Rostedt    }
17732545eb61SSteven Rostedt
17747faafbd6SSteven Rostedt    close(DMESG);
17752545eb61SSteven Rostedt
17762545eb61SSteven Rostedt    if ($bug) {
17772b7d9b21SSteven Rostedt	return 0 if ($in_bisect);
1778576f627cSSteven Rostedt	fail "failed - got a bug report" and return 0;
17792545eb61SSteven Rostedt    }
17805f9b6cedSSteven Rostedt
1781a75fececSSteven Rostedt    if (!$booted) {
1782a75fececSSteven Rostedt	return 0 if ($in_bisect);
1783576f627cSSteven Rostedt	fail "failed - never got a boot prompt." and return 0;
1784a75fececSSteven Rostedt    }
1785a75fececSSteven Rostedt
17866ca996ccSSteven Rostedt    if ($bug_ignored) {
17876ca996ccSSteven Rostedt	doprint "WARNING: Call Trace detected but ignored due to IGNORE_ERRORS=1\n";
17886ca996ccSSteven Rostedt    }
17896ca996ccSSteven Rostedt
17902b7d9b21SSteven Rostedt    return 1;
17912545eb61SSteven Rostedt}
17922545eb61SSteven Rostedt
17932b29b2f8SSteven Rostedtsub eval_kernel_version {
17942b29b2f8SSteven Rostedt    my ($option) = @_;
17952b29b2f8SSteven Rostedt
17962b29b2f8SSteven Rostedt    $option =~ s/\$KERNEL_VERSION/$version/g;
17972b29b2f8SSteven Rostedt
17982b29b2f8SSteven Rostedt    return $option;
17992b29b2f8SSteven Rostedt}
18002b29b2f8SSteven Rostedt
1801db05cfefSSteven Rostedtsub do_post_install {
1802db05cfefSSteven Rostedt
1803db05cfefSSteven Rostedt    return if (!defined($post_install));
1804db05cfefSSteven Rostedt
18052b29b2f8SSteven Rostedt    my $cp_post_install = eval_kernel_version $post_install;
1806db05cfefSSteven Rostedt    run_command "$cp_post_install" or
1807db05cfefSSteven Rostedt	dodie "Failed to run post install";
1808db05cfefSSteven Rostedt}
1809db05cfefSSteven Rostedt
1810*e1a6c3d7SSteven Rostedt# Sometimes the reboot fails, and will hang. We try to ssh to the box
1811*e1a6c3d7SSteven Rostedt# and if we fail, we force another reboot, that should powercycle it.
1812*e1a6c3d7SSteven Rostedtsub test_booted {
1813*e1a6c3d7SSteven Rostedt    if (!run_ssh "echo testing connection") {
1814*e1a6c3d7SSteven Rostedt	reboot $sleep_time;
1815*e1a6c3d7SSteven Rostedt    }
1816*e1a6c3d7SSteven Rostedt}
1817*e1a6c3d7SSteven Rostedt
18182545eb61SSteven Rostedtsub install {
18192545eb61SSteven Rostedt
1820e0a8742eSSteven Rostedt    return if ($no_install);
1821e0a8742eSSteven Rostedt
1822e5c2ec11SSteven Rostedt    if (defined($pre_install)) {
1823e5c2ec11SSteven Rostedt	my $cp_pre_install = eval_kernel_version $pre_install;
1824e5c2ec11SSteven Rostedt	run_command "$cp_pre_install" or
1825e5c2ec11SSteven Rostedt	    dodie "Failed to run pre install";
1826e5c2ec11SSteven Rostedt    }
1827e5c2ec11SSteven Rostedt
18282b29b2f8SSteven Rostedt    my $cp_target = eval_kernel_version $target_image;
18292b29b2f8SSteven Rostedt
1830*e1a6c3d7SSteven Rostedt    test_booted;
1831*e1a6c3d7SSteven Rostedt
183202ad2617SSteven Rostedt    run_scp_install "$outputdir/$build_target", "$cp_target" or
18335c42fc5bSSteven Rostedt	dodie "failed to copy image";
18345f9b6cedSSteven Rostedt
18355f9b6cedSSteven Rostedt    my $install_mods = 0;
18365f9b6cedSSteven Rostedt
18375f9b6cedSSteven Rostedt    # should we process modules?
18385f9b6cedSSteven Rostedt    $install_mods = 0;
183951ad1dd1SSteven Rostedt    open(IN, "$output_config") or dodie("Can't read config file");
18405f9b6cedSSteven Rostedt    while (<IN>) {
18415f9b6cedSSteven Rostedt	if (/CONFIG_MODULES(=y)?/) {
18428bc5e4eaSSteven Rostedt	    if (defined($1)) {
18438bc5e4eaSSteven Rostedt		$install_mods = 1;
18445f9b6cedSSteven Rostedt		last;
18455f9b6cedSSteven Rostedt	    }
18465f9b6cedSSteven Rostedt	}
18478bc5e4eaSSteven Rostedt    }
18485f9b6cedSSteven Rostedt    close(IN);
18495f9b6cedSSteven Rostedt
18505f9b6cedSSteven Rostedt    if (!$install_mods) {
1851db05cfefSSteven Rostedt	do_post_install;
18525f9b6cedSSteven Rostedt	doprint "No modules needed\n";
18535f9b6cedSSteven Rostedt	return;
18542545eb61SSteven Rostedt    }
18552545eb61SSteven Rostedt
1856627977d8SSteven Rostedt    run_command "$make INSTALL_MOD_STRIP=1 INSTALL_MOD_PATH=$tmpdir modules_install" or
18575f9b6cedSSteven Rostedt	dodie "Failed to install modules";
18585f9b6cedSSteven Rostedt
18592545eb61SSteven Rostedt    my $modlib = "/lib/modules/$version";
1860a57419b3SSteven Rostedt    my $modtar = "ktest-mods.tar.bz2";
18612545eb61SSteven Rostedt
1862e48c5293SSteven Rostedt    run_ssh "rm -rf $modlib" or
18635c42fc5bSSteven Rostedt	dodie "failed to remove old mods: $modlib";
18642545eb61SSteven Rostedt
18655c42fc5bSSteven Rostedt    # would be nice if scp -r did not follow symbolic links
1866a75fececSSteven Rostedt    run_command "cd $tmpdir && tar -cjf $modtar lib/modules/$version" or
18675c42fc5bSSteven Rostedt	dodie "making tarball";
18685c42fc5bSSteven Rostedt
186902ad2617SSteven Rostedt    run_scp_mod "$tmpdir/$modtar", "/tmp" or
18705c42fc5bSSteven Rostedt	dodie "failed to copy modules";
18715c42fc5bSSteven Rostedt
1872a75fececSSteven Rostedt    unlink "$tmpdir/$modtar";
18735c42fc5bSSteven Rostedt
1874e7b13441SSteven Rostedt    run_ssh "'(cd / && tar xjf /tmp/$modtar)'" or
18755c42fc5bSSteven Rostedt	dodie "failed to tar modules";
18765c42fc5bSSteven Rostedt
1877e48c5293SSteven Rostedt    run_ssh "rm -f /tmp/$modtar";
18788b37ca8cSSteven Rostedt
1879db05cfefSSteven Rostedt    do_post_install;
18802545eb61SSteven Rostedt}
18812545eb61SSteven Rostedt
1882ddf607e5SSteven Rostedtsub get_version {
1883ddf607e5SSteven Rostedt    # get the release name
1884683a3e64SSteven Rostedt    return if ($have_version);
1885ddf607e5SSteven Rostedt    doprint "$make kernelrelease ... ";
1886ddf607e5SSteven Rostedt    $version = `$make kernelrelease | tail -1`;
1887ddf607e5SSteven Rostedt    chomp($version);
1888ddf607e5SSteven Rostedt    doprint "$version\n";
1889683a3e64SSteven Rostedt    $have_version = 1;
1890ddf607e5SSteven Rostedt}
1891ddf607e5SSteven Rostedt
1892ddf607e5SSteven Rostedtsub start_monitor_and_boot {
18939f7424ccSSteven Rostedt    # Make sure the stable kernel has finished booting
18949f7424ccSSteven Rostedt    start_monitor;
18959f7424ccSSteven Rostedt    wait_for_monitor 5;
18969f7424ccSSteven Rostedt    end_monitor;
18979f7424ccSSteven Rostedt
1898ddf607e5SSteven Rostedt    get_grub_index;
1899ddf607e5SSteven Rostedt    get_version;
1900ddf607e5SSteven Rostedt    install;
1901ddf607e5SSteven Rostedt
1902ddf607e5SSteven Rostedt    start_monitor;
1903ddf607e5SSteven Rostedt    return monitor;
1904ddf607e5SSteven Rostedt}
1905ddf607e5SSteven Rostedt
19066c5ee0beSSteven Rostedtsub check_buildlog {
19076c5ee0beSSteven Rostedt    my ($patch) = @_;
19086c5ee0beSSteven Rostedt
19096c5ee0beSSteven Rostedt    my @files = `git show $patch | diffstat -l`;
19106c5ee0beSSteven Rostedt
19116c5ee0beSSteven Rostedt    open(IN, "git show $patch |") or
19126c5ee0beSSteven Rostedt	dodie "failed to show $patch";
19136c5ee0beSSteven Rostedt    while (<IN>) {
19146c5ee0beSSteven Rostedt	if (m,^--- a/(.*),) {
19156c5ee0beSSteven Rostedt	    chomp $1;
19166c5ee0beSSteven Rostedt	    $files[$#files] = $1;
19176c5ee0beSSteven Rostedt	}
19186c5ee0beSSteven Rostedt    }
19196c5ee0beSSteven Rostedt    close(IN);
19206c5ee0beSSteven Rostedt
19216c5ee0beSSteven Rostedt    open(IN, $buildlog) or dodie "Can't open $buildlog";
19226c5ee0beSSteven Rostedt    while (<IN>) {
19236c5ee0beSSteven Rostedt	if (/^\s*(.*?):.*(warning|error)/) {
19246c5ee0beSSteven Rostedt	    my $err = $1;
19256c5ee0beSSteven Rostedt	    foreach my $file (@files) {
1926a75fececSSteven Rostedt		my $fullpath = "$builddir/$file";
19276c5ee0beSSteven Rostedt		if ($file eq $err || $fullpath eq $err) {
19282b7d9b21SSteven Rostedt		    fail "$file built with warnings" and return 0;
19296c5ee0beSSteven Rostedt		}
19306c5ee0beSSteven Rostedt	    }
19316c5ee0beSSteven Rostedt	}
19326c5ee0beSSteven Rostedt    }
19336c5ee0beSSteven Rostedt    close(IN);
19342b7d9b21SSteven Rostedt
19352b7d9b21SSteven Rostedt    return 1;
19366c5ee0beSSteven Rostedt}
19376c5ee0beSSteven Rostedt
1938fcb3f16aSSteven Rostedtsub apply_min_config {
1939fcb3f16aSSteven Rostedt    my $outconfig = "$output_config.new";
1940612b9e9bSSteven Rostedt
1941fcb3f16aSSteven Rostedt    # Read the config file and remove anything that
1942fcb3f16aSSteven Rostedt    # is in the force_config hash (from minconfig and others)
1943fcb3f16aSSteven Rostedt    # then add the force config back.
1944fcb3f16aSSteven Rostedt
1945fcb3f16aSSteven Rostedt    doprint "Applying minimum configurations into $output_config.new\n";
1946fcb3f16aSSteven Rostedt
1947fcb3f16aSSteven Rostedt    open (OUT, ">$outconfig") or
1948fcb3f16aSSteven Rostedt	dodie "Can't create $outconfig";
1949fcb3f16aSSteven Rostedt
1950fcb3f16aSSteven Rostedt    if (-f $output_config) {
1951fcb3f16aSSteven Rostedt	open (IN, $output_config) or
1952fcb3f16aSSteven Rostedt	    dodie "Failed to open $output_config";
1953fcb3f16aSSteven Rostedt	while (<IN>) {
1954fcb3f16aSSteven Rostedt	    if (/^(# )?(CONFIG_[^\s=]*)/) {
1955fcb3f16aSSteven Rostedt		next if (defined($force_config{$2}));
1956fcb3f16aSSteven Rostedt	    }
1957fcb3f16aSSteven Rostedt	    print OUT;
1958fcb3f16aSSteven Rostedt	}
1959fcb3f16aSSteven Rostedt	close IN;
1960fcb3f16aSSteven Rostedt    }
1961fcb3f16aSSteven Rostedt    foreach my $config (keys %force_config) {
1962fcb3f16aSSteven Rostedt	print OUT "$force_config{$config}\n";
1963fcb3f16aSSteven Rostedt    }
1964fcb3f16aSSteven Rostedt    close OUT;
1965fcb3f16aSSteven Rostedt
1966fcb3f16aSSteven Rostedt    run_command "mv $outconfig $output_config";
1967fcb3f16aSSteven Rostedt}
1968fcb3f16aSSteven Rostedt
1969fcb3f16aSSteven Rostedtsub make_oldconfig {
1970fcb3f16aSSteven Rostedt
19714c4ab120SSteven Rostedt    my @force_list = keys %force_config;
19724c4ab120SSteven Rostedt
19734c4ab120SSteven Rostedt    if ($#force_list >= 0) {
1974fcb3f16aSSteven Rostedt	apply_min_config;
19754c4ab120SSteven Rostedt    }
1976fcb3f16aSSteven Rostedt
1977fb16d891SAdam Lee    if (!run_command "$make olddefconfig") {
1978fb16d891SAdam Lee	# Perhaps olddefconfig doesn't exist in this version of the kernel
197918925170SSteven Rostedt	# try oldnoconfig
198018925170SSteven Rostedt	doprint "olddefconfig failed, trying make oldnoconfig\n";
198118925170SSteven Rostedt	if (!run_command "$make oldnoconfig") {
198218925170SSteven Rostedt	    doprint "oldnoconfig failed, trying yes '' | make oldconfig\n";
1983612b9e9bSSteven Rostedt	    # try a yes '' | oldconfig
1984fcb3f16aSSteven Rostedt	    run_command "yes '' | $make oldconfig" or
1985612b9e9bSSteven Rostedt		dodie "failed make config oldconfig";
1986612b9e9bSSteven Rostedt	}
1987612b9e9bSSteven Rostedt    }
198818925170SSteven Rostedt}
1989612b9e9bSSteven Rostedt
1990fcb3f16aSSteven Rostedt# read a config file and use this to force new configs.
1991fcb3f16aSSteven Rostedtsub load_force_config {
1992fcb3f16aSSteven Rostedt    my ($config) = @_;
1993fcb3f16aSSteven Rostedt
1994cf79fab6SSteven Rostedt    doprint "Loading force configs from $config\n";
1995fcb3f16aSSteven Rostedt    open(IN, $config) or
1996fcb3f16aSSteven Rostedt	dodie "failed to read $config";
1997fcb3f16aSSteven Rostedt    while (<IN>) {
1998fcb3f16aSSteven Rostedt	chomp;
1999fcb3f16aSSteven Rostedt	if (/^(CONFIG[^\s=]*)(\s*=.*)/) {
2000fcb3f16aSSteven Rostedt	    $force_config{$1} = $_;
2001fcb3f16aSSteven Rostedt	} elsif (/^# (CONFIG_\S*) is not set/) {
2002fcb3f16aSSteven Rostedt	    $force_config{$1} = $_;
2003fcb3f16aSSteven Rostedt	}
2004fcb3f16aSSteven Rostedt    }
2005fcb3f16aSSteven Rostedt    close IN;
2006fcb3f16aSSteven Rostedt}
2007fcb3f16aSSteven Rostedt
20082545eb61SSteven Rostedtsub build {
20092545eb61SSteven Rostedt    my ($type) = @_;
20102545eb61SSteven Rostedt
20117faafbd6SSteven Rostedt    unlink $buildlog;
20127faafbd6SSteven Rostedt
20134ab1cce5SSteven Rostedt    # Failed builds should not reboot the target
20144ab1cce5SSteven Rostedt    my $save_no_reboot = $no_reboot;
20154ab1cce5SSteven Rostedt    $no_reboot = 1;
20164ab1cce5SSteven Rostedt
2017683a3e64SSteven Rostedt    # Calculate a new version from here.
2018683a3e64SSteven Rostedt    $have_version = 0;
2019683a3e64SSteven Rostedt
20200bd6c1a3SSteven Rostedt    if (defined($pre_build)) {
20210bd6c1a3SSteven Rostedt	my $ret = run_command $pre_build;
20220bd6c1a3SSteven Rostedt	if (!$ret && defined($pre_build_die) &&
20230bd6c1a3SSteven Rostedt	    $pre_build_die) {
20240bd6c1a3SSteven Rostedt	    dodie "failed to pre_build\n";
20250bd6c1a3SSteven Rostedt	}
20260bd6c1a3SSteven Rostedt    }
20270bd6c1a3SSteven Rostedt
202875c3fda7SSteven Rostedt    if ($type =~ /^useconfig:(.*)/) {
202951ad1dd1SSteven Rostedt	run_command "cp $1 $output_config" or
203075c3fda7SSteven Rostedt	    dodie "could not copy $1 to .config";
20315f9b6cedSSteven Rostedt
203275c3fda7SSteven Rostedt	$type = "oldconfig";
203375c3fda7SSteven Rostedt    }
203475c3fda7SSteven Rostedt
20355c42fc5bSSteven Rostedt    # old config can ask questions
20365c42fc5bSSteven Rostedt    if ($type eq "oldconfig") {
2037fb16d891SAdam Lee	$type = "olddefconfig";
203875c3fda7SSteven Rostedt
203975c3fda7SSteven Rostedt	# allow for empty configs
204051ad1dd1SSteven Rostedt	run_command "touch $output_config";
204175c3fda7SSteven Rostedt
204213488231SAndrew Jones	if (!$noclean) {
204351ad1dd1SSteven Rostedt	    run_command "mv $output_config $outputdir/config_temp" or
20445c42fc5bSSteven Rostedt		dodie "moving .config";
20455c42fc5bSSteven Rostedt
204613488231SAndrew Jones	    run_command "$make mrproper" or dodie "make mrproper";
20475c42fc5bSSteven Rostedt
204851ad1dd1SSteven Rostedt	    run_command "mv $outputdir/config_temp $output_config" or
20495c42fc5bSSteven Rostedt		dodie "moving config_temp";
205013488231SAndrew Jones	}
20515c42fc5bSSteven Rostedt
20525c42fc5bSSteven Rostedt    } elsif (!$noclean) {
205351ad1dd1SSteven Rostedt	unlink "$output_config";
20545f9b6cedSSteven Rostedt	run_command "$make mrproper" or
20555c42fc5bSSteven Rostedt	    dodie "make mrproper";
20565c42fc5bSSteven Rostedt    }
20572545eb61SSteven Rostedt
20582545eb61SSteven Rostedt    # add something to distinguish this build
2059a75fececSSteven Rostedt    open(OUT, "> $outputdir/localversion") or dodie("Can't make localversion file");
2060a75fececSSteven Rostedt    print OUT "$localversion\n";
20612545eb61SSteven Rostedt    close(OUT);
20622545eb61SSteven Rostedt
20635f9b6cedSSteven Rostedt    if (defined($minconfig)) {
2064fcb3f16aSSteven Rostedt	load_force_config($minconfig);
20652545eb61SSteven Rostedt    }
20662545eb61SSteven Rostedt
2067fb16d891SAdam Lee    if ($type ne "olddefconfig") {
2068fcb3f16aSSteven Rostedt	run_command "$make $type" or
20695c42fc5bSSteven Rostedt	    dodie "failed make config";
2070612b9e9bSSteven Rostedt    }
2071fcb3f16aSSteven Rostedt    # Run old config regardless, to enforce min configurations
2072fcb3f16aSSteven Rostedt    make_oldconfig;
20732545eb61SSteven Rostedt
2074a75fececSSteven Rostedt    $redirect = "$buildlog";
20750bd6c1a3SSteven Rostedt    my $build_ret = run_command "$make $build_options";
20766c5ee0beSSteven Rostedt    undef $redirect;
20770bd6c1a3SSteven Rostedt
20780bd6c1a3SSteven Rostedt    if (defined($post_build)) {
2079683a3e64SSteven Rostedt	# Because a post build may change the kernel version
2080683a3e64SSteven Rostedt	# do it now.
2081683a3e64SSteven Rostedt	get_version;
20820bd6c1a3SSteven Rostedt	my $ret = run_command $post_build;
20830bd6c1a3SSteven Rostedt	if (!$ret && defined($post_build_die) &&
20840bd6c1a3SSteven Rostedt	    $post_build_die) {
20850bd6c1a3SSteven Rostedt	    dodie "failed to post_build\n";
20860bd6c1a3SSteven Rostedt	}
20870bd6c1a3SSteven Rostedt    }
20880bd6c1a3SSteven Rostedt
20890bd6c1a3SSteven Rostedt    if (!$build_ret) {
20905f9b6cedSSteven Rostedt	# bisect may need this to pass
20914ab1cce5SSteven Rostedt	if ($in_bisect) {
20924ab1cce5SSteven Rostedt	    $no_reboot = $save_no_reboot;
20934ab1cce5SSteven Rostedt	    return 0;
20944ab1cce5SSteven Rostedt	}
20952b7d9b21SSteven Rostedt	fail "failed build" and return 0;
20962545eb61SSteven Rostedt    }
20975f9b6cedSSteven Rostedt
20984ab1cce5SSteven Rostedt    $no_reboot = $save_no_reboot;
20994ab1cce5SSteven Rostedt
21002b7d9b21SSteven Rostedt    return 1;
21012545eb61SSteven Rostedt}
21022545eb61SSteven Rostedt
210375c3fda7SSteven Rostedtsub halt {
2104e48c5293SSteven Rostedt    if (!run_ssh "halt" or defined($power_off)) {
2105576f627cSSteven Rostedt	if (defined($poweroff_after_halt)) {
2106576f627cSSteven Rostedt	    sleep $poweroff_after_halt;
2107576f627cSSteven Rostedt	    run_command "$power_off";
2108576f627cSSteven Rostedt	}
2109576f627cSSteven Rostedt    } else {
211075c3fda7SSteven Rostedt	# nope? the zap it!
2111a75fececSSteven Rostedt	run_command "$power_off";
211275c3fda7SSteven Rostedt    }
211375c3fda7SSteven Rostedt}
211475c3fda7SSteven Rostedt
21155f9b6cedSSteven Rostedtsub success {
21165f9b6cedSSteven Rostedt    my ($i) = @_;
21175f9b6cedSSteven Rostedt
2118921ed4c7SSteven Rostedt    if (defined($post_test)) {
2119921ed4c7SSteven Rostedt	run_command $post_test;
2120921ed4c7SSteven Rostedt    }
2121921ed4c7SSteven Rostedt
2122e48c5293SSteven Rostedt    $successes++;
2123e48c5293SSteven Rostedt
21249064af52SSteven Rostedt    my $name = "";
21259064af52SSteven Rostedt
21269064af52SSteven Rostedt    if (defined($test_name)) {
21279064af52SSteven Rostedt	$name = " ($test_name)";
21289064af52SSteven Rostedt    }
21299064af52SSteven Rostedt
21305f9b6cedSSteven Rostedt    doprint "\n\n*******************************************\n";
21315f9b6cedSSteven Rostedt    doprint     "*******************************************\n";
21329064af52SSteven Rostedt    doprint     "KTEST RESULT: TEST $i$name SUCCESS!!!!         **\n";
21335f9b6cedSSteven Rostedt    doprint     "*******************************************\n";
21345f9b6cedSSteven Rostedt    doprint     "*******************************************\n";
21355f9b6cedSSteven Rostedt
2136de5b6e3bSRabin Vincent    if (defined($store_successes)) {
2137de5b6e3bSRabin Vincent        save_logs "success", $store_successes;
2138de5b6e3bSRabin Vincent    }
2139de5b6e3bSRabin Vincent
2140576f627cSSteven Rostedt    if ($i != $opt{"NUM_TESTS"} && !do_not_reboot) {
2141a75fececSSteven Rostedt	doprint "Reboot and wait $sleep_time seconds\n";
2142bc7c5803SSteven Rostedt	reboot_to_good $sleep_time;
21435f9b6cedSSteven Rostedt    }
21445f9b6cedSSteven Rostedt}
21455f9b6cedSSteven Rostedt
2146c960bb9fSSteven Rostedtsub answer_bisect {
2147c960bb9fSSteven Rostedt    for (;;) {
2148c960bb9fSSteven Rostedt	doprint "Pass or fail? [p/f]";
2149c960bb9fSSteven Rostedt	my $ans = <STDIN>;
2150c960bb9fSSteven Rostedt	chomp $ans;
2151c960bb9fSSteven Rostedt	if ($ans eq "p" || $ans eq "P") {
2152c960bb9fSSteven Rostedt	    return 1;
2153c960bb9fSSteven Rostedt	} elsif ($ans eq "f" || $ans eq "F") {
2154c960bb9fSSteven Rostedt	    return 0;
2155c960bb9fSSteven Rostedt	} else {
2156c960bb9fSSteven Rostedt	    print "Please answer 'P' or 'F'\n";
2157c960bb9fSSteven Rostedt	}
2158c960bb9fSSteven Rostedt    }
2159c960bb9fSSteven Rostedt}
2160c960bb9fSSteven Rostedt
21615a391fbfSSteven Rostedtsub child_run_test {
21627faafbd6SSteven Rostedt    my $failed = 0;
21635a391fbfSSteven Rostedt
21647faafbd6SSteven Rostedt    # child should have no power
2165a75fececSSteven Rostedt    $reboot_on_error = 0;
2166a75fececSSteven Rostedt    $poweroff_on_error = 0;
2167a75fececSSteven Rostedt    $die_on_failure = 1;
21687faafbd6SSteven Rostedt
2169a9dd5d63SRabin Vincent    $redirect = "$testlog";
21707faafbd6SSteven Rostedt    run_command $run_test or $failed = 1;
2171a9dd5d63SRabin Vincent    undef $redirect;
2172a9dd5d63SRabin Vincent
21735a391fbfSSteven Rostedt    exit $failed;
21745a391fbfSSteven Rostedt}
21755a391fbfSSteven Rostedt
21765a391fbfSSteven Rostedtmy $child_done;
21775a391fbfSSteven Rostedt
21785a391fbfSSteven Rostedtsub child_finished {
21795a391fbfSSteven Rostedt    $child_done = 1;
21805a391fbfSSteven Rostedt}
21815a391fbfSSteven Rostedt
21825a391fbfSSteven Rostedtsub do_run_test {
21835a391fbfSSteven Rostedt    my $child_pid;
21845a391fbfSSteven Rostedt    my $child_exit;
21855a391fbfSSteven Rostedt    my $line;
21865a391fbfSSteven Rostedt    my $full_line;
21875a391fbfSSteven Rostedt    my $bug = 0;
21889b1d367dSSteven Rostedt    my $bug_ignored = 0;
21895a391fbfSSteven Rostedt
21907faafbd6SSteven Rostedt    wait_for_monitor 1;
21915a391fbfSSteven Rostedt
21927faafbd6SSteven Rostedt    doprint "run test $run_test\n";
21935a391fbfSSteven Rostedt
21945a391fbfSSteven Rostedt    $child_done = 0;
21955a391fbfSSteven Rostedt
21965a391fbfSSteven Rostedt    $SIG{CHLD} = qw(child_finished);
21975a391fbfSSteven Rostedt
21985a391fbfSSteven Rostedt    $child_pid = fork;
21995a391fbfSSteven Rostedt
22005a391fbfSSteven Rostedt    child_run_test if (!$child_pid);
22015a391fbfSSteven Rostedt
22025a391fbfSSteven Rostedt    $full_line = "";
22035a391fbfSSteven Rostedt
22045a391fbfSSteven Rostedt    do {
22057faafbd6SSteven Rostedt	$line = wait_for_input($monitor_fp, 1);
22065a391fbfSSteven Rostedt	if (defined($line)) {
22075a391fbfSSteven Rostedt
22085a391fbfSSteven Rostedt	    # we are not guaranteed to get a full line
22095a391fbfSSteven Rostedt	    $full_line .= $line;
22108ea0e063SSteven Rostedt	    doprint $line;
22115a391fbfSSteven Rostedt
22125a391fbfSSteven Rostedt	    if ($full_line =~ /call trace:/i) {
22139b1d367dSSteven Rostedt		if ($ignore_errors) {
22149b1d367dSSteven Rostedt		    $bug_ignored = 1;
22159b1d367dSSteven Rostedt		} else {
22165a391fbfSSteven Rostedt		    $bug = 1;
22175a391fbfSSteven Rostedt		}
22189b1d367dSSteven Rostedt	    }
22195a391fbfSSteven Rostedt
22205a391fbfSSteven Rostedt	    if ($full_line =~ /Kernel panic -/) {
22215a391fbfSSteven Rostedt		$bug = 1;
22225a391fbfSSteven Rostedt	    }
22235a391fbfSSteven Rostedt
22245a391fbfSSteven Rostedt	    if ($line =~ /\n/) {
22255a391fbfSSteven Rostedt		$full_line = "";
22265a391fbfSSteven Rostedt	    }
22275a391fbfSSteven Rostedt	}
22285a391fbfSSteven Rostedt    } while (!$child_done && !$bug);
22295a391fbfSSteven Rostedt
22309b1d367dSSteven Rostedt    if (!$bug && $bug_ignored) {
22319b1d367dSSteven Rostedt	doprint "WARNING: Call Trace detected but ignored due to IGNORE_ERRORS=1\n";
22329b1d367dSSteven Rostedt    }
22339b1d367dSSteven Rostedt
22345a391fbfSSteven Rostedt    if ($bug) {
22358ea0e063SSteven Rostedt	my $failure_start = time;
22368ea0e063SSteven Rostedt	my $now;
22378ea0e063SSteven Rostedt	do {
22388ea0e063SSteven Rostedt	    $line = wait_for_input($monitor_fp, 1);
22398ea0e063SSteven Rostedt	    if (defined($line)) {
22408ea0e063SSteven Rostedt		doprint $line;
22418ea0e063SSteven Rostedt	    }
22428ea0e063SSteven Rostedt	    $now = time;
22438ea0e063SSteven Rostedt	    if ($now - $failure_start >= $stop_after_failure) {
22448ea0e063SSteven Rostedt		last;
22458ea0e063SSteven Rostedt	    }
22468ea0e063SSteven Rostedt	} while (defined($line));
22478ea0e063SSteven Rostedt
22485a391fbfSSteven Rostedt	doprint "Detected kernel crash!\n";
22495a391fbfSSteven Rostedt	# kill the child with extreme prejudice
22505a391fbfSSteven Rostedt	kill 9, $child_pid;
22515a391fbfSSteven Rostedt    }
22525a391fbfSSteven Rostedt
22535a391fbfSSteven Rostedt    waitpid $child_pid, 0;
22545a391fbfSSteven Rostedt    $child_exit = $?;
22555a391fbfSSteven Rostedt
2256c5dacb88SSteven Rostedt    if (!$bug && $in_bisect) {
2257c5dacb88SSteven Rostedt	if (defined($bisect_ret_good)) {
2258c5dacb88SSteven Rostedt	    if ($child_exit == $bisect_ret_good) {
2259c5dacb88SSteven Rostedt		return 1;
2260c5dacb88SSteven Rostedt	    }
2261c5dacb88SSteven Rostedt	}
2262c5dacb88SSteven Rostedt	if (defined($bisect_ret_skip)) {
2263c5dacb88SSteven Rostedt	    if ($child_exit == $bisect_ret_skip) {
2264c5dacb88SSteven Rostedt		return -1;
2265c5dacb88SSteven Rostedt	    }
2266c5dacb88SSteven Rostedt	}
2267c5dacb88SSteven Rostedt	if (defined($bisect_ret_abort)) {
2268c5dacb88SSteven Rostedt	    if ($child_exit == $bisect_ret_abort) {
2269c5dacb88SSteven Rostedt		fail "test abort" and return -2;
2270c5dacb88SSteven Rostedt	    }
2271c5dacb88SSteven Rostedt	}
2272c5dacb88SSteven Rostedt	if (defined($bisect_ret_bad)) {
2273c5dacb88SSteven Rostedt	    if ($child_exit == $bisect_ret_skip) {
2274c5dacb88SSteven Rostedt		return 0;
2275c5dacb88SSteven Rostedt	    }
2276c5dacb88SSteven Rostedt	}
2277c5dacb88SSteven Rostedt	if (defined($bisect_ret_default)) {
2278c5dacb88SSteven Rostedt	    if ($bisect_ret_default eq "good") {
2279c5dacb88SSteven Rostedt		return 1;
2280c5dacb88SSteven Rostedt	    } elsif ($bisect_ret_default eq "bad") {
2281c5dacb88SSteven Rostedt		return 0;
2282c5dacb88SSteven Rostedt	    } elsif ($bisect_ret_default eq "skip") {
2283c5dacb88SSteven Rostedt		return -1;
2284c5dacb88SSteven Rostedt	    } elsif ($bisect_ret_default eq "abort") {
2285c5dacb88SSteven Rostedt		return -2;
2286c5dacb88SSteven Rostedt	    } else {
2287c5dacb88SSteven Rostedt		fail "unknown default action: $bisect_ret_default"
2288c5dacb88SSteven Rostedt		    and return -2;
2289c5dacb88SSteven Rostedt	    }
2290c5dacb88SSteven Rostedt	}
2291c5dacb88SSteven Rostedt    }
2292c5dacb88SSteven Rostedt
22935a391fbfSSteven Rostedt    if ($bug || $child_exit) {
22942b7d9b21SSteven Rostedt	return 0 if $in_bisect;
22952b7d9b21SSteven Rostedt	fail "test failed" and return 0;
22965a391fbfSSteven Rostedt    }
22972b7d9b21SSteven Rostedt    return 1;
22985a391fbfSSteven Rostedt}
22995a391fbfSSteven Rostedt
2300a75fececSSteven Rostedtsub run_git_bisect {
2301a75fececSSteven Rostedt    my ($command) = @_;
2302a75fececSSteven Rostedt
2303a75fececSSteven Rostedt    doprint "$command ... ";
2304a75fececSSteven Rostedt
2305a75fececSSteven Rostedt    my $output = `$command 2>&1`;
2306a75fececSSteven Rostedt    my $ret = $?;
2307a75fececSSteven Rostedt
2308a75fececSSteven Rostedt    logit $output;
2309a75fececSSteven Rostedt
2310a75fececSSteven Rostedt    if ($ret) {
2311a75fececSSteven Rostedt	doprint "FAILED\n";
2312a75fececSSteven Rostedt	dodie "Failed to git bisect";
2313a75fececSSteven Rostedt    }
2314a75fececSSteven Rostedt
2315a75fececSSteven Rostedt    doprint "SUCCESS\n";
2316a75fececSSteven Rostedt    if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\))\s+\[([[:xdigit:]]+)\]/) {
2317a75fececSSteven Rostedt	doprint "$1 [$2]\n";
2318a75fececSSteven Rostedt    } elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) {
2319b5f4aea6SSteven Rostedt	$bisect_bad_commit = $1;
2320a75fececSSteven Rostedt	doprint "Found bad commit... $1\n";
2321a75fececSSteven Rostedt	return 0;
2322a75fececSSteven Rostedt    } else {
2323a75fececSSteven Rostedt	# we already logged it, just print it now.
2324a75fececSSteven Rostedt	print $output;
2325a75fececSSteven Rostedt    }
2326a75fececSSteven Rostedt
2327a75fececSSteven Rostedt    return 1;
2328a75fececSSteven Rostedt}
2329a75fececSSteven Rostedt
2330c23dca7cSSteven Rostedtsub bisect_reboot {
2331c23dca7cSSteven Rostedt    doprint "Reboot and sleep $bisect_sleep_time seconds\n";
2332bc7c5803SSteven Rostedt    reboot_to_good $bisect_sleep_time;
2333c23dca7cSSteven Rostedt}
2334c23dca7cSSteven Rostedt
2335c23dca7cSSteven Rostedt# returns 1 on success, 0 on failure, -1 on skip
23360a05c769SSteven Rostedtsub run_bisect_test {
23370a05c769SSteven Rostedt    my ($type, $buildtype) = @_;
23385f9b6cedSSteven Rostedt
23392b7d9b21SSteven Rostedt    my $failed = 0;
23405f9b6cedSSteven Rostedt    my $result;
23415f9b6cedSSteven Rostedt    my $output;
23425f9b6cedSSteven Rostedt    my $ret;
23435f9b6cedSSteven Rostedt
23440a05c769SSteven Rostedt    $in_bisect = 1;
23450a05c769SSteven Rostedt
23460a05c769SSteven Rostedt    build $buildtype or $failed = 1;
23475f9b6cedSSteven Rostedt
23485f9b6cedSSteven Rostedt    if ($type ne "build") {
2349c23dca7cSSteven Rostedt	if ($failed && $bisect_skip) {
2350c23dca7cSSteven Rostedt	    $in_bisect = 0;
2351c23dca7cSSteven Rostedt	    return -1;
2352c23dca7cSSteven Rostedt	}
23537faafbd6SSteven Rostedt	dodie "Failed on build" if $failed;
23545f9b6cedSSteven Rostedt
23555f9b6cedSSteven Rostedt	# Now boot the box
2356ddf607e5SSteven Rostedt	start_monitor_and_boot or $failed = 1;
23575f9b6cedSSteven Rostedt
23585f9b6cedSSteven Rostedt	if ($type ne "boot") {
2359c23dca7cSSteven Rostedt	    if ($failed && $bisect_skip) {
2360c23dca7cSSteven Rostedt		end_monitor;
2361c23dca7cSSteven Rostedt		bisect_reboot;
2362c23dca7cSSteven Rostedt		$in_bisect = 0;
2363c23dca7cSSteven Rostedt		return -1;
2364c23dca7cSSteven Rostedt	    }
23657faafbd6SSteven Rostedt	    dodie "Failed on boot" if $failed;
23665a391fbfSSteven Rostedt
23672b7d9b21SSteven Rostedt	    do_run_test or $failed = 1;
23685f9b6cedSSteven Rostedt	}
23697faafbd6SSteven Rostedt	end_monitor;
23705f9b6cedSSteven Rostedt    }
23715f9b6cedSSteven Rostedt
23725f9b6cedSSteven Rostedt    if ($failed) {
23730a05c769SSteven Rostedt	$result = 0;
23745f9b6cedSSteven Rostedt    } else {
23750a05c769SSteven Rostedt	$result = 1;
23765f9b6cedSSteven Rostedt    }
23774025bc62SSteven Rostedt
23784025bc62SSteven Rostedt    # reboot the box to a kernel we can ssh to
23794025bc62SSteven Rostedt    if ($type ne "build") {
23804025bc62SSteven Rostedt	bisect_reboot;
23814025bc62SSteven Rostedt    }
23820a05c769SSteven Rostedt    $in_bisect = 0;
23830a05c769SSteven Rostedt
23840a05c769SSteven Rostedt    return $result;
23850a05c769SSteven Rostedt}
23860a05c769SSteven Rostedt
23870a05c769SSteven Rostedtsub run_bisect {
23880a05c769SSteven Rostedt    my ($type) = @_;
23890a05c769SSteven Rostedt    my $buildtype = "oldconfig";
23900a05c769SSteven Rostedt
23910a05c769SSteven Rostedt    # We should have a minconfig to use?
23920a05c769SSteven Rostedt    if (defined($minconfig)) {
23930a05c769SSteven Rostedt	$buildtype = "useconfig:$minconfig";
23940a05c769SSteven Rostedt    }
23950a05c769SSteven Rostedt
23960a05c769SSteven Rostedt    my $ret = run_bisect_test $type, $buildtype;
23970a05c769SSteven Rostedt
2398c960bb9fSSteven Rostedt    if ($bisect_manual) {
2399c960bb9fSSteven Rostedt	$ret = answer_bisect;
2400c960bb9fSSteven Rostedt    }
24015f9b6cedSSteven Rostedt
2402d6ce2a0bSSteven Rostedt    # Are we looking for where it worked, not failed?
24035158ba3eSRuss Dill    if ($reverse_bisect && $ret >= 0) {
24040a05c769SSteven Rostedt	$ret = !$ret;
2405d6ce2a0bSSteven Rostedt    }
2406d6ce2a0bSSteven Rostedt
2407c23dca7cSSteven Rostedt    if ($ret > 0) {
24080a05c769SSteven Rostedt	return "good";
2409c23dca7cSSteven Rostedt    } elsif ($ret == 0) {
24100a05c769SSteven Rostedt	return  "bad";
2411c23dca7cSSteven Rostedt    } elsif ($bisect_skip) {
2412c23dca7cSSteven Rostedt	doprint "HIT A BAD COMMIT ... SKIPPING\n";
2413c23dca7cSSteven Rostedt	return "skip";
24140a05c769SSteven Rostedt    }
24155f9b6cedSSteven Rostedt}
24165f9b6cedSSteven Rostedt
2417dad98754SSteven Rostedtsub update_bisect_replay {
2418dad98754SSteven Rostedt    my $tmp_log = "$tmpdir/ktest_bisect_log";
2419dad98754SSteven Rostedt    run_command "git bisect log > $tmp_log" or
2420dad98754SSteven Rostedt	die "can't create bisect log";
2421dad98754SSteven Rostedt    return $tmp_log;
2422dad98754SSteven Rostedt}
2423dad98754SSteven Rostedt
24245f9b6cedSSteven Rostedtsub bisect {
24255f9b6cedSSteven Rostedt    my ($i) = @_;
24265f9b6cedSSteven Rostedt
24275f9b6cedSSteven Rostedt    my $result;
24285f9b6cedSSteven Rostedt
2429b5f4aea6SSteven Rostedt    die "BISECT_GOOD[$i] not defined\n"	if (!defined($bisect_good));
2430b5f4aea6SSteven Rostedt    die "BISECT_BAD[$i] not defined\n"	if (!defined($bisect_bad));
2431b5f4aea6SSteven Rostedt    die "BISECT_TYPE[$i] not defined\n"	if (!defined($bisect_type));
24325f9b6cedSSteven Rostedt
2433b5f4aea6SSteven Rostedt    my $good = $bisect_good;
2434b5f4aea6SSteven Rostedt    my $bad = $bisect_bad;
2435b5f4aea6SSteven Rostedt    my $type = $bisect_type;
2436b5f4aea6SSteven Rostedt    my $start = $bisect_start;
2437b5f4aea6SSteven Rostedt    my $replay = $bisect_replay;
2438b5f4aea6SSteven Rostedt    my $start_files = $bisect_files;
24393410f6fdSSteven Rostedt
24403410f6fdSSteven Rostedt    if (defined($start_files)) {
24413410f6fdSSteven Rostedt	$start_files = " -- " . $start_files;
24423410f6fdSSteven Rostedt    } else {
24433410f6fdSSteven Rostedt	$start_files = "";
24443410f6fdSSteven Rostedt    }
24455f9b6cedSSteven Rostedt
2446a57419b3SSteven Rostedt    # convert to true sha1's
2447a57419b3SSteven Rostedt    $good = get_sha1($good);
2448a57419b3SSteven Rostedt    $bad = get_sha1($bad);
2449a57419b3SSteven Rostedt
2450b5f4aea6SSteven Rostedt    if (defined($bisect_reverse) && $bisect_reverse == 1) {
2451d6ce2a0bSSteven Rostedt	doprint "Performing a reverse bisect (bad is good, good is bad!)\n";
2452d6ce2a0bSSteven Rostedt	$reverse_bisect = 1;
2453d6ce2a0bSSteven Rostedt    } else {
2454d6ce2a0bSSteven Rostedt	$reverse_bisect = 0;
2455d6ce2a0bSSteven Rostedt    }
2456d6ce2a0bSSteven Rostedt
24575a391fbfSSteven Rostedt    # Can't have a test without having a test to run
24585a391fbfSSteven Rostedt    if ($type eq "test" && !defined($run_test)) {
24595a391fbfSSteven Rostedt	$type = "boot";
24605a391fbfSSteven Rostedt    }
24615a391fbfSSteven Rostedt
2462dad98754SSteven Rostedt    # Check if a bisect was running
2463dad98754SSteven Rostedt    my $bisect_start_file = "$builddir/.git/BISECT_START";
2464dad98754SSteven Rostedt
2465b5f4aea6SSteven Rostedt    my $check = $bisect_check;
2466dad98754SSteven Rostedt    my $do_check = defined($check) && $check ne "0";
2467dad98754SSteven Rostedt
2468dad98754SSteven Rostedt    if ( -f $bisect_start_file ) {
2469dad98754SSteven Rostedt	print "Bisect in progress found\n";
2470dad98754SSteven Rostedt	if ($do_check) {
2471dad98754SSteven Rostedt	    print " If you say yes, then no checks of good or bad will be done\n";
2472dad98754SSteven Rostedt	}
2473dad98754SSteven Rostedt	if (defined($replay)) {
2474dad98754SSteven Rostedt	    print "** BISECT_REPLAY is defined in config file **";
2475dad98754SSteven Rostedt	    print " Ignore config option and perform new git bisect log?\n";
2476dad98754SSteven Rostedt	    if (read_ync " (yes, no, or cancel) ") {
2477dad98754SSteven Rostedt		$replay = update_bisect_replay;
2478dad98754SSteven Rostedt		$do_check = 0;
2479dad98754SSteven Rostedt	    }
2480dad98754SSteven Rostedt	} elsif (read_yn "read git log and continue?") {
2481dad98754SSteven Rostedt	    $replay = update_bisect_replay;
2482dad98754SSteven Rostedt	    $do_check = 0;
2483dad98754SSteven Rostedt	}
2484dad98754SSteven Rostedt    }
2485dad98754SSteven Rostedt
2486dad98754SSteven Rostedt    if ($do_check) {
2487a75fececSSteven Rostedt
2488a75fececSSteven Rostedt	# get current HEAD
2489a57419b3SSteven Rostedt	my $head = get_sha1("HEAD");
2490a75fececSSteven Rostedt
2491a75fececSSteven Rostedt	if ($check ne "good") {
2492a75fececSSteven Rostedt	    doprint "TESTING BISECT BAD [$bad]\n";
2493a75fececSSteven Rostedt	    run_command "git checkout $bad" or
2494a75fececSSteven Rostedt		die "Failed to checkout $bad";
2495a75fececSSteven Rostedt
2496a75fececSSteven Rostedt	    $result = run_bisect $type;
2497a75fececSSteven Rostedt
2498a75fececSSteven Rostedt	    if ($result ne "bad") {
2499a75fececSSteven Rostedt		fail "Tested BISECT_BAD [$bad] and it succeeded" and return 0;
2500a75fececSSteven Rostedt	    }
2501a75fececSSteven Rostedt	}
2502a75fececSSteven Rostedt
2503a75fececSSteven Rostedt	if ($check ne "bad") {
2504a75fececSSteven Rostedt	    doprint "TESTING BISECT GOOD [$good]\n";
2505a75fececSSteven Rostedt	    run_command "git checkout $good" or
2506a75fececSSteven Rostedt		die "Failed to checkout $good";
2507a75fececSSteven Rostedt
2508a75fececSSteven Rostedt	    $result = run_bisect $type;
2509a75fececSSteven Rostedt
2510a75fececSSteven Rostedt	    if ($result ne "good") {
2511a75fececSSteven Rostedt		fail "Tested BISECT_GOOD [$good] and it failed" and return 0;
2512a75fececSSteven Rostedt	    }
2513a75fececSSteven Rostedt	}
2514a75fececSSteven Rostedt
2515a75fececSSteven Rostedt	# checkout where we started
2516a75fececSSteven Rostedt	run_command "git checkout $head" or
2517a75fececSSteven Rostedt	    die "Failed to checkout $head";
2518a75fececSSteven Rostedt    }
2519a75fececSSteven Rostedt
25203410f6fdSSteven Rostedt    run_command "git bisect start$start_files" or
2521a75fececSSteven Rostedt	dodie "could not start bisect";
2522a75fececSSteven Rostedt
2523a75fececSSteven Rostedt    run_command "git bisect good $good" or
2524a75fececSSteven Rostedt	dodie "could not set bisect good to $good";
2525a75fececSSteven Rostedt
2526a75fececSSteven Rostedt    run_git_bisect "git bisect bad $bad" or
2527a75fececSSteven Rostedt	dodie "could not set bisect bad to $bad";
2528a75fececSSteven Rostedt
2529a75fececSSteven Rostedt    if (defined($replay)) {
2530a75fececSSteven Rostedt	run_command "git bisect replay $replay" or
2531a75fececSSteven Rostedt	    dodie "failed to run replay";
2532a75fececSSteven Rostedt    }
2533a75fececSSteven Rostedt
2534a75fececSSteven Rostedt    if (defined($start)) {
2535a75fececSSteven Rostedt	run_command "git checkout $start" or
2536a75fececSSteven Rostedt	    dodie "failed to checkout $start";
2537a75fececSSteven Rostedt    }
2538a75fececSSteven Rostedt
2539a75fececSSteven Rostedt    my $test;
25405f9b6cedSSteven Rostedt    do {
25415f9b6cedSSteven Rostedt	$result = run_bisect $type;
2542a75fececSSteven Rostedt	$test = run_git_bisect "git bisect $result";
2543a75fececSSteven Rostedt    } while ($test);
25445f9b6cedSSteven Rostedt
25455f9b6cedSSteven Rostedt    run_command "git bisect log" or
25465f9b6cedSSteven Rostedt	dodie "could not capture git bisect log";
25475f9b6cedSSteven Rostedt
25485f9b6cedSSteven Rostedt    run_command "git bisect reset" or
25495f9b6cedSSteven Rostedt	dodie "could not reset git bisect";
25505f9b6cedSSteven Rostedt
2551b5f4aea6SSteven Rostedt    doprint "Bad commit was [$bisect_bad_commit]\n";
25525f9b6cedSSteven Rostedt
25530a05c769SSteven Rostedt    success $i;
25540a05c769SSteven Rostedt}
25550a05c769SSteven Rostedt
2556cf79fab6SSteven Rostedt# config_ignore holds the configs that were set (or unset) for
2557cf79fab6SSteven Rostedt# a good config and we will ignore these configs for the rest
2558cf79fab6SSteven Rostedt# of a config bisect. These configs stay as they were.
25590a05c769SSteven Rostedtmy %config_ignore;
2560cf79fab6SSteven Rostedt
2561cf79fab6SSteven Rostedt# config_set holds what all configs were set as.
25620a05c769SSteven Rostedtmy %config_set;
25630a05c769SSteven Rostedt
2564cf79fab6SSteven Rostedt# config_off holds the set of configs that the bad config had disabled.
2565cf79fab6SSteven Rostedt# We need to record them and set them in the .config when running
2566fb16d891SAdam Lee# olddefconfig, because olddefconfig keeps the defaults.
2567cf79fab6SSteven Rostedtmy %config_off;
2568cf79fab6SSteven Rostedt
2569cf79fab6SSteven Rostedt# config_off_tmp holds a set of configs to turn off for now
2570cf79fab6SSteven Rostedtmy @config_off_tmp;
2571cf79fab6SSteven Rostedt
2572cf79fab6SSteven Rostedt# config_list is the set of configs that are being tested
25730a05c769SSteven Rostedtmy %config_list;
25740a05c769SSteven Rostedtmy %null_config;
25750a05c769SSteven Rostedt
25760a05c769SSteven Rostedtmy %dependency;
25770a05c769SSteven Rostedt
25784c4ab120SSteven Rostedtsub assign_configs {
25794c4ab120SSteven Rostedt    my ($hash, $config) = @_;
25800a05c769SSteven Rostedt
25810a05c769SSteven Rostedt    open (IN, $config)
25820a05c769SSteven Rostedt	or dodie "Failed to read $config";
25830a05c769SSteven Rostedt
25840a05c769SSteven Rostedt    while (<IN>) {
25859bf71749SSteven Rostedt	if (/^((CONFIG\S*)=.*)/) {
25864c4ab120SSteven Rostedt	    ${$hash}{$2} = $1;
25870a05c769SSteven Rostedt	}
25880a05c769SSteven Rostedt    }
25890a05c769SSteven Rostedt
25900a05c769SSteven Rostedt    close(IN);
25910a05c769SSteven Rostedt}
25920a05c769SSteven Rostedt
25934c4ab120SSteven Rostedtsub process_config_ignore {
25944c4ab120SSteven Rostedt    my ($config) = @_;
25954c4ab120SSteven Rostedt
25964c4ab120SSteven Rostedt    assign_configs \%config_ignore, $config;
25974c4ab120SSteven Rostedt}
25984c4ab120SSteven Rostedt
25990a05c769SSteven Rostedtsub read_current_config {
26000a05c769SSteven Rostedt    my ($config_ref) = @_;
26010a05c769SSteven Rostedt
26020a05c769SSteven Rostedt    %{$config_ref} = ();
26030a05c769SSteven Rostedt    undef %{$config_ref};
26040a05c769SSteven Rostedt
26050a05c769SSteven Rostedt    my @key = keys %{$config_ref};
26060a05c769SSteven Rostedt    if ($#key >= 0) {
26070a05c769SSteven Rostedt	print "did not delete!\n";
26080a05c769SSteven Rostedt	exit;
26090a05c769SSteven Rostedt    }
26100a05c769SSteven Rostedt    open (IN, "$output_config");
26110a05c769SSteven Rostedt
26120a05c769SSteven Rostedt    while (<IN>) {
26130a05c769SSteven Rostedt	if (/^(CONFIG\S+)=(.*)/) {
26140a05c769SSteven Rostedt	    ${$config_ref}{$1} = $2;
26150a05c769SSteven Rostedt	}
26160a05c769SSteven Rostedt    }
26170a05c769SSteven Rostedt    close(IN);
26180a05c769SSteven Rostedt}
26190a05c769SSteven Rostedt
26200a05c769SSteven Rostedtsub get_dependencies {
26210a05c769SSteven Rostedt    my ($config) = @_;
26220a05c769SSteven Rostedt
26230a05c769SSteven Rostedt    my $arr = $dependency{$config};
26240a05c769SSteven Rostedt    if (!defined($arr)) {
26250a05c769SSteven Rostedt	return ();
26260a05c769SSteven Rostedt    }
26270a05c769SSteven Rostedt
26280a05c769SSteven Rostedt    my @deps = @{$arr};
26290a05c769SSteven Rostedt
26300a05c769SSteven Rostedt    foreach my $dep (@{$arr}) {
26310a05c769SSteven Rostedt	print "ADD DEP $dep\n";
26320a05c769SSteven Rostedt	@deps = (@deps, get_dependencies $dep);
26330a05c769SSteven Rostedt    }
26340a05c769SSteven Rostedt
26350a05c769SSteven Rostedt    return @deps;
26360a05c769SSteven Rostedt}
26370a05c769SSteven Rostedt
26380a05c769SSteven Rostedtsub create_config {
26390a05c769SSteven Rostedt    my @configs = @_;
26400a05c769SSteven Rostedt
26410a05c769SSteven Rostedt    open(OUT, ">$output_config") or dodie "Can not write to $output_config";
26420a05c769SSteven Rostedt
26430a05c769SSteven Rostedt    foreach my $config (@configs) {
26440a05c769SSteven Rostedt	print OUT "$config_set{$config}\n";
26450a05c769SSteven Rostedt	my @deps = get_dependencies $config;
26460a05c769SSteven Rostedt	foreach my $dep (@deps) {
26470a05c769SSteven Rostedt	    print OUT "$config_set{$dep}\n";
26480a05c769SSteven Rostedt	}
26490a05c769SSteven Rostedt    }
26500a05c769SSteven Rostedt
2651cf79fab6SSteven Rostedt    # turn off configs to keep off
2652cf79fab6SSteven Rostedt    foreach my $config (keys %config_off) {
2653cf79fab6SSteven Rostedt	print OUT "# $config is not set\n";
2654cf79fab6SSteven Rostedt    }
2655cf79fab6SSteven Rostedt
2656cf79fab6SSteven Rostedt    # turn off configs that should be off for now
2657cf79fab6SSteven Rostedt    foreach my $config (@config_off_tmp) {
2658cf79fab6SSteven Rostedt	print OUT "# $config is not set\n";
2659cf79fab6SSteven Rostedt    }
2660cf79fab6SSteven Rostedt
26610a05c769SSteven Rostedt    foreach my $config (keys %config_ignore) {
26620a05c769SSteven Rostedt	print OUT "$config_ignore{$config}\n";
26630a05c769SSteven Rostedt    }
26640a05c769SSteven Rostedt    close(OUT);
26650a05c769SSteven Rostedt
2666fcb3f16aSSteven Rostedt    make_oldconfig;
26670a05c769SSteven Rostedt}
26680a05c769SSteven Rostedt
26690a05c769SSteven Rostedtsub compare_configs {
26700a05c769SSteven Rostedt    my (%a, %b) = @_;
26710a05c769SSteven Rostedt
26720a05c769SSteven Rostedt    foreach my $item (keys %a) {
26730a05c769SSteven Rostedt	if (!defined($b{$item})) {
26740a05c769SSteven Rostedt	    print "diff $item\n";
26750a05c769SSteven Rostedt	    return 1;
26760a05c769SSteven Rostedt	}
26770a05c769SSteven Rostedt	delete $b{$item};
26780a05c769SSteven Rostedt    }
26790a05c769SSteven Rostedt
26800a05c769SSteven Rostedt    my @keys = keys %b;
26810a05c769SSteven Rostedt    if ($#keys) {
26820a05c769SSteven Rostedt	print "diff2 $keys[0]\n";
26830a05c769SSteven Rostedt    }
26840a05c769SSteven Rostedt    return -1 if ($#keys >= 0);
26850a05c769SSteven Rostedt
26860a05c769SSteven Rostedt    return 0;
26870a05c769SSteven Rostedt}
26880a05c769SSteven Rostedt
26890a05c769SSteven Rostedtsub run_config_bisect_test {
26900a05c769SSteven Rostedt    my ($type) = @_;
26910a05c769SSteven Rostedt
26920a05c769SSteven Rostedt    return run_bisect_test $type, "oldconfig";
26930a05c769SSteven Rostedt}
26940a05c769SSteven Rostedt
26950a05c769SSteven Rostedtsub process_passed {
26960a05c769SSteven Rostedt    my (%configs) = @_;
26970a05c769SSteven Rostedt
26980a05c769SSteven Rostedt    doprint "These configs had no failure: (Enabling them for further compiles)\n";
26990a05c769SSteven Rostedt    # Passed! All these configs are part of a good compile.
27000a05c769SSteven Rostedt    # Add them to the min options.
27010a05c769SSteven Rostedt    foreach my $config (keys %configs) {
27020a05c769SSteven Rostedt	if (defined($config_list{$config})) {
27030a05c769SSteven Rostedt	    doprint " removing $config\n";
27040a05c769SSteven Rostedt	    $config_ignore{$config} = $config_list{$config};
27050a05c769SSteven Rostedt	    delete $config_list{$config};
27060a05c769SSteven Rostedt	}
27070a05c769SSteven Rostedt    }
2708f1a27850SSteven Rostedt    doprint "config copied to $outputdir/config_good\n";
2709f1a27850SSteven Rostedt    run_command "cp -f $output_config $outputdir/config_good";
27100a05c769SSteven Rostedt}
27110a05c769SSteven Rostedt
27120a05c769SSteven Rostedtsub process_failed {
27130a05c769SSteven Rostedt    my ($config) = @_;
27140a05c769SSteven Rostedt
27150a05c769SSteven Rostedt    doprint "\n\n***************************************\n";
27160a05c769SSteven Rostedt    doprint "Found bad config: $config\n";
27170a05c769SSteven Rostedt    doprint "***************************************\n\n";
27180a05c769SSteven Rostedt}
27190a05c769SSteven Rostedt
27200a05c769SSteven Rostedtsub run_config_bisect {
27210a05c769SSteven Rostedt
27220a05c769SSteven Rostedt    my @start_list = keys %config_list;
27230a05c769SSteven Rostedt
27240a05c769SSteven Rostedt    if ($#start_list < 0) {
27250a05c769SSteven Rostedt	doprint "No more configs to test!!!\n";
27260a05c769SSteven Rostedt	return -1;
27270a05c769SSteven Rostedt    }
27280a05c769SSteven Rostedt
27290a05c769SSteven Rostedt    doprint "***** RUN TEST ***\n";
2730b5f4aea6SSteven Rostedt    my $type = $config_bisect_type;
27310a05c769SSteven Rostedt    my $ret;
27320a05c769SSteven Rostedt    my %current_config;
27330a05c769SSteven Rostedt
27340a05c769SSteven Rostedt    my $count = $#start_list + 1;
27350a05c769SSteven Rostedt    doprint "  $count configs to test\n";
27360a05c769SSteven Rostedt
27370a05c769SSteven Rostedt    my $half = int($#start_list / 2);
27380a05c769SSteven Rostedt
27390a05c769SSteven Rostedt    do {
27400a05c769SSteven Rostedt	my @tophalf = @start_list[0 .. $half];
27410a05c769SSteven Rostedt
2742cf79fab6SSteven Rostedt	# keep the bottom half off
2743cf79fab6SSteven Rostedt	if ($half < $#start_list) {
2744cf79fab6SSteven Rostedt	    @config_off_tmp = @start_list[$half + 1 .. $#start_list];
2745cf79fab6SSteven Rostedt	} else {
2746cf79fab6SSteven Rostedt	    @config_off_tmp = ();
2747cf79fab6SSteven Rostedt	}
2748cf79fab6SSteven Rostedt
27490a05c769SSteven Rostedt	create_config @tophalf;
27500a05c769SSteven Rostedt	read_current_config \%current_config;
27510a05c769SSteven Rostedt
27520a05c769SSteven Rostedt	$count = $#tophalf + 1;
27530a05c769SSteven Rostedt	doprint "Testing $count configs\n";
27540a05c769SSteven Rostedt	my $found = 0;
27550a05c769SSteven Rostedt	# make sure we test something
27560a05c769SSteven Rostedt	foreach my $config (@tophalf) {
27570a05c769SSteven Rostedt	    if (defined($current_config{$config})) {
27580a05c769SSteven Rostedt		logit " $config\n";
27590a05c769SSteven Rostedt		$found = 1;
27600a05c769SSteven Rostedt	    }
27610a05c769SSteven Rostedt	}
27620a05c769SSteven Rostedt	if (!$found) {
27630a05c769SSteven Rostedt	    # try the other half
27640a05c769SSteven Rostedt	    doprint "Top half produced no set configs, trying bottom half\n";
2765cf79fab6SSteven Rostedt
2766cf79fab6SSteven Rostedt	    # keep the top half off
2767cf79fab6SSteven Rostedt	    @config_off_tmp = @tophalf;
27684c8cc55bSSteven Rostedt	    @tophalf = @start_list[$half + 1 .. $#start_list];
2769cf79fab6SSteven Rostedt
27700a05c769SSteven Rostedt	    create_config @tophalf;
27710a05c769SSteven Rostedt	    read_current_config \%current_config;
27720a05c769SSteven Rostedt	    foreach my $config (@tophalf) {
27730a05c769SSteven Rostedt		if (defined($current_config{$config})) {
27740a05c769SSteven Rostedt		    logit " $config\n";
27750a05c769SSteven Rostedt		    $found = 1;
27760a05c769SSteven Rostedt		}
27770a05c769SSteven Rostedt	    }
27780a05c769SSteven Rostedt	    if (!$found) {
27790a05c769SSteven Rostedt		doprint "Failed: Can't make new config with current configs\n";
27800a05c769SSteven Rostedt		foreach my $config (@start_list) {
27810a05c769SSteven Rostedt		    doprint "  CONFIG: $config\n";
27820a05c769SSteven Rostedt		}
27830a05c769SSteven Rostedt		return -1;
27840a05c769SSteven Rostedt	    }
27850a05c769SSteven Rostedt	    $count = $#tophalf + 1;
27860a05c769SSteven Rostedt	    doprint "Testing $count configs\n";
27870a05c769SSteven Rostedt	}
27880a05c769SSteven Rostedt
27890a05c769SSteven Rostedt	$ret = run_config_bisect_test $type;
2790c960bb9fSSteven Rostedt	if ($bisect_manual) {
2791c960bb9fSSteven Rostedt	    $ret = answer_bisect;
2792c960bb9fSSteven Rostedt	}
27930a05c769SSteven Rostedt	if ($ret) {
27940a05c769SSteven Rostedt	    process_passed %current_config;
27950a05c769SSteven Rostedt	    return 0;
27960a05c769SSteven Rostedt	}
27970a05c769SSteven Rostedt
27980a05c769SSteven Rostedt	doprint "This config had a failure.\n";
27990a05c769SSteven Rostedt	doprint "Removing these configs that were not set in this config:\n";
2800f1a27850SSteven Rostedt	doprint "config copied to $outputdir/config_bad\n";
2801f1a27850SSteven Rostedt	run_command "cp -f $output_config $outputdir/config_bad";
28020a05c769SSteven Rostedt
28030a05c769SSteven Rostedt	# A config exists in this group that was bad.
28040a05c769SSteven Rostedt	foreach my $config (keys %config_list) {
28050a05c769SSteven Rostedt	    if (!defined($current_config{$config})) {
28060a05c769SSteven Rostedt		doprint " removing $config\n";
28070a05c769SSteven Rostedt		delete $config_list{$config};
28080a05c769SSteven Rostedt	    }
28090a05c769SSteven Rostedt	}
28100a05c769SSteven Rostedt
28110a05c769SSteven Rostedt	@start_list = @tophalf;
28120a05c769SSteven Rostedt
28130a05c769SSteven Rostedt	if ($#start_list == 0) {
28140a05c769SSteven Rostedt	    process_failed $start_list[0];
28150a05c769SSteven Rostedt	    return 1;
28160a05c769SSteven Rostedt	}
28170a05c769SSteven Rostedt
28180a05c769SSteven Rostedt	# remove half the configs we are looking at and see if
28190a05c769SSteven Rostedt	# they are good.
28200a05c769SSteven Rostedt	$half = int($#start_list / 2);
28214c8cc55bSSteven Rostedt    } while ($#start_list > 0);
28220a05c769SSteven Rostedt
2823c960bb9fSSteven Rostedt    # we found a single config, try it again unless we are running manually
2824c960bb9fSSteven Rostedt
2825c960bb9fSSteven Rostedt    if ($bisect_manual) {
2826c960bb9fSSteven Rostedt	process_failed $start_list[0];
2827c960bb9fSSteven Rostedt	return 1;
2828c960bb9fSSteven Rostedt    }
2829c960bb9fSSteven Rostedt
28300a05c769SSteven Rostedt    my @tophalf = @start_list[0 .. 0];
28310a05c769SSteven Rostedt
28320a05c769SSteven Rostedt    $ret = run_config_bisect_test $type;
28330a05c769SSteven Rostedt    if ($ret) {
28340a05c769SSteven Rostedt	process_passed %current_config;
28350a05c769SSteven Rostedt	return 0;
28360a05c769SSteven Rostedt    }
28370a05c769SSteven Rostedt
28380a05c769SSteven Rostedt    process_failed $start_list[0];
28390a05c769SSteven Rostedt    return 1;
28400a05c769SSteven Rostedt}
28410a05c769SSteven Rostedt
28420a05c769SSteven Rostedtsub config_bisect {
28430a05c769SSteven Rostedt    my ($i) = @_;
28440a05c769SSteven Rostedt
2845b5f4aea6SSteven Rostedt    my $start_config = $config_bisect;
28460a05c769SSteven Rostedt
28470a05c769SSteven Rostedt    my $tmpconfig = "$tmpdir/use_config";
28480a05c769SSteven Rostedt
284930f75da5SSteven Rostedt    if (defined($config_bisect_good)) {
285030f75da5SSteven Rostedt	process_config_ignore $config_bisect_good;
285130f75da5SSteven Rostedt    }
285230f75da5SSteven Rostedt
28530a05c769SSteven Rostedt    # Make the file with the bad config and the min config
28540a05c769SSteven Rostedt    if (defined($minconfig)) {
28550a05c769SSteven Rostedt	# read the min config for things to ignore
28560a05c769SSteven Rostedt	run_command "cp $minconfig $tmpconfig" or
28570a05c769SSteven Rostedt	    dodie "failed to copy $minconfig to $tmpconfig";
28580a05c769SSteven Rostedt    } else {
28590a05c769SSteven Rostedt	unlink $tmpconfig;
28600a05c769SSteven Rostedt    }
28610a05c769SSteven Rostedt
28620a05c769SSteven Rostedt    if (-f $tmpconfig) {
2863fcb3f16aSSteven Rostedt	load_force_config($tmpconfig);
28640a05c769SSteven Rostedt	process_config_ignore $tmpconfig;
28650a05c769SSteven Rostedt    }
28660a05c769SSteven Rostedt
28670a05c769SSteven Rostedt    # now process the start config
28680a05c769SSteven Rostedt    run_command "cp $start_config $output_config" or
28690a05c769SSteven Rostedt	dodie "failed to copy $start_config to $output_config";
28700a05c769SSteven Rostedt
28710a05c769SSteven Rostedt    # read directly what we want to check
28720a05c769SSteven Rostedt    my %config_check;
28730a05c769SSteven Rostedt    open (IN, $output_config)
2874f9dee311SMasanari Iida	or dodie "failed to open $output_config";
28750a05c769SSteven Rostedt
28760a05c769SSteven Rostedt    while (<IN>) {
28770a05c769SSteven Rostedt	if (/^((CONFIG\S*)=.*)/) {
28780a05c769SSteven Rostedt	    $config_check{$2} = $1;
28790a05c769SSteven Rostedt	}
28800a05c769SSteven Rostedt    }
28810a05c769SSteven Rostedt    close(IN);
28820a05c769SSteven Rostedt
2883250bae8bSSteven Rostedt    # Now run oldconfig with the minconfig
2884fcb3f16aSSteven Rostedt    make_oldconfig;
28850a05c769SSteven Rostedt
28860a05c769SSteven Rostedt    # check to see what we lost (or gained)
28870a05c769SSteven Rostedt    open (IN, $output_config)
28880a05c769SSteven Rostedt	or dodie "Failed to read $start_config";
28890a05c769SSteven Rostedt
28900a05c769SSteven Rostedt    my %removed_configs;
28910a05c769SSteven Rostedt    my %added_configs;
28920a05c769SSteven Rostedt
28930a05c769SSteven Rostedt    while (<IN>) {
28940a05c769SSteven Rostedt	if (/^((CONFIG\S*)=.*)/) {
28950a05c769SSteven Rostedt	    # save off all options
28960a05c769SSteven Rostedt	    $config_set{$2} = $1;
28970a05c769SSteven Rostedt	    if (defined($config_check{$2})) {
28980a05c769SSteven Rostedt		if (defined($config_ignore{$2})) {
28990a05c769SSteven Rostedt		    $removed_configs{$2} = $1;
29000a05c769SSteven Rostedt		} else {
29010a05c769SSteven Rostedt		    $config_list{$2} = $1;
29020a05c769SSteven Rostedt		}
29030a05c769SSteven Rostedt	    } elsif (!defined($config_ignore{$2})) {
29040a05c769SSteven Rostedt		$added_configs{$2} = $1;
29050a05c769SSteven Rostedt		$config_list{$2} = $1;
29060a05c769SSteven Rostedt	    }
2907cf79fab6SSteven Rostedt	} elsif (/^# ((CONFIG\S*).*)/) {
2908cf79fab6SSteven Rostedt	    # Keep these configs disabled
2909cf79fab6SSteven Rostedt	    $config_set{$2} = $1;
2910cf79fab6SSteven Rostedt	    $config_off{$2} = $1;
29110a05c769SSteven Rostedt	}
29120a05c769SSteven Rostedt    }
29130a05c769SSteven Rostedt    close(IN);
29140a05c769SSteven Rostedt
29150a05c769SSteven Rostedt    my @confs = keys %removed_configs;
29160a05c769SSteven Rostedt    if ($#confs >= 0) {
29170a05c769SSteven Rostedt	doprint "Configs overridden by default configs and removed from check:\n";
29180a05c769SSteven Rostedt	foreach my $config (@confs) {
29190a05c769SSteven Rostedt	    doprint " $config\n";
29200a05c769SSteven Rostedt	}
29210a05c769SSteven Rostedt    }
29220a05c769SSteven Rostedt    @confs = keys %added_configs;
29230a05c769SSteven Rostedt    if ($#confs >= 0) {
29240a05c769SSteven Rostedt	doprint "Configs appearing in make oldconfig and added:\n";
29250a05c769SSteven Rostedt	foreach my $config (@confs) {
29260a05c769SSteven Rostedt	    doprint " $config\n";
29270a05c769SSteven Rostedt	}
29280a05c769SSteven Rostedt    }
29290a05c769SSteven Rostedt
29300a05c769SSteven Rostedt    my %config_test;
29310a05c769SSteven Rostedt    my $once = 0;
29320a05c769SSteven Rostedt
2933cf79fab6SSteven Rostedt    @config_off_tmp = ();
2934cf79fab6SSteven Rostedt
29350a05c769SSteven Rostedt    # Sometimes kconfig does weird things. We must make sure
29360a05c769SSteven Rostedt    # that the config we autocreate has everything we need
29370a05c769SSteven Rostedt    # to test, otherwise we may miss testing configs, or
29380a05c769SSteven Rostedt    # may not be able to create a new config.
29390a05c769SSteven Rostedt    # Here we create a config with everything set.
29400a05c769SSteven Rostedt    create_config (keys %config_list);
29410a05c769SSteven Rostedt    read_current_config \%config_test;
29420a05c769SSteven Rostedt    foreach my $config (keys %config_list) {
29430a05c769SSteven Rostedt	if (!defined($config_test{$config})) {
29440a05c769SSteven Rostedt	    if (!$once) {
29450a05c769SSteven Rostedt		$once = 1;
29460a05c769SSteven Rostedt		doprint "Configs not produced by kconfig (will not be checked):\n";
29470a05c769SSteven Rostedt	    }
29480a05c769SSteven Rostedt	    doprint "  $config\n";
29490a05c769SSteven Rostedt	    delete $config_list{$config};
29500a05c769SSteven Rostedt	}
29510a05c769SSteven Rostedt    }
29520a05c769SSteven Rostedt    my $ret;
2953b0918612SSteven Rostedt
2954b0918612SSteven Rostedt    if (defined($config_bisect_check) && $config_bisect_check) {
2955b0918612SSteven Rostedt	doprint " Checking to make sure bad config with min config fails\n";
2956b0918612SSteven Rostedt	create_config keys %config_list;
2957b0918612SSteven Rostedt	$ret = run_config_bisect_test $config_bisect_type;
2958b0918612SSteven Rostedt	if ($ret) {
2959b0918612SSteven Rostedt	    doprint " FAILED! Bad config with min config boots fine\n";
2960b0918612SSteven Rostedt	    return -1;
2961b0918612SSteven Rostedt	}
2962b0918612SSteven Rostedt	doprint " Bad config with min config fails as expected\n";
2963b0918612SSteven Rostedt    }
2964b0918612SSteven Rostedt
29650a05c769SSteven Rostedt    do {
29660a05c769SSteven Rostedt	$ret = run_config_bisect;
29670a05c769SSteven Rostedt    } while (!$ret);
29680a05c769SSteven Rostedt
29690a05c769SSteven Rostedt    return $ret if ($ret < 0);
29705f9b6cedSSteven Rostedt
29715f9b6cedSSteven Rostedt    success $i;
29725f9b6cedSSteven Rostedt}
29735f9b6cedSSteven Rostedt
297427d934b2SSteven Rostedtsub patchcheck_reboot {
297527d934b2SSteven Rostedt    doprint "Reboot and sleep $patchcheck_sleep_time seconds\n";
2976bc7c5803SSteven Rostedt    reboot_to_good $patchcheck_sleep_time;
297727d934b2SSteven Rostedt}
297827d934b2SSteven Rostedt
29796c5ee0beSSteven Rostedtsub patchcheck {
29806c5ee0beSSteven Rostedt    my ($i) = @_;
29816c5ee0beSSteven Rostedt
29826c5ee0beSSteven Rostedt    die "PATCHCHECK_START[$i] not defined\n"
2983b5f4aea6SSteven Rostedt	if (!defined($patchcheck_start));
29846c5ee0beSSteven Rostedt    die "PATCHCHECK_TYPE[$i] not defined\n"
2985b5f4aea6SSteven Rostedt	if (!defined($patchcheck_type));
29866c5ee0beSSteven Rostedt
2987b5f4aea6SSteven Rostedt    my $start = $patchcheck_start;
29886c5ee0beSSteven Rostedt
29896c5ee0beSSteven Rostedt    my $end = "HEAD";
2990b5f4aea6SSteven Rostedt    if (defined($patchcheck_end)) {
2991b5f4aea6SSteven Rostedt	$end = $patchcheck_end;
29926c5ee0beSSteven Rostedt    }
29936c5ee0beSSteven Rostedt
2994a57419b3SSteven Rostedt    # Get the true sha1's since we can use things like HEAD~3
2995a57419b3SSteven Rostedt    $start = get_sha1($start);
2996a57419b3SSteven Rostedt    $end = get_sha1($end);
2997a57419b3SSteven Rostedt
2998b5f4aea6SSteven Rostedt    my $type = $patchcheck_type;
29996c5ee0beSSteven Rostedt
30006c5ee0beSSteven Rostedt    # Can't have a test without having a test to run
30016c5ee0beSSteven Rostedt    if ($type eq "test" && !defined($run_test)) {
30026c5ee0beSSteven Rostedt	$type = "boot";
30036c5ee0beSSteven Rostedt    }
30046c5ee0beSSteven Rostedt
30056c5ee0beSSteven Rostedt    open (IN, "git log --pretty=oneline $end|") or
30066c5ee0beSSteven Rostedt	dodie "could not get git list";
30076c5ee0beSSteven Rostedt
30086c5ee0beSSteven Rostedt    my @list;
30096c5ee0beSSteven Rostedt
30106c5ee0beSSteven Rostedt    while (<IN>) {
30116c5ee0beSSteven Rostedt	chomp;
30126c5ee0beSSteven Rostedt	$list[$#list+1] = $_;
30136c5ee0beSSteven Rostedt	last if (/^$start/);
30146c5ee0beSSteven Rostedt    }
30156c5ee0beSSteven Rostedt    close(IN);
30166c5ee0beSSteven Rostedt
30176c5ee0beSSteven Rostedt    if ($list[$#list] !~ /^$start/) {
30182b7d9b21SSteven Rostedt	fail "SHA1 $start not found";
30196c5ee0beSSteven Rostedt    }
30206c5ee0beSSteven Rostedt
30216c5ee0beSSteven Rostedt    # go backwards in the list
30226c5ee0beSSteven Rostedt    @list = reverse @list;
30236c5ee0beSSteven Rostedt
30246c5ee0beSSteven Rostedt    my $save_clean = $noclean;
30251990207dSSteven Rostedt    my %ignored_warnings;
30261990207dSSteven Rostedt
30271990207dSSteven Rostedt    if (defined($ignore_warnings)) {
30281990207dSSteven Rostedt	foreach my $sha1 (split /\s+/, $ignore_warnings) {
30291990207dSSteven Rostedt	    $ignored_warnings{$sha1} = 1;
30301990207dSSteven Rostedt	}
30311990207dSSteven Rostedt    }
30326c5ee0beSSteven Rostedt
30336c5ee0beSSteven Rostedt    $in_patchcheck = 1;
30346c5ee0beSSteven Rostedt    foreach my $item (@list) {
30356c5ee0beSSteven Rostedt	my $sha1 = $item;
30366c5ee0beSSteven Rostedt	$sha1 =~ s/^([[:xdigit:]]+).*/$1/;
30376c5ee0beSSteven Rostedt
30386c5ee0beSSteven Rostedt	doprint "\nProcessing commit $item\n\n";
30396c5ee0beSSteven Rostedt
30406c5ee0beSSteven Rostedt	run_command "git checkout $sha1" or
30416c5ee0beSSteven Rostedt	    die "Failed to checkout $sha1";
30426c5ee0beSSteven Rostedt
30436c5ee0beSSteven Rostedt	# only clean on the first and last patch
30446c5ee0beSSteven Rostedt	if ($item eq $list[0] ||
30456c5ee0beSSteven Rostedt	    $item eq $list[$#list]) {
30466c5ee0beSSteven Rostedt	    $noclean = $save_clean;
30476c5ee0beSSteven Rostedt	} else {
30486c5ee0beSSteven Rostedt	    $noclean = 1;
30496c5ee0beSSteven Rostedt	}
30506c5ee0beSSteven Rostedt
30516c5ee0beSSteven Rostedt	if (defined($minconfig)) {
30522b7d9b21SSteven Rostedt	    build "useconfig:$minconfig" or return 0;
30536c5ee0beSSteven Rostedt	} else {
30546c5ee0beSSteven Rostedt	    # ?? no config to use?
30552b7d9b21SSteven Rostedt	    build "oldconfig" or return 0;
30566c5ee0beSSteven Rostedt	}
30576c5ee0beSSteven Rostedt
30581990207dSSteven Rostedt
30591990207dSSteven Rostedt	if (!defined($ignored_warnings{$sha1})) {
30602b7d9b21SSteven Rostedt	    check_buildlog $sha1 or return 0;
30611990207dSSteven Rostedt	}
30626c5ee0beSSteven Rostedt
30636c5ee0beSSteven Rostedt	next if ($type eq "build");
30646c5ee0beSSteven Rostedt
30657faafbd6SSteven Rostedt	my $failed = 0;
30667faafbd6SSteven Rostedt
3067ddf607e5SSteven Rostedt	start_monitor_and_boot or $failed = 1;
30687faafbd6SSteven Rostedt
30697faafbd6SSteven Rostedt	if (!$failed && $type ne "boot"){
30707faafbd6SSteven Rostedt	    do_run_test or $failed = 1;
30717faafbd6SSteven Rostedt	}
30727faafbd6SSteven Rostedt	end_monitor;
30737faafbd6SSteven Rostedt	return 0 if ($failed);
30747faafbd6SSteven Rostedt
307527d934b2SSteven Rostedt	patchcheck_reboot;
307627d934b2SSteven Rostedt
30776c5ee0beSSteven Rostedt    }
30786c5ee0beSSteven Rostedt    $in_patchcheck = 0;
30796c5ee0beSSteven Rostedt    success $i;
30802b7d9b21SSteven Rostedt
30812b7d9b21SSteven Rostedt    return 1;
30826c5ee0beSSteven Rostedt}
30836c5ee0beSSteven Rostedt
3084b9066f6cSSteven Rostedtmy %depends;
3085ac6974c7SSteven Rostedtmy %depcount;
3086b9066f6cSSteven Rostedtmy $iflevel = 0;
3087b9066f6cSSteven Rostedtmy @ifdeps;
3088b9066f6cSSteven Rostedt
3089b9066f6cSSteven Rostedt# prevent recursion
3090b9066f6cSSteven Rostedtmy %read_kconfigs;
3091b9066f6cSSteven Rostedt
3092ac6974c7SSteven Rostedtsub add_dep {
3093ac6974c7SSteven Rostedt    # $config depends on $dep
3094ac6974c7SSteven Rostedt    my ($config, $dep) = @_;
3095ac6974c7SSteven Rostedt
3096ac6974c7SSteven Rostedt    if (defined($depends{$config})) {
3097ac6974c7SSteven Rostedt	$depends{$config} .= " " . $dep;
3098ac6974c7SSteven Rostedt    } else {
3099ac6974c7SSteven Rostedt	$depends{$config} = $dep;
3100ac6974c7SSteven Rostedt    }
3101ac6974c7SSteven Rostedt
3102ac6974c7SSteven Rostedt    # record the number of configs depending on $dep
3103ac6974c7SSteven Rostedt    if (defined $depcount{$dep}) {
3104ac6974c7SSteven Rostedt	$depcount{$dep}++;
3105ac6974c7SSteven Rostedt    } else {
3106ac6974c7SSteven Rostedt	$depcount{$dep} = 1;
3107ac6974c7SSteven Rostedt    }
3108ac6974c7SSteven Rostedt}
3109ac6974c7SSteven Rostedt
3110b9066f6cSSteven Rostedt# taken from streamline_config.pl
3111b9066f6cSSteven Rostedtsub read_kconfig {
3112b9066f6cSSteven Rostedt    my ($kconfig) = @_;
3113b9066f6cSSteven Rostedt
3114b9066f6cSSteven Rostedt    my $state = "NONE";
3115b9066f6cSSteven Rostedt    my $config;
3116b9066f6cSSteven Rostedt    my @kconfigs;
3117b9066f6cSSteven Rostedt
3118b9066f6cSSteven Rostedt    my $cont = 0;
3119b9066f6cSSteven Rostedt    my $line;
3120b9066f6cSSteven Rostedt
3121b9066f6cSSteven Rostedt
3122b9066f6cSSteven Rostedt    if (! -f $kconfig) {
3123b9066f6cSSteven Rostedt	doprint "file $kconfig does not exist, skipping\n";
3124b9066f6cSSteven Rostedt	return;
3125b9066f6cSSteven Rostedt    }
3126b9066f6cSSteven Rostedt
3127b9066f6cSSteven Rostedt    open(KIN, "$kconfig")
3128b9066f6cSSteven Rostedt	or die "Can't open $kconfig";
3129b9066f6cSSteven Rostedt    while (<KIN>) {
3130b9066f6cSSteven Rostedt	chomp;
3131b9066f6cSSteven Rostedt
3132b9066f6cSSteven Rostedt	# Make sure that lines ending with \ continue
3133b9066f6cSSteven Rostedt	if ($cont) {
3134b9066f6cSSteven Rostedt	    $_ = $line . " " . $_;
3135b9066f6cSSteven Rostedt	}
3136b9066f6cSSteven Rostedt
3137b9066f6cSSteven Rostedt	if (s/\\$//) {
3138b9066f6cSSteven Rostedt	    $cont = 1;
3139b9066f6cSSteven Rostedt	    $line = $_;
3140b9066f6cSSteven Rostedt	    next;
3141b9066f6cSSteven Rostedt	}
3142b9066f6cSSteven Rostedt
3143b9066f6cSSteven Rostedt	$cont = 0;
3144b9066f6cSSteven Rostedt
3145b9066f6cSSteven Rostedt	# collect any Kconfig sources
3146b9066f6cSSteven Rostedt	if (/^source\s*"(.*)"/) {
3147b9066f6cSSteven Rostedt	    $kconfigs[$#kconfigs+1] = $1;
3148b9066f6cSSteven Rostedt	}
3149b9066f6cSSteven Rostedt
3150b9066f6cSSteven Rostedt	# configs found
3151b9066f6cSSteven Rostedt	if (/^\s*(menu)?config\s+(\S+)\s*$/) {
3152b9066f6cSSteven Rostedt	    $state = "NEW";
3153b9066f6cSSteven Rostedt	    $config = $2;
3154b9066f6cSSteven Rostedt
3155b9066f6cSSteven Rostedt	    for (my $i = 0; $i < $iflevel; $i++) {
3156ac6974c7SSteven Rostedt		add_dep $config, $ifdeps[$i];
3157b9066f6cSSteven Rostedt	    }
3158b9066f6cSSteven Rostedt
3159b9066f6cSSteven Rostedt	# collect the depends for the config
3160b9066f6cSSteven Rostedt	} elsif ($state eq "NEW" && /^\s*depends\s+on\s+(.*)$/) {
3161b9066f6cSSteven Rostedt
3162ac6974c7SSteven Rostedt	    add_dep $config, $1;
3163b9066f6cSSteven Rostedt
3164b9066f6cSSteven Rostedt	# Get the configs that select this config
3165ac6974c7SSteven Rostedt	} elsif ($state eq "NEW" && /^\s*select\s+(\S+)/) {
3166ac6974c7SSteven Rostedt
3167ac6974c7SSteven Rostedt	    # selected by depends on config
3168ac6974c7SSteven Rostedt	    add_dep $1, $config;
3169b9066f6cSSteven Rostedt
3170b9066f6cSSteven Rostedt	# Check for if statements
3171b9066f6cSSteven Rostedt	} elsif (/^if\s+(.*\S)\s*$/) {
3172b9066f6cSSteven Rostedt	    my $deps = $1;
3173b9066f6cSSteven Rostedt	    # remove beginning and ending non text
3174b9066f6cSSteven Rostedt	    $deps =~ s/^[^a-zA-Z0-9_]*//;
3175b9066f6cSSteven Rostedt	    $deps =~ s/[^a-zA-Z0-9_]*$//;
3176b9066f6cSSteven Rostedt
3177b9066f6cSSteven Rostedt	    my @deps = split /[^a-zA-Z0-9_]+/, $deps;
3178b9066f6cSSteven Rostedt
3179b9066f6cSSteven Rostedt	    $ifdeps[$iflevel++] = join ':', @deps;
3180b9066f6cSSteven Rostedt
3181b9066f6cSSteven Rostedt	} elsif (/^endif/) {
3182b9066f6cSSteven Rostedt
3183b9066f6cSSteven Rostedt	    $iflevel-- if ($iflevel);
3184b9066f6cSSteven Rostedt
3185b9066f6cSSteven Rostedt	# stop on "help"
3186b9066f6cSSteven Rostedt	} elsif (/^\s*help\s*$/) {
3187b9066f6cSSteven Rostedt	    $state = "NONE";
3188b9066f6cSSteven Rostedt	}
3189b9066f6cSSteven Rostedt    }
3190b9066f6cSSteven Rostedt    close(KIN);
3191b9066f6cSSteven Rostedt
3192b9066f6cSSteven Rostedt    # read in any configs that were found.
3193b9066f6cSSteven Rostedt    foreach $kconfig (@kconfigs) {
3194b9066f6cSSteven Rostedt	if (!defined($read_kconfigs{$kconfig})) {
3195b9066f6cSSteven Rostedt	    $read_kconfigs{$kconfig} = 1;
3196b9066f6cSSteven Rostedt	    read_kconfig("$builddir/$kconfig");
3197b9066f6cSSteven Rostedt	}
3198b9066f6cSSteven Rostedt    }
3199b9066f6cSSteven Rostedt}
3200b9066f6cSSteven Rostedt
3201b9066f6cSSteven Rostedtsub read_depends {
3202b9066f6cSSteven Rostedt    # find out which arch this is by the kconfig file
3203b9066f6cSSteven Rostedt    open (IN, $output_config)
3204b9066f6cSSteven Rostedt	or dodie "Failed to read $output_config";
3205b9066f6cSSteven Rostedt    my $arch;
3206b9066f6cSSteven Rostedt    while (<IN>) {
3207b9066f6cSSteven Rostedt	if (m,Linux/(\S+)\s+\S+\s+Kernel Configuration,) {
3208b9066f6cSSteven Rostedt	    $arch = $1;
3209b9066f6cSSteven Rostedt	    last;
3210b9066f6cSSteven Rostedt	}
3211b9066f6cSSteven Rostedt    }
3212b9066f6cSSteven Rostedt    close IN;
3213b9066f6cSSteven Rostedt
3214b9066f6cSSteven Rostedt    if (!defined($arch)) {
3215b9066f6cSSteven Rostedt	doprint "Could not find arch from config file\n";
3216b9066f6cSSteven Rostedt	doprint "no dependencies used\n";
3217b9066f6cSSteven Rostedt	return;
3218b9066f6cSSteven Rostedt    }
3219b9066f6cSSteven Rostedt
3220b9066f6cSSteven Rostedt    # arch is really the subarch, we need to know
3221b9066f6cSSteven Rostedt    # what directory to look at.
3222b9066f6cSSteven Rostedt    if ($arch eq "i386" || $arch eq "x86_64") {
3223b9066f6cSSteven Rostedt	$arch = "x86";
3224b9066f6cSSteven Rostedt    } elsif ($arch =~ /^tile/) {
3225b9066f6cSSteven Rostedt	$arch = "tile";
3226b9066f6cSSteven Rostedt    }
3227b9066f6cSSteven Rostedt
3228b9066f6cSSteven Rostedt    my $kconfig = "$builddir/arch/$arch/Kconfig";
3229b9066f6cSSteven Rostedt
3230b9066f6cSSteven Rostedt    if (! -f $kconfig && $arch =~ /\d$/) {
3231b9066f6cSSteven Rostedt	my $orig = $arch;
3232b9066f6cSSteven Rostedt 	# some subarchs have numbers, truncate them
3233b9066f6cSSteven Rostedt	$arch =~ s/\d*$//;
3234b9066f6cSSteven Rostedt	$kconfig = "$builddir/arch/$arch/Kconfig";
3235b9066f6cSSteven Rostedt	if (! -f $kconfig) {
3236b9066f6cSSteven Rostedt	    doprint "No idea what arch dir $orig is for\n";
3237b9066f6cSSteven Rostedt	    doprint "no dependencies used\n";
3238b9066f6cSSteven Rostedt	    return;
3239b9066f6cSSteven Rostedt	}
3240b9066f6cSSteven Rostedt    }
3241b9066f6cSSteven Rostedt
3242b9066f6cSSteven Rostedt    read_kconfig($kconfig);
3243b9066f6cSSteven Rostedt}
3244b9066f6cSSteven Rostedt
32454c4ab120SSteven Rostedtsub read_config_list {
32464c4ab120SSteven Rostedt    my ($config) = @_;
32474c4ab120SSteven Rostedt
32484c4ab120SSteven Rostedt    open (IN, $config)
32494c4ab120SSteven Rostedt	or dodie "Failed to read $config";
32504c4ab120SSteven Rostedt
32514c4ab120SSteven Rostedt    while (<IN>) {
32524c4ab120SSteven Rostedt	if (/^((CONFIG\S*)=.*)/) {
32534c4ab120SSteven Rostedt	    if (!defined($config_ignore{$2})) {
32544c4ab120SSteven Rostedt		$config_list{$2} = $1;
32554c4ab120SSteven Rostedt	    }
32564c4ab120SSteven Rostedt	}
32574c4ab120SSteven Rostedt    }
32584c4ab120SSteven Rostedt
32594c4ab120SSteven Rostedt    close(IN);
32604c4ab120SSteven Rostedt}
32614c4ab120SSteven Rostedt
32624c4ab120SSteven Rostedtsub read_output_config {
32634c4ab120SSteven Rostedt    my ($config) = @_;
32644c4ab120SSteven Rostedt
32654c4ab120SSteven Rostedt    assign_configs \%config_ignore, $config;
32664c4ab120SSteven Rostedt}
32674c4ab120SSteven Rostedt
32684c4ab120SSteven Rostedtsub make_new_config {
32694c4ab120SSteven Rostedt    my @configs = @_;
32704c4ab120SSteven Rostedt
32714c4ab120SSteven Rostedt    open (OUT, ">$output_config")
32724c4ab120SSteven Rostedt	or dodie "Failed to write $output_config";
32734c4ab120SSteven Rostedt
32744c4ab120SSteven Rostedt    foreach my $config (@configs) {
32754c4ab120SSteven Rostedt	print OUT "$config\n";
32764c4ab120SSteven Rostedt    }
32774c4ab120SSteven Rostedt    close OUT;
32784c4ab120SSteven Rostedt}
32794c4ab120SSteven Rostedt
3280ac6974c7SSteven Rostedtsub chomp_config {
3281ac6974c7SSteven Rostedt    my ($config) = @_;
3282ac6974c7SSteven Rostedt
3283ac6974c7SSteven Rostedt    $config =~ s/CONFIG_//;
3284ac6974c7SSteven Rostedt
3285ac6974c7SSteven Rostedt    return $config;
3286ac6974c7SSteven Rostedt}
3287ac6974c7SSteven Rostedt
3288b9066f6cSSteven Rostedtsub get_depends {
3289b9066f6cSSteven Rostedt    my ($dep) = @_;
3290b9066f6cSSteven Rostedt
3291ac6974c7SSteven Rostedt    my $kconfig = chomp_config $dep;
3292b9066f6cSSteven Rostedt
3293b9066f6cSSteven Rostedt    $dep = $depends{"$kconfig"};
3294b9066f6cSSteven Rostedt
3295b9066f6cSSteven Rostedt    # the dep string we have saves the dependencies as they
3296b9066f6cSSteven Rostedt    # were found, including expressions like ! && ||. We
3297b9066f6cSSteven Rostedt    # want to split this out into just an array of configs.
3298b9066f6cSSteven Rostedt
3299b9066f6cSSteven Rostedt    my $valid = "A-Za-z_0-9";
3300b9066f6cSSteven Rostedt
3301b9066f6cSSteven Rostedt    my @configs;
3302b9066f6cSSteven Rostedt
3303b9066f6cSSteven Rostedt    while ($dep =~ /[$valid]/) {
3304b9066f6cSSteven Rostedt
3305b9066f6cSSteven Rostedt	if ($dep =~ /^[^$valid]*([$valid]+)/) {
3306b9066f6cSSteven Rostedt	    my $conf = "CONFIG_" . $1;
3307b9066f6cSSteven Rostedt
3308b9066f6cSSteven Rostedt	    $configs[$#configs + 1] = $conf;
3309b9066f6cSSteven Rostedt
3310b9066f6cSSteven Rostedt	    $dep =~ s/^[^$valid]*[$valid]+//;
3311b9066f6cSSteven Rostedt	} else {
3312b9066f6cSSteven Rostedt	    die "this should never happen";
3313b9066f6cSSteven Rostedt	}
3314b9066f6cSSteven Rostedt    }
3315b9066f6cSSteven Rostedt
3316b9066f6cSSteven Rostedt    return @configs;
3317b9066f6cSSteven Rostedt}
3318b9066f6cSSteven Rostedt
3319b9066f6cSSteven Rostedtmy %min_configs;
3320b9066f6cSSteven Rostedtmy %keep_configs;
332143d1b651SSteven Rostedtmy %save_configs;
3322b9066f6cSSteven Rostedtmy %processed_configs;
3323b9066f6cSSteven Rostedtmy %nochange_config;
3324b9066f6cSSteven Rostedt
3325b9066f6cSSteven Rostedtsub test_this_config {
3326b9066f6cSSteven Rostedt    my ($config) = @_;
3327b9066f6cSSteven Rostedt
3328b9066f6cSSteven Rostedt    my $found;
3329b9066f6cSSteven Rostedt
3330b9066f6cSSteven Rostedt    # if we already processed this config, skip it
3331b9066f6cSSteven Rostedt    if (defined($processed_configs{$config})) {
3332b9066f6cSSteven Rostedt	return undef;
3333b9066f6cSSteven Rostedt    }
3334b9066f6cSSteven Rostedt    $processed_configs{$config} = 1;
3335b9066f6cSSteven Rostedt
3336b9066f6cSSteven Rostedt    # if this config failed during this round, skip it
3337b9066f6cSSteven Rostedt    if (defined($nochange_config{$config})) {
3338b9066f6cSSteven Rostedt	return undef;
3339b9066f6cSSteven Rostedt    }
3340b9066f6cSSteven Rostedt
3341ac6974c7SSteven Rostedt    my $kconfig = chomp_config $config;
3342b9066f6cSSteven Rostedt
3343b9066f6cSSteven Rostedt    # Test dependencies first
3344b9066f6cSSteven Rostedt    if (defined($depends{"$kconfig"})) {
3345b9066f6cSSteven Rostedt	my @parents = get_depends $config;
3346b9066f6cSSteven Rostedt	foreach my $parent (@parents) {
3347b9066f6cSSteven Rostedt	    # if the parent is in the min config, check it first
3348b9066f6cSSteven Rostedt	    next if (!defined($min_configs{$parent}));
3349b9066f6cSSteven Rostedt	    $found = test_this_config($parent);
3350b9066f6cSSteven Rostedt	    if (defined($found)) {
3351b9066f6cSSteven Rostedt		return $found;
3352b9066f6cSSteven Rostedt	    }
3353b9066f6cSSteven Rostedt	}
3354b9066f6cSSteven Rostedt    }
3355b9066f6cSSteven Rostedt
3356b9066f6cSSteven Rostedt    # Remove this config from the list of configs
3357fb16d891SAdam Lee    # do a make olddefconfig and then read the resulting
3358b9066f6cSSteven Rostedt    # .config to make sure it is missing the config that
3359b9066f6cSSteven Rostedt    # we had before
3360b9066f6cSSteven Rostedt    my %configs = %min_configs;
3361b9066f6cSSteven Rostedt    delete $configs{$config};
3362b9066f6cSSteven Rostedt    make_new_config ((values %configs), (values %keep_configs));
3363b9066f6cSSteven Rostedt    make_oldconfig;
3364b9066f6cSSteven Rostedt    undef %configs;
3365b9066f6cSSteven Rostedt    assign_configs \%configs, $output_config;
3366b9066f6cSSteven Rostedt
3367b9066f6cSSteven Rostedt    return $config if (!defined($configs{$config}));
3368b9066f6cSSteven Rostedt
3369b9066f6cSSteven Rostedt    doprint "disabling config $config did not change .config\n";
3370b9066f6cSSteven Rostedt
3371b9066f6cSSteven Rostedt    $nochange_config{$config} = 1;
3372b9066f6cSSteven Rostedt
3373b9066f6cSSteven Rostedt    return undef;
3374b9066f6cSSteven Rostedt}
3375b9066f6cSSteven Rostedt
33764c4ab120SSteven Rostedtsub make_min_config {
33774c4ab120SSteven Rostedt    my ($i) = @_;
33784c4ab120SSteven Rostedt
3379ccc513b6SSteven Rostedt    my $type = $minconfig_type;
3380ccc513b6SSteven Rostedt    if ($type ne "boot" && $type ne "test") {
3381ccc513b6SSteven Rostedt	fail "Invalid MIN_CONFIG_TYPE '$minconfig_type'\n" .
3382ccc513b6SSteven Rostedt	    " make_min_config works only with 'boot' and 'test'\n" and return;
3383ccc513b6SSteven Rostedt    }
3384ccc513b6SSteven Rostedt
33854c4ab120SSteven Rostedt    if (!defined($output_minconfig)) {
33864c4ab120SSteven Rostedt	fail "OUTPUT_MIN_CONFIG not defined" and return;
33874c4ab120SSteven Rostedt    }
338835ce5952SSteven Rostedt
338935ce5952SSteven Rostedt    # If output_minconfig exists, and the start_minconfig
339035ce5952SSteven Rostedt    # came from min_config, than ask if we should use
339135ce5952SSteven Rostedt    # that instead.
339235ce5952SSteven Rostedt    if (-f $output_minconfig && !$start_minconfig_defined) {
339335ce5952SSteven Rostedt	print "$output_minconfig exists\n";
339443de3316SSteven Rostedt	if (!defined($use_output_minconfig)) {
339535ce5952SSteven Rostedt	    if (read_yn " Use it as minconfig?") {
339635ce5952SSteven Rostedt		$start_minconfig = $output_minconfig;
339735ce5952SSteven Rostedt	    }
339843de3316SSteven Rostedt	} elsif ($use_output_minconfig > 0) {
339943de3316SSteven Rostedt	    doprint "Using $output_minconfig as MIN_CONFIG\n";
340043de3316SSteven Rostedt	    $start_minconfig = $output_minconfig;
340143de3316SSteven Rostedt	} else {
340243de3316SSteven Rostedt	    doprint "Set to still use MIN_CONFIG as starting point\n";
340343de3316SSteven Rostedt	}
340435ce5952SSteven Rostedt    }
340535ce5952SSteven Rostedt
34064c4ab120SSteven Rostedt    if (!defined($start_minconfig)) {
34074c4ab120SSteven Rostedt	fail "START_MIN_CONFIG or MIN_CONFIG not defined" and return;
34084c4ab120SSteven Rostedt    }
34094c4ab120SSteven Rostedt
341035ce5952SSteven Rostedt    my $temp_config = "$tmpdir/temp_config";
341135ce5952SSteven Rostedt
34124c4ab120SSteven Rostedt    # First things first. We build an allnoconfig to find
34134c4ab120SSteven Rostedt    # out what the defaults are that we can't touch.
34144c4ab120SSteven Rostedt    # Some are selections, but we really can't handle selections.
34154c4ab120SSteven Rostedt
34164c4ab120SSteven Rostedt    my $save_minconfig = $minconfig;
34174c4ab120SSteven Rostedt    undef $minconfig;
34184c4ab120SSteven Rostedt
34194c4ab120SSteven Rostedt    run_command "$make allnoconfig" or return 0;
34204c4ab120SSteven Rostedt
3421b9066f6cSSteven Rostedt    read_depends;
3422b9066f6cSSteven Rostedt
34234c4ab120SSteven Rostedt    process_config_ignore $output_config;
3424b9066f6cSSteven Rostedt
342543d1b651SSteven Rostedt    undef %save_configs;
3426b9066f6cSSteven Rostedt    undef %min_configs;
34274c4ab120SSteven Rostedt
34284c4ab120SSteven Rostedt    if (defined($ignore_config)) {
34294c4ab120SSteven Rostedt	# make sure the file exists
34304c4ab120SSteven Rostedt	`touch $ignore_config`;
343143d1b651SSteven Rostedt	assign_configs \%save_configs, $ignore_config;
34324c4ab120SSteven Rostedt    }
34334c4ab120SSteven Rostedt
343443d1b651SSteven Rostedt    %keep_configs = %save_configs;
343543d1b651SSteven Rostedt
34364c4ab120SSteven Rostedt    doprint "Load initial configs from $start_minconfig\n";
34374c4ab120SSteven Rostedt
34384c4ab120SSteven Rostedt    # Look at the current min configs, and save off all the
34394c4ab120SSteven Rostedt    # ones that were set via the allnoconfig
34404c4ab120SSteven Rostedt    assign_configs \%min_configs, $start_minconfig;
34414c4ab120SSteven Rostedt
34424c4ab120SSteven Rostedt    my @config_keys = keys %min_configs;
34434c4ab120SSteven Rostedt
3444ac6974c7SSteven Rostedt    # All configs need a depcount
3445ac6974c7SSteven Rostedt    foreach my $config (@config_keys) {
3446ac6974c7SSteven Rostedt	my $kconfig = chomp_config $config;
3447ac6974c7SSteven Rostedt	if (!defined $depcount{$kconfig}) {
3448ac6974c7SSteven Rostedt		$depcount{$kconfig} = 0;
3449ac6974c7SSteven Rostedt	}
3450ac6974c7SSteven Rostedt    }
3451ac6974c7SSteven Rostedt
34524c4ab120SSteven Rostedt    # Remove anything that was set by the make allnoconfig
34534c4ab120SSteven Rostedt    # we shouldn't need them as they get set for us anyway.
34544c4ab120SSteven Rostedt    foreach my $config (@config_keys) {
34554c4ab120SSteven Rostedt	# Remove anything in the ignore_config
34564c4ab120SSteven Rostedt	if (defined($keep_configs{$config})) {
34574c4ab120SSteven Rostedt	    my $file = $ignore_config;
34584c4ab120SSteven Rostedt	    $file =~ s,.*/(.*?)$,$1,;
34594c4ab120SSteven Rostedt	    doprint "$config set by $file ... ignored\n";
34604c4ab120SSteven Rostedt	    delete $min_configs{$config};
34614c4ab120SSteven Rostedt	    next;
34624c4ab120SSteven Rostedt	}
34634c4ab120SSteven Rostedt	# But make sure the settings are the same. If a min config
34644c4ab120SSteven Rostedt	# sets a selection, we do not want to get rid of it if
34654c4ab120SSteven Rostedt	# it is not the same as what we have. Just move it into
34664c4ab120SSteven Rostedt	# the keep configs.
34674c4ab120SSteven Rostedt	if (defined($config_ignore{$config})) {
34684c4ab120SSteven Rostedt	    if ($config_ignore{$config} ne $min_configs{$config}) {
34694c4ab120SSteven Rostedt		doprint "$config is in allnoconfig as '$config_ignore{$config}'";
34704c4ab120SSteven Rostedt		doprint " but it is '$min_configs{$config}' in minconfig .. keeping\n";
34714c4ab120SSteven Rostedt		$keep_configs{$config} = $min_configs{$config};
34724c4ab120SSteven Rostedt	    } else {
34734c4ab120SSteven Rostedt		doprint "$config set by allnoconfig ... ignored\n";
34744c4ab120SSteven Rostedt	    }
34754c4ab120SSteven Rostedt	    delete $min_configs{$config};
34764c4ab120SSteven Rostedt	}
34774c4ab120SSteven Rostedt    }
34784c4ab120SSteven Rostedt
34794c4ab120SSteven Rostedt    my $done = 0;
3480b9066f6cSSteven Rostedt    my $take_two = 0;
34814c4ab120SSteven Rostedt
34824c4ab120SSteven Rostedt    while (!$done) {
34834c4ab120SSteven Rostedt
34844c4ab120SSteven Rostedt	my $config;
34854c4ab120SSteven Rostedt	my $found;
34864c4ab120SSteven Rostedt
34874c4ab120SSteven Rostedt	# Now disable each config one by one and do a make oldconfig
34884c4ab120SSteven Rostedt	# till we find a config that changes our list.
34894c4ab120SSteven Rostedt
34904c4ab120SSteven Rostedt	my @test_configs = keys %min_configs;
3491ac6974c7SSteven Rostedt
3492ac6974c7SSteven Rostedt	# Sort keys by who is most dependent on
3493ac6974c7SSteven Rostedt	@test_configs = sort  { $depcount{chomp_config($b)} <=> $depcount{chomp_config($a)} }
3494ac6974c7SSteven Rostedt			  @test_configs ;
3495ac6974c7SSteven Rostedt
3496ac6974c7SSteven Rostedt	# Put configs that did not modify the config at the end.
34974c4ab120SSteven Rostedt	my $reset = 1;
34984c4ab120SSteven Rostedt	for (my $i = 0; $i < $#test_configs; $i++) {
34994c4ab120SSteven Rostedt	    if (!defined($nochange_config{$test_configs[0]})) {
35004c4ab120SSteven Rostedt		$reset = 0;
35014c4ab120SSteven Rostedt		last;
35024c4ab120SSteven Rostedt	    }
35034c4ab120SSteven Rostedt	    # This config didn't change the .config last time.
35044c4ab120SSteven Rostedt	    # Place it at the end
35054c4ab120SSteven Rostedt	    my $config = shift @test_configs;
35064c4ab120SSteven Rostedt	    push @test_configs, $config;
35074c4ab120SSteven Rostedt	}
35084c4ab120SSteven Rostedt
35094c4ab120SSteven Rostedt	# if every test config has failed to modify the .config file
35104c4ab120SSteven Rostedt	# in the past, then reset and start over.
35114c4ab120SSteven Rostedt	if ($reset) {
35124c4ab120SSteven Rostedt	    undef %nochange_config;
35134c4ab120SSteven Rostedt	}
35144c4ab120SSteven Rostedt
3515b9066f6cSSteven Rostedt	undef %processed_configs;
3516b9066f6cSSteven Rostedt
35174c4ab120SSteven Rostedt	foreach my $config (@test_configs) {
35184c4ab120SSteven Rostedt
3519b9066f6cSSteven Rostedt	    $found = test_this_config $config;
35204c4ab120SSteven Rostedt
3521b9066f6cSSteven Rostedt	    last if (defined($found));
35224c4ab120SSteven Rostedt
35234c4ab120SSteven Rostedt	    # oh well, try another config
35244c4ab120SSteven Rostedt	}
35254c4ab120SSteven Rostedt
35264c4ab120SSteven Rostedt	if (!defined($found)) {
3527b9066f6cSSteven Rostedt	    # we could have failed due to the nochange_config hash
3528b9066f6cSSteven Rostedt	    # reset and try again
3529b9066f6cSSteven Rostedt	    if (!$take_two) {
3530b9066f6cSSteven Rostedt		undef %nochange_config;
3531b9066f6cSSteven Rostedt		$take_two = 1;
3532b9066f6cSSteven Rostedt		next;
3533b9066f6cSSteven Rostedt	    }
35344c4ab120SSteven Rostedt	    doprint "No more configs found that we can disable\n";
35354c4ab120SSteven Rostedt	    $done = 1;
35364c4ab120SSteven Rostedt	    last;
35374c4ab120SSteven Rostedt	}
3538b9066f6cSSteven Rostedt	$take_two = 0;
35394c4ab120SSteven Rostedt
35404c4ab120SSteven Rostedt	$config = $found;
35414c4ab120SSteven Rostedt
35424c4ab120SSteven Rostedt	doprint "Test with $config disabled\n";
35434c4ab120SSteven Rostedt
35444c4ab120SSteven Rostedt	# set in_bisect to keep build and monitor from dieing
35454c4ab120SSteven Rostedt	$in_bisect = 1;
35464c4ab120SSteven Rostedt
35474c4ab120SSteven Rostedt	my $failed = 0;
3548bf1c95abSSteven Rostedt	build "oldconfig" or $failed = 1;
3549bf1c95abSSteven Rostedt	if (!$failed) {
35504c4ab120SSteven Rostedt		start_monitor_and_boot or $failed = 1;
3551ccc513b6SSteven Rostedt
3552ccc513b6SSteven Rostedt		if ($type eq "test" && !$failed) {
3553ccc513b6SSteven Rostedt		    do_run_test or $failed = 1;
3554ccc513b6SSteven Rostedt		}
3555ccc513b6SSteven Rostedt
35564c4ab120SSteven Rostedt		end_monitor;
3557bf1c95abSSteven Rostedt	}
35584c4ab120SSteven Rostedt
35594c4ab120SSteven Rostedt	$in_bisect = 0;
35604c4ab120SSteven Rostedt
35614c4ab120SSteven Rostedt	if ($failed) {
3562b9066f6cSSteven Rostedt	    doprint "$min_configs{$config} is needed to boot the box... keeping\n";
35634c4ab120SSteven Rostedt	    # this config is needed, add it to the ignore list.
35644c4ab120SSteven Rostedt	    $keep_configs{$config} = $min_configs{$config};
356543d1b651SSteven Rostedt	    $save_configs{$config} = $min_configs{$config};
35664c4ab120SSteven Rostedt	    delete $min_configs{$config};
356735ce5952SSteven Rostedt
356835ce5952SSteven Rostedt	    # update new ignore configs
356935ce5952SSteven Rostedt	    if (defined($ignore_config)) {
357035ce5952SSteven Rostedt		open (OUT, ">$temp_config")
357135ce5952SSteven Rostedt		    or die "Can't write to $temp_config";
357243d1b651SSteven Rostedt		foreach my $config (keys %save_configs) {
357343d1b651SSteven Rostedt		    print OUT "$save_configs{$config}\n";
357435ce5952SSteven Rostedt		}
357535ce5952SSteven Rostedt		close OUT;
357635ce5952SSteven Rostedt		run_command "mv $temp_config $ignore_config" or
357735ce5952SSteven Rostedt		    dodie "failed to copy update to $ignore_config";
357835ce5952SSteven Rostedt	    }
357935ce5952SSteven Rostedt
35804c4ab120SSteven Rostedt	} else {
35814c4ab120SSteven Rostedt	    # We booted without this config, remove it from the minconfigs.
35824c4ab120SSteven Rostedt	    doprint "$config is not needed, disabling\n";
35834c4ab120SSteven Rostedt
35844c4ab120SSteven Rostedt	    delete $min_configs{$config};
35854c4ab120SSteven Rostedt
35864c4ab120SSteven Rostedt	    # Also disable anything that is not enabled in this config
35874c4ab120SSteven Rostedt	    my %configs;
35884c4ab120SSteven Rostedt	    assign_configs \%configs, $output_config;
35894c4ab120SSteven Rostedt	    my @config_keys = keys %min_configs;
35904c4ab120SSteven Rostedt	    foreach my $config (@config_keys) {
35914c4ab120SSteven Rostedt		if (!defined($configs{$config})) {
35924c4ab120SSteven Rostedt		    doprint "$config is not set, disabling\n";
35934c4ab120SSteven Rostedt		    delete $min_configs{$config};
35944c4ab120SSteven Rostedt		}
35954c4ab120SSteven Rostedt	    }
35964c4ab120SSteven Rostedt
35974c4ab120SSteven Rostedt	    # Save off all the current mandidory configs
359835ce5952SSteven Rostedt	    open (OUT, ">$temp_config")
359935ce5952SSteven Rostedt		or die "Can't write to $temp_config";
36004c4ab120SSteven Rostedt	    foreach my $config (keys %keep_configs) {
36014c4ab120SSteven Rostedt		print OUT "$keep_configs{$config}\n";
36024c4ab120SSteven Rostedt	    }
36034c4ab120SSteven Rostedt	    foreach my $config (keys %min_configs) {
36044c4ab120SSteven Rostedt		print OUT "$min_configs{$config}\n";
36054c4ab120SSteven Rostedt	    }
36064c4ab120SSteven Rostedt	    close OUT;
360735ce5952SSteven Rostedt
360835ce5952SSteven Rostedt	    run_command "mv $temp_config $output_minconfig" or
360935ce5952SSteven Rostedt		dodie "failed to copy update to $output_minconfig";
36104c4ab120SSteven Rostedt	}
36114c4ab120SSteven Rostedt
36124c4ab120SSteven Rostedt	doprint "Reboot and wait $sleep_time seconds\n";
3613bc7c5803SSteven Rostedt	reboot_to_good $sleep_time;
36144c4ab120SSteven Rostedt    }
36154c4ab120SSteven Rostedt
36164c4ab120SSteven Rostedt    success $i;
36174c4ab120SSteven Rostedt    return 1;
36184c4ab120SSteven Rostedt}
36194c4ab120SSteven Rostedt
36208d1491baSSteven Rostedt$#ARGV < 1 or die "ktest.pl version: $VERSION\n   usage: ktest.pl config-file\n";
36212545eb61SSteven Rostedt
36228d1491baSSteven Rostedtif ($#ARGV == 0) {
36238d1491baSSteven Rostedt    $ktest_config = $ARGV[0];
36248d1491baSSteven Rostedt    if (! -f $ktest_config) {
36258d1491baSSteven Rostedt	print "$ktest_config does not exist.\n";
362635ce5952SSteven Rostedt	if (!read_yn "Create it?") {
36278d1491baSSteven Rostedt	    exit 0;
36288d1491baSSteven Rostedt	}
36298d1491baSSteven Rostedt    }
36308d1491baSSteven Rostedt} else {
36318d1491baSSteven Rostedt    $ktest_config = "ktest.conf";
36328d1491baSSteven Rostedt}
36338d1491baSSteven Rostedt
36348d1491baSSteven Rostedtif (! -f $ktest_config) {
3635dbd3783bSSteven Rostedt    $newconfig = 1;
3636c4261d0fSSteven Rostedt    get_test_case;
36378d1491baSSteven Rostedt    open(OUT, ">$ktest_config") or die "Can not create $ktest_config";
36388d1491baSSteven Rostedt    print OUT << "EOF"
36398d1491baSSteven Rostedt# Generated by ktest.pl
36408d1491baSSteven Rostedt#
36410e7a22deSSteven Rostedt
36420e7a22deSSteven Rostedt# PWD is a ktest.pl variable that will result in the process working
36430e7a22deSSteven Rostedt# directory that ktest.pl is executed in.
36440e7a22deSSteven Rostedt
36450e7a22deSSteven Rostedt# THIS_DIR is automatically assigned the PWD of the path that generated
36460e7a22deSSteven Rostedt# the config file. It is best to use this variable when assigning other
36470e7a22deSSteven Rostedt# directory paths within this directory. This allows you to easily
36480e7a22deSSteven Rostedt# move the test cases to other locations or to other machines.
36490e7a22deSSteven Rostedt#
36500e7a22deSSteven RostedtTHIS_DIR := $variable{"PWD"}
36510e7a22deSSteven Rostedt
36528d1491baSSteven Rostedt# Define each test with TEST_START
36538d1491baSSteven Rostedt# The config options below it will override the defaults
36548d1491baSSteven RostedtTEST_START
3655c4261d0fSSteven RostedtTEST_TYPE = $default{"TEST_TYPE"}
36568d1491baSSteven Rostedt
36578d1491baSSteven RostedtDEFAULTS
36588d1491baSSteven RostedtEOF
36598d1491baSSteven Rostedt;
36608d1491baSSteven Rostedt    close(OUT);
36618d1491baSSteven Rostedt}
36628d1491baSSteven Rostedtread_config $ktest_config;
36638d1491baSSteven Rostedt
366423715c3cSSteven Rostedtif (defined($opt{"LOG_FILE"})) {
366523715c3cSSteven Rostedt    $opt{"LOG_FILE"} = eval_option($opt{"LOG_FILE"}, -1);
366623715c3cSSteven Rostedt}
366723715c3cSSteven Rostedt
36688d1491baSSteven Rostedt# Append any configs entered in manually to the config file.
36698d1491baSSteven Rostedtmy @new_configs = keys %entered_configs;
36708d1491baSSteven Rostedtif ($#new_configs >= 0) {
36718d1491baSSteven Rostedt    print "\nAppending entered in configs to $ktest_config\n";
36728d1491baSSteven Rostedt    open(OUT, ">>$ktest_config") or die "Can not append to $ktest_config";
36738d1491baSSteven Rostedt    foreach my $config (@new_configs) {
36748d1491baSSteven Rostedt	print OUT "$config = $entered_configs{$config}\n";
36750e7a22deSSteven Rostedt	$opt{$config} = process_variables($entered_configs{$config});
36768d1491baSSteven Rostedt    }
36778d1491baSSteven Rostedt}
36782545eb61SSteven Rostedt
36792b7d9b21SSteven Rostedtif ($opt{"CLEAR_LOG"} && defined($opt{"LOG_FILE"})) {
36802b7d9b21SSteven Rostedt    unlink $opt{"LOG_FILE"};
36812b7d9b21SSteven Rostedt}
36822545eb61SSteven Rostedt
36832b7d9b21SSteven Rostedtdoprint "\n\nSTARTING AUTOMATED TESTS\n\n";
36842b7d9b21SSteven Rostedt
3685a57419b3SSteven Rostedtfor (my $i = 0, my $repeat = 1; $i <= $opt{"NUM_TESTS"}; $i += $repeat) {
3686a57419b3SSteven Rostedt
3687a57419b3SSteven Rostedt    if (!$i) {
3688a57419b3SSteven Rostedt	doprint "DEFAULT OPTIONS:\n";
3689a57419b3SSteven Rostedt    } else {
3690a57419b3SSteven Rostedt	doprint "\nTEST $i OPTIONS";
3691a57419b3SSteven Rostedt	if (defined($repeat_tests{$i})) {
3692a57419b3SSteven Rostedt	    $repeat = $repeat_tests{$i};
3693a57419b3SSteven Rostedt	    doprint " ITERATE $repeat";
3694a57419b3SSteven Rostedt	}
3695a57419b3SSteven Rostedt	doprint "\n";
3696a57419b3SSteven Rostedt    }
3697a57419b3SSteven Rostedt
36982b7d9b21SSteven Rostedt    foreach my $option (sort keys %opt) {
3699a57419b3SSteven Rostedt
3700a57419b3SSteven Rostedt	if ($option =~ /\[(\d+)\]$/) {
3701a57419b3SSteven Rostedt	    next if ($i != $1);
3702a57419b3SSteven Rostedt	} else {
3703a57419b3SSteven Rostedt	    next if ($i);
3704a57419b3SSteven Rostedt	}
3705a57419b3SSteven Rostedt
37062b7d9b21SSteven Rostedt	doprint "$option = $opt{$option}\n";
37072b7d9b21SSteven Rostedt    }
3708a57419b3SSteven Rostedt}
37092545eb61SSteven Rostedt
37102a62512bSSteven Rostedtsub __set_test_option {
37115a391fbfSSteven Rostedt    my ($name, $i) = @_;
37125a391fbfSSteven Rostedt
37135a391fbfSSteven Rostedt    my $option = "$name\[$i\]";
37145a391fbfSSteven Rostedt
37155a391fbfSSteven Rostedt    if (defined($opt{$option})) {
37165a391fbfSSteven Rostedt	return $opt{$option};
37175a391fbfSSteven Rostedt    }
37185a391fbfSSteven Rostedt
3719a57419b3SSteven Rostedt    foreach my $test (keys %repeat_tests) {
3720a57419b3SSteven Rostedt	if ($i >= $test &&
3721a57419b3SSteven Rostedt	    $i < $test + $repeat_tests{$test}) {
3722a57419b3SSteven Rostedt	    $option = "$name\[$test\]";
3723a57419b3SSteven Rostedt	    if (defined($opt{$option})) {
3724a57419b3SSteven Rostedt		return $opt{$option};
3725a57419b3SSteven Rostedt	    }
3726a57419b3SSteven Rostedt	}
3727a57419b3SSteven Rostedt    }
3728a57419b3SSteven Rostedt
37295a391fbfSSteven Rostedt    if (defined($opt{$name})) {
37305a391fbfSSteven Rostedt	return $opt{$name};
37315a391fbfSSteven Rostedt    }
37325a391fbfSSteven Rostedt
37335a391fbfSSteven Rostedt    return undef;
37345a391fbfSSteven Rostedt}
37355a391fbfSSteven Rostedt
37362a62512bSSteven Rostedtsub set_test_option {
37372a62512bSSteven Rostedt    my ($name, $i) = @_;
37382a62512bSSteven Rostedt
37392a62512bSSteven Rostedt    my $option = __set_test_option($name, $i);
37402a62512bSSteven Rostedt    return $option if (!defined($option));
37412a62512bSSteven Rostedt
374223715c3cSSteven Rostedt    return eval_option($option, $i);
37432a62512bSSteven Rostedt}
37442a62512bSSteven Rostedt
37452545eb61SSteven Rostedt# First we need to do is the builds
3746a75fececSSteven Rostedtfor (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
37472545eb61SSteven Rostedt
37484ab1cce5SSteven Rostedt    # Do not reboot on failing test options
37494ab1cce5SSteven Rostedt    $no_reboot = 1;
3750759a3cc6SSteven Rostedt    $reboot_success = 0;
37514ab1cce5SSteven Rostedt
3752683a3e64SSteven Rostedt    $have_version = 0;
3753683a3e64SSteven Rostedt
3754576f627cSSteven Rostedt    $iteration = $i;
3755576f627cSSteven Rostedt
3756c1434dccSSteven Rostedt    undef %force_config;
3757c1434dccSSteven Rostedt
3758a75fececSSteven Rostedt    my $makecmd = set_test_option("MAKE_CMD", $i);
3759a75fececSSteven Rostedt
37609cc9e091SSteven Rostedt    # Load all the options into their mapped variable names
37619cc9e091SSteven Rostedt    foreach my $opt (keys %option_map) {
37629cc9e091SSteven Rostedt	${$option_map{$opt}} = set_test_option($opt, $i);
37639cc9e091SSteven Rostedt    }
3764b5f4aea6SSteven Rostedt
376535ce5952SSteven Rostedt    $start_minconfig_defined = 1;
376635ce5952SSteven Rostedt
3767921ed4c7SSteven Rostedt    # The first test may override the PRE_KTEST option
3768921ed4c7SSteven Rostedt    if (defined($pre_ktest) && $i == 1) {
3769921ed4c7SSteven Rostedt	doprint "\n";
3770921ed4c7SSteven Rostedt	run_command $pre_ktest;
3771921ed4c7SSteven Rostedt    }
3772921ed4c7SSteven Rostedt
3773921ed4c7SSteven Rostedt    # Any test can override the POST_KTEST option
3774921ed4c7SSteven Rostedt    # The last test takes precedence.
3775921ed4c7SSteven Rostedt    if (defined($post_ktest)) {
3776921ed4c7SSteven Rostedt	$final_post_ktest = $post_ktest;
3777921ed4c7SSteven Rostedt    }
3778921ed4c7SSteven Rostedt
37794c4ab120SSteven Rostedt    if (!defined($start_minconfig)) {
378035ce5952SSteven Rostedt	$start_minconfig_defined = 0;
37814c4ab120SSteven Rostedt	$start_minconfig = $minconfig;
37824c4ab120SSteven Rostedt    }
37834c4ab120SSteven Rostedt
3784a75fececSSteven Rostedt    chdir $builddir || die "can't change directory to $builddir";
3785a75fececSSteven Rostedt
3786a908a665SAndrew Jones    foreach my $dir ($tmpdir, $outputdir) {
3787a908a665SAndrew Jones	if (!-d $dir) {
3788a908a665SAndrew Jones	    mkpath($dir) or
3789a908a665SAndrew Jones		die "can't create $dir";
3790a908a665SAndrew Jones	}
3791a75fececSSteven Rostedt    }
3792a75fececSSteven Rostedt
3793e48c5293SSteven Rostedt    $ENV{"SSH_USER"} = $ssh_user;
3794e48c5293SSteven Rostedt    $ENV{"MACHINE"} = $machine;
3795e48c5293SSteven Rostedt
3796a75fececSSteven Rostedt    $buildlog = "$tmpdir/buildlog-$machine";
3797a9dd5d63SRabin Vincent    $testlog = "$tmpdir/testlog-$machine";
3798a75fececSSteven Rostedt    $dmesg = "$tmpdir/dmesg-$machine";
3799a75fececSSteven Rostedt    $make = "$makecmd O=$outputdir";
380051ad1dd1SSteven Rostedt    $output_config = "$outputdir/.config";
3801a75fececSSteven Rostedt
3802bb8474b1SSteven Rostedt    if (!$buildonly) {
3803bb8474b1SSteven Rostedt	$target = "$ssh_user\@$machine";
3804a75fececSSteven Rostedt	if ($reboot_type eq "grub") {
3805576f627cSSteven Rostedt	    dodie "GRUB_MENU not defined" if (!defined($grub_menu));
3806a15ba913SSteven Rostedt	} elsif ($reboot_type eq "grub2") {
3807a15ba913SSteven Rostedt	    dodie "GRUB_MENU not defined" if (!defined($grub_menu));
3808a15ba913SSteven Rostedt	    dodie "GRUB_FILE not defined" if (!defined($grub_file));
38097786954cSSteven Rostedt	} elsif ($reboot_type eq "syslinux") {
38107786954cSSteven Rostedt	    dodie "SYSLINUX_LABEL not defined" if (!defined($syslinux_label));
3811a75fececSSteven Rostedt	}
3812bb8474b1SSteven Rostedt    }
3813a75fececSSteven Rostedt
3814a75fececSSteven Rostedt    my $run_type = $build_type;
3815a75fececSSteven Rostedt    if ($test_type eq "patchcheck") {
3816b5f4aea6SSteven Rostedt	$run_type = $patchcheck_type;
3817a75fececSSteven Rostedt    } elsif ($test_type eq "bisect") {
3818b5f4aea6SSteven Rostedt	$run_type = $bisect_type;
38190a05c769SSteven Rostedt    } elsif ($test_type eq "config_bisect") {
3820b5f4aea6SSteven Rostedt	$run_type = $config_bisect_type;
3821a75fececSSteven Rostedt    }
3822a75fececSSteven Rostedt
38234c4ab120SSteven Rostedt    if ($test_type eq "make_min_config") {
38244c4ab120SSteven Rostedt	$run_type = "";
38254c4ab120SSteven Rostedt    }
38264c4ab120SSteven Rostedt
3827a75fececSSteven Rostedt    # mistake in config file?
3828a75fececSSteven Rostedt    if (!defined($run_type)) {
3829a75fececSSteven Rostedt	$run_type = "ERROR";
3830a75fececSSteven Rostedt    }
38312545eb61SSteven Rostedt
3832e0a8742eSSteven Rostedt    my $installme = "";
3833e0a8742eSSteven Rostedt    $installme = " no_install" if ($no_install);
3834e0a8742eSSteven Rostedt
38352545eb61SSteven Rostedt    doprint "\n\n";
3836e0a8742eSSteven Rostedt    doprint "RUNNING TEST $i of $opt{NUM_TESTS} with option $test_type $run_type$installme\n\n";
38377faafbd6SSteven Rostedt
3838921ed4c7SSteven Rostedt    if (defined($pre_test)) {
3839921ed4c7SSteven Rostedt	run_command $pre_test;
3840921ed4c7SSteven Rostedt    }
3841921ed4c7SSteven Rostedt
38427faafbd6SSteven Rostedt    unlink $dmesg;
38437faafbd6SSteven Rostedt    unlink $buildlog;
3844a9dd5d63SRabin Vincent    unlink $testlog;
38452545eb61SSteven Rostedt
3846250bae8bSSteven Rostedt    if (defined($addconfig)) {
3847250bae8bSSteven Rostedt	my $min = $minconfig;
38482b7d9b21SSteven Rostedt	if (!defined($minconfig)) {
3849250bae8bSSteven Rostedt	    $min = "";
3850250bae8bSSteven Rostedt	}
3851250bae8bSSteven Rostedt	run_command "cat $addconfig $min > $tmpdir/add_config" or
38522b7d9b21SSteven Rostedt	    dodie "Failed to create temp config";
38539be2e6b5SSteven Rostedt	$minconfig = "$tmpdir/add_config";
38542b7d9b21SSteven Rostedt    }
38552b7d9b21SSteven Rostedt
38566c5ee0beSSteven Rostedt    if (defined($checkout)) {
38576c5ee0beSSteven Rostedt	run_command "git checkout $checkout" or
38586c5ee0beSSteven Rostedt	    die "failed to checkout $checkout";
38596c5ee0beSSteven Rostedt    }
38606c5ee0beSSteven Rostedt
3861759a3cc6SSteven Rostedt    $no_reboot = 0;
3862759a3cc6SSteven Rostedt
3863648a182cSSteven Rostedt    # A test may opt to not reboot the box
3864648a182cSSteven Rostedt    if ($reboot_on_success) {
3865759a3cc6SSteven Rostedt	$reboot_success = 1;
3866648a182cSSteven Rostedt    }
38674ab1cce5SSteven Rostedt
3868a75fececSSteven Rostedt    if ($test_type eq "bisect") {
38695f9b6cedSSteven Rostedt	bisect $i;
38705f9b6cedSSteven Rostedt	next;
38710a05c769SSteven Rostedt    } elsif ($test_type eq "config_bisect") {
38720a05c769SSteven Rostedt	config_bisect $i;
38730a05c769SSteven Rostedt	next;
3874a75fececSSteven Rostedt    } elsif ($test_type eq "patchcheck") {
38756c5ee0beSSteven Rostedt	patchcheck $i;
38766c5ee0beSSteven Rostedt	next;
38774c4ab120SSteven Rostedt    } elsif ($test_type eq "make_min_config") {
38784c4ab120SSteven Rostedt	make_min_config $i;
38794c4ab120SSteven Rostedt	next;
38805f9b6cedSSteven Rostedt    }
38815f9b6cedSSteven Rostedt
38827faafbd6SSteven Rostedt    if ($build_type ne "nobuild") {
38837faafbd6SSteven Rostedt	build $build_type or next;
38842545eb61SSteven Rostedt    }
38852545eb61SSteven Rostedt
3886cd8e368fSSteven Rostedt    if ($test_type eq "install") {
3887cd8e368fSSteven Rostedt	get_version;
3888cd8e368fSSteven Rostedt	install;
3889cd8e368fSSteven Rostedt	success $i;
3890cd8e368fSSteven Rostedt	next;
3891cd8e368fSSteven Rostedt    }
3892cd8e368fSSteven Rostedt
3893a75fececSSteven Rostedt    if ($test_type ne "build") {
38947faafbd6SSteven Rostedt	my $failed = 0;
3895ddf607e5SSteven Rostedt	start_monitor_and_boot or $failed = 1;
3896a75fececSSteven Rostedt
3897a75fececSSteven Rostedt	if (!$failed && $test_type ne "boot" && defined($run_test)) {
38987faafbd6SSteven Rostedt	    do_run_test or $failed = 1;
38995a391fbfSSteven Rostedt	}
39007faafbd6SSteven Rostedt	end_monitor;
39017faafbd6SSteven Rostedt	next if ($failed);
3902a75fececSSteven Rostedt    }
39035a391fbfSSteven Rostedt
39045f9b6cedSSteven Rostedt    success $i;
390575c3fda7SSteven Rostedt}
39062545eb61SSteven Rostedt
3907921ed4c7SSteven Rostedtif (defined($final_post_ktest)) {
3908921ed4c7SSteven Rostedt    run_command $final_post_ktest;
3909921ed4c7SSteven Rostedt}
3910921ed4c7SSteven Rostedt
39115c42fc5bSSteven Rostedtif ($opt{"POWEROFF_ON_SUCCESS"}) {
391275c3fda7SSteven Rostedt    halt;
3913759a3cc6SSteven Rostedt} elsif ($opt{"REBOOT_ON_SUCCESS"} && !do_not_reboot && $reboot_success) {
3914bc7c5803SSteven Rostedt    reboot_to_good;
3915648a182cSSteven Rostedt} elsif (defined($switch_to_good)) {
3916648a182cSSteven Rostedt    # still need to get to the good kernel
3917648a182cSSteven Rostedt    run_command $switch_to_good;
39185c42fc5bSSteven Rostedt}
391975c3fda7SSteven Rostedt
3920648a182cSSteven Rostedt
3921e48c5293SSteven Rostedtdoprint "\n    $successes of $opt{NUM_TESTS} tests were successful\n\n";
3922e48c5293SSteven Rostedt
39232545eb61SSteven Rostedtexit 0;
3924