xref: /openbmc/linux/tools/testing/ktest/ktest.pl (revision 5a5d8e4844987b6d8d64d583eb33dd926973a270)
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",
28*5a5d8e48SSatoru Takeuchi    "CLOSE_CONSOLE_SIGNAL"	=> "INT",
294f43e0dcSSteven Rostedt    "TIMEOUT"			=> 120,
304f43e0dcSSteven Rostedt    "TMP_DIR"			=> "/tmp/ktest/\${MACHINE}",
314f43e0dcSSteven Rostedt    "SLEEP_TIME"		=> 60,	# sleep time between tests
324f43e0dcSSteven Rostedt    "BUILD_NOCLEAN"		=> 0,
334f43e0dcSSteven Rostedt    "REBOOT_ON_ERROR"		=> 0,
344f43e0dcSSteven Rostedt    "POWEROFF_ON_ERROR"		=> 0,
354f43e0dcSSteven Rostedt    "REBOOT_ON_SUCCESS"		=> 1,
364f43e0dcSSteven Rostedt    "POWEROFF_ON_SUCCESS"	=> 0,
374f43e0dcSSteven Rostedt    "BUILD_OPTIONS"		=> "",
384f43e0dcSSteven Rostedt    "BISECT_SLEEP_TIME"		=> 60,   # sleep time between bisects
394f43e0dcSSteven Rostedt    "PATCHCHECK_SLEEP_TIME"	=> 60, # sleep time between patch checks
404f43e0dcSSteven Rostedt    "CLEAR_LOG"			=> 0,
414f43e0dcSSteven Rostedt    "BISECT_MANUAL"		=> 0,
424f43e0dcSSteven Rostedt    "BISECT_SKIP"		=> 1,
43ccc513b6SSteven Rostedt    "MIN_CONFIG_TYPE"		=> "boot",
444f43e0dcSSteven Rostedt    "SUCCESS_LINE"		=> "login:",
454f43e0dcSSteven Rostedt    "DETECT_TRIPLE_FAULT"	=> 1,
464f43e0dcSSteven Rostedt    "NO_INSTALL"		=> 0,
474f43e0dcSSteven Rostedt    "BOOTED_TIMEOUT"		=> 1,
484f43e0dcSSteven Rostedt    "DIE_ON_FAILURE"		=> 1,
494f43e0dcSSteven Rostedt    "SSH_EXEC"			=> "ssh \$SSH_USER\@\$MACHINE \$SSH_COMMAND",
504f43e0dcSSteven Rostedt    "SCP_TO_TARGET"		=> "scp \$SRC_FILE \$SSH_USER\@\$MACHINE:\$DST_FILE",
5102ad2617SSteven Rostedt    "SCP_TO_TARGET_INSTALL"	=> "\${SCP_TO_TARGET}",
524f43e0dcSSteven Rostedt    "REBOOT"			=> "ssh \$SSH_USER\@\$MACHINE reboot",
534f43e0dcSSteven Rostedt    "STOP_AFTER_SUCCESS"	=> 10,
544f43e0dcSSteven Rostedt    "STOP_AFTER_FAILURE"	=> 60,
554f43e0dcSSteven Rostedt    "STOP_TEST_AFTER"		=> 600,
56407b95b7SSteven Rostedt    "MAX_MONITOR_WAIT"		=> 1800,
57a15ba913SSteven Rostedt    "GRUB_REBOOT"		=> "grub2-reboot",
587786954cSSteven Rostedt    "SYSLINUX"			=> "extlinux",
597786954cSSteven Rostedt    "SYSLINUX_PATH"		=> "/boot/extlinux",
60600bbf0aSSteven Rostedt
61600bbf0aSSteven Rostedt# required, and we will ask users if they don't have them but we keep the default
62600bbf0aSSteven Rostedt# value something that is common.
634f43e0dcSSteven Rostedt    "REBOOT_TYPE"		=> "grub",
644f43e0dcSSteven Rostedt    "LOCALVERSION"		=> "-test",
654f43e0dcSSteven Rostedt    "SSH_USER"			=> "root",
664f43e0dcSSteven Rostedt    "BUILD_TARGET"	 	=> "arch/x86/boot/bzImage",
674f43e0dcSSteven Rostedt    "TARGET_IMAGE"		=> "/boot/vmlinuz-test",
689cc9e091SSteven Rostedt
699cc9e091SSteven Rostedt    "LOG_FILE"			=> undef,
709cc9e091SSteven Rostedt    "IGNORE_UNUSED"		=> 0,
714f43e0dcSSteven Rostedt);
722545eb61SSteven Rostedt
738d1491baSSteven Rostedtmy $ktest_config;
742545eb61SSteven Rostedtmy $version;
75683a3e64SSteven Rostedtmy $have_version = 0;
76a75fececSSteven Rostedtmy $machine;
77df5f7c66SSteven Rostedt (Red Hat)my $last_machine;
78e48c5293SSteven Rostedtmy $ssh_user;
79a75fececSSteven Rostedtmy $tmpdir;
80a75fececSSteven Rostedtmy $builddir;
81a75fececSSteven Rostedtmy $outputdir;
8251ad1dd1SSteven Rostedtmy $output_config;
83a75fececSSteven Rostedtmy $test_type;
847faafbd6SSteven Rostedtmy $build_type;
85a75fececSSteven Rostedtmy $build_options;
86921ed4c7SSteven Rostedtmy $final_post_ktest;
87921ed4c7SSteven Rostedtmy $pre_ktest;
88921ed4c7SSteven Rostedtmy $post_ktest;
89921ed4c7SSteven Rostedtmy $pre_test;
90921ed4c7SSteven Rostedtmy $post_test;
910bd6c1a3SSteven Rostedtmy $pre_build;
920bd6c1a3SSteven Rostedtmy $post_build;
930bd6c1a3SSteven Rostedtmy $pre_build_die;
940bd6c1a3SSteven Rostedtmy $post_build_die;
95a75fececSSteven Rostedtmy $reboot_type;
96a75fececSSteven Rostedtmy $reboot_script;
97a75fececSSteven Rostedtmy $power_cycle;
98e48c5293SSteven Rostedtmy $reboot;
99a75fececSSteven Rostedtmy $reboot_on_error;
100bc7c5803SSteven Rostedtmy $switch_to_good;
101bc7c5803SSteven Rostedtmy $switch_to_test;
102a75fececSSteven Rostedtmy $poweroff_on_error;
103648a182cSSteven Rostedtmy $reboot_on_success;
104a75fececSSteven Rostedtmy $die_on_failure;
105576f627cSSteven Rostedtmy $powercycle_after_reboot;
106576f627cSSteven Rostedtmy $poweroff_after_halt;
107407b95b7SSteven Rostedtmy $max_monitor_wait;
108e48c5293SSteven Rostedtmy $ssh_exec;
109e48c5293SSteven Rostedtmy $scp_to_target;
11002ad2617SSteven Rostedtmy $scp_to_target_install;
111a75fececSSteven Rostedtmy $power_off;
112a75fececSSteven Rostedtmy $grub_menu;
113752d9665SSteven Rostedt (Red Hat)my $last_grub_menu;
114a15ba913SSteven Rostedtmy $grub_file;
1152545eb61SSteven Rostedtmy $grub_number;
116a15ba913SSteven Rostedtmy $grub_reboot;
1177786954cSSteven Rostedtmy $syslinux;
1187786954cSSteven Rostedtmy $syslinux_path;
1197786954cSSteven Rostedtmy $syslinux_label;
1202545eb61SSteven Rostedtmy $target;
1212545eb61SSteven Rostedtmy $make;
122e5c2ec11SSteven Rostedtmy $pre_install;
1238b37ca8cSSteven Rostedtmy $post_install;
124e0a8742eSSteven Rostedtmy $no_install;
1255c42fc5bSSteven Rostedtmy $noclean;
1265f9b6cedSSteven Rostedtmy $minconfig;
1274c4ab120SSteven Rostedtmy $start_minconfig;
12835ce5952SSteven Rostedtmy $start_minconfig_defined;
1294c4ab120SSteven Rostedtmy $output_minconfig;
130ccc513b6SSteven Rostedtmy $minconfig_type;
13143de3316SSteven Rostedtmy $use_output_minconfig;
1324283b169SSteven Rostedt (Red Hat)my $warnings_file;
1334c4ab120SSteven Rostedtmy $ignore_config;
134be405f95SSteven Rostedtmy $ignore_errors;
1352b7d9b21SSteven Rostedtmy $addconfig;
1365f9b6cedSSteven Rostedtmy $in_bisect = 0;
137b5f4aea6SSteven Rostedtmy $bisect_bad_commit = "";
138d6ce2a0bSSteven Rostedtmy $reverse_bisect;
139c960bb9fSSteven Rostedtmy $bisect_manual;
140c23dca7cSSteven Rostedtmy $bisect_skip;
14130f75da5SSteven Rostedtmy $config_bisect_good;
142c5dacb88SSteven Rostedtmy $bisect_ret_good;
143c5dacb88SSteven Rostedtmy $bisect_ret_bad;
144c5dacb88SSteven Rostedtmy $bisect_ret_skip;
145c5dacb88SSteven Rostedtmy $bisect_ret_abort;
146c5dacb88SSteven Rostedtmy $bisect_ret_default;
1476c5ee0beSSteven Rostedtmy $in_patchcheck = 0;
1485a391fbfSSteven Rostedtmy $run_test;
1496c5ee0beSSteven Rostedtmy $redirect;
1507faafbd6SSteven Rostedtmy $buildlog;
151a9dd5d63SRabin Vincentmy $testlog;
1527faafbd6SSteven Rostedtmy $dmesg;
1537faafbd6SSteven Rostedtmy $monitor_fp;
1547faafbd6SSteven Rostedtmy $monitor_pid;
1557faafbd6SSteven Rostedtmy $monitor_cnt = 0;
156a75fececSSteven Rostedtmy $sleep_time;
157a75fececSSteven Rostedtmy $bisect_sleep_time;
15827d934b2SSteven Rostedtmy $patchcheck_sleep_time;
1591990207dSSteven Rostedtmy $ignore_warnings;
160a75fececSSteven Rostedtmy $store_failures;
161de5b6e3bSRabin Vincentmy $store_successes;
1629064af52SSteven Rostedtmy $test_name;
163a75fececSSteven Rostedtmy $timeout;
164a75fececSSteven Rostedtmy $booted_timeout;
165f1a5b962SSteven Rostedtmy $detect_triplefault;
166a75fececSSteven Rostedtmy $console;
167*5a5d8e48SSatoru Takeuchimy $close_console_signal;
1682b803365SSteven Rostedtmy $reboot_success_line;
169a75fececSSteven Rostedtmy $success_line;
1701c8a617aSSteven Rostedtmy $stop_after_success;
1711c8a617aSSteven Rostedtmy $stop_after_failure;
1722d01b26aSSteven Rostedtmy $stop_test_after;
173a75fececSSteven Rostedtmy $build_target;
174a75fececSSteven Rostedtmy $target_image;
175b5f4aea6SSteven Rostedtmy $checkout;
176a75fececSSteven Rostedtmy $localversion;
177576f627cSSteven Rostedtmy $iteration = 0;
178e48c5293SSteven Rostedtmy $successes = 0;
1792545eb61SSteven Rostedt
180b5f4aea6SSteven Rostedtmy $bisect_good;
181b5f4aea6SSteven Rostedtmy $bisect_bad;
182b5f4aea6SSteven Rostedtmy $bisect_type;
183b5f4aea6SSteven Rostedtmy $bisect_start;
184b5f4aea6SSteven Rostedtmy $bisect_replay;
185b5f4aea6SSteven Rostedtmy $bisect_files;
186b5f4aea6SSteven Rostedtmy $bisect_reverse;
187b5f4aea6SSteven Rostedtmy $bisect_check;
188b5f4aea6SSteven Rostedt
189b5f4aea6SSteven Rostedtmy $config_bisect;
190b5f4aea6SSteven Rostedtmy $config_bisect_type;
191b0918612SSteven Rostedtmy $config_bisect_check;
192b5f4aea6SSteven Rostedt
193b5f4aea6SSteven Rostedtmy $patchcheck_type;
194b5f4aea6SSteven Rostedtmy $patchcheck_start;
195b5f4aea6SSteven Rostedtmy $patchcheck_end;
196b5f4aea6SSteven Rostedt
197165708b2SSteven Rostedt# set when a test is something other that just building or install
198bb8474b1SSteven Rostedt# which would require more options.
199bb8474b1SSteven Rostedtmy $buildonly = 1;
200bb8474b1SSteven Rostedt
2014283b169SSteven Rostedt (Red Hat)# tell build not to worry about warnings, even when WARNINGS_FILE is set
2024283b169SSteven Rostedt (Red Hat)my $warnings_ok = 0;
2034283b169SSteven Rostedt (Red Hat)
204dbd3783bSSteven Rostedt# set when creating a new config
205dbd3783bSSteven Rostedtmy $newconfig = 0;
206dbd3783bSSteven Rostedt
2078d1491baSSteven Rostedtmy %entered_configs;
2088d1491baSSteven Rostedtmy %config_help;
20977d942ceSSteven Rostedtmy %variable;
210cf79fab6SSteven Rostedt
211cf79fab6SSteven Rostedt# force_config is the list of configs that we force enabled (or disabled)
212cf79fab6SSteven Rostedt# in a .config file. The MIN_CONFIG and ADD_CONFIG configs.
213fcb3f16aSSteven Rostedtmy %force_config;
2148d1491baSSteven Rostedt
2154ab1cce5SSteven Rostedt# do not force reboots on config problems
2164ab1cce5SSteven Rostedtmy $no_reboot = 1;
2174ab1cce5SSteven Rostedt
218759a3cc6SSteven Rostedt# reboot on success
219759a3cc6SSteven Rostedtmy $reboot_success = 0;
220759a3cc6SSteven Rostedt
2219cc9e091SSteven Rostedtmy %option_map = (
2229cc9e091SSteven Rostedt    "MACHINE"			=> \$machine,
2239cc9e091SSteven Rostedt    "SSH_USER"			=> \$ssh_user,
2249cc9e091SSteven Rostedt    "TMP_DIR"			=> \$tmpdir,
2259cc9e091SSteven Rostedt    "OUTPUT_DIR"		=> \$outputdir,
2269cc9e091SSteven Rostedt    "BUILD_DIR"			=> \$builddir,
2279cc9e091SSteven Rostedt    "TEST_TYPE"			=> \$test_type,
228921ed4c7SSteven Rostedt    "PRE_KTEST"			=> \$pre_ktest,
229921ed4c7SSteven Rostedt    "POST_KTEST"		=> \$post_ktest,
230921ed4c7SSteven Rostedt    "PRE_TEST"			=> \$pre_test,
231921ed4c7SSteven Rostedt    "POST_TEST"			=> \$post_test,
2329cc9e091SSteven Rostedt    "BUILD_TYPE"		=> \$build_type,
2339cc9e091SSteven Rostedt    "BUILD_OPTIONS"		=> \$build_options,
2349cc9e091SSteven Rostedt    "PRE_BUILD"			=> \$pre_build,
2359cc9e091SSteven Rostedt    "POST_BUILD"		=> \$post_build,
2369cc9e091SSteven Rostedt    "PRE_BUILD_DIE"		=> \$pre_build_die,
2379cc9e091SSteven Rostedt    "POST_BUILD_DIE"		=> \$post_build_die,
2389cc9e091SSteven Rostedt    "POWER_CYCLE"		=> \$power_cycle,
2399cc9e091SSteven Rostedt    "REBOOT"			=> \$reboot,
2409cc9e091SSteven Rostedt    "BUILD_NOCLEAN"		=> \$noclean,
2419cc9e091SSteven Rostedt    "MIN_CONFIG"		=> \$minconfig,
2429cc9e091SSteven Rostedt    "OUTPUT_MIN_CONFIG"		=> \$output_minconfig,
2439cc9e091SSteven Rostedt    "START_MIN_CONFIG"		=> \$start_minconfig,
244ccc513b6SSteven Rostedt    "MIN_CONFIG_TYPE"		=> \$minconfig_type,
24543de3316SSteven Rostedt    "USE_OUTPUT_MIN_CONFIG"	=> \$use_output_minconfig,
2464283b169SSteven Rostedt (Red Hat)    "WARNINGS_FILE"		=> \$warnings_file,
2479cc9e091SSteven Rostedt    "IGNORE_CONFIG"		=> \$ignore_config,
2489cc9e091SSteven Rostedt    "TEST"			=> \$run_test,
2499cc9e091SSteven Rostedt    "ADD_CONFIG"		=> \$addconfig,
2509cc9e091SSteven Rostedt    "REBOOT_TYPE"		=> \$reboot_type,
2519cc9e091SSteven Rostedt    "GRUB_MENU"			=> \$grub_menu,
252a15ba913SSteven Rostedt    "GRUB_FILE"			=> \$grub_file,
253a15ba913SSteven Rostedt    "GRUB_REBOOT"		=> \$grub_reboot,
2547786954cSSteven Rostedt    "SYSLINUX"			=> \$syslinux,
2557786954cSSteven Rostedt    "SYSLINUX_PATH"		=> \$syslinux_path,
2567786954cSSteven Rostedt    "SYSLINUX_LABEL"		=> \$syslinux_label,
257e5c2ec11SSteven Rostedt    "PRE_INSTALL"		=> \$pre_install,
2589cc9e091SSteven Rostedt    "POST_INSTALL"		=> \$post_install,
2599cc9e091SSteven Rostedt    "NO_INSTALL"		=> \$no_install,
2609cc9e091SSteven Rostedt    "REBOOT_SCRIPT"		=> \$reboot_script,
2619cc9e091SSteven Rostedt    "REBOOT_ON_ERROR"		=> \$reboot_on_error,
2629cc9e091SSteven Rostedt    "SWITCH_TO_GOOD"		=> \$switch_to_good,
2639cc9e091SSteven Rostedt    "SWITCH_TO_TEST"		=> \$switch_to_test,
2649cc9e091SSteven Rostedt    "POWEROFF_ON_ERROR"		=> \$poweroff_on_error,
265648a182cSSteven Rostedt    "REBOOT_ON_SUCCESS"		=> \$reboot_on_success,
2669cc9e091SSteven Rostedt    "DIE_ON_FAILURE"		=> \$die_on_failure,
2679cc9e091SSteven Rostedt    "POWER_OFF"			=> \$power_off,
2689cc9e091SSteven Rostedt    "POWERCYCLE_AFTER_REBOOT"	=> \$powercycle_after_reboot,
2699cc9e091SSteven Rostedt    "POWEROFF_AFTER_HALT"	=> \$poweroff_after_halt,
270407b95b7SSteven Rostedt    "MAX_MONITOR_WAIT"		=> \$max_monitor_wait,
2719cc9e091SSteven Rostedt    "SLEEP_TIME"		=> \$sleep_time,
2729cc9e091SSteven Rostedt    "BISECT_SLEEP_TIME"		=> \$bisect_sleep_time,
2739cc9e091SSteven Rostedt    "PATCHCHECK_SLEEP_TIME"	=> \$patchcheck_sleep_time,
2749cc9e091SSteven Rostedt    "IGNORE_WARNINGS"		=> \$ignore_warnings,
275be405f95SSteven Rostedt    "IGNORE_ERRORS"		=> \$ignore_errors,
2769cc9e091SSteven Rostedt    "BISECT_MANUAL"		=> \$bisect_manual,
2779cc9e091SSteven Rostedt    "BISECT_SKIP"		=> \$bisect_skip,
2789cc9e091SSteven Rostedt    "CONFIG_BISECT_GOOD"	=> \$config_bisect_good,
2799cc9e091SSteven Rostedt    "BISECT_RET_GOOD"		=> \$bisect_ret_good,
2809cc9e091SSteven Rostedt    "BISECT_RET_BAD"		=> \$bisect_ret_bad,
2819cc9e091SSteven Rostedt    "BISECT_RET_SKIP"		=> \$bisect_ret_skip,
2829cc9e091SSteven Rostedt    "BISECT_RET_ABORT"		=> \$bisect_ret_abort,
2839cc9e091SSteven Rostedt    "BISECT_RET_DEFAULT"	=> \$bisect_ret_default,
2849cc9e091SSteven Rostedt    "STORE_FAILURES"		=> \$store_failures,
2859cc9e091SSteven Rostedt    "STORE_SUCCESSES"		=> \$store_successes,
2869cc9e091SSteven Rostedt    "TEST_NAME"			=> \$test_name,
2879cc9e091SSteven Rostedt    "TIMEOUT"			=> \$timeout,
2889cc9e091SSteven Rostedt    "BOOTED_TIMEOUT"		=> \$booted_timeout,
2899cc9e091SSteven Rostedt    "CONSOLE"			=> \$console,
290*5a5d8e48SSatoru Takeuchi    "CLOSE_CONSOLE_SIGNAL"	=> \$close_console_signal,
2919cc9e091SSteven Rostedt    "DETECT_TRIPLE_FAULT"	=> \$detect_triplefault,
2929cc9e091SSteven Rostedt    "SUCCESS_LINE"		=> \$success_line,
2939cc9e091SSteven Rostedt    "REBOOT_SUCCESS_LINE"	=> \$reboot_success_line,
2949cc9e091SSteven Rostedt    "STOP_AFTER_SUCCESS"	=> \$stop_after_success,
2959cc9e091SSteven Rostedt    "STOP_AFTER_FAILURE"	=> \$stop_after_failure,
2969cc9e091SSteven Rostedt    "STOP_TEST_AFTER"		=> \$stop_test_after,
2979cc9e091SSteven Rostedt    "BUILD_TARGET"		=> \$build_target,
2989cc9e091SSteven Rostedt    "SSH_EXEC"			=> \$ssh_exec,
2999cc9e091SSteven Rostedt    "SCP_TO_TARGET"		=> \$scp_to_target,
30002ad2617SSteven Rostedt    "SCP_TO_TARGET_INSTALL"	=> \$scp_to_target_install,
3019cc9e091SSteven Rostedt    "CHECKOUT"			=> \$checkout,
3029cc9e091SSteven Rostedt    "TARGET_IMAGE"		=> \$target_image,
3039cc9e091SSteven Rostedt    "LOCALVERSION"		=> \$localversion,
3049cc9e091SSteven Rostedt
3059cc9e091SSteven Rostedt    "BISECT_GOOD"		=> \$bisect_good,
3069cc9e091SSteven Rostedt    "BISECT_BAD"		=> \$bisect_bad,
3079cc9e091SSteven Rostedt    "BISECT_TYPE"		=> \$bisect_type,
3089cc9e091SSteven Rostedt    "BISECT_START"		=> \$bisect_start,
3099cc9e091SSteven Rostedt    "BISECT_REPLAY"		=> \$bisect_replay,
3109cc9e091SSteven Rostedt    "BISECT_FILES"		=> \$bisect_files,
3119cc9e091SSteven Rostedt    "BISECT_REVERSE"		=> \$bisect_reverse,
3129cc9e091SSteven Rostedt    "BISECT_CHECK"		=> \$bisect_check,
3139cc9e091SSteven Rostedt
3149cc9e091SSteven Rostedt    "CONFIG_BISECT"		=> \$config_bisect,
3159cc9e091SSteven Rostedt    "CONFIG_BISECT_TYPE"	=> \$config_bisect_type,
316b0918612SSteven Rostedt    "CONFIG_BISECT_CHECK"	=> \$config_bisect_check,
3179cc9e091SSteven Rostedt
3189cc9e091SSteven Rostedt    "PATCHCHECK_TYPE"		=> \$patchcheck_type,
3199cc9e091SSteven Rostedt    "PATCHCHECK_START"		=> \$patchcheck_start,
3209cc9e091SSteven Rostedt    "PATCHCHECK_END"		=> \$patchcheck_end,
3219cc9e091SSteven Rostedt);
3229cc9e091SSteven Rostedt
3239cc9e091SSteven Rostedt# Options may be used by other options, record them.
3249cc9e091SSteven Rostedtmy %used_options;
3259cc9e091SSteven Rostedt
3267bf51073SSteven Rostedt# default variables that can be used
3277bf51073SSteven Rostedtchomp ($variable{"PWD"} = `pwd`);
3287bf51073SSteven Rostedt
3298d1491baSSteven Rostedt$config_help{"MACHINE"} = << "EOF"
3308d1491baSSteven Rostedt The machine hostname that you will test.
331bb8474b1SSteven Rostedt For build only tests, it is still needed to differentiate log files.
3328d1491baSSteven RostedtEOF
3338d1491baSSteven Rostedt    ;
3348d1491baSSteven Rostedt$config_help{"SSH_USER"} = << "EOF"
3358d1491baSSteven Rostedt The box is expected to have ssh on normal bootup, provide the user
3368d1491baSSteven Rostedt  (most likely root, since you need privileged operations)
3378d1491baSSteven RostedtEOF
3388d1491baSSteven Rostedt    ;
3398d1491baSSteven Rostedt$config_help{"BUILD_DIR"} = << "EOF"
3408d1491baSSteven Rostedt The directory that contains the Linux source code (full path).
3410e7a22deSSteven Rostedt You can use \${PWD} that will be the path where ktest.pl is run, or use
3420e7a22deSSteven Rostedt \${THIS_DIR} which is assigned \${PWD} but may be changed later.
3438d1491baSSteven RostedtEOF
3448d1491baSSteven Rostedt    ;
3458d1491baSSteven Rostedt$config_help{"OUTPUT_DIR"} = << "EOF"
3468d1491baSSteven Rostedt The directory that the objects will be built (full path).
3478d1491baSSteven Rostedt (can not be same as BUILD_DIR)
3480e7a22deSSteven Rostedt You can use \${PWD} that will be the path where ktest.pl is run, or use
3490e7a22deSSteven Rostedt \${THIS_DIR} which is assigned \${PWD} but may be changed later.
3508d1491baSSteven RostedtEOF
3518d1491baSSteven Rostedt    ;
3528d1491baSSteven Rostedt$config_help{"BUILD_TARGET"} = << "EOF"
3538d1491baSSteven Rostedt The location of the compiled file to copy to the target.
3548d1491baSSteven Rostedt (relative to OUTPUT_DIR)
3558d1491baSSteven RostedtEOF
3568d1491baSSteven Rostedt    ;
357dbd3783bSSteven Rostedt$config_help{"BUILD_OPTIONS"} = << "EOF"
358dbd3783bSSteven Rostedt Options to add to \"make\" when building.
359dbd3783bSSteven Rostedt i.e.  -j20
360dbd3783bSSteven RostedtEOF
361dbd3783bSSteven Rostedt    ;
3628d1491baSSteven Rostedt$config_help{"TARGET_IMAGE"} = << "EOF"
3638d1491baSSteven Rostedt The place to put your image on the test machine.
3648d1491baSSteven RostedtEOF
3658d1491baSSteven Rostedt    ;
3668d1491baSSteven Rostedt$config_help{"POWER_CYCLE"} = << "EOF"
3678d1491baSSteven Rostedt A script or command to reboot the box.
3688d1491baSSteven Rostedt
3698d1491baSSteven Rostedt Here is a digital loggers power switch example
3708d1491baSSteven Rostedt POWER_CYCLE = wget --no-proxy -O /dev/null -q  --auth-no-challenge 'http://admin:admin\@power/outlet?5=CCL'
3718d1491baSSteven Rostedt
3728d1491baSSteven Rostedt Here is an example to reboot a virtual box on the current host
3738d1491baSSteven Rostedt with the name "Guest".
3748d1491baSSteven Rostedt POWER_CYCLE = virsh destroy Guest; sleep 5; virsh start Guest
3758d1491baSSteven RostedtEOF
3768d1491baSSteven Rostedt    ;
3778d1491baSSteven Rostedt$config_help{"CONSOLE"} = << "EOF"
3788d1491baSSteven Rostedt The script or command that reads the console
3798d1491baSSteven Rostedt
3808d1491baSSteven Rostedt  If you use ttywatch server, something like the following would work.
3818d1491baSSteven RostedtCONSOLE = nc -d localhost 3001
3828d1491baSSteven Rostedt
3838d1491baSSteven Rostedt For a virtual machine with guest name "Guest".
3848d1491baSSteven RostedtCONSOLE =  virsh console Guest
3858d1491baSSteven RostedtEOF
3868d1491baSSteven Rostedt    ;
3878d1491baSSteven Rostedt$config_help{"LOCALVERSION"} = << "EOF"
3888d1491baSSteven Rostedt Required version ending to differentiate the test
3898d1491baSSteven Rostedt from other linux builds on the system.
3908d1491baSSteven RostedtEOF
3918d1491baSSteven Rostedt    ;
3928d1491baSSteven Rostedt$config_help{"REBOOT_TYPE"} = << "EOF"
3938d1491baSSteven Rostedt Way to reboot the box to the test kernel.
3947786954cSSteven Rostedt Only valid options so far are "grub", "grub2", "syslinux", and "script".
3958d1491baSSteven Rostedt
3968d1491baSSteven Rostedt If you specify grub, it will assume grub version 1
3978d1491baSSteven Rostedt and will search in /boot/grub/menu.lst for the title \$GRUB_MENU
3988d1491baSSteven Rostedt and select that target to reboot to the kernel. If this is not
3998d1491baSSteven Rostedt your setup, then specify "script" and have a command or script
4008d1491baSSteven Rostedt specified in REBOOT_SCRIPT to boot to the target.
4018d1491baSSteven Rostedt
4028d1491baSSteven Rostedt The entry in /boot/grub/menu.lst must be entered in manually.
4038d1491baSSteven Rostedt The test will not modify that file.
404a15ba913SSteven Rostedt
405a15ba913SSteven Rostedt If you specify grub2, then you also need to specify both \$GRUB_MENU
406a15ba913SSteven Rostedt and \$GRUB_FILE.
4077786954cSSteven Rostedt
4087786954cSSteven Rostedt If you specify syslinux, then you may use SYSLINUX to define the syslinux
4097786954cSSteven Rostedt command (defaults to extlinux), and SYSLINUX_PATH to specify the path to
4107786954cSSteven Rostedt the syslinux install (defaults to /boot/extlinux). But you have to specify
4117786954cSSteven Rostedt SYSLINUX_LABEL to define the label to boot to for the test kernel.
4128d1491baSSteven RostedtEOF
4138d1491baSSteven Rostedt    ;
4148d1491baSSteven Rostedt$config_help{"GRUB_MENU"} = << "EOF"
4158d1491baSSteven Rostedt The grub title name for the test kernel to boot
416a15ba913SSteven Rostedt (Only mandatory if REBOOT_TYPE = grub or grub2)
4178d1491baSSteven Rostedt
4188d1491baSSteven Rostedt Note, ktest.pl will not update the grub menu.lst, you need to
4198d1491baSSteven Rostedt manually add an option for the test. ktest.pl will search
4208d1491baSSteven Rostedt the grub menu.lst for this option to find what kernel to
4218d1491baSSteven Rostedt reboot into.
4228d1491baSSteven Rostedt
4238d1491baSSteven Rostedt For example, if in the /boot/grub/menu.lst the test kernel title has:
4248d1491baSSteven Rostedt title Test Kernel
4258d1491baSSteven Rostedt kernel vmlinuz-test
4268d1491baSSteven Rostedt GRUB_MENU = Test Kernel
427a15ba913SSteven Rostedt
428a15ba913SSteven Rostedt For grub2, a search of \$GRUB_FILE is performed for the lines
429a15ba913SSteven Rostedt that begin with "menuentry". It will not detect submenus. The
430a15ba913SSteven Rostedt menu must be a non-nested menu. Add the quotes used in the menu
431a15ba913SSteven Rostedt to guarantee your selection, as the first menuentry with the content
432a15ba913SSteven Rostedt of \$GRUB_MENU that is found will be used.
433a15ba913SSteven RostedtEOF
434a15ba913SSteven Rostedt    ;
435a15ba913SSteven Rostedt$config_help{"GRUB_FILE"} = << "EOF"
436a15ba913SSteven Rostedt If grub2 is used, the full path for the grub.cfg file is placed
437a15ba913SSteven Rostedt here. Use something like /boot/grub2/grub.cfg to search.
4388d1491baSSteven RostedtEOF
4398d1491baSSteven Rostedt    ;
4407786954cSSteven Rostedt$config_help{"SYSLINUX_LABEL"} = << "EOF"
4417786954cSSteven Rostedt If syslinux is used, the label that boots the target kernel must
4427786954cSSteven Rostedt be specified with SYSLINUX_LABEL.
4437786954cSSteven RostedtEOF
4447786954cSSteven Rostedt    ;
4458d1491baSSteven Rostedt$config_help{"REBOOT_SCRIPT"} = << "EOF"
4468d1491baSSteven Rostedt A script to reboot the target into the test kernel
4478d1491baSSteven Rostedt (Only mandatory if REBOOT_TYPE = script)
4488d1491baSSteven RostedtEOF
4498d1491baSSteven Rostedt    ;
4508d1491baSSteven Rostedt
451dad98754SSteven Rostedtsub read_prompt {
452dad98754SSteven Rostedt    my ($cancel, $prompt) = @_;
45335ce5952SSteven Rostedt
45435ce5952SSteven Rostedt    my $ans;
45535ce5952SSteven Rostedt
45635ce5952SSteven Rostedt    for (;;) {
457dad98754SSteven Rostedt	if ($cancel) {
458dad98754SSteven Rostedt	    print "$prompt [y/n/C] ";
459dad98754SSteven Rostedt	} else {
46035ce5952SSteven Rostedt	    print "$prompt [Y/n] ";
461dad98754SSteven Rostedt	}
46235ce5952SSteven Rostedt	$ans = <STDIN>;
46335ce5952SSteven Rostedt	chomp $ans;
46435ce5952SSteven Rostedt	if ($ans =~ /^\s*$/) {
465dad98754SSteven Rostedt	    if ($cancel) {
466dad98754SSteven Rostedt		$ans = "c";
467dad98754SSteven Rostedt	    } else {
46835ce5952SSteven Rostedt		$ans = "y";
46935ce5952SSteven Rostedt	    }
470dad98754SSteven Rostedt	}
47135ce5952SSteven Rostedt	last if ($ans =~ /^y$/i || $ans =~ /^n$/i);
472dad98754SSteven Rostedt	if ($cancel) {
473dad98754SSteven Rostedt	    last if ($ans =~ /^c$/i);
474dad98754SSteven Rostedt	    print "Please answer either 'y', 'n' or 'c'.\n";
475dad98754SSteven Rostedt	} else {
47635ce5952SSteven Rostedt	    print "Please answer either 'y' or 'n'.\n";
47735ce5952SSteven Rostedt	}
478dad98754SSteven Rostedt    }
479dad98754SSteven Rostedt    if ($ans =~ /^c/i) {
480dad98754SSteven Rostedt	exit;
481dad98754SSteven Rostedt    }
48235ce5952SSteven Rostedt    if ($ans !~ /^y$/i) {
48335ce5952SSteven Rostedt	return 0;
48435ce5952SSteven Rostedt    }
48535ce5952SSteven Rostedt    return 1;
48635ce5952SSteven Rostedt}
4878d1491baSSteven Rostedt
488dad98754SSteven Rostedtsub read_yn {
489dad98754SSteven Rostedt    my ($prompt) = @_;
490dad98754SSteven Rostedt
491dad98754SSteven Rostedt    return read_prompt 0, $prompt;
492dad98754SSteven Rostedt}
493dad98754SSteven Rostedt
494dad98754SSteven Rostedtsub read_ync {
495dad98754SSteven Rostedt    my ($prompt) = @_;
496dad98754SSteven Rostedt
497dad98754SSteven Rostedt    return read_prompt 1, $prompt;
498dad98754SSteven Rostedt}
499dad98754SSteven Rostedt
5008d1491baSSteven Rostedtsub get_ktest_config {
5018d1491baSSteven Rostedt    my ($config) = @_;
502815e2bd7SSteven Rostedt    my $ans;
5038d1491baSSteven Rostedt
5048d1491baSSteven Rostedt    return if (defined($opt{$config}));
5058d1491baSSteven Rostedt
5068d1491baSSteven Rostedt    if (defined($config_help{$config})) {
5078d1491baSSteven Rostedt	print "\n";
5088d1491baSSteven Rostedt	print $config_help{$config};
5098d1491baSSteven Rostedt    }
5108d1491baSSteven Rostedt
5118d1491baSSteven Rostedt    for (;;) {
5128d1491baSSteven Rostedt	print "$config = ";
513dbd3783bSSteven Rostedt	if (defined($default{$config}) && length($default{$config})) {
5148d1491baSSteven Rostedt	    print "\[$default{$config}\] ";
5158d1491baSSteven Rostedt	}
516815e2bd7SSteven Rostedt	$ans = <STDIN>;
517815e2bd7SSteven Rostedt	$ans =~ s/^\s*(.*\S)\s*$/$1/;
518815e2bd7SSteven Rostedt	if ($ans =~ /^\s*$/) {
5198d1491baSSteven Rostedt	    if ($default{$config}) {
520815e2bd7SSteven Rostedt		$ans = $default{$config};
5218d1491baSSteven Rostedt	    } else {
5228d1491baSSteven Rostedt		print "Your answer can not be blank\n";
5238d1491baSSteven Rostedt		next;
5248d1491baSSteven Rostedt	    }
5258d1491baSSteven Rostedt	}
5260e7a22deSSteven Rostedt	$entered_configs{$config} = ${ans};
5278d1491baSSteven Rostedt	last;
5288d1491baSSteven Rostedt    }
5298d1491baSSteven Rostedt}
5308d1491baSSteven Rostedt
5318d1491baSSteven Rostedtsub get_ktest_configs {
5328d1491baSSteven Rostedt    get_ktest_config("MACHINE");
5338d1491baSSteven Rostedt    get_ktest_config("BUILD_DIR");
5348d1491baSSteven Rostedt    get_ktest_config("OUTPUT_DIR");
535bb8474b1SSteven Rostedt
536dbd3783bSSteven Rostedt    if ($newconfig) {
537dbd3783bSSteven Rostedt	get_ktest_config("BUILD_OPTIONS");
538dbd3783bSSteven Rostedt    }
539dbd3783bSSteven Rostedt
540bb8474b1SSteven Rostedt    # options required for other than just building a kernel
541bb8474b1SSteven Rostedt    if (!$buildonly) {
542165708b2SSteven Rostedt	get_ktest_config("POWER_CYCLE");
543165708b2SSteven Rostedt	get_ktest_config("CONSOLE");
544165708b2SSteven Rostedt    }
545165708b2SSteven Rostedt
546165708b2SSteven Rostedt    # options required for install and more
547165708b2SSteven Rostedt    if ($buildonly != 1) {
548bb8474b1SSteven Rostedt	get_ktest_config("SSH_USER");
5498d1491baSSteven Rostedt	get_ktest_config("BUILD_TARGET");
5508d1491baSSteven Rostedt	get_ktest_config("TARGET_IMAGE");
551bb8474b1SSteven Rostedt    }
552bb8474b1SSteven Rostedt
5538d1491baSSteven Rostedt    get_ktest_config("LOCALVERSION");
5548d1491baSSteven Rostedt
555bb8474b1SSteven Rostedt    return if ($buildonly);
556bb8474b1SSteven Rostedt
5578d1491baSSteven Rostedt    my $rtype = $opt{"REBOOT_TYPE"};
5588d1491baSSteven Rostedt
5598d1491baSSteven Rostedt    if (!defined($rtype)) {
5608d1491baSSteven Rostedt	if (!defined($opt{"GRUB_MENU"})) {
5618d1491baSSteven Rostedt	    get_ktest_config("REBOOT_TYPE");
5628d1491baSSteven Rostedt	    $rtype = $entered_configs{"REBOOT_TYPE"};
5638d1491baSSteven Rostedt	} else {
5648d1491baSSteven Rostedt	    $rtype = "grub";
5658d1491baSSteven Rostedt	}
5668d1491baSSteven Rostedt    }
5678d1491baSSteven Rostedt
5688d1491baSSteven Rostedt    if ($rtype eq "grub") {
5698d1491baSSteven Rostedt	get_ktest_config("GRUB_MENU");
5708d1491baSSteven Rostedt    }
571a15ba913SSteven Rostedt
572a15ba913SSteven Rostedt    if ($rtype eq "grub2") {
573a15ba913SSteven Rostedt	get_ktest_config("GRUB_MENU");
574a15ba913SSteven Rostedt	get_ktest_config("GRUB_FILE");
575a15ba913SSteven Rostedt    }
5767786954cSSteven Rostedt
5777786954cSSteven Rostedt    if ($rtype eq "syslinux") {
5787786954cSSteven Rostedt	get_ktest_config("SYSLINUX_LABEL");
5797786954cSSteven Rostedt    }
5808d1491baSSteven Rostedt}
5818d1491baSSteven Rostedt
58277d942ceSSteven Rostedtsub process_variables {
5838d735212SSteven Rostedt    my ($value, $remove_undef) = @_;
58477d942ceSSteven Rostedt    my $retval = "";
58577d942ceSSteven Rostedt
58677d942ceSSteven Rostedt    # We want to check for '\', and it is just easier
58777d942ceSSteven Rostedt    # to check the previous characet of '$' and not need
58877d942ceSSteven Rostedt    # to worry if '$' is the first character. By adding
58977d942ceSSteven Rostedt    # a space to $value, we can just check [^\\]\$ and
59077d942ceSSteven Rostedt    # it will still work.
59177d942ceSSteven Rostedt    $value = " $value";
59277d942ceSSteven Rostedt
59377d942ceSSteven Rostedt    while ($value =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) {
59477d942ceSSteven Rostedt	my $begin = $1;
59577d942ceSSteven Rostedt	my $var = $2;
59677d942ceSSteven Rostedt	my $end = $3;
59777d942ceSSteven Rostedt	# append beginning of value to retval
59877d942ceSSteven Rostedt	$retval = "$retval$begin";
59977d942ceSSteven Rostedt	if (defined($variable{$var})) {
60077d942ceSSteven Rostedt	    $retval = "$retval$variable{$var}";
6018d735212SSteven Rostedt	} elsif (defined($remove_undef) && $remove_undef) {
6028d735212SSteven Rostedt	    # for if statements, any variable that is not defined,
6038d735212SSteven Rostedt	    # we simple convert to 0
6048d735212SSteven Rostedt	    $retval = "${retval}0";
60577d942ceSSteven Rostedt	} else {
60677d942ceSSteven Rostedt	    # put back the origin piece.
60777d942ceSSteven Rostedt	    $retval = "$retval\$\{$var\}";
6089cc9e091SSteven Rostedt	    # This could be an option that is used later, save
6099cc9e091SSteven Rostedt	    # it so we don't warn if this option is not one of
6109cc9e091SSteven Rostedt	    # ktests options.
6119cc9e091SSteven Rostedt	    $used_options{$var} = 1;
61277d942ceSSteven Rostedt	}
61377d942ceSSteven Rostedt	$value = $end;
61477d942ceSSteven Rostedt    }
61577d942ceSSteven Rostedt    $retval = "$retval$value";
61677d942ceSSteven Rostedt
61777d942ceSSteven Rostedt    # remove the space added in the beginning
61877d942ceSSteven Rostedt    $retval =~ s/ //;
61977d942ceSSteven Rostedt
62077d942ceSSteven Rostedt    return "$retval"
62177d942ceSSteven Rostedt}
62277d942ceSSteven Rostedt
623a57419b3SSteven Rostedtsub set_value {
6243d1cc414SSteven Rostedt    my ($lvalue, $rvalue, $override, $overrides, $name) = @_;
6252545eb61SSteven Rostedt
626cad96669SSteven Rostedt    my $prvalue = process_variables($rvalue);
627cad96669SSteven Rostedt
628cad96669SSteven Rostedt    if ($buildonly && $lvalue =~ /^TEST_TYPE(\[.*\])?$/ && $prvalue ne "build") {
629bb8474b1SSteven Rostedt	# Note if a test is something other than build, then we
630bb8474b1SSteven Rostedt	# will need other manditory options.
631cad96669SSteven Rostedt	if ($prvalue ne "install") {
632319ab14fSSteven Rostedt (Red Hat)	    # for bisect, we need to check BISECT_TYPE
633319ab14fSSteven Rostedt (Red Hat)	    if ($prvalue ne "bisect") {
634319ab14fSSteven Rostedt (Red Hat)		$buildonly = 0;
635319ab14fSSteven Rostedt (Red Hat)	    }
636319ab14fSSteven Rostedt (Red Hat)	} else {
637319ab14fSSteven Rostedt (Red Hat)	    # install still limits some manditory options.
638319ab14fSSteven Rostedt (Red Hat)	    $buildonly = 2;
639319ab14fSSteven Rostedt (Red Hat)	}
640319ab14fSSteven Rostedt (Red Hat)    }
641319ab14fSSteven Rostedt (Red Hat)
642319ab14fSSteven Rostedt (Red Hat)    if ($buildonly && $lvalue =~ /^BISECT_TYPE(\[.*\])?$/ && $prvalue ne "build") {
643319ab14fSSteven Rostedt (Red Hat)	if ($prvalue ne "install") {
644bb8474b1SSteven Rostedt	    $buildonly = 0;
645165708b2SSteven Rostedt	} else {
646165708b2SSteven Rostedt	    # install still limits some manditory options.
647165708b2SSteven Rostedt	    $buildonly = 2;
648165708b2SSteven Rostedt	}
649bb8474b1SSteven Rostedt    }
650bb8474b1SSteven Rostedt
651a75fececSSteven Rostedt    if (defined($opt{$lvalue})) {
6523d1cc414SSteven Rostedt	if (!$override || defined(${$overrides}{$lvalue})) {
6533d1cc414SSteven Rostedt	    my $extra = "";
6543d1cc414SSteven Rostedt	    if ($override) {
6553d1cc414SSteven Rostedt		$extra = "In the same override section!\n";
6563d1cc414SSteven Rostedt	    }
6573d1cc414SSteven Rostedt	    die "$name: $.: Option $lvalue defined more than once!\n$extra";
6583d1cc414SSteven Rostedt	}
659cad96669SSteven Rostedt	${$overrides}{$lvalue} = $prvalue;
660a75fececSSteven Rostedt    }
66121a9679fSSteven Rostedt    if ($rvalue =~ /^\s*$/) {
66221a9679fSSteven Rostedt	delete $opt{$lvalue};
66321a9679fSSteven Rostedt    } else {
664cad96669SSteven Rostedt	$opt{$lvalue} = $prvalue;
66521a9679fSSteven Rostedt    }
6662545eb61SSteven Rostedt}
667a57419b3SSteven Rostedt
66877d942ceSSteven Rostedtsub set_variable {
66977d942ceSSteven Rostedt    my ($lvalue, $rvalue) = @_;
67077d942ceSSteven Rostedt
67177d942ceSSteven Rostedt    if ($rvalue =~ /^\s*$/) {
67277d942ceSSteven Rostedt	delete $variable{$lvalue};
67377d942ceSSteven Rostedt    } else {
67477d942ceSSteven Rostedt	$rvalue = process_variables($rvalue);
67577d942ceSSteven Rostedt	$variable{$lvalue} = $rvalue;
67677d942ceSSteven Rostedt    }
67777d942ceSSteven Rostedt}
67877d942ceSSteven Rostedt
679ab7a3f52SSteven Rostedtsub process_compare {
680ab7a3f52SSteven Rostedt    my ($lval, $cmp, $rval) = @_;
681ab7a3f52SSteven Rostedt
682ab7a3f52SSteven Rostedt    # remove whitespace
683ab7a3f52SSteven Rostedt
684ab7a3f52SSteven Rostedt    $lval =~ s/^\s*//;
685ab7a3f52SSteven Rostedt    $lval =~ s/\s*$//;
686ab7a3f52SSteven Rostedt
687ab7a3f52SSteven Rostedt    $rval =~ s/^\s*//;
688ab7a3f52SSteven Rostedt    $rval =~ s/\s*$//;
689ab7a3f52SSteven Rostedt
690ab7a3f52SSteven Rostedt    if ($cmp eq "==") {
691ab7a3f52SSteven Rostedt	return $lval eq $rval;
692ab7a3f52SSteven Rostedt    } elsif ($cmp eq "!=") {
693ab7a3f52SSteven Rostedt	return $lval ne $rval;
6948fddbe9bSSteven Rostedt    } elsif ($cmp eq "=~") {
6958fddbe9bSSteven Rostedt	return $lval =~ m/$rval/;
6968fddbe9bSSteven Rostedt    } elsif ($cmp eq "!~") {
6978fddbe9bSSteven Rostedt	return $lval !~ m/$rval/;
698ab7a3f52SSteven Rostedt    }
699ab7a3f52SSteven Rostedt
700ab7a3f52SSteven Rostedt    my $statement = "$lval $cmp $rval";
701ab7a3f52SSteven Rostedt    my $ret = eval $statement;
702ab7a3f52SSteven Rostedt
703ab7a3f52SSteven Rostedt    # $@ stores error of eval
704ab7a3f52SSteven Rostedt    if ($@) {
705ab7a3f52SSteven Rostedt	return -1;
706ab7a3f52SSteven Rostedt    }
707ab7a3f52SSteven Rostedt
708ab7a3f52SSteven Rostedt    return $ret;
709ab7a3f52SSteven Rostedt}
710ab7a3f52SSteven Rostedt
7119900b5dcSSteven Rostedtsub value_defined {
7129900b5dcSSteven Rostedt    my ($val) = @_;
7139900b5dcSSteven Rostedt
7149900b5dcSSteven Rostedt    return defined($variable{$2}) ||
7159900b5dcSSteven Rostedt	defined($opt{$2});
7169900b5dcSSteven Rostedt}
7179900b5dcSSteven Rostedt
7188d735212SSteven Rostedtmy $d = 0;
7198d735212SSteven Rostedtsub process_expression {
7208d735212SSteven Rostedt    my ($name, $val) = @_;
72145d73a5dSSteven Rostedt
7228d735212SSteven Rostedt    my $c = $d++;
7238d735212SSteven Rostedt
7248d735212SSteven Rostedt    while ($val =~ s/\(([^\(]*?)\)/\&\&\&\&VAL\&\&\&\&/) {
7258d735212SSteven Rostedt	my $express = $1;
7268d735212SSteven Rostedt
7278d735212SSteven Rostedt	if (process_expression($name, $express)) {
7288d735212SSteven Rostedt	    $val =~ s/\&\&\&\&VAL\&\&\&\&/ 1 /;
7298d735212SSteven Rostedt	} else {
7308d735212SSteven Rostedt	    $val =~ s/\&\&\&\&VAL\&\&\&\&/ 0 /;
7318d735212SSteven Rostedt	}
7328d735212SSteven Rostedt    }
7338d735212SSteven Rostedt
7348d735212SSteven Rostedt    $d--;
7358d735212SSteven Rostedt    my $OR = "\\|\\|";
7368d735212SSteven Rostedt    my $AND = "\\&\\&";
7378d735212SSteven Rostedt
7388d735212SSteven Rostedt    while ($val =~ s/^(.*?)($OR|$AND)//) {
7398d735212SSteven Rostedt	my $express = $1;
7408d735212SSteven Rostedt	my $op = $2;
7418d735212SSteven Rostedt
7428d735212SSteven Rostedt	if (process_expression($name, $express)) {
7438d735212SSteven Rostedt	    if ($op eq "||") {
7448d735212SSteven Rostedt		return 1;
7458d735212SSteven Rostedt	    }
7468d735212SSteven Rostedt	} else {
7478d735212SSteven Rostedt	    if ($op eq "&&") {
7488d735212SSteven Rostedt		return 0;
7498d735212SSteven Rostedt	    }
7508d735212SSteven Rostedt	}
7518d735212SSteven Rostedt    }
75245d73a5dSSteven Rostedt
7538fddbe9bSSteven Rostedt    if ($val =~ /(.*)(==|\!=|>=|<=|>|<|=~|\!~)(.*)/) {
754ab7a3f52SSteven Rostedt	my $ret = process_compare($1, $2, $3);
755ab7a3f52SSteven Rostedt	if ($ret < 0) {
756ab7a3f52SSteven Rostedt	    die "$name: $.: Unable to process comparison\n";
757ab7a3f52SSteven Rostedt	}
758ab7a3f52SSteven Rostedt	return $ret;
759ab7a3f52SSteven Rostedt    }
760ab7a3f52SSteven Rostedt
7619900b5dcSSteven Rostedt    if ($val =~ /^\s*(NOT\s*)?DEFINED\s+(\S+)\s*$/) {
7629900b5dcSSteven Rostedt	if (defined $1) {
7639900b5dcSSteven Rostedt	    return !value_defined($2);
7649900b5dcSSteven Rostedt	} else {
7659900b5dcSSteven Rostedt	    return value_defined($2);
7669900b5dcSSteven Rostedt	}
7679900b5dcSSteven Rostedt    }
7689900b5dcSSteven Rostedt
76945d73a5dSSteven Rostedt    if ($val =~ /^\s*0\s*$/) {
77045d73a5dSSteven Rostedt	return 0;
77145d73a5dSSteven Rostedt    } elsif ($val =~ /^\s*\d+\s*$/) {
77245d73a5dSSteven Rostedt	return 1;
77345d73a5dSSteven Rostedt    }
77445d73a5dSSteven Rostedt
7759900b5dcSSteven Rostedt    die ("$name: $.: Undefined content $val in if statement\n");
7768d735212SSteven Rostedt}
7778d735212SSteven Rostedt
7788d735212SSteven Rostedtsub process_if {
7798d735212SSteven Rostedt    my ($name, $value) = @_;
7808d735212SSteven Rostedt
7818d735212SSteven Rostedt    # Convert variables and replace undefined ones with 0
7828d735212SSteven Rostedt    my $val = process_variables($value, 1);
7838d735212SSteven Rostedt    my $ret = process_expression $name, $val;
7848d735212SSteven Rostedt
7858d735212SSteven Rostedt    return $ret;
78645d73a5dSSteven Rostedt}
78745d73a5dSSteven Rostedt
7882ed3b161SSteven Rostedtsub __read_config {
7892ed3b161SSteven Rostedt    my ($config, $current_test_num) = @_;
790a57419b3SSteven Rostedt
7912ed3b161SSteven Rostedt    my $in;
7922ed3b161SSteven Rostedt    open($in, $config) || die "can't read file $config";
793a57419b3SSteven Rostedt
794a57419b3SSteven Rostedt    my $name = $config;
795a57419b3SSteven Rostedt    $name =~ s,.*/(.*),$1,;
796a57419b3SSteven Rostedt
7972ed3b161SSteven Rostedt    my $test_num = $$current_test_num;
798a57419b3SSteven Rostedt    my $default = 1;
799a57419b3SSteven Rostedt    my $repeat = 1;
800a57419b3SSteven Rostedt    my $num_tests_set = 0;
801a57419b3SSteven Rostedt    my $skip = 0;
802a57419b3SSteven Rostedt    my $rest;
803a9f84424SSteven Rostedt    my $line;
8040df213caSSteven Rostedt    my $test_case = 0;
80545d73a5dSSteven Rostedt    my $if = 0;
80645d73a5dSSteven Rostedt    my $if_set = 0;
8073d1cc414SSteven Rostedt    my $override = 0;
8083d1cc414SSteven Rostedt
8093d1cc414SSteven Rostedt    my %overrides;
810a57419b3SSteven Rostedt
8112ed3b161SSteven Rostedt    while (<$in>) {
812a57419b3SSteven Rostedt
813a57419b3SSteven Rostedt	# ignore blank lines and comments
814a57419b3SSteven Rostedt	next if (/^\s*$/ || /\s*\#/);
815a57419b3SSteven Rostedt
8160050b6bbSSteven Rostedt	if (/^\s*(TEST_START|DEFAULTS)\b(.*)/) {
817a57419b3SSteven Rostedt
8180050b6bbSSteven Rostedt	    my $type = $1;
8190050b6bbSSteven Rostedt	    $rest = $2;
820a9f84424SSteven Rostedt	    $line = $2;
8210050b6bbSSteven Rostedt
8220050b6bbSSteven Rostedt	    my $old_test_num;
8230050b6bbSSteven Rostedt	    my $old_repeat;
8243d1cc414SSteven Rostedt	    $override = 0;
8250050b6bbSSteven Rostedt
8260050b6bbSSteven Rostedt	    if ($type eq "TEST_START") {
827a57419b3SSteven Rostedt
828a57419b3SSteven Rostedt		if ($num_tests_set) {
829a57419b3SSteven Rostedt		    die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
830a57419b3SSteven Rostedt		}
831a57419b3SSteven Rostedt
8320050b6bbSSteven Rostedt		$old_test_num = $test_num;
8330050b6bbSSteven Rostedt		$old_repeat = $repeat;
834a57419b3SSteven Rostedt
835a57419b3SSteven Rostedt		$test_num += $repeat;
836a57419b3SSteven Rostedt		$default = 0;
837a57419b3SSteven Rostedt		$repeat = 1;
8380050b6bbSSteven Rostedt	    } else {
8390050b6bbSSteven Rostedt		$default = 1;
8400050b6bbSSteven Rostedt	    }
841a57419b3SSteven Rostedt
842a9f84424SSteven Rostedt	    # If SKIP is anywhere in the line, the command will be skipped
843a9f84424SSteven Rostedt	    if ($rest =~ s/\s+SKIP\b//) {
844a57419b3SSteven Rostedt		$skip = 1;
845a57419b3SSteven Rostedt	    } else {
8460df213caSSteven Rostedt		$test_case = 1;
847a57419b3SSteven Rostedt		$skip = 0;
848a57419b3SSteven Rostedt	    }
849a57419b3SSteven Rostedt
850a9f84424SSteven Rostedt	    if ($rest =~ s/\sELSE\b//) {
851a9f84424SSteven Rostedt		if (!$if) {
852a9f84424SSteven Rostedt		    die "$name: $.: ELSE found with out matching IF section\n$_";
853a57419b3SSteven Rostedt		}
854a9f84424SSteven Rostedt		$if = 0;
855a9f84424SSteven Rostedt
856a9f84424SSteven Rostedt		if ($if_set) {
857a9f84424SSteven Rostedt		    $skip = 1;
858a9f84424SSteven Rostedt		} else {
859a9f84424SSteven Rostedt		    $skip = 0;
8603d1cc414SSteven Rostedt		}
8613d1cc414SSteven Rostedt	    }
862a57419b3SSteven Rostedt
863a9f84424SSteven Rostedt	    if ($rest =~ s/\sIF\s+(.*)//) {
86445d73a5dSSteven Rostedt		if (process_if($name, $1)) {
86545d73a5dSSteven Rostedt		    $if_set = 1;
86645d73a5dSSteven Rostedt		} else {
867a57419b3SSteven Rostedt		    $skip = 1;
868a57419b3SSteven Rostedt		}
86945d73a5dSSteven Rostedt		$if = 1;
87045d73a5dSSteven Rostedt	    } else {
87145d73a5dSSteven Rostedt		$if = 0;
872a9f84424SSteven Rostedt		$if_set = 0;
87345d73a5dSSteven Rostedt	    }
874a57419b3SSteven Rostedt
875a9f84424SSteven Rostedt	    if (!$skip) {
876a9f84424SSteven Rostedt		if ($type eq "TEST_START") {
877a9f84424SSteven Rostedt		    if ($rest =~ s/\s+ITERATE\s+(\d+)//) {
878a9f84424SSteven Rostedt			$repeat = $1;
879a9f84424SSteven Rostedt			$repeat_tests{"$test_num"} = $repeat;
880a9f84424SSteven Rostedt		    }
881a9f84424SSteven Rostedt		} elsif ($rest =~ s/\sOVERRIDE\b//) {
882a9f84424SSteven Rostedt		    # DEFAULT only
883a9f84424SSteven Rostedt		    $override = 1;
884a9f84424SSteven Rostedt		    # Clear previous overrides
885a9f84424SSteven Rostedt		    %overrides = ();
886a9f84424SSteven Rostedt		}
887a9f84424SSteven Rostedt	    }
888a9f84424SSteven Rostedt
889a9f84424SSteven Rostedt	    if (!$skip && $rest !~ /^\s*$/) {
8900050b6bbSSteven Rostedt		die "$name: $.: Gargbage found after $type\n$_";
891a57419b3SSteven Rostedt	    }
892a57419b3SSteven Rostedt
8930050b6bbSSteven Rostedt	    if ($skip && $type eq "TEST_START") {
894a57419b3SSteven Rostedt		$test_num = $old_test_num;
895e48c5293SSteven Rostedt		$repeat = $old_repeat;
896a57419b3SSteven Rostedt	    }
897a57419b3SSteven Rostedt
898ab7a3f52SSteven Rostedt	} elsif (/^\s*ELSE\b(.*)$/) {
89945d73a5dSSteven Rostedt	    if (!$if) {
90045d73a5dSSteven Rostedt		die "$name: $.: ELSE found with out matching IF section\n$_";
90145d73a5dSSteven Rostedt	    }
90245d73a5dSSteven Rostedt	    $rest = $1;
90345d73a5dSSteven Rostedt	    if ($if_set) {
90445d73a5dSSteven Rostedt		$skip = 1;
905ab7a3f52SSteven Rostedt		$rest = "";
90645d73a5dSSteven Rostedt	    } else {
90745d73a5dSSteven Rostedt		$skip = 0;
90845d73a5dSSteven Rostedt
909ab7a3f52SSteven Rostedt		if ($rest =~ /\sIF\s+(.*)/) {
91045d73a5dSSteven Rostedt		    # May be a ELSE IF section.
91195f57838SSteven Rostedt		    if (process_if($name, $1)) {
91295f57838SSteven Rostedt			$if_set = 1;
91395f57838SSteven Rostedt		    } else {
91445d73a5dSSteven Rostedt			$skip = 1;
91545d73a5dSSteven Rostedt		    }
916ab7a3f52SSteven Rostedt		    $rest = "";
91745d73a5dSSteven Rostedt		} else {
91845d73a5dSSteven Rostedt		    $if = 0;
91945d73a5dSSteven Rostedt		}
92045d73a5dSSteven Rostedt	    }
92145d73a5dSSteven Rostedt
922ab7a3f52SSteven Rostedt	    if ($rest !~ /^\s*$/) {
923ab7a3f52SSteven Rostedt		die "$name: $.: Gargbage found after DEFAULTS\n$_";
924ab7a3f52SSteven Rostedt	    }
925ab7a3f52SSteven Rostedt
9262ed3b161SSteven Rostedt	} elsif (/^\s*INCLUDE\s+(\S+)/) {
9272ed3b161SSteven Rostedt
9282ed3b161SSteven Rostedt	    next if ($skip);
9292ed3b161SSteven Rostedt
9302ed3b161SSteven Rostedt	    if (!$default) {
9312ed3b161SSteven Rostedt		die "$name: $.: INCLUDE can only be done in default sections\n$_";
9322ed3b161SSteven Rostedt	    }
9332ed3b161SSteven Rostedt
9342ed3b161SSteven Rostedt	    my $file = process_variables($1);
9352ed3b161SSteven Rostedt
9362ed3b161SSteven Rostedt	    if ($file !~ m,^/,) {
9372ed3b161SSteven Rostedt		# check the path of the config file first
9382ed3b161SSteven Rostedt		if ($config =~ m,(.*)/,) {
9392ed3b161SSteven Rostedt		    if (-f "$1/$file") {
9402ed3b161SSteven Rostedt			$file = "$1/$file";
9412ed3b161SSteven Rostedt		    }
9422ed3b161SSteven Rostedt		}
9432ed3b161SSteven Rostedt	    }
9442ed3b161SSteven Rostedt
9452ed3b161SSteven Rostedt	    if ( ! -r $file ) {
9462ed3b161SSteven Rostedt		die "$name: $.: Can't read file $file\n$_";
9472ed3b161SSteven Rostedt	    }
9482ed3b161SSteven Rostedt
9492ed3b161SSteven Rostedt	    if (__read_config($file, \$test_num)) {
9502ed3b161SSteven Rostedt		$test_case = 1;
9512ed3b161SSteven Rostedt	    }
9522ed3b161SSteven Rostedt
953a57419b3SSteven Rostedt	} elsif (/^\s*([A-Z_\[\]\d]+)\s*=\s*(.*?)\s*$/) {
954a57419b3SSteven Rostedt
955a57419b3SSteven Rostedt	    next if ($skip);
956a57419b3SSteven Rostedt
957a57419b3SSteven Rostedt	    my $lvalue = $1;
958a57419b3SSteven Rostedt	    my $rvalue = $2;
959a57419b3SSteven Rostedt
960a57419b3SSteven Rostedt	    if (!$default &&
961a57419b3SSteven Rostedt		($lvalue eq "NUM_TESTS" ||
962a57419b3SSteven Rostedt		 $lvalue eq "LOG_FILE" ||
963a57419b3SSteven Rostedt		 $lvalue eq "CLEAR_LOG")) {
964a57419b3SSteven Rostedt		die "$name: $.: $lvalue must be set in DEFAULTS section\n";
965a57419b3SSteven Rostedt	    }
966a57419b3SSteven Rostedt
967a57419b3SSteven Rostedt	    if ($lvalue eq "NUM_TESTS") {
968a57419b3SSteven Rostedt		if ($test_num) {
969a57419b3SSteven Rostedt		    die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
970a57419b3SSteven Rostedt		}
971a57419b3SSteven Rostedt		if (!$default) {
972a57419b3SSteven Rostedt		    die "$name: $.: NUM_TESTS must be set in default section\n";
973a57419b3SSteven Rostedt		}
974a57419b3SSteven Rostedt		$num_tests_set = 1;
975a57419b3SSteven Rostedt	    }
976a57419b3SSteven Rostedt
977a57419b3SSteven Rostedt	    if ($default || $lvalue =~ /\[\d+\]$/) {
9783d1cc414SSteven Rostedt		set_value($lvalue, $rvalue, $override, \%overrides, $name);
979a57419b3SSteven Rostedt	    } else {
980a57419b3SSteven Rostedt		my $val = "$lvalue\[$test_num\]";
9813d1cc414SSteven Rostedt		set_value($val, $rvalue, $override, \%overrides, $name);
982a57419b3SSteven Rostedt
983a57419b3SSteven Rostedt		if ($repeat > 1) {
984a57419b3SSteven Rostedt		    $repeats{$val} = $repeat;
985a57419b3SSteven Rostedt		}
986a57419b3SSteven Rostedt	    }
98777d942ceSSteven Rostedt	} elsif (/^\s*([A-Z_\[\]\d]+)\s*:=\s*(.*?)\s*$/) {
98877d942ceSSteven Rostedt	    next if ($skip);
98977d942ceSSteven Rostedt
99077d942ceSSteven Rostedt	    my $lvalue = $1;
99177d942ceSSteven Rostedt	    my $rvalue = $2;
99277d942ceSSteven Rostedt
99377d942ceSSteven Rostedt	    # process config variables.
99477d942ceSSteven Rostedt	    # Config variables are only active while reading the
99577d942ceSSteven Rostedt	    # config and can be defined anywhere. They also ignore
99677d942ceSSteven Rostedt	    # TEST_START and DEFAULTS, but are skipped if they are in
99777d942ceSSteven Rostedt	    # on of these sections that have SKIP defined.
99877d942ceSSteven Rostedt	    # The save variable can be
99977d942ceSSteven Rostedt	    # defined multiple times and the new one simply overrides
100077d942ceSSteven Rostedt	    # the prevous one.
100177d942ceSSteven Rostedt	    set_variable($lvalue, $rvalue);
100277d942ceSSteven Rostedt
1003a57419b3SSteven Rostedt	} else {
1004a57419b3SSteven Rostedt	    die "$name: $.: Garbage found in config\n$_";
1005a57419b3SSteven Rostedt	}
10062545eb61SSteven Rostedt    }
10072545eb61SSteven Rostedt
1008a57419b3SSteven Rostedt    if ($test_num) {
1009a57419b3SSteven Rostedt	$test_num += $repeat - 1;
1010a57419b3SSteven Rostedt	$opt{"NUM_TESTS"} = $test_num;
1011a57419b3SSteven Rostedt    }
1012a57419b3SSteven Rostedt
10132ed3b161SSteven Rostedt    close($in);
10142ed3b161SSteven Rostedt
10152ed3b161SSteven Rostedt    $$current_test_num = $test_num;
10162ed3b161SSteven Rostedt
10172ed3b161SSteven Rostedt    return $test_case;
10182ed3b161SSteven Rostedt}
10192ed3b161SSteven Rostedt
1020c4261d0fSSteven Rostedtsub get_test_case {
1021c4261d0fSSteven Rostedt	print "What test case would you like to run?\n";
1022c4261d0fSSteven Rostedt	print " (build, install or boot)\n";
1023c4261d0fSSteven Rostedt	print " Other tests are available but require editing the config file\n";
1024c4261d0fSSteven Rostedt	my $ans = <STDIN>;
1025c4261d0fSSteven Rostedt	chomp $ans;
1026c4261d0fSSteven Rostedt	$default{"TEST_TYPE"} = $ans;
1027c4261d0fSSteven Rostedt}
1028c4261d0fSSteven Rostedt
10292ed3b161SSteven Rostedtsub read_config {
10302ed3b161SSteven Rostedt    my ($config) = @_;
10312ed3b161SSteven Rostedt
10322ed3b161SSteven Rostedt    my $test_case;
10332ed3b161SSteven Rostedt    my $test_num = 0;
10342ed3b161SSteven Rostedt
10352ed3b161SSteven Rostedt    $test_case = __read_config $config, \$test_num;
10362ed3b161SSteven Rostedt
10378d1491baSSteven Rostedt    # make sure we have all mandatory configs
10388d1491baSSteven Rostedt    get_ktest_configs;
10398d1491baSSteven Rostedt
10400df213caSSteven Rostedt    # was a test specified?
10410df213caSSteven Rostedt    if (!$test_case) {
10420df213caSSteven Rostedt	print "No test case specified.\n";
1043c4261d0fSSteven Rostedt	get_test_case;
10440df213caSSteven Rostedt    }
10450df213caSSteven Rostedt
1046a75fececSSteven Rostedt    # set any defaults
1047a75fececSSteven Rostedt
1048a75fececSSteven Rostedt    foreach my $default (keys %default) {
1049a75fececSSteven Rostedt	if (!defined($opt{$default})) {
1050a75fececSSteven Rostedt	    $opt{$default} = $default{$default};
1051a75fececSSteven Rostedt	}
1052a75fececSSteven Rostedt    }
10539cc9e091SSteven Rostedt
10549cc9e091SSteven Rostedt    if ($opt{"IGNORE_UNUSED"} == 1) {
10559cc9e091SSteven Rostedt	return;
10569cc9e091SSteven Rostedt    }
10579cc9e091SSteven Rostedt
10589cc9e091SSteven Rostedt    my %not_used;
10599cc9e091SSteven Rostedt
10609cc9e091SSteven Rostedt    # check if there are any stragglers (typos?)
10619cc9e091SSteven Rostedt    foreach my $option (keys %opt) {
10629cc9e091SSteven Rostedt	my $op = $option;
10639cc9e091SSteven Rostedt	# remove per test labels.
10649cc9e091SSteven Rostedt	$op =~ s/\[.*\]//;
10659cc9e091SSteven Rostedt	if (!exists($option_map{$op}) &&
10669cc9e091SSteven Rostedt	    !exists($default{$op}) &&
10679cc9e091SSteven Rostedt	    !exists($used_options{$op})) {
10689cc9e091SSteven Rostedt	    $not_used{$op} = 1;
10699cc9e091SSteven Rostedt	}
10709cc9e091SSteven Rostedt    }
10719cc9e091SSteven Rostedt
10729cc9e091SSteven Rostedt    if (%not_used) {
10739cc9e091SSteven Rostedt	my $s = "s are";
10749cc9e091SSteven Rostedt	$s = " is" if (keys %not_used == 1);
10759cc9e091SSteven Rostedt	print "The following option$s not used; could be a typo:\n";
10769cc9e091SSteven Rostedt	foreach my $option (keys %not_used) {
10779cc9e091SSteven Rostedt	    print "$option\n";
10789cc9e091SSteven Rostedt	}
10799cc9e091SSteven Rostedt	print "Set IGRNORE_UNUSED = 1 to have ktest ignore unused variables\n";
10809cc9e091SSteven Rostedt	if (!read_yn "Do you want to continue?") {
10819cc9e091SSteven Rostedt	    exit -1;
10829cc9e091SSteven Rostedt	}
10839cc9e091SSteven Rostedt    }
10842545eb61SSteven Rostedt}
10852545eb61SSteven Rostedt
108623715c3cSSteven Rostedtsub __eval_option {
108704262be3SSteven Rostedt (Red Hat)    my ($name, $option, $i) = @_;
108823715c3cSSteven Rostedt
108923715c3cSSteven Rostedt    # Add space to evaluate the character before $
109023715c3cSSteven Rostedt    $option = " $option";
109123715c3cSSteven Rostedt    my $retval = "";
1092f9dfb65bSRabin Vincent    my $repeated = 0;
1093f9dfb65bSRabin Vincent    my $parent = 0;
1094f9dfb65bSRabin Vincent
1095f9dfb65bSRabin Vincent    foreach my $test (keys %repeat_tests) {
1096f9dfb65bSRabin Vincent	if ($i >= $test &&
1097f9dfb65bSRabin Vincent	    $i < $test + $repeat_tests{$test}) {
1098f9dfb65bSRabin Vincent
1099f9dfb65bSRabin Vincent	    $repeated = 1;
1100f9dfb65bSRabin Vincent	    $parent = $test;
1101f9dfb65bSRabin Vincent	    last;
1102f9dfb65bSRabin Vincent	}
1103f9dfb65bSRabin Vincent    }
110423715c3cSSteven Rostedt
110523715c3cSSteven Rostedt    while ($option =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) {
110623715c3cSSteven Rostedt	my $start = $1;
110723715c3cSSteven Rostedt	my $var = $2;
110823715c3cSSteven Rostedt	my $end = $3;
110923715c3cSSteven Rostedt
111023715c3cSSteven Rostedt	# Append beginning of line
111123715c3cSSteven Rostedt	$retval = "$retval$start";
111223715c3cSSteven Rostedt
111323715c3cSSteven Rostedt	# If the iteration option OPT[$i] exists, then use that.
111423715c3cSSteven Rostedt	# otherwise see if the default OPT (without [$i]) exists.
111523715c3cSSteven Rostedt
111623715c3cSSteven Rostedt	my $o = "$var\[$i\]";
1117f9dfb65bSRabin Vincent	my $parento = "$var\[$parent\]";
111823715c3cSSteven Rostedt
111904262be3SSteven Rostedt (Red Hat)	# If a variable contains itself, use the default var
112004262be3SSteven Rostedt (Red Hat)	if (($var eq $name) && defined($opt{$var})) {
112104262be3SSteven Rostedt (Red Hat)	    $o = $opt{$var};
112204262be3SSteven Rostedt (Red Hat)	    $retval = "$retval$o";
112304262be3SSteven Rostedt (Red Hat)	} elsif (defined($opt{$o})) {
112423715c3cSSteven Rostedt	    $o = $opt{$o};
112523715c3cSSteven Rostedt	    $retval = "$retval$o";
1126f9dfb65bSRabin Vincent	} elsif ($repeated && defined($opt{$parento})) {
1127f9dfb65bSRabin Vincent	    $o = $opt{$parento};
1128f9dfb65bSRabin Vincent	    $retval = "$retval$o";
112923715c3cSSteven Rostedt	} elsif (defined($opt{$var})) {
113023715c3cSSteven Rostedt	    $o = $opt{$var};
113123715c3cSSteven Rostedt	    $retval = "$retval$o";
113223715c3cSSteven Rostedt	} else {
113323715c3cSSteven Rostedt	    $retval = "$retval\$\{$var\}";
113423715c3cSSteven Rostedt	}
113523715c3cSSteven Rostedt
113623715c3cSSteven Rostedt	$option = $end;
113723715c3cSSteven Rostedt    }
113823715c3cSSteven Rostedt
113923715c3cSSteven Rostedt    $retval = "$retval$option";
114023715c3cSSteven Rostedt
114123715c3cSSteven Rostedt    $retval =~ s/^ //;
114223715c3cSSteven Rostedt
114323715c3cSSteven Rostedt    return $retval;
114423715c3cSSteven Rostedt}
114523715c3cSSteven Rostedt
114623715c3cSSteven Rostedtsub eval_option {
114704262be3SSteven Rostedt (Red Hat)    my ($name, $option, $i) = @_;
114823715c3cSSteven Rostedt
114923715c3cSSteven Rostedt    my $prev = "";
115023715c3cSSteven Rostedt
115123715c3cSSteven Rostedt    # Since an option can evaluate to another option,
115223715c3cSSteven Rostedt    # keep iterating until we do not evaluate any more
115323715c3cSSteven Rostedt    # options.
115423715c3cSSteven Rostedt    my $r = 0;
115523715c3cSSteven Rostedt    while ($prev ne $option) {
115623715c3cSSteven Rostedt	# Check for recursive evaluations.
115723715c3cSSteven Rostedt	# 100 deep should be more than enough.
115823715c3cSSteven Rostedt	if ($r++ > 100) {
115923715c3cSSteven Rostedt	    die "Over 100 evaluations accurred with $option\n" .
116023715c3cSSteven Rostedt		"Check for recursive variables\n";
116123715c3cSSteven Rostedt	}
116223715c3cSSteven Rostedt	$prev = $option;
116304262be3SSteven Rostedt (Red Hat)	$option = __eval_option($name, $option, $i);
116423715c3cSSteven Rostedt    }
116523715c3cSSteven Rostedt
116623715c3cSSteven Rostedt    return $option;
116723715c3cSSteven Rostedt}
116823715c3cSSteven Rostedt
1169d1e2f22aSSteven Rostedtsub _logit {
11702545eb61SSteven Rostedt    if (defined($opt{"LOG_FILE"})) {
11712545eb61SSteven Rostedt	open(OUT, ">> $opt{LOG_FILE}") or die "Can't write to $opt{LOG_FILE}";
11722545eb61SSteven Rostedt	print OUT @_;
11732545eb61SSteven Rostedt	close(OUT);
11742545eb61SSteven Rostedt    }
11752545eb61SSteven Rostedt}
11762545eb61SSteven Rostedt
1177d1e2f22aSSteven Rostedtsub logit {
1178d1e2f22aSSteven Rostedt    if (defined($opt{"LOG_FILE"})) {
1179d1e2f22aSSteven Rostedt	_logit @_;
1180d1e2f22aSSteven Rostedt    } else {
1181d1e2f22aSSteven Rostedt	print @_;
1182d1e2f22aSSteven Rostedt    }
1183d1e2f22aSSteven Rostedt}
1184d1e2f22aSSteven Rostedt
11855f9b6cedSSteven Rostedtsub doprint {
11865f9b6cedSSteven Rostedt    print @_;
1187d1e2f22aSSteven Rostedt    _logit @_;
11885f9b6cedSSteven Rostedt}
11895f9b6cedSSteven Rostedt
11907faafbd6SSteven Rostedtsub run_command;
11912728be41SAndrew Jonessub start_monitor;
11922728be41SAndrew Jonessub end_monitor;
11932728be41SAndrew Jonessub wait_for_monitor;
11947faafbd6SSteven Rostedt
11957faafbd6SSteven Rostedtsub reboot {
11962728be41SAndrew Jones    my ($time) = @_;
11972728be41SAndrew Jones
1198a4968722SSteven Rostedt    # Make sure everything has been written to disk
1199a4968722SSteven Rostedt    run_ssh("sync");
1200a4968722SSteven Rostedt
12012b803365SSteven Rostedt    if (defined($time)) {
12022b803365SSteven Rostedt	start_monitor;
12032b803365SSteven Rostedt	# flush out current monitor
12042b803365SSteven Rostedt	# May contain the reboot success line
12052b803365SSteven Rostedt	wait_for_monitor 1;
12062b803365SSteven Rostedt    }
12072b803365SSteven Rostedt
12087faafbd6SSteven Rostedt    # try to reboot normally
1209e48c5293SSteven Rostedt    if (run_command $reboot) {
1210576f627cSSteven Rostedt	if (defined($powercycle_after_reboot)) {
1211576f627cSSteven Rostedt	    sleep $powercycle_after_reboot;
1212576f627cSSteven Rostedt	    run_command "$power_cycle";
1213576f627cSSteven Rostedt	}
1214576f627cSSteven Rostedt    } else {
12157faafbd6SSteven Rostedt	# nope? power cycle it.
1216a75fececSSteven Rostedt	run_command "$power_cycle";
12177faafbd6SSteven Rostedt    }
12182728be41SAndrew Jones
12192728be41SAndrew Jones    if (defined($time)) {
12204c0b67a2SSteven Rostedt (Red Hat)
12214c0b67a2SSteven Rostedt (Red Hat)	# We only want to get to the new kernel, don't fail
12224c0b67a2SSteven Rostedt (Red Hat)	# if we stumble over a call trace.
12234c0b67a2SSteven Rostedt (Red Hat)	my $save_ignore_errors = $ignore_errors;
12244c0b67a2SSteven Rostedt (Red Hat)	$ignore_errors = 1;
12254c0b67a2SSteven Rostedt (Red Hat)
1226d6845536SSteven Rostedt (Red Hat)	# Look for the good kernel to boot
1227d6845536SSteven Rostedt (Red Hat)	if (wait_for_monitor($time, "Linux version")) {
1228407b95b7SSteven Rostedt	    # reboot got stuck?
12298a80c727SSteven Rostedt	    doprint "Reboot did not finish. Forcing power cycle\n";
1230407b95b7SSteven Rostedt	    run_command "$power_cycle";
1231407b95b7SSteven Rostedt	}
1232d6845536SSteven Rostedt (Red Hat)
12334c0b67a2SSteven Rostedt (Red Hat)	$ignore_errors = $save_ignore_errors;
12344c0b67a2SSteven Rostedt (Red Hat)
1235d6845536SSteven Rostedt (Red Hat)	# Still need to wait for the reboot to finish
1236d6845536SSteven Rostedt (Red Hat)	wait_for_monitor($time, $reboot_success_line);
1237d6845536SSteven Rostedt (Red Hat)
12382728be41SAndrew Jones	end_monitor;
12392728be41SAndrew Jones    }
12407faafbd6SSteven Rostedt}
12417faafbd6SSteven Rostedt
1242bc7c5803SSteven Rostedtsub reboot_to_good {
1243bc7c5803SSteven Rostedt    my ($time) = @_;
1244bc7c5803SSteven Rostedt
1245bc7c5803SSteven Rostedt    if (defined($switch_to_good)) {
1246bc7c5803SSteven Rostedt	run_command $switch_to_good;
1247bc7c5803SSteven Rostedt    }
1248bc7c5803SSteven Rostedt
1249bc7c5803SSteven Rostedt    reboot $time;
1250bc7c5803SSteven Rostedt}
1251bc7c5803SSteven Rostedt
1252576f627cSSteven Rostedtsub do_not_reboot {
1253576f627cSSteven Rostedt    my $i = $iteration;
1254576f627cSSteven Rostedt
12554ab1cce5SSteven Rostedt    return $test_type eq "build" || $no_reboot ||
1256576f627cSSteven Rostedt	($test_type eq "patchcheck" && $opt{"PATCHCHECK_TYPE[$i]"} eq "build") ||
1257576f627cSSteven Rostedt	($test_type eq "bisect" && $opt{"BISECT_TYPE[$i]"} eq "build");
1258576f627cSSteven Rostedt}
1259576f627cSSteven Rostedt
12605c42fc5bSSteven Rostedtsub dodie {
12615a391fbfSSteven Rostedt    doprint "CRITICAL FAILURE... ", @_, "\n";
12625c42fc5bSSteven Rostedt
1263576f627cSSteven Rostedt    my $i = $iteration;
1264576f627cSSteven Rostedt
1265576f627cSSteven Rostedt    if ($reboot_on_error && !do_not_reboot) {
1266576f627cSSteven Rostedt
126775c3fda7SSteven Rostedt	doprint "REBOOTING\n";
1268bc7c5803SSteven Rostedt	reboot_to_good;
126975c3fda7SSteven Rostedt
1270a75fececSSteven Rostedt    } elsif ($poweroff_on_error && defined($power_off)) {
12715c42fc5bSSteven Rostedt	doprint "POWERING OFF\n";
1272a75fececSSteven Rostedt	`$power_off`;
12735c42fc5bSSteven Rostedt    }
127475c3fda7SSteven Rostedt
1275f80802cbSSteven Rostedt    if (defined($opt{"LOG_FILE"})) {
1276f80802cbSSteven Rostedt	print " See $opt{LOG_FILE} for more info.\n";
1277f80802cbSSteven Rostedt    }
1278f80802cbSSteven Rostedt
1279576f627cSSteven Rostedt    die @_, "\n";
12805c42fc5bSSteven Rostedt}
12815c42fc5bSSteven Rostedt
12827faafbd6SSteven Rostedtsub open_console {
12837faafbd6SSteven Rostedt    my ($fp) = @_;
12847faafbd6SSteven Rostedt
12857faafbd6SSteven Rostedt    my $flags;
12867faafbd6SSteven Rostedt
1287a75fececSSteven Rostedt    my $pid = open($fp, "$console|") or
1288a75fececSSteven Rostedt	dodie "Can't open console $console";
12897faafbd6SSteven Rostedt
12907faafbd6SSteven Rostedt    $flags = fcntl($fp, F_GETFL, 0) or
1291576f627cSSteven Rostedt	dodie "Can't get flags for the socket: $!";
12927faafbd6SSteven Rostedt    $flags = fcntl($fp, F_SETFL, $flags | O_NONBLOCK) or
1293576f627cSSteven Rostedt	dodie "Can't set flags for the socket: $!";
12947faafbd6SSteven Rostedt
12957faafbd6SSteven Rostedt    return $pid;
12967faafbd6SSteven Rostedt}
12977faafbd6SSteven Rostedt
12987faafbd6SSteven Rostedtsub close_console {
12997faafbd6SSteven Rostedt    my ($fp, $pid) = @_;
13007faafbd6SSteven Rostedt
13017faafbd6SSteven Rostedt    doprint "kill child process $pid\n";
1302*5a5d8e48SSatoru Takeuchi    kill $close_console_signal, $pid;
13037faafbd6SSteven Rostedt
13047faafbd6SSteven Rostedt    print "closing!\n";
13057faafbd6SSteven Rostedt    close($fp);
13067faafbd6SSteven Rostedt}
13077faafbd6SSteven Rostedt
13087faafbd6SSteven Rostedtsub start_monitor {
13097faafbd6SSteven Rostedt    if ($monitor_cnt++) {
13107faafbd6SSteven Rostedt	return;
13117faafbd6SSteven Rostedt    }
13127faafbd6SSteven Rostedt    $monitor_fp = \*MONFD;
13137faafbd6SSteven Rostedt    $monitor_pid = open_console $monitor_fp;
1314a75fececSSteven Rostedt
1315a75fececSSteven Rostedt    return;
1316a75fececSSteven Rostedt
1317a75fececSSteven Rostedt    open(MONFD, "Stop perl from warning about single use of MONFD");
13187faafbd6SSteven Rostedt}
13197faafbd6SSteven Rostedt
13207faafbd6SSteven Rostedtsub end_monitor {
1321319ab14fSSteven Rostedt (Red Hat)    return if (!defined $console);
13227faafbd6SSteven Rostedt    if (--$monitor_cnt) {
13237faafbd6SSteven Rostedt	return;
13247faafbd6SSteven Rostedt    }
13257faafbd6SSteven Rostedt    close_console($monitor_fp, $monitor_pid);
13267faafbd6SSteven Rostedt}
13277faafbd6SSteven Rostedt
13287faafbd6SSteven Rostedtsub wait_for_monitor {
13292b803365SSteven Rostedt    my ($time, $stop) = @_;
13302b803365SSteven Rostedt    my $full_line = "";
13317faafbd6SSteven Rostedt    my $line;
13322b803365SSteven Rostedt    my $booted = 0;
1333407b95b7SSteven Rostedt    my $start_time = time;
13348a80c727SSteven Rostedt    my $skip_call_trace = 0;
13358a80c727SSteven Rostedt    my $bug = 0;
13368a80c727SSteven Rostedt    my $bug_ignored = 0;
1337407b95b7SSteven Rostedt    my $now;
13387faafbd6SSteven Rostedt
1339a75fececSSteven Rostedt    doprint "** Wait for monitor to settle down **\n";
13407faafbd6SSteven Rostedt
13417faafbd6SSteven Rostedt    # read the monitor and wait for the system to calm down
13422b803365SSteven Rostedt    while (!$booted) {
13437faafbd6SSteven Rostedt	$line = wait_for_input($monitor_fp, $time);
13442b803365SSteven Rostedt	last if (!defined($line));
13452b803365SSteven Rostedt	print "$line";
13462b803365SSteven Rostedt	$full_line .= $line;
13472b803365SSteven Rostedt
13482b803365SSteven Rostedt	if (defined($stop) && $full_line =~ /$stop/) {
13492b803365SSteven Rostedt	    doprint "wait for monitor detected $stop\n";
13502b803365SSteven Rostedt	    $booted = 1;
13512b803365SSteven Rostedt	}
13522b803365SSteven Rostedt
13538a80c727SSteven Rostedt	if ($full_line =~ /\[ backtrace testing \]/) {
13548a80c727SSteven Rostedt	    $skip_call_trace = 1;
13558a80c727SSteven Rostedt	}
13568a80c727SSteven Rostedt
13578a80c727SSteven Rostedt	if ($full_line =~ /call trace:/i) {
13588a80c727SSteven Rostedt	    if (!$bug && !$skip_call_trace) {
13598a80c727SSteven Rostedt		if ($ignore_errors) {
13608a80c727SSteven Rostedt		    $bug_ignored = 1;
13618a80c727SSteven Rostedt		} else {
13628a80c727SSteven Rostedt		    $bug = 1;
13638a80c727SSteven Rostedt		}
13648a80c727SSteven Rostedt	    }
13658a80c727SSteven Rostedt	}
13668a80c727SSteven Rostedt
13678a80c727SSteven Rostedt	if ($full_line =~ /\[ end of backtrace testing \]/) {
13688a80c727SSteven Rostedt	    $skip_call_trace = 0;
13698a80c727SSteven Rostedt	}
13708a80c727SSteven Rostedt
13718a80c727SSteven Rostedt	if ($full_line =~ /Kernel panic -/) {
13728a80c727SSteven Rostedt	    $bug = 1;
13738a80c727SSteven Rostedt	}
13748a80c727SSteven Rostedt
13752b803365SSteven Rostedt	if ($line =~ /\n/) {
13762b803365SSteven Rostedt	    $full_line = "";
13772b803365SSteven Rostedt	}
1378407b95b7SSteven Rostedt	$now = time;
1379407b95b7SSteven Rostedt	if ($now - $start_time >= $max_monitor_wait) {
1380407b95b7SSteven Rostedt	    doprint "Exiting monitor flush due to hitting MAX_MONITOR_WAIT\n";
1381407b95b7SSteven Rostedt	    return 1;
1382407b95b7SSteven Rostedt	}
13832b803365SSteven Rostedt    }
1384a75fececSSteven Rostedt    print "** Monitor flushed **\n";
13858a80c727SSteven Rostedt    return $bug;
13867faafbd6SSteven Rostedt}
13877faafbd6SSteven Rostedt
1388de5b6e3bSRabin Vincentsub save_logs {
1389de5b6e3bSRabin Vincent	my ($result, $basedir) = @_;
1390de5b6e3bSRabin Vincent	my @t = localtime;
1391de5b6e3bSRabin Vincent	my $date = sprintf "%04d%02d%02d%02d%02d%02d",
1392de5b6e3bSRabin Vincent		1900+$t[5],$t[4],$t[3],$t[2],$t[1],$t[0];
1393de5b6e3bSRabin Vincent
1394de5b6e3bSRabin Vincent	my $type = $build_type;
1395de5b6e3bSRabin Vincent	if ($type =~ /useconfig/) {
1396de5b6e3bSRabin Vincent	    $type = "useconfig";
1397de5b6e3bSRabin Vincent	}
1398de5b6e3bSRabin Vincent
1399de5b6e3bSRabin Vincent	my $dir = "$machine-$test_type-$type-$result-$date";
1400de5b6e3bSRabin Vincent
1401de5b6e3bSRabin Vincent	$dir = "$basedir/$dir";
1402de5b6e3bSRabin Vincent
1403de5b6e3bSRabin Vincent	if (!-d $dir) {
1404de5b6e3bSRabin Vincent	    mkpath($dir) or
1405de5b6e3bSRabin Vincent		die "can't create $dir";
1406de5b6e3bSRabin Vincent	}
1407de5b6e3bSRabin Vincent
1408de5b6e3bSRabin Vincent	my %files = (
1409de5b6e3bSRabin Vincent		"config" => $output_config,
1410de5b6e3bSRabin Vincent		"buildlog" => $buildlog,
1411de5b6e3bSRabin Vincent		"dmesg" => $dmesg,
1412de5b6e3bSRabin Vincent		"testlog" => $testlog,
1413de5b6e3bSRabin Vincent	);
1414de5b6e3bSRabin Vincent
1415de5b6e3bSRabin Vincent	while (my ($name, $source) = each(%files)) {
1416de5b6e3bSRabin Vincent		if (-f "$source") {
1417de5b6e3bSRabin Vincent			cp "$source", "$dir/$name" or
1418de5b6e3bSRabin Vincent				die "failed to copy $source";
1419de5b6e3bSRabin Vincent		}
1420de5b6e3bSRabin Vincent	}
1421de5b6e3bSRabin Vincent
1422de5b6e3bSRabin Vincent	doprint "*** Saved info to $dir ***\n";
1423de5b6e3bSRabin Vincent}
1424de5b6e3bSRabin Vincent
14252b7d9b21SSteven Rostedtsub fail {
14262b7d9b21SSteven Rostedt
1427921ed4c7SSteven Rostedt	if (defined($post_test)) {
1428921ed4c7SSteven Rostedt		run_command $post_test;
1429921ed4c7SSteven Rostedt	}
1430921ed4c7SSteven Rostedt
1431a75fececSSteven Rostedt	if ($die_on_failure) {
14322b7d9b21SSteven Rostedt		dodie @_;
14332b7d9b21SSteven Rostedt	}
14342b7d9b21SSteven Rostedt
1435a75fececSSteven Rostedt	doprint "FAILED\n";
14367faafbd6SSteven Rostedt
1437576f627cSSteven Rostedt	my $i = $iteration;
1438576f627cSSteven Rostedt
1439a75fececSSteven Rostedt	# no need to reboot for just building.
1440576f627cSSteven Rostedt	if (!do_not_reboot) {
14417faafbd6SSteven Rostedt	    doprint "REBOOTING\n";
1442bc7c5803SSteven Rostedt	    reboot_to_good $sleep_time;
1443a75fececSSteven Rostedt	}
14447faafbd6SSteven Rostedt
14459064af52SSteven Rostedt	my $name = "";
14469064af52SSteven Rostedt
14479064af52SSteven Rostedt	if (defined($test_name)) {
14489064af52SSteven Rostedt	    $name = " ($test_name)";
14499064af52SSteven Rostedt	}
14509064af52SSteven Rostedt
1451576f627cSSteven Rostedt	doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
1452576f627cSSteven Rostedt	doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
14539064af52SSteven Rostedt	doprint "KTEST RESULT: TEST $i$name Failed: ", @_, "\n";
1454576f627cSSteven Rostedt	doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
1455576f627cSSteven Rostedt	doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
1456a75fececSSteven Rostedt
1457de5b6e3bSRabin Vincent	if (defined($store_failures)) {
1458de5b6e3bSRabin Vincent	    save_logs "fail", $store_failures;
1459cccae1a6SSteven Rostedt        }
1460cccae1a6SSteven Rostedt
14612b7d9b21SSteven Rostedt	return 1;
14622b7d9b21SSteven Rostedt}
14632b7d9b21SSteven Rostedt
14642545eb61SSteven Rostedtsub run_command {
14652545eb61SSteven Rostedt    my ($command) = @_;
1466d6ce2a0bSSteven Rostedt    my $dolog = 0;
1467d6ce2a0bSSteven Rostedt    my $dord = 0;
1468d6ce2a0bSSteven Rostedt    my $pid;
1469d6ce2a0bSSteven Rostedt
1470e48c5293SSteven Rostedt    $command =~ s/\$SSH_USER/$ssh_user/g;
1471e48c5293SSteven Rostedt    $command =~ s/\$MACHINE/$machine/g;
1472e48c5293SSteven Rostedt
1473d6ce2a0bSSteven Rostedt    doprint("$command ... ");
1474d6ce2a0bSSteven Rostedt
1475d6ce2a0bSSteven Rostedt    $pid = open(CMD, "$command 2>&1 |") or
14762b7d9b21SSteven Rostedt	(fail "unable to exec $command" and return 0);
14772545eb61SSteven Rostedt
14782545eb61SSteven Rostedt    if (defined($opt{"LOG_FILE"})) {
1479d6ce2a0bSSteven Rostedt	open(LOG, ">>$opt{LOG_FILE}") or
1480d6ce2a0bSSteven Rostedt	    dodie "failed to write to log";
1481d6ce2a0bSSteven Rostedt	$dolog = 1;
14826c5ee0beSSteven Rostedt    }
14836c5ee0beSSteven Rostedt
14846c5ee0beSSteven Rostedt    if (defined($redirect)) {
1485d6ce2a0bSSteven Rostedt	open (RD, ">$redirect") or
1486d6ce2a0bSSteven Rostedt	    dodie "failed to write to redirect $redirect";
1487d6ce2a0bSSteven Rostedt	$dord = 1;
14882545eb61SSteven Rostedt    }
14892545eb61SSteven Rostedt
1490d6ce2a0bSSteven Rostedt    while (<CMD>) {
1491d6ce2a0bSSteven Rostedt	print LOG if ($dolog);
1492d6ce2a0bSSteven Rostedt	print RD  if ($dord);
1493d6ce2a0bSSteven Rostedt    }
14942545eb61SSteven Rostedt
1495d6ce2a0bSSteven Rostedt    waitpid($pid, 0);
14962545eb61SSteven Rostedt    my $failed = $?;
14972545eb61SSteven Rostedt
1498d6ce2a0bSSteven Rostedt    close(CMD);
1499d6ce2a0bSSteven Rostedt    close(LOG) if ($dolog);
1500d6ce2a0bSSteven Rostedt    close(RD)  if ($dord);
1501d6ce2a0bSSteven Rostedt
15022545eb61SSteven Rostedt    if ($failed) {
15032545eb61SSteven Rostedt	doprint "FAILED!\n";
15042545eb61SSteven Rostedt    } else {
15052545eb61SSteven Rostedt	doprint "SUCCESS\n";
15062545eb61SSteven Rostedt    }
15072545eb61SSteven Rostedt
15085f9b6cedSSteven Rostedt    return !$failed;
15095f9b6cedSSteven Rostedt}
15105f9b6cedSSteven Rostedt
1511e48c5293SSteven Rostedtsub run_ssh {
1512e48c5293SSteven Rostedt    my ($cmd) = @_;
1513e48c5293SSteven Rostedt    my $cp_exec = $ssh_exec;
1514e48c5293SSteven Rostedt
1515e48c5293SSteven Rostedt    $cp_exec =~ s/\$SSH_COMMAND/$cmd/g;
1516e48c5293SSteven Rostedt    return run_command "$cp_exec";
1517e48c5293SSteven Rostedt}
1518e48c5293SSteven Rostedt
1519e48c5293SSteven Rostedtsub run_scp {
152002ad2617SSteven Rostedt    my ($src, $dst, $cp_scp) = @_;
1521e48c5293SSteven Rostedt
1522e48c5293SSteven Rostedt    $cp_scp =~ s/\$SRC_FILE/$src/g;
1523e48c5293SSteven Rostedt    $cp_scp =~ s/\$DST_FILE/$dst/g;
1524e48c5293SSteven Rostedt
1525e48c5293SSteven Rostedt    return run_command "$cp_scp";
1526e48c5293SSteven Rostedt}
1527e48c5293SSteven Rostedt
152802ad2617SSteven Rostedtsub run_scp_install {
152902ad2617SSteven Rostedt    my ($src, $dst) = @_;
153002ad2617SSteven Rostedt
153102ad2617SSteven Rostedt    my $cp_scp = $scp_to_target_install;
153202ad2617SSteven Rostedt
153302ad2617SSteven Rostedt    return run_scp($src, $dst, $cp_scp);
153402ad2617SSteven Rostedt}
153502ad2617SSteven Rostedt
153602ad2617SSteven Rostedtsub run_scp_mod {
153702ad2617SSteven Rostedt    my ($src, $dst) = @_;
153802ad2617SSteven Rostedt
153902ad2617SSteven Rostedt    my $cp_scp = $scp_to_target;
154002ad2617SSteven Rostedt
154102ad2617SSteven Rostedt    return run_scp($src, $dst, $cp_scp);
154202ad2617SSteven Rostedt}
154302ad2617SSteven Rostedt
1544a15ba913SSteven Rostedtsub get_grub2_index {
1545a15ba913SSteven Rostedt
1546752d9665SSteven Rostedt (Red Hat)    return if (defined($grub_number) && defined($last_grub_menu) &&
1547df5f7c66SSteven Rostedt (Red Hat)	       $last_grub_menu eq $grub_menu && defined($last_machine) &&
1548df5f7c66SSteven Rostedt (Red Hat)	       $last_machine eq $machine);
1549a15ba913SSteven Rostedt
1550a15ba913SSteven Rostedt    doprint "Find grub2 menu ... ";
1551a15ba913SSteven Rostedt    $grub_number = -1;
1552a15ba913SSteven Rostedt
1553a15ba913SSteven Rostedt    my $ssh_grub = $ssh_exec;
1554a15ba913SSteven Rostedt    $ssh_grub =~ s,\$SSH_COMMAND,cat $grub_file,g;
1555a15ba913SSteven Rostedt
1556a15ba913SSteven Rostedt    open(IN, "$ssh_grub |")
1557a15ba913SSteven Rostedt	or die "unable to get $grub_file";
1558a15ba913SSteven Rostedt
1559a15ba913SSteven Rostedt    my $found = 0;
1560a15ba913SSteven Rostedt
1561a15ba913SSteven Rostedt    while (<IN>) {
1562a15ba913SSteven Rostedt	if (/^menuentry.*$grub_menu/) {
1563a15ba913SSteven Rostedt	    $grub_number++;
1564a15ba913SSteven Rostedt	    $found = 1;
1565a15ba913SSteven Rostedt	    last;
1566a15ba913SSteven Rostedt	} elsif (/^menuentry\s/) {
1567a15ba913SSteven Rostedt	    $grub_number++;
1568a15ba913SSteven Rostedt	}
1569a15ba913SSteven Rostedt    }
1570a15ba913SSteven Rostedt    close(IN);
1571a15ba913SSteven Rostedt
1572a15ba913SSteven Rostedt    die "Could not find '$grub_menu' in $grub_file on $machine"
1573a15ba913SSteven Rostedt	if (!$found);
1574a15ba913SSteven Rostedt    doprint "$grub_number\n";
1575752d9665SSteven Rostedt (Red Hat)    $last_grub_menu = $grub_menu;
1576df5f7c66SSteven Rostedt (Red Hat)    $last_machine = $machine;
1577a15ba913SSteven Rostedt}
1578a15ba913SSteven Rostedt
15795f9b6cedSSteven Rostedtsub get_grub_index {
15805f9b6cedSSteven Rostedt
1581a15ba913SSteven Rostedt    if ($reboot_type eq "grub2") {
1582a15ba913SSteven Rostedt	get_grub2_index;
1583a15ba913SSteven Rostedt	return;
1584a15ba913SSteven Rostedt    }
1585a15ba913SSteven Rostedt
1586a75fececSSteven Rostedt    if ($reboot_type ne "grub") {
1587a75fececSSteven Rostedt	return;
1588a75fececSSteven Rostedt    }
1589752d9665SSteven Rostedt (Red Hat)    return if (defined($grub_number) && defined($last_grub_menu) &&
1590df5f7c66SSteven Rostedt (Red Hat)	       $last_grub_menu eq $grub_menu && defined($last_machine) &&
1591df5f7c66SSteven Rostedt (Red Hat)	       $last_machine eq $machine);
15925f9b6cedSSteven Rostedt
15935f9b6cedSSteven Rostedt    doprint "Find grub menu ... ";
15945f9b6cedSSteven Rostedt    $grub_number = -1;
1595e48c5293SSteven Rostedt
1596e48c5293SSteven Rostedt    my $ssh_grub = $ssh_exec;
1597e48c5293SSteven Rostedt    $ssh_grub =~ s,\$SSH_COMMAND,cat /boot/grub/menu.lst,g;
1598e48c5293SSteven Rostedt
1599e48c5293SSteven Rostedt    open(IN, "$ssh_grub |")
16005f9b6cedSSteven Rostedt	or die "unable to get menu.lst";
1601e48c5293SSteven Rostedt
1602eaa1fe25SSteven Rostedt    my $found = 0;
1603eaa1fe25SSteven Rostedt
16045f9b6cedSSteven Rostedt    while (<IN>) {
1605a75fececSSteven Rostedt	if (/^\s*title\s+$grub_menu\s*$/) {
16065f9b6cedSSteven Rostedt	    $grub_number++;
1607eaa1fe25SSteven Rostedt	    $found = 1;
16085f9b6cedSSteven Rostedt	    last;
16095f9b6cedSSteven Rostedt	} elsif (/^\s*title\s/) {
16105f9b6cedSSteven Rostedt	    $grub_number++;
16115f9b6cedSSteven Rostedt	}
16125f9b6cedSSteven Rostedt    }
16135f9b6cedSSteven Rostedt    close(IN);
16145f9b6cedSSteven Rostedt
1615a75fececSSteven Rostedt    die "Could not find '$grub_menu' in /boot/grub/menu on $machine"
1616eaa1fe25SSteven Rostedt	if (!$found);
16175f9b6cedSSteven Rostedt    doprint "$grub_number\n";
1618752d9665SSteven Rostedt (Red Hat)    $last_grub_menu = $grub_menu;
1619df5f7c66SSteven Rostedt (Red Hat)    $last_machine = $machine;
16202545eb61SSteven Rostedt}
16212545eb61SSteven Rostedt
16222545eb61SSteven Rostedtsub wait_for_input
16232545eb61SSteven Rostedt{
16242545eb61SSteven Rostedt    my ($fp, $time) = @_;
16252545eb61SSteven Rostedt    my $rin;
16262545eb61SSteven Rostedt    my $ready;
16272545eb61SSteven Rostedt    my $line;
16282545eb61SSteven Rostedt    my $ch;
16292545eb61SSteven Rostedt
16302545eb61SSteven Rostedt    if (!defined($time)) {
16312545eb61SSteven Rostedt	$time = $timeout;
16322545eb61SSteven Rostedt    }
16332545eb61SSteven Rostedt
16342545eb61SSteven Rostedt    $rin = '';
16352545eb61SSteven Rostedt    vec($rin, fileno($fp), 1) = 1;
1636319ab14fSSteven Rostedt (Red Hat)    ($ready, $time) = select($rin, undef, undef, $time);
16372545eb61SSteven Rostedt
16382545eb61SSteven Rostedt    $line = "";
16392545eb61SSteven Rostedt
16402545eb61SSteven Rostedt    # try to read one char at a time
16412545eb61SSteven Rostedt    while (sysread $fp, $ch, 1) {
16422545eb61SSteven Rostedt	$line .= $ch;
16432545eb61SSteven Rostedt	last if ($ch eq "\n");
16442545eb61SSteven Rostedt    }
16452545eb61SSteven Rostedt
16462545eb61SSteven Rostedt    if (!length($line)) {
16472545eb61SSteven Rostedt	return undef;
16482545eb61SSteven Rostedt    }
16492545eb61SSteven Rostedt
16502545eb61SSteven Rostedt    return $line;
16512545eb61SSteven Rostedt}
16522545eb61SSteven Rostedt
165375c3fda7SSteven Rostedtsub reboot_to {
1654bc7c5803SSteven Rostedt    if (defined($switch_to_test)) {
1655bc7c5803SSteven Rostedt	run_command $switch_to_test;
1656bc7c5803SSteven Rostedt    }
1657bc7c5803SSteven Rostedt
1658a75fececSSteven Rostedt    if ($reboot_type eq "grub") {
1659c54367f9SSteven Rostedt	run_ssh "'(echo \"savedefault --default=$grub_number --once\" | grub --batch)'";
1660a15ba913SSteven Rostedt    } elsif ($reboot_type eq "grub2") {
1661a15ba913SSteven Rostedt	run_ssh "$grub_reboot $grub_number";
16627786954cSSteven Rostedt    } elsif ($reboot_type eq "syslinux") {
16637786954cSSteven Rostedt	run_ssh "$syslinux --once \\\"$syslinux_label\\\" $syslinux_path";
166496f6a0dfSSteven Rostedt    } elsif (defined $reboot_script) {
1665a75fececSSteven Rostedt	run_command "$reboot_script";
16662545eb61SSteven Rostedt    }
166796f6a0dfSSteven Rostedt    reboot;
166896f6a0dfSSteven Rostedt}
16692545eb61SSteven Rostedt
1670a57419b3SSteven Rostedtsub get_sha1 {
1671a57419b3SSteven Rostedt    my ($commit) = @_;
1672a57419b3SSteven Rostedt
1673a57419b3SSteven Rostedt    doprint "git rev-list --max-count=1 $commit ... ";
1674a57419b3SSteven Rostedt    my $sha1 = `git rev-list --max-count=1 $commit`;
1675a57419b3SSteven Rostedt    my $ret = $?;
1676a57419b3SSteven Rostedt
1677a57419b3SSteven Rostedt    logit $sha1;
1678a57419b3SSteven Rostedt
1679a57419b3SSteven Rostedt    if ($ret) {
1680a57419b3SSteven Rostedt	doprint "FAILED\n";
1681a57419b3SSteven Rostedt	dodie "Failed to get git $commit";
1682a57419b3SSteven Rostedt    }
1683a57419b3SSteven Rostedt
1684a57419b3SSteven Rostedt    print "SUCCESS\n";
1685a57419b3SSteven Rostedt
1686a57419b3SSteven Rostedt    chomp $sha1;
1687a57419b3SSteven Rostedt
1688a57419b3SSteven Rostedt    return $sha1;
1689a57419b3SSteven Rostedt}
1690a57419b3SSteven Rostedt
16915a391fbfSSteven Rostedtsub monitor {
16922545eb61SSteven Rostedt    my $booted = 0;
16932545eb61SSteven Rostedt    my $bug = 0;
16946ca996ccSSteven Rostedt    my $bug_ignored = 0;
16955c42fc5bSSteven Rostedt    my $skip_call_trace = 0;
16962b7d9b21SSteven Rostedt    my $loops;
16972545eb61SSteven Rostedt
16987faafbd6SSteven Rostedt    wait_for_monitor 5;
16992545eb61SSteven Rostedt
17002545eb61SSteven Rostedt    my $line;
17012545eb61SSteven Rostedt    my $full_line = "";
17022545eb61SSteven Rostedt
17037faafbd6SSteven Rostedt    open(DMESG, "> $dmesg") or
17047faafbd6SSteven Rostedt	die "unable to write to $dmesg";
17052545eb61SSteven Rostedt
170675c3fda7SSteven Rostedt    reboot_to;
17072545eb61SSteven Rostedt
17081c8a617aSSteven Rostedt    my $success_start;
17091c8a617aSSteven Rostedt    my $failure_start;
17102d01b26aSSteven Rostedt    my $monitor_start = time;
17112d01b26aSSteven Rostedt    my $done = 0;
1712f1a5b962SSteven Rostedt    my $version_found = 0;
17131c8a617aSSteven Rostedt
17142d01b26aSSteven Rostedt    while (!$done) {
17152545eb61SSteven Rostedt
1716ecaf8e52SSteven Rostedt	if ($bug && defined($stop_after_failure) &&
1717ecaf8e52SSteven Rostedt	    $stop_after_failure >= 0) {
1718ecaf8e52SSteven Rostedt	    my $time = $stop_after_failure - (time - $failure_start);
1719ecaf8e52SSteven Rostedt	    $line = wait_for_input($monitor_fp, $time);
1720ecaf8e52SSteven Rostedt	    if (!defined($line)) {
1721ecaf8e52SSteven Rostedt		doprint "bug timed out after $booted_timeout seconds\n";
1722ecaf8e52SSteven Rostedt		doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
1723ecaf8e52SSteven Rostedt		last;
1724ecaf8e52SSteven Rostedt	    }
1725ecaf8e52SSteven Rostedt	} elsif ($booted) {
1726a75fececSSteven Rostedt	    $line = wait_for_input($monitor_fp, $booted_timeout);
1727cd4f1d53SSteven Rostedt	    if (!defined($line)) {
1728cd4f1d53SSteven Rostedt		my $s = $booted_timeout == 1 ? "" : "s";
1729cd4f1d53SSteven Rostedt		doprint "Successful boot found: break after $booted_timeout second$s\n";
1730cd4f1d53SSteven Rostedt		last;
1731cd4f1d53SSteven Rostedt	    }
17322b7d9b21SSteven Rostedt	} else {
17337faafbd6SSteven Rostedt	    $line = wait_for_input($monitor_fp);
1734cd4f1d53SSteven Rostedt	    if (!defined($line)) {
1735cd4f1d53SSteven Rostedt		my $s = $timeout == 1 ? "" : "s";
1736cd4f1d53SSteven Rostedt		doprint "Timed out after $timeout second$s\n";
1737cd4f1d53SSteven Rostedt		last;
17382b7d9b21SSteven Rostedt	    }
1739cd4f1d53SSteven Rostedt	}
17402545eb61SSteven Rostedt
17412545eb61SSteven Rostedt	doprint $line;
17427faafbd6SSteven Rostedt	print DMESG $line;
17432545eb61SSteven Rostedt
17442545eb61SSteven Rostedt	# we are not guaranteed to get a full line
17452545eb61SSteven Rostedt	$full_line .= $line;
17462545eb61SSteven Rostedt
1747a75fececSSteven Rostedt	if ($full_line =~ /$success_line/) {
17482545eb61SSteven Rostedt	    $booted = 1;
17491c8a617aSSteven Rostedt	    $success_start = time;
17501c8a617aSSteven Rostedt	}
17511c8a617aSSteven Rostedt
17521c8a617aSSteven Rostedt	if ($booted && defined($stop_after_success) &&
17531c8a617aSSteven Rostedt	    $stop_after_success >= 0) {
17541c8a617aSSteven Rostedt	    my $now = time;
17551c8a617aSSteven Rostedt	    if ($now - $success_start >= $stop_after_success) {
17561c8a617aSSteven Rostedt		doprint "Test forced to stop after $stop_after_success seconds after success\n";
17571c8a617aSSteven Rostedt		last;
17581c8a617aSSteven Rostedt	    }
17592545eb61SSteven Rostedt	}
17602545eb61SSteven Rostedt
17615c42fc5bSSteven Rostedt	if ($full_line =~ /\[ backtrace testing \]/) {
17625c42fc5bSSteven Rostedt	    $skip_call_trace = 1;
17635c42fc5bSSteven Rostedt	}
17645c42fc5bSSteven Rostedt
17652545eb61SSteven Rostedt	if ($full_line =~ /call trace:/i) {
17666ca996ccSSteven Rostedt	    if (!$bug && !$skip_call_trace) {
17676ca996ccSSteven Rostedt		if ($ignore_errors) {
17686ca996ccSSteven Rostedt		    $bug_ignored = 1;
17696ca996ccSSteven Rostedt		} else {
17701c8a617aSSteven Rostedt		    $bug = 1;
17711c8a617aSSteven Rostedt		    $failure_start = time;
17721c8a617aSSteven Rostedt		}
17731c8a617aSSteven Rostedt	    }
17746ca996ccSSteven Rostedt	}
17751c8a617aSSteven Rostedt
17761c8a617aSSteven Rostedt	if ($bug && defined($stop_after_failure) &&
17771c8a617aSSteven Rostedt	    $stop_after_failure >= 0) {
17781c8a617aSSteven Rostedt	    my $now = time;
17791c8a617aSSteven Rostedt	    if ($now - $failure_start >= $stop_after_failure) {
17801c8a617aSSteven Rostedt		doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
17811c8a617aSSteven Rostedt		last;
17821c8a617aSSteven Rostedt	    }
17835c42fc5bSSteven Rostedt	}
17845c42fc5bSSteven Rostedt
17855c42fc5bSSteven Rostedt	if ($full_line =~ /\[ end of backtrace testing \]/) {
17865c42fc5bSSteven Rostedt	    $skip_call_trace = 0;
17875c42fc5bSSteven Rostedt	}
17885c42fc5bSSteven Rostedt
17895c42fc5bSSteven Rostedt	if ($full_line =~ /Kernel panic -/) {
179010abf118SSteven Rostedt	    $failure_start = time;
17912545eb61SSteven Rostedt	    $bug = 1;
17922545eb61SSteven Rostedt	}
17932545eb61SSteven Rostedt
1794f1a5b962SSteven Rostedt	# Detect triple faults by testing the banner
1795f1a5b962SSteven Rostedt	if ($full_line =~ /\bLinux version (\S+).*\n/) {
1796f1a5b962SSteven Rostedt	    if ($1 eq $version) {
1797f1a5b962SSteven Rostedt		$version_found = 1;
1798f1a5b962SSteven Rostedt	    } elsif ($version_found && $detect_triplefault) {
1799f1a5b962SSteven Rostedt		# We already booted into the kernel we are testing,
1800f1a5b962SSteven Rostedt		# but now we booted into another kernel?
1801f1a5b962SSteven Rostedt		# Consider this a triple fault.
1802f1a5b962SSteven Rostedt		doprint "Aleady booted in Linux kernel $version, but now\n";
1803f1a5b962SSteven Rostedt		doprint "we booted into Linux kernel $1.\n";
1804f1a5b962SSteven Rostedt		doprint "Assuming that this is a triple fault.\n";
1805f1a5b962SSteven Rostedt		doprint "To disable this: set DETECT_TRIPLE_FAULT to 0\n";
1806f1a5b962SSteven Rostedt		last;
1807f1a5b962SSteven Rostedt	    }
1808f1a5b962SSteven Rostedt	}
1809f1a5b962SSteven Rostedt
18102545eb61SSteven Rostedt	if ($line =~ /\n/) {
18112545eb61SSteven Rostedt	    $full_line = "";
18122545eb61SSteven Rostedt	}
18132d01b26aSSteven Rostedt
18142d01b26aSSteven Rostedt	if ($stop_test_after > 0 && !$booted && !$bug) {
18152d01b26aSSteven Rostedt	    if (time - $monitor_start > $stop_test_after) {
18164d62bf51SSteven Rostedt		doprint "STOP_TEST_AFTER ($stop_test_after seconds) timed out\n";
18172d01b26aSSteven Rostedt		$done = 1;
18182d01b26aSSteven Rostedt	    }
18192d01b26aSSteven Rostedt	}
18202545eb61SSteven Rostedt    }
18212545eb61SSteven Rostedt
18227faafbd6SSteven Rostedt    close(DMESG);
18232545eb61SSteven Rostedt
18242545eb61SSteven Rostedt    if ($bug) {
18252b7d9b21SSteven Rostedt	return 0 if ($in_bisect);
1826576f627cSSteven Rostedt	fail "failed - got a bug report" and return 0;
18272545eb61SSteven Rostedt    }
18285f9b6cedSSteven Rostedt
1829a75fececSSteven Rostedt    if (!$booted) {
1830a75fececSSteven Rostedt	return 0 if ($in_bisect);
1831576f627cSSteven Rostedt	fail "failed - never got a boot prompt." and return 0;
1832a75fececSSteven Rostedt    }
1833a75fececSSteven Rostedt
18346ca996ccSSteven Rostedt    if ($bug_ignored) {
18356ca996ccSSteven Rostedt	doprint "WARNING: Call Trace detected but ignored due to IGNORE_ERRORS=1\n";
18366ca996ccSSteven Rostedt    }
18376ca996ccSSteven Rostedt
18382b7d9b21SSteven Rostedt    return 1;
18392545eb61SSteven Rostedt}
18402545eb61SSteven Rostedt
18412b29b2f8SSteven Rostedtsub eval_kernel_version {
18422b29b2f8SSteven Rostedt    my ($option) = @_;
18432b29b2f8SSteven Rostedt
18442b29b2f8SSteven Rostedt    $option =~ s/\$KERNEL_VERSION/$version/g;
18452b29b2f8SSteven Rostedt
18462b29b2f8SSteven Rostedt    return $option;
18472b29b2f8SSteven Rostedt}
18482b29b2f8SSteven Rostedt
1849db05cfefSSteven Rostedtsub do_post_install {
1850db05cfefSSteven Rostedt
1851db05cfefSSteven Rostedt    return if (!defined($post_install));
1852db05cfefSSteven Rostedt
18532b29b2f8SSteven Rostedt    my $cp_post_install = eval_kernel_version $post_install;
1854db05cfefSSteven Rostedt    run_command "$cp_post_install" or
1855db05cfefSSteven Rostedt	dodie "Failed to run post install";
1856db05cfefSSteven Rostedt}
1857db05cfefSSteven Rostedt
1858e1a6c3d7SSteven Rostedt# Sometimes the reboot fails, and will hang. We try to ssh to the box
1859e1a6c3d7SSteven Rostedt# and if we fail, we force another reboot, that should powercycle it.
1860e1a6c3d7SSteven Rostedtsub test_booted {
1861e1a6c3d7SSteven Rostedt    if (!run_ssh "echo testing connection") {
1862e1a6c3d7SSteven Rostedt	reboot $sleep_time;
1863e1a6c3d7SSteven Rostedt    }
1864e1a6c3d7SSteven Rostedt}
1865e1a6c3d7SSteven Rostedt
18662545eb61SSteven Rostedtsub install {
18672545eb61SSteven Rostedt
1868e0a8742eSSteven Rostedt    return if ($no_install);
1869e0a8742eSSteven Rostedt
1870e5c2ec11SSteven Rostedt    if (defined($pre_install)) {
1871e5c2ec11SSteven Rostedt	my $cp_pre_install = eval_kernel_version $pre_install;
1872e5c2ec11SSteven Rostedt	run_command "$cp_pre_install" or
1873e5c2ec11SSteven Rostedt	    dodie "Failed to run pre install";
1874e5c2ec11SSteven Rostedt    }
1875e5c2ec11SSteven Rostedt
18762b29b2f8SSteven Rostedt    my $cp_target = eval_kernel_version $target_image;
18772b29b2f8SSteven Rostedt
1878e1a6c3d7SSteven Rostedt    test_booted;
1879e1a6c3d7SSteven Rostedt
188002ad2617SSteven Rostedt    run_scp_install "$outputdir/$build_target", "$cp_target" or
18815c42fc5bSSteven Rostedt	dodie "failed to copy image";
18825f9b6cedSSteven Rostedt
18835f9b6cedSSteven Rostedt    my $install_mods = 0;
18845f9b6cedSSteven Rostedt
18855f9b6cedSSteven Rostedt    # should we process modules?
18865f9b6cedSSteven Rostedt    $install_mods = 0;
188751ad1dd1SSteven Rostedt    open(IN, "$output_config") or dodie("Can't read config file");
18885f9b6cedSSteven Rostedt    while (<IN>) {
18895f9b6cedSSteven Rostedt	if (/CONFIG_MODULES(=y)?/) {
18908bc5e4eaSSteven Rostedt	    if (defined($1)) {
18918bc5e4eaSSteven Rostedt		$install_mods = 1;
18925f9b6cedSSteven Rostedt		last;
18935f9b6cedSSteven Rostedt	    }
18945f9b6cedSSteven Rostedt	}
18958bc5e4eaSSteven Rostedt    }
18965f9b6cedSSteven Rostedt    close(IN);
18975f9b6cedSSteven Rostedt
18985f9b6cedSSteven Rostedt    if (!$install_mods) {
1899db05cfefSSteven Rostedt	do_post_install;
19005f9b6cedSSteven Rostedt	doprint "No modules needed\n";
19015f9b6cedSSteven Rostedt	return;
19022545eb61SSteven Rostedt    }
19032545eb61SSteven Rostedt
1904627977d8SSteven Rostedt    run_command "$make INSTALL_MOD_STRIP=1 INSTALL_MOD_PATH=$tmpdir modules_install" or
19055f9b6cedSSteven Rostedt	dodie "Failed to install modules";
19065f9b6cedSSteven Rostedt
19072545eb61SSteven Rostedt    my $modlib = "/lib/modules/$version";
1908a57419b3SSteven Rostedt    my $modtar = "ktest-mods.tar.bz2";
19092545eb61SSteven Rostedt
1910e48c5293SSteven Rostedt    run_ssh "rm -rf $modlib" or
19115c42fc5bSSteven Rostedt	dodie "failed to remove old mods: $modlib";
19122545eb61SSteven Rostedt
19135c42fc5bSSteven Rostedt    # would be nice if scp -r did not follow symbolic links
1914a75fececSSteven Rostedt    run_command "cd $tmpdir && tar -cjf $modtar lib/modules/$version" or
19155c42fc5bSSteven Rostedt	dodie "making tarball";
19165c42fc5bSSteven Rostedt
191702ad2617SSteven Rostedt    run_scp_mod "$tmpdir/$modtar", "/tmp" or
19185c42fc5bSSteven Rostedt	dodie "failed to copy modules";
19195c42fc5bSSteven Rostedt
1920a75fececSSteven Rostedt    unlink "$tmpdir/$modtar";
19215c42fc5bSSteven Rostedt
1922e7b13441SSteven Rostedt    run_ssh "'(cd / && tar xjf /tmp/$modtar)'" or
19235c42fc5bSSteven Rostedt	dodie "failed to tar modules";
19245c42fc5bSSteven Rostedt
1925e48c5293SSteven Rostedt    run_ssh "rm -f /tmp/$modtar";
19268b37ca8cSSteven Rostedt
1927db05cfefSSteven Rostedt    do_post_install;
19282545eb61SSteven Rostedt}
19292545eb61SSteven Rostedt
1930ddf607e5SSteven Rostedtsub get_version {
1931ddf607e5SSteven Rostedt    # get the release name
1932683a3e64SSteven Rostedt    return if ($have_version);
1933ddf607e5SSteven Rostedt    doprint "$make kernelrelease ... ";
1934ddf607e5SSteven Rostedt    $version = `$make kernelrelease | tail -1`;
1935ddf607e5SSteven Rostedt    chomp($version);
1936ddf607e5SSteven Rostedt    doprint "$version\n";
1937683a3e64SSteven Rostedt    $have_version = 1;
1938ddf607e5SSteven Rostedt}
1939ddf607e5SSteven Rostedt
1940ddf607e5SSteven Rostedtsub start_monitor_and_boot {
19419f7424ccSSteven Rostedt    # Make sure the stable kernel has finished booting
1942319ab14fSSteven Rostedt (Red Hat)
1943319ab14fSSteven Rostedt (Red Hat)    # Install bisects, don't need console
1944319ab14fSSteven Rostedt (Red Hat)    if (defined $console) {
19459f7424ccSSteven Rostedt	start_monitor;
19469f7424ccSSteven Rostedt	wait_for_monitor 5;
19479f7424ccSSteven Rostedt	end_monitor;
1948319ab14fSSteven Rostedt (Red Hat)    }
19499f7424ccSSteven Rostedt
1950ddf607e5SSteven Rostedt    get_grub_index;
1951ddf607e5SSteven Rostedt    get_version;
1952ddf607e5SSteven Rostedt    install;
1953ddf607e5SSteven Rostedt
1954319ab14fSSteven Rostedt (Red Hat)    start_monitor if (defined $console);
1955ddf607e5SSteven Rostedt    return monitor;
1956ddf607e5SSteven Rostedt}
1957ddf607e5SSteven Rostedt
19584283b169SSteven Rostedt (Red Hat)my $check_build_re = ".*:.*(warning|error|Error):.*";
19594283b169SSteven Rostedt (Red Hat)my $utf8_quote = "\\x{e2}\\x{80}(\\x{98}|\\x{99})";
19604283b169SSteven Rostedt (Red Hat)
19617328735cSSteven Rostedt (Red Hat)sub process_warning_line {
19627328735cSSteven Rostedt (Red Hat)    my ($line) = @_;
19637328735cSSteven Rostedt (Red Hat)
19647328735cSSteven Rostedt (Red Hat)    chomp $line;
19657328735cSSteven Rostedt (Red Hat)
19667328735cSSteven Rostedt (Red Hat)    # for distcc heterogeneous systems, some compilers
19677328735cSSteven Rostedt (Red Hat)    # do things differently causing warning lines
19687328735cSSteven Rostedt (Red Hat)    # to be slightly different. This makes an attempt
19697328735cSSteven Rostedt (Red Hat)    # to fixe those issues.
19707328735cSSteven Rostedt (Red Hat)
19717328735cSSteven Rostedt (Red Hat)    # chop off the index into the line
19727328735cSSteven Rostedt (Red Hat)    # using distcc, some compilers give different indexes
19737328735cSSteven Rostedt (Red Hat)    # depending on white space
19747328735cSSteven Rostedt (Red Hat)    $line =~ s/^(\s*\S+:\d+:)\d+/$1/;
19757328735cSSteven Rostedt (Red Hat)
19767328735cSSteven Rostedt (Red Hat)    # Some compilers use UTF-8 extended for quotes and some don't.
19777328735cSSteven Rostedt (Red Hat)    $line =~ s/$utf8_quote/'/g;
19787328735cSSteven Rostedt (Red Hat)
19797328735cSSteven Rostedt (Red Hat)    return $line;
19807328735cSSteven Rostedt (Red Hat)}
19817328735cSSteven Rostedt (Red Hat)
19824283b169SSteven Rostedt (Red Hat)# Read buildlog and check against warnings file for any
19834283b169SSteven Rostedt (Red Hat)# new warnings.
19844283b169SSteven Rostedt (Red Hat)#
19854283b169SSteven Rostedt (Red Hat)# Returns 1 if OK
19864283b169SSteven Rostedt (Red Hat)#         0 otherwise
19876c5ee0beSSteven Rostedtsub check_buildlog {
19884283b169SSteven Rostedt (Red Hat)    return 1 if (!defined $warnings_file);
19894283b169SSteven Rostedt (Red Hat)
19904283b169SSteven Rostedt (Red Hat)    my %warnings_list;
19914283b169SSteven Rostedt (Red Hat)
19924283b169SSteven Rostedt (Red Hat)    # Failed builds should not reboot the target
19934283b169SSteven Rostedt (Red Hat)    my $save_no_reboot = $no_reboot;
19944283b169SSteven Rostedt (Red Hat)    $no_reboot = 1;
19954283b169SSteven Rostedt (Red Hat)
19964283b169SSteven Rostedt (Red Hat)    if (-f $warnings_file) {
19974283b169SSteven Rostedt (Red Hat)	open(IN, $warnings_file) or
19984283b169SSteven Rostedt (Red Hat)	    dodie "Error opening $warnings_file";
19994283b169SSteven Rostedt (Red Hat)
20004283b169SSteven Rostedt (Red Hat)	while (<IN>) {
20014283b169SSteven Rostedt (Red Hat)	    if (/$check_build_re/) {
20027328735cSSteven Rostedt (Red Hat)		my $warning = process_warning_line $_;
20037328735cSSteven Rostedt (Red Hat)
20047328735cSSteven Rostedt (Red Hat)		$warnings_list{$warning} = 1;
20054283b169SSteven Rostedt (Red Hat)	    }
20064283b169SSteven Rostedt (Red Hat)	}
20074283b169SSteven Rostedt (Red Hat)	close(IN);
20084283b169SSteven Rostedt (Red Hat)    }
20094283b169SSteven Rostedt (Red Hat)
20104283b169SSteven Rostedt (Red Hat)    # If warnings file didn't exist, and WARNINGS_FILE exist,
20114283b169SSteven Rostedt (Red Hat)    # then we fail on any warning!
20124283b169SSteven Rostedt (Red Hat)
20134283b169SSteven Rostedt (Red Hat)    open(IN, $buildlog) or dodie "Can't open $buildlog";
20144283b169SSteven Rostedt (Red Hat)    while (<IN>) {
20154283b169SSteven Rostedt (Red Hat)	if (/$check_build_re/) {
20167328735cSSteven Rostedt (Red Hat)	    my $warning = process_warning_line $_;
20174283b169SSteven Rostedt (Red Hat)
20187328735cSSteven Rostedt (Red Hat)	    if (!defined $warnings_list{$warning}) {
20194283b169SSteven Rostedt (Red Hat)		fail "New warning found (not in $warnings_file)\n$_\n";
20204283b169SSteven Rostedt (Red Hat)		$no_reboot = $save_no_reboot;
20214283b169SSteven Rostedt (Red Hat)		return 0;
20224283b169SSteven Rostedt (Red Hat)	    }
20234283b169SSteven Rostedt (Red Hat)	}
20244283b169SSteven Rostedt (Red Hat)    }
20254283b169SSteven Rostedt (Red Hat)    $no_reboot = $save_no_reboot;
20264283b169SSteven Rostedt (Red Hat)    close(IN);
20274283b169SSteven Rostedt (Red Hat)}
20284283b169SSteven Rostedt (Red Hat)
20294283b169SSteven Rostedt (Red Hat)sub check_patch_buildlog {
20306c5ee0beSSteven Rostedt    my ($patch) = @_;
20316c5ee0beSSteven Rostedt
20326c5ee0beSSteven Rostedt    my @files = `git show $patch | diffstat -l`;
20336c5ee0beSSteven Rostedt
203435275685SSteven Rostedt (Red Hat)    foreach my $file (@files) {
203535275685SSteven Rostedt (Red Hat)	chomp $file;
203635275685SSteven Rostedt (Red Hat)    }
203735275685SSteven Rostedt (Red Hat)
20386c5ee0beSSteven Rostedt    open(IN, "git show $patch |") or
20396c5ee0beSSteven Rostedt	dodie "failed to show $patch";
20406c5ee0beSSteven Rostedt    while (<IN>) {
20416c5ee0beSSteven Rostedt	if (m,^--- a/(.*),) {
20426c5ee0beSSteven Rostedt	    chomp $1;
20436c5ee0beSSteven Rostedt	    $files[$#files] = $1;
20446c5ee0beSSteven Rostedt	}
20456c5ee0beSSteven Rostedt    }
20466c5ee0beSSteven Rostedt    close(IN);
20476c5ee0beSSteven Rostedt
20486c5ee0beSSteven Rostedt    open(IN, $buildlog) or dodie "Can't open $buildlog";
20496c5ee0beSSteven Rostedt    while (<IN>) {
20506c5ee0beSSteven Rostedt	if (/^\s*(.*?):.*(warning|error)/) {
20516c5ee0beSSteven Rostedt	    my $err = $1;
20526c5ee0beSSteven Rostedt	    foreach my $file (@files) {
2053a75fececSSteven Rostedt		my $fullpath = "$builddir/$file";
20546c5ee0beSSteven Rostedt		if ($file eq $err || $fullpath eq $err) {
20552b7d9b21SSteven Rostedt		    fail "$file built with warnings" and return 0;
20566c5ee0beSSteven Rostedt		}
20576c5ee0beSSteven Rostedt	    }
20586c5ee0beSSteven Rostedt	}
20596c5ee0beSSteven Rostedt    }
20606c5ee0beSSteven Rostedt    close(IN);
20612b7d9b21SSteven Rostedt
20622b7d9b21SSteven Rostedt    return 1;
20636c5ee0beSSteven Rostedt}
20646c5ee0beSSteven Rostedt
2065fcb3f16aSSteven Rostedtsub apply_min_config {
2066fcb3f16aSSteven Rostedt    my $outconfig = "$output_config.new";
2067612b9e9bSSteven Rostedt
2068fcb3f16aSSteven Rostedt    # Read the config file and remove anything that
2069fcb3f16aSSteven Rostedt    # is in the force_config hash (from minconfig and others)
2070fcb3f16aSSteven Rostedt    # then add the force config back.
2071fcb3f16aSSteven Rostedt
2072fcb3f16aSSteven Rostedt    doprint "Applying minimum configurations into $output_config.new\n";
2073fcb3f16aSSteven Rostedt
2074fcb3f16aSSteven Rostedt    open (OUT, ">$outconfig") or
2075fcb3f16aSSteven Rostedt	dodie "Can't create $outconfig";
2076fcb3f16aSSteven Rostedt
2077fcb3f16aSSteven Rostedt    if (-f $output_config) {
2078fcb3f16aSSteven Rostedt	open (IN, $output_config) or
2079fcb3f16aSSteven Rostedt	    dodie "Failed to open $output_config";
2080fcb3f16aSSteven Rostedt	while (<IN>) {
2081fcb3f16aSSteven Rostedt	    if (/^(# )?(CONFIG_[^\s=]*)/) {
2082fcb3f16aSSteven Rostedt		next if (defined($force_config{$2}));
2083fcb3f16aSSteven Rostedt	    }
2084fcb3f16aSSteven Rostedt	    print OUT;
2085fcb3f16aSSteven Rostedt	}
2086fcb3f16aSSteven Rostedt	close IN;
2087fcb3f16aSSteven Rostedt    }
2088fcb3f16aSSteven Rostedt    foreach my $config (keys %force_config) {
2089fcb3f16aSSteven Rostedt	print OUT "$force_config{$config}\n";
2090fcb3f16aSSteven Rostedt    }
2091fcb3f16aSSteven Rostedt    close OUT;
2092fcb3f16aSSteven Rostedt
2093fcb3f16aSSteven Rostedt    run_command "mv $outconfig $output_config";
2094fcb3f16aSSteven Rostedt}
2095fcb3f16aSSteven Rostedt
2096fcb3f16aSSteven Rostedtsub make_oldconfig {
2097fcb3f16aSSteven Rostedt
20984c4ab120SSteven Rostedt    my @force_list = keys %force_config;
20994c4ab120SSteven Rostedt
21004c4ab120SSteven Rostedt    if ($#force_list >= 0) {
2101fcb3f16aSSteven Rostedt	apply_min_config;
21024c4ab120SSteven Rostedt    }
2103fcb3f16aSSteven Rostedt
2104fb16d891SAdam Lee    if (!run_command "$make olddefconfig") {
2105fb16d891SAdam Lee	# Perhaps olddefconfig doesn't exist in this version of the kernel
210618925170SSteven Rostedt	# try oldnoconfig
210718925170SSteven Rostedt	doprint "olddefconfig failed, trying make oldnoconfig\n";
210818925170SSteven Rostedt	if (!run_command "$make oldnoconfig") {
210918925170SSteven Rostedt	    doprint "oldnoconfig failed, trying yes '' | make oldconfig\n";
2110612b9e9bSSteven Rostedt	    # try a yes '' | oldconfig
2111fcb3f16aSSteven Rostedt	    run_command "yes '' | $make oldconfig" or
2112612b9e9bSSteven Rostedt		dodie "failed make config oldconfig";
2113612b9e9bSSteven Rostedt	}
2114612b9e9bSSteven Rostedt    }
211518925170SSteven Rostedt}
2116612b9e9bSSteven Rostedt
2117fcb3f16aSSteven Rostedt# read a config file and use this to force new configs.
2118fcb3f16aSSteven Rostedtsub load_force_config {
2119fcb3f16aSSteven Rostedt    my ($config) = @_;
2120fcb3f16aSSteven Rostedt
2121cf79fab6SSteven Rostedt    doprint "Loading force configs from $config\n";
2122fcb3f16aSSteven Rostedt    open(IN, $config) or
2123fcb3f16aSSteven Rostedt	dodie "failed to read $config";
2124fcb3f16aSSteven Rostedt    while (<IN>) {
2125fcb3f16aSSteven Rostedt	chomp;
2126fcb3f16aSSteven Rostedt	if (/^(CONFIG[^\s=]*)(\s*=.*)/) {
2127fcb3f16aSSteven Rostedt	    $force_config{$1} = $_;
2128fcb3f16aSSteven Rostedt	} elsif (/^# (CONFIG_\S*) is not set/) {
2129fcb3f16aSSteven Rostedt	    $force_config{$1} = $_;
2130fcb3f16aSSteven Rostedt	}
2131fcb3f16aSSteven Rostedt    }
2132fcb3f16aSSteven Rostedt    close IN;
2133fcb3f16aSSteven Rostedt}
2134fcb3f16aSSteven Rostedt
21352545eb61SSteven Rostedtsub build {
21362545eb61SSteven Rostedt    my ($type) = @_;
21372545eb61SSteven Rostedt
21387faafbd6SSteven Rostedt    unlink $buildlog;
21397faafbd6SSteven Rostedt
21404ab1cce5SSteven Rostedt    # Failed builds should not reboot the target
21414ab1cce5SSteven Rostedt    my $save_no_reboot = $no_reboot;
21424ab1cce5SSteven Rostedt    $no_reboot = 1;
21434ab1cce5SSteven Rostedt
2144683a3e64SSteven Rostedt    # Calculate a new version from here.
2145683a3e64SSteven Rostedt    $have_version = 0;
2146683a3e64SSteven Rostedt
21470bd6c1a3SSteven Rostedt    if (defined($pre_build)) {
21480bd6c1a3SSteven Rostedt	my $ret = run_command $pre_build;
21490bd6c1a3SSteven Rostedt	if (!$ret && defined($pre_build_die) &&
21500bd6c1a3SSteven Rostedt	    $pre_build_die) {
21510bd6c1a3SSteven Rostedt	    dodie "failed to pre_build\n";
21520bd6c1a3SSteven Rostedt	}
21530bd6c1a3SSteven Rostedt    }
21540bd6c1a3SSteven Rostedt
215575c3fda7SSteven Rostedt    if ($type =~ /^useconfig:(.*)/) {
215651ad1dd1SSteven Rostedt	run_command "cp $1 $output_config" or
215775c3fda7SSteven Rostedt	    dodie "could not copy $1 to .config";
21585f9b6cedSSteven Rostedt
215975c3fda7SSteven Rostedt	$type = "oldconfig";
216075c3fda7SSteven Rostedt    }
216175c3fda7SSteven Rostedt
21625c42fc5bSSteven Rostedt    # old config can ask questions
21635c42fc5bSSteven Rostedt    if ($type eq "oldconfig") {
2164fb16d891SAdam Lee	$type = "olddefconfig";
216575c3fda7SSteven Rostedt
216675c3fda7SSteven Rostedt	# allow for empty configs
216751ad1dd1SSteven Rostedt	run_command "touch $output_config";
216875c3fda7SSteven Rostedt
216913488231SAndrew Jones	if (!$noclean) {
217051ad1dd1SSteven Rostedt	    run_command "mv $output_config $outputdir/config_temp" or
21715c42fc5bSSteven Rostedt		dodie "moving .config";
21725c42fc5bSSteven Rostedt
217313488231SAndrew Jones	    run_command "$make mrproper" or dodie "make mrproper";
21745c42fc5bSSteven Rostedt
217551ad1dd1SSteven Rostedt	    run_command "mv $outputdir/config_temp $output_config" or
21765c42fc5bSSteven Rostedt		dodie "moving config_temp";
217713488231SAndrew Jones	}
21785c42fc5bSSteven Rostedt
21795c42fc5bSSteven Rostedt    } elsif (!$noclean) {
218051ad1dd1SSteven Rostedt	unlink "$output_config";
21815f9b6cedSSteven Rostedt	run_command "$make mrproper" or
21825c42fc5bSSteven Rostedt	    dodie "make mrproper";
21835c42fc5bSSteven Rostedt    }
21842545eb61SSteven Rostedt
21852545eb61SSteven Rostedt    # add something to distinguish this build
2186a75fececSSteven Rostedt    open(OUT, "> $outputdir/localversion") or dodie("Can't make localversion file");
2187a75fececSSteven Rostedt    print OUT "$localversion\n";
21882545eb61SSteven Rostedt    close(OUT);
21892545eb61SSteven Rostedt
21905f9b6cedSSteven Rostedt    if (defined($minconfig)) {
2191fcb3f16aSSteven Rostedt	load_force_config($minconfig);
21922545eb61SSteven Rostedt    }
21932545eb61SSteven Rostedt
2194fb16d891SAdam Lee    if ($type ne "olddefconfig") {
2195fcb3f16aSSteven Rostedt	run_command "$make $type" or
21965c42fc5bSSteven Rostedt	    dodie "failed make config";
2197612b9e9bSSteven Rostedt    }
2198fcb3f16aSSteven Rostedt    # Run old config regardless, to enforce min configurations
2199fcb3f16aSSteven Rostedt    make_oldconfig;
22002545eb61SSteven Rostedt
2201a75fececSSteven Rostedt    $redirect = "$buildlog";
22020bd6c1a3SSteven Rostedt    my $build_ret = run_command "$make $build_options";
22036c5ee0beSSteven Rostedt    undef $redirect;
22040bd6c1a3SSteven Rostedt
22050bd6c1a3SSteven Rostedt    if (defined($post_build)) {
2206683a3e64SSteven Rostedt	# Because a post build may change the kernel version
2207683a3e64SSteven Rostedt	# do it now.
2208683a3e64SSteven Rostedt	get_version;
22090bd6c1a3SSteven Rostedt	my $ret = run_command $post_build;
22100bd6c1a3SSteven Rostedt	if (!$ret && defined($post_build_die) &&
22110bd6c1a3SSteven Rostedt	    $post_build_die) {
22120bd6c1a3SSteven Rostedt	    dodie "failed to post_build\n";
22130bd6c1a3SSteven Rostedt	}
22140bd6c1a3SSteven Rostedt    }
22150bd6c1a3SSteven Rostedt
22160bd6c1a3SSteven Rostedt    if (!$build_ret) {
22175f9b6cedSSteven Rostedt	# bisect may need this to pass
22184ab1cce5SSteven Rostedt	if ($in_bisect) {
22194ab1cce5SSteven Rostedt	    $no_reboot = $save_no_reboot;
22204ab1cce5SSteven Rostedt	    return 0;
22214ab1cce5SSteven Rostedt	}
22222b7d9b21SSteven Rostedt	fail "failed build" and return 0;
22232545eb61SSteven Rostedt    }
22245f9b6cedSSteven Rostedt
22254ab1cce5SSteven Rostedt    $no_reboot = $save_no_reboot;
22264ab1cce5SSteven Rostedt
22272b7d9b21SSteven Rostedt    return 1;
22282545eb61SSteven Rostedt}
22292545eb61SSteven Rostedt
223075c3fda7SSteven Rostedtsub halt {
2231e48c5293SSteven Rostedt    if (!run_ssh "halt" or defined($power_off)) {
2232576f627cSSteven Rostedt	if (defined($poweroff_after_halt)) {
2233576f627cSSteven Rostedt	    sleep $poweroff_after_halt;
2234576f627cSSteven Rostedt	    run_command "$power_off";
2235576f627cSSteven Rostedt	}
2236576f627cSSteven Rostedt    } else {
223775c3fda7SSteven Rostedt	# nope? the zap it!
2238a75fececSSteven Rostedt	run_command "$power_off";
223975c3fda7SSteven Rostedt    }
224075c3fda7SSteven Rostedt}
224175c3fda7SSteven Rostedt
22425f9b6cedSSteven Rostedtsub success {
22435f9b6cedSSteven Rostedt    my ($i) = @_;
22445f9b6cedSSteven Rostedt
2245921ed4c7SSteven Rostedt    if (defined($post_test)) {
2246921ed4c7SSteven Rostedt	run_command $post_test;
2247921ed4c7SSteven Rostedt    }
2248921ed4c7SSteven Rostedt
2249e48c5293SSteven Rostedt    $successes++;
2250e48c5293SSteven Rostedt
22519064af52SSteven Rostedt    my $name = "";
22529064af52SSteven Rostedt
22539064af52SSteven Rostedt    if (defined($test_name)) {
22549064af52SSteven Rostedt	$name = " ($test_name)";
22559064af52SSteven Rostedt    }
22569064af52SSteven Rostedt
22575f9b6cedSSteven Rostedt    doprint "\n\n*******************************************\n";
22585f9b6cedSSteven Rostedt    doprint     "*******************************************\n";
22599064af52SSteven Rostedt    doprint     "KTEST RESULT: TEST $i$name SUCCESS!!!!         **\n";
22605f9b6cedSSteven Rostedt    doprint     "*******************************************\n";
22615f9b6cedSSteven Rostedt    doprint     "*******************************************\n";
22625f9b6cedSSteven Rostedt
2263de5b6e3bSRabin Vincent    if (defined($store_successes)) {
2264de5b6e3bSRabin Vincent        save_logs "success", $store_successes;
2265de5b6e3bSRabin Vincent    }
2266de5b6e3bSRabin Vincent
2267576f627cSSteven Rostedt    if ($i != $opt{"NUM_TESTS"} && !do_not_reboot) {
2268a75fececSSteven Rostedt	doprint "Reboot and wait $sleep_time seconds\n";
2269bc7c5803SSteven Rostedt	reboot_to_good $sleep_time;
22705f9b6cedSSteven Rostedt    }
22715f9b6cedSSteven Rostedt}
22725f9b6cedSSteven Rostedt
2273c960bb9fSSteven Rostedtsub answer_bisect {
2274c960bb9fSSteven Rostedt    for (;;) {
2275c960bb9fSSteven Rostedt	doprint "Pass or fail? [p/f]";
2276c960bb9fSSteven Rostedt	my $ans = <STDIN>;
2277c960bb9fSSteven Rostedt	chomp $ans;
2278c960bb9fSSteven Rostedt	if ($ans eq "p" || $ans eq "P") {
2279c960bb9fSSteven Rostedt	    return 1;
2280c960bb9fSSteven Rostedt	} elsif ($ans eq "f" || $ans eq "F") {
2281c960bb9fSSteven Rostedt	    return 0;
2282c960bb9fSSteven Rostedt	} else {
2283c960bb9fSSteven Rostedt	    print "Please answer 'P' or 'F'\n";
2284c960bb9fSSteven Rostedt	}
2285c960bb9fSSteven Rostedt    }
2286c960bb9fSSteven Rostedt}
2287c960bb9fSSteven Rostedt
22885a391fbfSSteven Rostedtsub child_run_test {
22897faafbd6SSteven Rostedt    my $failed = 0;
22905a391fbfSSteven Rostedt
22917faafbd6SSteven Rostedt    # child should have no power
2292a75fececSSteven Rostedt    $reboot_on_error = 0;
2293a75fececSSteven Rostedt    $poweroff_on_error = 0;
2294a75fececSSteven Rostedt    $die_on_failure = 1;
22957faafbd6SSteven Rostedt
2296a9dd5d63SRabin Vincent    $redirect = "$testlog";
22977faafbd6SSteven Rostedt    run_command $run_test or $failed = 1;
2298a9dd5d63SRabin Vincent    undef $redirect;
2299a9dd5d63SRabin Vincent
23005a391fbfSSteven Rostedt    exit $failed;
23015a391fbfSSteven Rostedt}
23025a391fbfSSteven Rostedt
23035a391fbfSSteven Rostedtmy $child_done;
23045a391fbfSSteven Rostedt
23055a391fbfSSteven Rostedtsub child_finished {
23065a391fbfSSteven Rostedt    $child_done = 1;
23075a391fbfSSteven Rostedt}
23085a391fbfSSteven Rostedt
23095a391fbfSSteven Rostedtsub do_run_test {
23105a391fbfSSteven Rostedt    my $child_pid;
23115a391fbfSSteven Rostedt    my $child_exit;
23125a391fbfSSteven Rostedt    my $line;
23135a391fbfSSteven Rostedt    my $full_line;
23145a391fbfSSteven Rostedt    my $bug = 0;
23159b1d367dSSteven Rostedt    my $bug_ignored = 0;
23165a391fbfSSteven Rostedt
23177faafbd6SSteven Rostedt    wait_for_monitor 1;
23185a391fbfSSteven Rostedt
23197faafbd6SSteven Rostedt    doprint "run test $run_test\n";
23205a391fbfSSteven Rostedt
23215a391fbfSSteven Rostedt    $child_done = 0;
23225a391fbfSSteven Rostedt
23235a391fbfSSteven Rostedt    $SIG{CHLD} = qw(child_finished);
23245a391fbfSSteven Rostedt
23255a391fbfSSteven Rostedt    $child_pid = fork;
23265a391fbfSSteven Rostedt
23275a391fbfSSteven Rostedt    child_run_test if (!$child_pid);
23285a391fbfSSteven Rostedt
23295a391fbfSSteven Rostedt    $full_line = "";
23305a391fbfSSteven Rostedt
23315a391fbfSSteven Rostedt    do {
23327faafbd6SSteven Rostedt	$line = wait_for_input($monitor_fp, 1);
23335a391fbfSSteven Rostedt	if (defined($line)) {
23345a391fbfSSteven Rostedt
23355a391fbfSSteven Rostedt	    # we are not guaranteed to get a full line
23365a391fbfSSteven Rostedt	    $full_line .= $line;
23378ea0e063SSteven Rostedt	    doprint $line;
23385a391fbfSSteven Rostedt
23395a391fbfSSteven Rostedt	    if ($full_line =~ /call trace:/i) {
23409b1d367dSSteven Rostedt		if ($ignore_errors) {
23419b1d367dSSteven Rostedt		    $bug_ignored = 1;
23429b1d367dSSteven Rostedt		} else {
23435a391fbfSSteven Rostedt		    $bug = 1;
23445a391fbfSSteven Rostedt		}
23459b1d367dSSteven Rostedt	    }
23465a391fbfSSteven Rostedt
23475a391fbfSSteven Rostedt	    if ($full_line =~ /Kernel panic -/) {
23485a391fbfSSteven Rostedt		$bug = 1;
23495a391fbfSSteven Rostedt	    }
23505a391fbfSSteven Rostedt
23515a391fbfSSteven Rostedt	    if ($line =~ /\n/) {
23525a391fbfSSteven Rostedt		$full_line = "";
23535a391fbfSSteven Rostedt	    }
23545a391fbfSSteven Rostedt	}
23555a391fbfSSteven Rostedt    } while (!$child_done && !$bug);
23565a391fbfSSteven Rostedt
23579b1d367dSSteven Rostedt    if (!$bug && $bug_ignored) {
23589b1d367dSSteven Rostedt	doprint "WARNING: Call Trace detected but ignored due to IGNORE_ERRORS=1\n";
23599b1d367dSSteven Rostedt    }
23609b1d367dSSteven Rostedt
23615a391fbfSSteven Rostedt    if ($bug) {
23628ea0e063SSteven Rostedt	my $failure_start = time;
23638ea0e063SSteven Rostedt	my $now;
23648ea0e063SSteven Rostedt	do {
23658ea0e063SSteven Rostedt	    $line = wait_for_input($monitor_fp, 1);
23668ea0e063SSteven Rostedt	    if (defined($line)) {
23678ea0e063SSteven Rostedt		doprint $line;
23688ea0e063SSteven Rostedt	    }
23698ea0e063SSteven Rostedt	    $now = time;
23708ea0e063SSteven Rostedt	    if ($now - $failure_start >= $stop_after_failure) {
23718ea0e063SSteven Rostedt		last;
23728ea0e063SSteven Rostedt	    }
23738ea0e063SSteven Rostedt	} while (defined($line));
23748ea0e063SSteven Rostedt
23755a391fbfSSteven Rostedt	doprint "Detected kernel crash!\n";
23765a391fbfSSteven Rostedt	# kill the child with extreme prejudice
23775a391fbfSSteven Rostedt	kill 9, $child_pid;
23785a391fbfSSteven Rostedt    }
23795a391fbfSSteven Rostedt
23805a391fbfSSteven Rostedt    waitpid $child_pid, 0;
23815a391fbfSSteven Rostedt    $child_exit = $?;
23825a391fbfSSteven Rostedt
2383c5dacb88SSteven Rostedt    if (!$bug && $in_bisect) {
2384c5dacb88SSteven Rostedt	if (defined($bisect_ret_good)) {
2385c5dacb88SSteven Rostedt	    if ($child_exit == $bisect_ret_good) {
2386c5dacb88SSteven Rostedt		return 1;
2387c5dacb88SSteven Rostedt	    }
2388c5dacb88SSteven Rostedt	}
2389c5dacb88SSteven Rostedt	if (defined($bisect_ret_skip)) {
2390c5dacb88SSteven Rostedt	    if ($child_exit == $bisect_ret_skip) {
2391c5dacb88SSteven Rostedt		return -1;
2392c5dacb88SSteven Rostedt	    }
2393c5dacb88SSteven Rostedt	}
2394c5dacb88SSteven Rostedt	if (defined($bisect_ret_abort)) {
2395c5dacb88SSteven Rostedt	    if ($child_exit == $bisect_ret_abort) {
2396c5dacb88SSteven Rostedt		fail "test abort" and return -2;
2397c5dacb88SSteven Rostedt	    }
2398c5dacb88SSteven Rostedt	}
2399c5dacb88SSteven Rostedt	if (defined($bisect_ret_bad)) {
2400c5dacb88SSteven Rostedt	    if ($child_exit == $bisect_ret_skip) {
2401c5dacb88SSteven Rostedt		return 0;
2402c5dacb88SSteven Rostedt	    }
2403c5dacb88SSteven Rostedt	}
2404c5dacb88SSteven Rostedt	if (defined($bisect_ret_default)) {
2405c5dacb88SSteven Rostedt	    if ($bisect_ret_default eq "good") {
2406c5dacb88SSteven Rostedt		return 1;
2407c5dacb88SSteven Rostedt	    } elsif ($bisect_ret_default eq "bad") {
2408c5dacb88SSteven Rostedt		return 0;
2409c5dacb88SSteven Rostedt	    } elsif ($bisect_ret_default eq "skip") {
2410c5dacb88SSteven Rostedt		return -1;
2411c5dacb88SSteven Rostedt	    } elsif ($bisect_ret_default eq "abort") {
2412c5dacb88SSteven Rostedt		return -2;
2413c5dacb88SSteven Rostedt	    } else {
2414c5dacb88SSteven Rostedt		fail "unknown default action: $bisect_ret_default"
2415c5dacb88SSteven Rostedt		    and return -2;
2416c5dacb88SSteven Rostedt	    }
2417c5dacb88SSteven Rostedt	}
2418c5dacb88SSteven Rostedt    }
2419c5dacb88SSteven Rostedt
24205a391fbfSSteven Rostedt    if ($bug || $child_exit) {
24212b7d9b21SSteven Rostedt	return 0 if $in_bisect;
24222b7d9b21SSteven Rostedt	fail "test failed" and return 0;
24235a391fbfSSteven Rostedt    }
24242b7d9b21SSteven Rostedt    return 1;
24255a391fbfSSteven Rostedt}
24265a391fbfSSteven Rostedt
2427a75fececSSteven Rostedtsub run_git_bisect {
2428a75fececSSteven Rostedt    my ($command) = @_;
2429a75fececSSteven Rostedt
2430a75fececSSteven Rostedt    doprint "$command ... ";
2431a75fececSSteven Rostedt
2432a75fececSSteven Rostedt    my $output = `$command 2>&1`;
2433a75fececSSteven Rostedt    my $ret = $?;
2434a75fececSSteven Rostedt
2435a75fececSSteven Rostedt    logit $output;
2436a75fececSSteven Rostedt
2437a75fececSSteven Rostedt    if ($ret) {
2438a75fececSSteven Rostedt	doprint "FAILED\n";
2439a75fececSSteven Rostedt	dodie "Failed to git bisect";
2440a75fececSSteven Rostedt    }
2441a75fececSSteven Rostedt
2442a75fececSSteven Rostedt    doprint "SUCCESS\n";
2443a75fececSSteven Rostedt    if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\))\s+\[([[:xdigit:]]+)\]/) {
2444a75fececSSteven Rostedt	doprint "$1 [$2]\n";
2445a75fececSSteven Rostedt    } elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) {
2446b5f4aea6SSteven Rostedt	$bisect_bad_commit = $1;
2447a75fececSSteven Rostedt	doprint "Found bad commit... $1\n";
2448a75fececSSteven Rostedt	return 0;
2449a75fececSSteven Rostedt    } else {
2450a75fececSSteven Rostedt	# we already logged it, just print it now.
2451a75fececSSteven Rostedt	print $output;
2452a75fececSSteven Rostedt    }
2453a75fececSSteven Rostedt
2454a75fececSSteven Rostedt    return 1;
2455a75fececSSteven Rostedt}
2456a75fececSSteven Rostedt
2457c23dca7cSSteven Rostedtsub bisect_reboot {
2458c23dca7cSSteven Rostedt    doprint "Reboot and sleep $bisect_sleep_time seconds\n";
2459bc7c5803SSteven Rostedt    reboot_to_good $bisect_sleep_time;
2460c23dca7cSSteven Rostedt}
2461c23dca7cSSteven Rostedt
2462c23dca7cSSteven Rostedt# returns 1 on success, 0 on failure, -1 on skip
24630a05c769SSteven Rostedtsub run_bisect_test {
24640a05c769SSteven Rostedt    my ($type, $buildtype) = @_;
24655f9b6cedSSteven Rostedt
24662b7d9b21SSteven Rostedt    my $failed = 0;
24675f9b6cedSSteven Rostedt    my $result;
24685f9b6cedSSteven Rostedt    my $output;
24695f9b6cedSSteven Rostedt    my $ret;
24705f9b6cedSSteven Rostedt
24710a05c769SSteven Rostedt    $in_bisect = 1;
24720a05c769SSteven Rostedt
24730a05c769SSteven Rostedt    build $buildtype or $failed = 1;
24745f9b6cedSSteven Rostedt
24755f9b6cedSSteven Rostedt    if ($type ne "build") {
2476c23dca7cSSteven Rostedt	if ($failed && $bisect_skip) {
2477c23dca7cSSteven Rostedt	    $in_bisect = 0;
2478c23dca7cSSteven Rostedt	    return -1;
2479c23dca7cSSteven Rostedt	}
24807faafbd6SSteven Rostedt	dodie "Failed on build" if $failed;
24815f9b6cedSSteven Rostedt
24825f9b6cedSSteven Rostedt	# Now boot the box
2483ddf607e5SSteven Rostedt	start_monitor_and_boot or $failed = 1;
24845f9b6cedSSteven Rostedt
24855f9b6cedSSteven Rostedt	if ($type ne "boot") {
2486c23dca7cSSteven Rostedt	    if ($failed && $bisect_skip) {
2487c23dca7cSSteven Rostedt		end_monitor;
2488c23dca7cSSteven Rostedt		bisect_reboot;
2489c23dca7cSSteven Rostedt		$in_bisect = 0;
2490c23dca7cSSteven Rostedt		return -1;
2491c23dca7cSSteven Rostedt	    }
24927faafbd6SSteven Rostedt	    dodie "Failed on boot" if $failed;
24935a391fbfSSteven Rostedt
24942b7d9b21SSteven Rostedt	    do_run_test or $failed = 1;
24955f9b6cedSSteven Rostedt	}
24967faafbd6SSteven Rostedt	end_monitor;
24975f9b6cedSSteven Rostedt    }
24985f9b6cedSSteven Rostedt
24995f9b6cedSSteven Rostedt    if ($failed) {
25000a05c769SSteven Rostedt	$result = 0;
25015f9b6cedSSteven Rostedt    } else {
25020a05c769SSteven Rostedt	$result = 1;
25035f9b6cedSSteven Rostedt    }
25044025bc62SSteven Rostedt
25054025bc62SSteven Rostedt    # reboot the box to a kernel we can ssh to
25064025bc62SSteven Rostedt    if ($type ne "build") {
25074025bc62SSteven Rostedt	bisect_reboot;
25084025bc62SSteven Rostedt    }
25090a05c769SSteven Rostedt    $in_bisect = 0;
25100a05c769SSteven Rostedt
25110a05c769SSteven Rostedt    return $result;
25120a05c769SSteven Rostedt}
25130a05c769SSteven Rostedt
25140a05c769SSteven Rostedtsub run_bisect {
25150a05c769SSteven Rostedt    my ($type) = @_;
25160a05c769SSteven Rostedt    my $buildtype = "oldconfig";
25170a05c769SSteven Rostedt
25180a05c769SSteven Rostedt    # We should have a minconfig to use?
25190a05c769SSteven Rostedt    if (defined($minconfig)) {
25200a05c769SSteven Rostedt	$buildtype = "useconfig:$minconfig";
25210a05c769SSteven Rostedt    }
25220a05c769SSteven Rostedt
25230a05c769SSteven Rostedt    my $ret = run_bisect_test $type, $buildtype;
25240a05c769SSteven Rostedt
2525c960bb9fSSteven Rostedt    if ($bisect_manual) {
2526c960bb9fSSteven Rostedt	$ret = answer_bisect;
2527c960bb9fSSteven Rostedt    }
25285f9b6cedSSteven Rostedt
2529d6ce2a0bSSteven Rostedt    # Are we looking for where it worked, not failed?
25305158ba3eSRuss Dill    if ($reverse_bisect && $ret >= 0) {
25310a05c769SSteven Rostedt	$ret = !$ret;
2532d6ce2a0bSSteven Rostedt    }
2533d6ce2a0bSSteven Rostedt
2534c23dca7cSSteven Rostedt    if ($ret > 0) {
25350a05c769SSteven Rostedt	return "good";
2536c23dca7cSSteven Rostedt    } elsif ($ret == 0) {
25370a05c769SSteven Rostedt	return  "bad";
2538c23dca7cSSteven Rostedt    } elsif ($bisect_skip) {
2539c23dca7cSSteven Rostedt	doprint "HIT A BAD COMMIT ... SKIPPING\n";
2540c23dca7cSSteven Rostedt	return "skip";
25410a05c769SSteven Rostedt    }
25425f9b6cedSSteven Rostedt}
25435f9b6cedSSteven Rostedt
2544dad98754SSteven Rostedtsub update_bisect_replay {
2545dad98754SSteven Rostedt    my $tmp_log = "$tmpdir/ktest_bisect_log";
2546dad98754SSteven Rostedt    run_command "git bisect log > $tmp_log" or
2547dad98754SSteven Rostedt	die "can't create bisect log";
2548dad98754SSteven Rostedt    return $tmp_log;
2549dad98754SSteven Rostedt}
2550dad98754SSteven Rostedt
25515f9b6cedSSteven Rostedtsub bisect {
25525f9b6cedSSteven Rostedt    my ($i) = @_;
25535f9b6cedSSteven Rostedt
25545f9b6cedSSteven Rostedt    my $result;
25555f9b6cedSSteven Rostedt
2556b5f4aea6SSteven Rostedt    die "BISECT_GOOD[$i] not defined\n"	if (!defined($bisect_good));
2557b5f4aea6SSteven Rostedt    die "BISECT_BAD[$i] not defined\n"	if (!defined($bisect_bad));
2558b5f4aea6SSteven Rostedt    die "BISECT_TYPE[$i] not defined\n"	if (!defined($bisect_type));
25595f9b6cedSSteven Rostedt
2560b5f4aea6SSteven Rostedt    my $good = $bisect_good;
2561b5f4aea6SSteven Rostedt    my $bad = $bisect_bad;
2562b5f4aea6SSteven Rostedt    my $type = $bisect_type;
2563b5f4aea6SSteven Rostedt    my $start = $bisect_start;
2564b5f4aea6SSteven Rostedt    my $replay = $bisect_replay;
2565b5f4aea6SSteven Rostedt    my $start_files = $bisect_files;
25663410f6fdSSteven Rostedt
25673410f6fdSSteven Rostedt    if (defined($start_files)) {
25683410f6fdSSteven Rostedt	$start_files = " -- " . $start_files;
25693410f6fdSSteven Rostedt    } else {
25703410f6fdSSteven Rostedt	$start_files = "";
25713410f6fdSSteven Rostedt    }
25725f9b6cedSSteven Rostedt
2573a57419b3SSteven Rostedt    # convert to true sha1's
2574a57419b3SSteven Rostedt    $good = get_sha1($good);
2575a57419b3SSteven Rostedt    $bad = get_sha1($bad);
2576a57419b3SSteven Rostedt
2577b5f4aea6SSteven Rostedt    if (defined($bisect_reverse) && $bisect_reverse == 1) {
2578d6ce2a0bSSteven Rostedt	doprint "Performing a reverse bisect (bad is good, good is bad!)\n";
2579d6ce2a0bSSteven Rostedt	$reverse_bisect = 1;
2580d6ce2a0bSSteven Rostedt    } else {
2581d6ce2a0bSSteven Rostedt	$reverse_bisect = 0;
2582d6ce2a0bSSteven Rostedt    }
2583d6ce2a0bSSteven Rostedt
25845a391fbfSSteven Rostedt    # Can't have a test without having a test to run
25855a391fbfSSteven Rostedt    if ($type eq "test" && !defined($run_test)) {
25865a391fbfSSteven Rostedt	$type = "boot";
25875a391fbfSSteven Rostedt    }
25885a391fbfSSteven Rostedt
2589dad98754SSteven Rostedt    # Check if a bisect was running
2590dad98754SSteven Rostedt    my $bisect_start_file = "$builddir/.git/BISECT_START";
2591dad98754SSteven Rostedt
2592b5f4aea6SSteven Rostedt    my $check = $bisect_check;
2593dad98754SSteven Rostedt    my $do_check = defined($check) && $check ne "0";
2594dad98754SSteven Rostedt
2595dad98754SSteven Rostedt    if ( -f $bisect_start_file ) {
2596dad98754SSteven Rostedt	print "Bisect in progress found\n";
2597dad98754SSteven Rostedt	if ($do_check) {
2598dad98754SSteven Rostedt	    print " If you say yes, then no checks of good or bad will be done\n";
2599dad98754SSteven Rostedt	}
2600dad98754SSteven Rostedt	if (defined($replay)) {
2601dad98754SSteven Rostedt	    print "** BISECT_REPLAY is defined in config file **";
2602dad98754SSteven Rostedt	    print " Ignore config option and perform new git bisect log?\n";
2603dad98754SSteven Rostedt	    if (read_ync " (yes, no, or cancel) ") {
2604dad98754SSteven Rostedt		$replay = update_bisect_replay;
2605dad98754SSteven Rostedt		$do_check = 0;
2606dad98754SSteven Rostedt	    }
2607dad98754SSteven Rostedt	} elsif (read_yn "read git log and continue?") {
2608dad98754SSteven Rostedt	    $replay = update_bisect_replay;
2609dad98754SSteven Rostedt	    $do_check = 0;
2610dad98754SSteven Rostedt	}
2611dad98754SSteven Rostedt    }
2612dad98754SSteven Rostedt
2613dad98754SSteven Rostedt    if ($do_check) {
2614a75fececSSteven Rostedt
2615a75fececSSteven Rostedt	# get current HEAD
2616a57419b3SSteven Rostedt	my $head = get_sha1("HEAD");
2617a75fececSSteven Rostedt
2618a75fececSSteven Rostedt	if ($check ne "good") {
2619a75fececSSteven Rostedt	    doprint "TESTING BISECT BAD [$bad]\n";
2620a75fececSSteven Rostedt	    run_command "git checkout $bad" or
2621a75fececSSteven Rostedt		die "Failed to checkout $bad";
2622a75fececSSteven Rostedt
2623a75fececSSteven Rostedt	    $result = run_bisect $type;
2624a75fececSSteven Rostedt
2625a75fececSSteven Rostedt	    if ($result ne "bad") {
2626a75fececSSteven Rostedt		fail "Tested BISECT_BAD [$bad] and it succeeded" and return 0;
2627a75fececSSteven Rostedt	    }
2628a75fececSSteven Rostedt	}
2629a75fececSSteven Rostedt
2630a75fececSSteven Rostedt	if ($check ne "bad") {
2631a75fececSSteven Rostedt	    doprint "TESTING BISECT GOOD [$good]\n";
2632a75fececSSteven Rostedt	    run_command "git checkout $good" or
2633a75fececSSteven Rostedt		die "Failed to checkout $good";
2634a75fececSSteven Rostedt
2635a75fececSSteven Rostedt	    $result = run_bisect $type;
2636a75fececSSteven Rostedt
2637a75fececSSteven Rostedt	    if ($result ne "good") {
2638a75fececSSteven Rostedt		fail "Tested BISECT_GOOD [$good] and it failed" and return 0;
2639a75fececSSteven Rostedt	    }
2640a75fececSSteven Rostedt	}
2641a75fececSSteven Rostedt
2642a75fececSSteven Rostedt	# checkout where we started
2643a75fececSSteven Rostedt	run_command "git checkout $head" or
2644a75fececSSteven Rostedt	    die "Failed to checkout $head";
2645a75fececSSteven Rostedt    }
2646a75fececSSteven Rostedt
26473410f6fdSSteven Rostedt    run_command "git bisect start$start_files" or
2648a75fececSSteven Rostedt	dodie "could not start bisect";
2649a75fececSSteven Rostedt
2650a75fececSSteven Rostedt    run_command "git bisect good $good" or
2651a75fececSSteven Rostedt	dodie "could not set bisect good to $good";
2652a75fececSSteven Rostedt
2653a75fececSSteven Rostedt    run_git_bisect "git bisect bad $bad" or
2654a75fececSSteven Rostedt	dodie "could not set bisect bad to $bad";
2655a75fececSSteven Rostedt
2656a75fececSSteven Rostedt    if (defined($replay)) {
2657a75fececSSteven Rostedt	run_command "git bisect replay $replay" or
2658a75fececSSteven Rostedt	    dodie "failed to run replay";
2659a75fececSSteven Rostedt    }
2660a75fececSSteven Rostedt
2661a75fececSSteven Rostedt    if (defined($start)) {
2662a75fececSSteven Rostedt	run_command "git checkout $start" or
2663a75fececSSteven Rostedt	    dodie "failed to checkout $start";
2664a75fececSSteven Rostedt    }
2665a75fececSSteven Rostedt
2666a75fececSSteven Rostedt    my $test;
26675f9b6cedSSteven Rostedt    do {
26685f9b6cedSSteven Rostedt	$result = run_bisect $type;
2669a75fececSSteven Rostedt	$test = run_git_bisect "git bisect $result";
2670a75fececSSteven Rostedt    } while ($test);
26715f9b6cedSSteven Rostedt
26725f9b6cedSSteven Rostedt    run_command "git bisect log" or
26735f9b6cedSSteven Rostedt	dodie "could not capture git bisect log";
26745f9b6cedSSteven Rostedt
26755f9b6cedSSteven Rostedt    run_command "git bisect reset" or
26765f9b6cedSSteven Rostedt	dodie "could not reset git bisect";
26775f9b6cedSSteven Rostedt
2678b5f4aea6SSteven Rostedt    doprint "Bad commit was [$bisect_bad_commit]\n";
26795f9b6cedSSteven Rostedt
26800a05c769SSteven Rostedt    success $i;
26810a05c769SSteven Rostedt}
26820a05c769SSteven Rostedt
2683cf79fab6SSteven Rostedt# config_ignore holds the configs that were set (or unset) for
2684cf79fab6SSteven Rostedt# a good config and we will ignore these configs for the rest
2685cf79fab6SSteven Rostedt# of a config bisect. These configs stay as they were.
26860a05c769SSteven Rostedtmy %config_ignore;
2687cf79fab6SSteven Rostedt
2688cf79fab6SSteven Rostedt# config_set holds what all configs were set as.
26890a05c769SSteven Rostedtmy %config_set;
26900a05c769SSteven Rostedt
2691cf79fab6SSteven Rostedt# config_off holds the set of configs that the bad config had disabled.
2692cf79fab6SSteven Rostedt# We need to record them and set them in the .config when running
2693fb16d891SAdam Lee# olddefconfig, because olddefconfig keeps the defaults.
2694cf79fab6SSteven Rostedtmy %config_off;
2695cf79fab6SSteven Rostedt
2696cf79fab6SSteven Rostedt# config_off_tmp holds a set of configs to turn off for now
2697cf79fab6SSteven Rostedtmy @config_off_tmp;
2698cf79fab6SSteven Rostedt
2699cf79fab6SSteven Rostedt# config_list is the set of configs that are being tested
27000a05c769SSteven Rostedtmy %config_list;
27010a05c769SSteven Rostedtmy %null_config;
27020a05c769SSteven Rostedt
27030a05c769SSteven Rostedtmy %dependency;
27040a05c769SSteven Rostedt
27054c4ab120SSteven Rostedtsub assign_configs {
27064c4ab120SSteven Rostedt    my ($hash, $config) = @_;
27070a05c769SSteven Rostedt
27080a05c769SSteven Rostedt    open (IN, $config)
27090a05c769SSteven Rostedt	or dodie "Failed to read $config";
27100a05c769SSteven Rostedt
27110a05c769SSteven Rostedt    while (<IN>) {
27129bf71749SSteven Rostedt	if (/^((CONFIG\S*)=.*)/) {
27134c4ab120SSteven Rostedt	    ${$hash}{$2} = $1;
27140a05c769SSteven Rostedt	}
27150a05c769SSteven Rostedt    }
27160a05c769SSteven Rostedt
27170a05c769SSteven Rostedt    close(IN);
27180a05c769SSteven Rostedt}
27190a05c769SSteven Rostedt
27204c4ab120SSteven Rostedtsub process_config_ignore {
27214c4ab120SSteven Rostedt    my ($config) = @_;
27224c4ab120SSteven Rostedt
27234c4ab120SSteven Rostedt    assign_configs \%config_ignore, $config;
27244c4ab120SSteven Rostedt}
27254c4ab120SSteven Rostedt
27260a05c769SSteven Rostedtsub read_current_config {
27270a05c769SSteven Rostedt    my ($config_ref) = @_;
27280a05c769SSteven Rostedt
27290a05c769SSteven Rostedt    %{$config_ref} = ();
27300a05c769SSteven Rostedt    undef %{$config_ref};
27310a05c769SSteven Rostedt
27320a05c769SSteven Rostedt    my @key = keys %{$config_ref};
27330a05c769SSteven Rostedt    if ($#key >= 0) {
27340a05c769SSteven Rostedt	print "did not delete!\n";
27350a05c769SSteven Rostedt	exit;
27360a05c769SSteven Rostedt    }
27370a05c769SSteven Rostedt    open (IN, "$output_config");
27380a05c769SSteven Rostedt
27390a05c769SSteven Rostedt    while (<IN>) {
27400a05c769SSteven Rostedt	if (/^(CONFIG\S+)=(.*)/) {
27410a05c769SSteven Rostedt	    ${$config_ref}{$1} = $2;
27420a05c769SSteven Rostedt	}
27430a05c769SSteven Rostedt    }
27440a05c769SSteven Rostedt    close(IN);
27450a05c769SSteven Rostedt}
27460a05c769SSteven Rostedt
27470a05c769SSteven Rostedtsub get_dependencies {
27480a05c769SSteven Rostedt    my ($config) = @_;
27490a05c769SSteven Rostedt
27500a05c769SSteven Rostedt    my $arr = $dependency{$config};
27510a05c769SSteven Rostedt    if (!defined($arr)) {
27520a05c769SSteven Rostedt	return ();
27530a05c769SSteven Rostedt    }
27540a05c769SSteven Rostedt
27550a05c769SSteven Rostedt    my @deps = @{$arr};
27560a05c769SSteven Rostedt
27570a05c769SSteven Rostedt    foreach my $dep (@{$arr}) {
27580a05c769SSteven Rostedt	print "ADD DEP $dep\n";
27590a05c769SSteven Rostedt	@deps = (@deps, get_dependencies $dep);
27600a05c769SSteven Rostedt    }
27610a05c769SSteven Rostedt
27620a05c769SSteven Rostedt    return @deps;
27630a05c769SSteven Rostedt}
27640a05c769SSteven Rostedt
27650a05c769SSteven Rostedtsub create_config {
27660a05c769SSteven Rostedt    my @configs = @_;
27670a05c769SSteven Rostedt
27680a05c769SSteven Rostedt    open(OUT, ">$output_config") or dodie "Can not write to $output_config";
27690a05c769SSteven Rostedt
27700a05c769SSteven Rostedt    foreach my $config (@configs) {
27710a05c769SSteven Rostedt	print OUT "$config_set{$config}\n";
27720a05c769SSteven Rostedt	my @deps = get_dependencies $config;
27730a05c769SSteven Rostedt	foreach my $dep (@deps) {
27740a05c769SSteven Rostedt	    print OUT "$config_set{$dep}\n";
27750a05c769SSteven Rostedt	}
27760a05c769SSteven Rostedt    }
27770a05c769SSteven Rostedt
2778cf79fab6SSteven Rostedt    # turn off configs to keep off
2779cf79fab6SSteven Rostedt    foreach my $config (keys %config_off) {
2780cf79fab6SSteven Rostedt	print OUT "# $config is not set\n";
2781cf79fab6SSteven Rostedt    }
2782cf79fab6SSteven Rostedt
2783cf79fab6SSteven Rostedt    # turn off configs that should be off for now
2784cf79fab6SSteven Rostedt    foreach my $config (@config_off_tmp) {
2785cf79fab6SSteven Rostedt	print OUT "# $config is not set\n";
2786cf79fab6SSteven Rostedt    }
2787cf79fab6SSteven Rostedt
27880a05c769SSteven Rostedt    foreach my $config (keys %config_ignore) {
27890a05c769SSteven Rostedt	print OUT "$config_ignore{$config}\n";
27900a05c769SSteven Rostedt    }
27910a05c769SSteven Rostedt    close(OUT);
27920a05c769SSteven Rostedt
2793fcb3f16aSSteven Rostedt    make_oldconfig;
27940a05c769SSteven Rostedt}
27950a05c769SSteven Rostedt
27960a05c769SSteven Rostedtsub compare_configs {
27970a05c769SSteven Rostedt    my (%a, %b) = @_;
27980a05c769SSteven Rostedt
27990a05c769SSteven Rostedt    foreach my $item (keys %a) {
28000a05c769SSteven Rostedt	if (!defined($b{$item})) {
28010a05c769SSteven Rostedt	    print "diff $item\n";
28020a05c769SSteven Rostedt	    return 1;
28030a05c769SSteven Rostedt	}
28040a05c769SSteven Rostedt	delete $b{$item};
28050a05c769SSteven Rostedt    }
28060a05c769SSteven Rostedt
28070a05c769SSteven Rostedt    my @keys = keys %b;
28080a05c769SSteven Rostedt    if ($#keys) {
28090a05c769SSteven Rostedt	print "diff2 $keys[0]\n";
28100a05c769SSteven Rostedt    }
28110a05c769SSteven Rostedt    return -1 if ($#keys >= 0);
28120a05c769SSteven Rostedt
28130a05c769SSteven Rostedt    return 0;
28140a05c769SSteven Rostedt}
28150a05c769SSteven Rostedt
28160a05c769SSteven Rostedtsub run_config_bisect_test {
28170a05c769SSteven Rostedt    my ($type) = @_;
28180a05c769SSteven Rostedt
28190a05c769SSteven Rostedt    return run_bisect_test $type, "oldconfig";
28200a05c769SSteven Rostedt}
28210a05c769SSteven Rostedt
28220a05c769SSteven Rostedtsub process_passed {
28230a05c769SSteven Rostedt    my (%configs) = @_;
28240a05c769SSteven Rostedt
28250a05c769SSteven Rostedt    doprint "These configs had no failure: (Enabling them for further compiles)\n";
28260a05c769SSteven Rostedt    # Passed! All these configs are part of a good compile.
28270a05c769SSteven Rostedt    # Add them to the min options.
28280a05c769SSteven Rostedt    foreach my $config (keys %configs) {
28290a05c769SSteven Rostedt	if (defined($config_list{$config})) {
28300a05c769SSteven Rostedt	    doprint " removing $config\n";
28310a05c769SSteven Rostedt	    $config_ignore{$config} = $config_list{$config};
28320a05c769SSteven Rostedt	    delete $config_list{$config};
28330a05c769SSteven Rostedt	}
28340a05c769SSteven Rostedt    }
2835f1a27850SSteven Rostedt    doprint "config copied to $outputdir/config_good\n";
2836f1a27850SSteven Rostedt    run_command "cp -f $output_config $outputdir/config_good";
28370a05c769SSteven Rostedt}
28380a05c769SSteven Rostedt
28390a05c769SSteven Rostedtsub process_failed {
28400a05c769SSteven Rostedt    my ($config) = @_;
28410a05c769SSteven Rostedt
28420a05c769SSteven Rostedt    doprint "\n\n***************************************\n";
28430a05c769SSteven Rostedt    doprint "Found bad config: $config\n";
28440a05c769SSteven Rostedt    doprint "***************************************\n\n";
28450a05c769SSteven Rostedt}
28460a05c769SSteven Rostedt
28470a05c769SSteven Rostedtsub run_config_bisect {
28480a05c769SSteven Rostedt
28490a05c769SSteven Rostedt    my @start_list = keys %config_list;
28500a05c769SSteven Rostedt
28510a05c769SSteven Rostedt    if ($#start_list < 0) {
28520a05c769SSteven Rostedt	doprint "No more configs to test!!!\n";
28530a05c769SSteven Rostedt	return -1;
28540a05c769SSteven Rostedt    }
28550a05c769SSteven Rostedt
28560a05c769SSteven Rostedt    doprint "***** RUN TEST ***\n";
2857b5f4aea6SSteven Rostedt    my $type = $config_bisect_type;
28580a05c769SSteven Rostedt    my $ret;
28590a05c769SSteven Rostedt    my %current_config;
28600a05c769SSteven Rostedt
28610a05c769SSteven Rostedt    my $count = $#start_list + 1;
28620a05c769SSteven Rostedt    doprint "  $count configs to test\n";
28630a05c769SSteven Rostedt
28640a05c769SSteven Rostedt    my $half = int($#start_list / 2);
28650a05c769SSteven Rostedt
28660a05c769SSteven Rostedt    do {
28670a05c769SSteven Rostedt	my @tophalf = @start_list[0 .. $half];
28680a05c769SSteven Rostedt
2869cf79fab6SSteven Rostedt	# keep the bottom half off
2870cf79fab6SSteven Rostedt	if ($half < $#start_list) {
2871cf79fab6SSteven Rostedt	    @config_off_tmp = @start_list[$half + 1 .. $#start_list];
2872cf79fab6SSteven Rostedt	} else {
2873cf79fab6SSteven Rostedt	    @config_off_tmp = ();
2874cf79fab6SSteven Rostedt	}
2875cf79fab6SSteven Rostedt
28760a05c769SSteven Rostedt	create_config @tophalf;
28770a05c769SSteven Rostedt	read_current_config \%current_config;
28780a05c769SSteven Rostedt
28790a05c769SSteven Rostedt	$count = $#tophalf + 1;
28800a05c769SSteven Rostedt	doprint "Testing $count configs\n";
28810a05c769SSteven Rostedt	my $found = 0;
28820a05c769SSteven Rostedt	# make sure we test something
28830a05c769SSteven Rostedt	foreach my $config (@tophalf) {
28840a05c769SSteven Rostedt	    if (defined($current_config{$config})) {
28850a05c769SSteven Rostedt		logit " $config\n";
28860a05c769SSteven Rostedt		$found = 1;
28870a05c769SSteven Rostedt	    }
28880a05c769SSteven Rostedt	}
28890a05c769SSteven Rostedt	if (!$found) {
28900a05c769SSteven Rostedt	    # try the other half
28910a05c769SSteven Rostedt	    doprint "Top half produced no set configs, trying bottom half\n";
2892cf79fab6SSteven Rostedt
2893cf79fab6SSteven Rostedt	    # keep the top half off
2894cf79fab6SSteven Rostedt	    @config_off_tmp = @tophalf;
28954c8cc55bSSteven Rostedt	    @tophalf = @start_list[$half + 1 .. $#start_list];
2896cf79fab6SSteven Rostedt
28970a05c769SSteven Rostedt	    create_config @tophalf;
28980a05c769SSteven Rostedt	    read_current_config \%current_config;
28990a05c769SSteven Rostedt	    foreach my $config (@tophalf) {
29000a05c769SSteven Rostedt		if (defined($current_config{$config})) {
29010a05c769SSteven Rostedt		    logit " $config\n";
29020a05c769SSteven Rostedt		    $found = 1;
29030a05c769SSteven Rostedt		}
29040a05c769SSteven Rostedt	    }
29050a05c769SSteven Rostedt	    if (!$found) {
29060a05c769SSteven Rostedt		doprint "Failed: Can't make new config with current configs\n";
29070a05c769SSteven Rostedt		foreach my $config (@start_list) {
29080a05c769SSteven Rostedt		    doprint "  CONFIG: $config\n";
29090a05c769SSteven Rostedt		}
29100a05c769SSteven Rostedt		return -1;
29110a05c769SSteven Rostedt	    }
29120a05c769SSteven Rostedt	    $count = $#tophalf + 1;
29130a05c769SSteven Rostedt	    doprint "Testing $count configs\n";
29140a05c769SSteven Rostedt	}
29150a05c769SSteven Rostedt
29160a05c769SSteven Rostedt	$ret = run_config_bisect_test $type;
2917c960bb9fSSteven Rostedt	if ($bisect_manual) {
2918c960bb9fSSteven Rostedt	    $ret = answer_bisect;
2919c960bb9fSSteven Rostedt	}
29200a05c769SSteven Rostedt	if ($ret) {
29210a05c769SSteven Rostedt	    process_passed %current_config;
29220a05c769SSteven Rostedt	    return 0;
29230a05c769SSteven Rostedt	}
29240a05c769SSteven Rostedt
29250a05c769SSteven Rostedt	doprint "This config had a failure.\n";
29260a05c769SSteven Rostedt	doprint "Removing these configs that were not set in this config:\n";
2927f1a27850SSteven Rostedt	doprint "config copied to $outputdir/config_bad\n";
2928f1a27850SSteven Rostedt	run_command "cp -f $output_config $outputdir/config_bad";
29290a05c769SSteven Rostedt
29300a05c769SSteven Rostedt	# A config exists in this group that was bad.
29310a05c769SSteven Rostedt	foreach my $config (keys %config_list) {
29320a05c769SSteven Rostedt	    if (!defined($current_config{$config})) {
29330a05c769SSteven Rostedt		doprint " removing $config\n";
29340a05c769SSteven Rostedt		delete $config_list{$config};
29350a05c769SSteven Rostedt	    }
29360a05c769SSteven Rostedt	}
29370a05c769SSteven Rostedt
29380a05c769SSteven Rostedt	@start_list = @tophalf;
29390a05c769SSteven Rostedt
29400a05c769SSteven Rostedt	if ($#start_list == 0) {
29410a05c769SSteven Rostedt	    process_failed $start_list[0];
29420a05c769SSteven Rostedt	    return 1;
29430a05c769SSteven Rostedt	}
29440a05c769SSteven Rostedt
29450a05c769SSteven Rostedt	# remove half the configs we are looking at and see if
29460a05c769SSteven Rostedt	# they are good.
29470a05c769SSteven Rostedt	$half = int($#start_list / 2);
29484c8cc55bSSteven Rostedt    } while ($#start_list > 0);
29490a05c769SSteven Rostedt
2950c960bb9fSSteven Rostedt    # we found a single config, try it again unless we are running manually
2951c960bb9fSSteven Rostedt
2952c960bb9fSSteven Rostedt    if ($bisect_manual) {
2953c960bb9fSSteven Rostedt	process_failed $start_list[0];
2954c960bb9fSSteven Rostedt	return 1;
2955c960bb9fSSteven Rostedt    }
2956c960bb9fSSteven Rostedt
29570a05c769SSteven Rostedt    my @tophalf = @start_list[0 .. 0];
29580a05c769SSteven Rostedt
29590a05c769SSteven Rostedt    $ret = run_config_bisect_test $type;
29600a05c769SSteven Rostedt    if ($ret) {
29610a05c769SSteven Rostedt	process_passed %current_config;
29620a05c769SSteven Rostedt	return 0;
29630a05c769SSteven Rostedt    }
29640a05c769SSteven Rostedt
29650a05c769SSteven Rostedt    process_failed $start_list[0];
29660a05c769SSteven Rostedt    return 1;
29670a05c769SSteven Rostedt}
29680a05c769SSteven Rostedt
29690a05c769SSteven Rostedtsub config_bisect {
29700a05c769SSteven Rostedt    my ($i) = @_;
29710a05c769SSteven Rostedt
2972b5f4aea6SSteven Rostedt    my $start_config = $config_bisect;
29730a05c769SSteven Rostedt
29740a05c769SSteven Rostedt    my $tmpconfig = "$tmpdir/use_config";
29750a05c769SSteven Rostedt
297630f75da5SSteven Rostedt    if (defined($config_bisect_good)) {
297730f75da5SSteven Rostedt	process_config_ignore $config_bisect_good;
297830f75da5SSteven Rostedt    }
297930f75da5SSteven Rostedt
29800a05c769SSteven Rostedt    # Make the file with the bad config and the min config
29810a05c769SSteven Rostedt    if (defined($minconfig)) {
29820a05c769SSteven Rostedt	# read the min config for things to ignore
29830a05c769SSteven Rostedt	run_command "cp $minconfig $tmpconfig" or
29840a05c769SSteven Rostedt	    dodie "failed to copy $minconfig to $tmpconfig";
29850a05c769SSteven Rostedt    } else {
29860a05c769SSteven Rostedt	unlink $tmpconfig;
29870a05c769SSteven Rostedt    }
29880a05c769SSteven Rostedt
29890a05c769SSteven Rostedt    if (-f $tmpconfig) {
2990fcb3f16aSSteven Rostedt	load_force_config($tmpconfig);
29910a05c769SSteven Rostedt	process_config_ignore $tmpconfig;
29920a05c769SSteven Rostedt    }
29930a05c769SSteven Rostedt
29940a05c769SSteven Rostedt    # now process the start config
29950a05c769SSteven Rostedt    run_command "cp $start_config $output_config" or
29960a05c769SSteven Rostedt	dodie "failed to copy $start_config to $output_config";
29970a05c769SSteven Rostedt
29980a05c769SSteven Rostedt    # read directly what we want to check
29990a05c769SSteven Rostedt    my %config_check;
30000a05c769SSteven Rostedt    open (IN, $output_config)
3001f9dee311SMasanari Iida	or dodie "failed to open $output_config";
30020a05c769SSteven Rostedt
30030a05c769SSteven Rostedt    while (<IN>) {
30040a05c769SSteven Rostedt	if (/^((CONFIG\S*)=.*)/) {
30050a05c769SSteven Rostedt	    $config_check{$2} = $1;
30060a05c769SSteven Rostedt	}
30070a05c769SSteven Rostedt    }
30080a05c769SSteven Rostedt    close(IN);
30090a05c769SSteven Rostedt
3010250bae8bSSteven Rostedt    # Now run oldconfig with the minconfig
3011fcb3f16aSSteven Rostedt    make_oldconfig;
30120a05c769SSteven Rostedt
30130a05c769SSteven Rostedt    # check to see what we lost (or gained)
30140a05c769SSteven Rostedt    open (IN, $output_config)
30150a05c769SSteven Rostedt	or dodie "Failed to read $start_config";
30160a05c769SSteven Rostedt
30170a05c769SSteven Rostedt    my %removed_configs;
30180a05c769SSteven Rostedt    my %added_configs;
30190a05c769SSteven Rostedt
30200a05c769SSteven Rostedt    while (<IN>) {
30210a05c769SSteven Rostedt	if (/^((CONFIG\S*)=.*)/) {
30220a05c769SSteven Rostedt	    # save off all options
30230a05c769SSteven Rostedt	    $config_set{$2} = $1;
30240a05c769SSteven Rostedt	    if (defined($config_check{$2})) {
30250a05c769SSteven Rostedt		if (defined($config_ignore{$2})) {
30260a05c769SSteven Rostedt		    $removed_configs{$2} = $1;
30270a05c769SSteven Rostedt		} else {
30280a05c769SSteven Rostedt		    $config_list{$2} = $1;
30290a05c769SSteven Rostedt		}
30300a05c769SSteven Rostedt	    } elsif (!defined($config_ignore{$2})) {
30310a05c769SSteven Rostedt		$added_configs{$2} = $1;
30320a05c769SSteven Rostedt		$config_list{$2} = $1;
30330a05c769SSteven Rostedt	    }
3034cf79fab6SSteven Rostedt	} elsif (/^# ((CONFIG\S*).*)/) {
3035cf79fab6SSteven Rostedt	    # Keep these configs disabled
3036cf79fab6SSteven Rostedt	    $config_set{$2} = $1;
3037cf79fab6SSteven Rostedt	    $config_off{$2} = $1;
30380a05c769SSteven Rostedt	}
30390a05c769SSteven Rostedt    }
30400a05c769SSteven Rostedt    close(IN);
30410a05c769SSteven Rostedt
30420a05c769SSteven Rostedt    my @confs = keys %removed_configs;
30430a05c769SSteven Rostedt    if ($#confs >= 0) {
30440a05c769SSteven Rostedt	doprint "Configs overridden by default configs and removed from check:\n";
30450a05c769SSteven Rostedt	foreach my $config (@confs) {
30460a05c769SSteven Rostedt	    doprint " $config\n";
30470a05c769SSteven Rostedt	}
30480a05c769SSteven Rostedt    }
30490a05c769SSteven Rostedt    @confs = keys %added_configs;
30500a05c769SSteven Rostedt    if ($#confs >= 0) {
30510a05c769SSteven Rostedt	doprint "Configs appearing in make oldconfig and added:\n";
30520a05c769SSteven Rostedt	foreach my $config (@confs) {
30530a05c769SSteven Rostedt	    doprint " $config\n";
30540a05c769SSteven Rostedt	}
30550a05c769SSteven Rostedt    }
30560a05c769SSteven Rostedt
30570a05c769SSteven Rostedt    my %config_test;
30580a05c769SSteven Rostedt    my $once = 0;
30590a05c769SSteven Rostedt
3060cf79fab6SSteven Rostedt    @config_off_tmp = ();
3061cf79fab6SSteven Rostedt
30620a05c769SSteven Rostedt    # Sometimes kconfig does weird things. We must make sure
30630a05c769SSteven Rostedt    # that the config we autocreate has everything we need
30640a05c769SSteven Rostedt    # to test, otherwise we may miss testing configs, or
30650a05c769SSteven Rostedt    # may not be able to create a new config.
30660a05c769SSteven Rostedt    # Here we create a config with everything set.
30670a05c769SSteven Rostedt    create_config (keys %config_list);
30680a05c769SSteven Rostedt    read_current_config \%config_test;
30690a05c769SSteven Rostedt    foreach my $config (keys %config_list) {
30700a05c769SSteven Rostedt	if (!defined($config_test{$config})) {
30710a05c769SSteven Rostedt	    if (!$once) {
30720a05c769SSteven Rostedt		$once = 1;
30730a05c769SSteven Rostedt		doprint "Configs not produced by kconfig (will not be checked):\n";
30740a05c769SSteven Rostedt	    }
30750a05c769SSteven Rostedt	    doprint "  $config\n";
30760a05c769SSteven Rostedt	    delete $config_list{$config};
30770a05c769SSteven Rostedt	}
30780a05c769SSteven Rostedt    }
30790a05c769SSteven Rostedt    my $ret;
3080b0918612SSteven Rostedt
3081b0918612SSteven Rostedt    if (defined($config_bisect_check) && $config_bisect_check) {
3082b0918612SSteven Rostedt	doprint " Checking to make sure bad config with min config fails\n";
3083b0918612SSteven Rostedt	create_config keys %config_list;
3084b0918612SSteven Rostedt	$ret = run_config_bisect_test $config_bisect_type;
3085b0918612SSteven Rostedt	if ($ret) {
3086b0918612SSteven Rostedt	    doprint " FAILED! Bad config with min config boots fine\n";
3087b0918612SSteven Rostedt	    return -1;
3088b0918612SSteven Rostedt	}
3089b0918612SSteven Rostedt	doprint " Bad config with min config fails as expected\n";
3090b0918612SSteven Rostedt    }
3091b0918612SSteven Rostedt
30920a05c769SSteven Rostedt    do {
30930a05c769SSteven Rostedt	$ret = run_config_bisect;
30940a05c769SSteven Rostedt    } while (!$ret);
30950a05c769SSteven Rostedt
30960a05c769SSteven Rostedt    return $ret if ($ret < 0);
30975f9b6cedSSteven Rostedt
30985f9b6cedSSteven Rostedt    success $i;
30995f9b6cedSSteven Rostedt}
31005f9b6cedSSteven Rostedt
310127d934b2SSteven Rostedtsub patchcheck_reboot {
310227d934b2SSteven Rostedt    doprint "Reboot and sleep $patchcheck_sleep_time seconds\n";
3103bc7c5803SSteven Rostedt    reboot_to_good $patchcheck_sleep_time;
310427d934b2SSteven Rostedt}
310527d934b2SSteven Rostedt
31066c5ee0beSSteven Rostedtsub patchcheck {
31076c5ee0beSSteven Rostedt    my ($i) = @_;
31086c5ee0beSSteven Rostedt
31096c5ee0beSSteven Rostedt    die "PATCHCHECK_START[$i] not defined\n"
3110b5f4aea6SSteven Rostedt	if (!defined($patchcheck_start));
31116c5ee0beSSteven Rostedt    die "PATCHCHECK_TYPE[$i] not defined\n"
3112b5f4aea6SSteven Rostedt	if (!defined($patchcheck_type));
31136c5ee0beSSteven Rostedt
3114b5f4aea6SSteven Rostedt    my $start = $patchcheck_start;
31156c5ee0beSSteven Rostedt
31166c5ee0beSSteven Rostedt    my $end = "HEAD";
3117b5f4aea6SSteven Rostedt    if (defined($patchcheck_end)) {
3118b5f4aea6SSteven Rostedt	$end = $patchcheck_end;
31196c5ee0beSSteven Rostedt    }
31206c5ee0beSSteven Rostedt
3121a57419b3SSteven Rostedt    # Get the true sha1's since we can use things like HEAD~3
3122a57419b3SSteven Rostedt    $start = get_sha1($start);
3123a57419b3SSteven Rostedt    $end = get_sha1($end);
3124a57419b3SSteven Rostedt
3125b5f4aea6SSteven Rostedt    my $type = $patchcheck_type;
31266c5ee0beSSteven Rostedt
31276c5ee0beSSteven Rostedt    # Can't have a test without having a test to run
31286c5ee0beSSteven Rostedt    if ($type eq "test" && !defined($run_test)) {
31296c5ee0beSSteven Rostedt	$type = "boot";
31306c5ee0beSSteven Rostedt    }
31316c5ee0beSSteven Rostedt
31326c5ee0beSSteven Rostedt    open (IN, "git log --pretty=oneline $end|") or
31336c5ee0beSSteven Rostedt	dodie "could not get git list";
31346c5ee0beSSteven Rostedt
31356c5ee0beSSteven Rostedt    my @list;
31366c5ee0beSSteven Rostedt
31376c5ee0beSSteven Rostedt    while (<IN>) {
31386c5ee0beSSteven Rostedt	chomp;
31396c5ee0beSSteven Rostedt	$list[$#list+1] = $_;
31406c5ee0beSSteven Rostedt	last if (/^$start/);
31416c5ee0beSSteven Rostedt    }
31426c5ee0beSSteven Rostedt    close(IN);
31436c5ee0beSSteven Rostedt
31446c5ee0beSSteven Rostedt    if ($list[$#list] !~ /^$start/) {
31452b7d9b21SSteven Rostedt	fail "SHA1 $start not found";
31466c5ee0beSSteven Rostedt    }
31476c5ee0beSSteven Rostedt
31486c5ee0beSSteven Rostedt    # go backwards in the list
31496c5ee0beSSteven Rostedt    @list = reverse @list;
31506c5ee0beSSteven Rostedt
31516c5ee0beSSteven Rostedt    my $save_clean = $noclean;
31521990207dSSteven Rostedt    my %ignored_warnings;
31531990207dSSteven Rostedt
31541990207dSSteven Rostedt    if (defined($ignore_warnings)) {
31551990207dSSteven Rostedt	foreach my $sha1 (split /\s+/, $ignore_warnings) {
31561990207dSSteven Rostedt	    $ignored_warnings{$sha1} = 1;
31571990207dSSteven Rostedt	}
31581990207dSSteven Rostedt    }
31596c5ee0beSSteven Rostedt
31606c5ee0beSSteven Rostedt    $in_patchcheck = 1;
31616c5ee0beSSteven Rostedt    foreach my $item (@list) {
31626c5ee0beSSteven Rostedt	my $sha1 = $item;
31636c5ee0beSSteven Rostedt	$sha1 =~ s/^([[:xdigit:]]+).*/$1/;
31646c5ee0beSSteven Rostedt
31656c5ee0beSSteven Rostedt	doprint "\nProcessing commit $item\n\n";
31666c5ee0beSSteven Rostedt
31676c5ee0beSSteven Rostedt	run_command "git checkout $sha1" or
31686c5ee0beSSteven Rostedt	    die "Failed to checkout $sha1";
31696c5ee0beSSteven Rostedt
31706c5ee0beSSteven Rostedt	# only clean on the first and last patch
31716c5ee0beSSteven Rostedt	if ($item eq $list[0] ||
31726c5ee0beSSteven Rostedt	    $item eq $list[$#list]) {
31736c5ee0beSSteven Rostedt	    $noclean = $save_clean;
31746c5ee0beSSteven Rostedt	} else {
31756c5ee0beSSteven Rostedt	    $noclean = 1;
31766c5ee0beSSteven Rostedt	}
31776c5ee0beSSteven Rostedt
31786c5ee0beSSteven Rostedt	if (defined($minconfig)) {
31792b7d9b21SSteven Rostedt	    build "useconfig:$minconfig" or return 0;
31806c5ee0beSSteven Rostedt	} else {
31816c5ee0beSSteven Rostedt	    # ?? no config to use?
31822b7d9b21SSteven Rostedt	    build "oldconfig" or return 0;
31836c5ee0beSSteven Rostedt	}
31846c5ee0beSSteven Rostedt
31854283b169SSteven Rostedt (Red Hat)	# No need to do per patch checking if warnings file exists
31864283b169SSteven Rostedt (Red Hat)	if (!defined($warnings_file) && !defined($ignored_warnings{$sha1})) {
31874283b169SSteven Rostedt (Red Hat)	    check_patch_buildlog $sha1 or return 0;
31881990207dSSteven Rostedt	}
31896c5ee0beSSteven Rostedt
31904283b169SSteven Rostedt (Red Hat)	check_buildlog or return 0;
31914283b169SSteven Rostedt (Red Hat)
31926c5ee0beSSteven Rostedt	next if ($type eq "build");
31936c5ee0beSSteven Rostedt
31947faafbd6SSteven Rostedt	my $failed = 0;
31957faafbd6SSteven Rostedt
3196ddf607e5SSteven Rostedt	start_monitor_and_boot or $failed = 1;
31977faafbd6SSteven Rostedt
31987faafbd6SSteven Rostedt	if (!$failed && $type ne "boot"){
31997faafbd6SSteven Rostedt	    do_run_test or $failed = 1;
32007faafbd6SSteven Rostedt	}
32017faafbd6SSteven Rostedt	end_monitor;
32027faafbd6SSteven Rostedt	return 0 if ($failed);
32037faafbd6SSteven Rostedt
320427d934b2SSteven Rostedt	patchcheck_reboot;
320527d934b2SSteven Rostedt
32066c5ee0beSSteven Rostedt    }
32076c5ee0beSSteven Rostedt    $in_patchcheck = 0;
32086c5ee0beSSteven Rostedt    success $i;
32092b7d9b21SSteven Rostedt
32102b7d9b21SSteven Rostedt    return 1;
32116c5ee0beSSteven Rostedt}
32126c5ee0beSSteven Rostedt
3213b9066f6cSSteven Rostedtmy %depends;
3214ac6974c7SSteven Rostedtmy %depcount;
3215b9066f6cSSteven Rostedtmy $iflevel = 0;
3216b9066f6cSSteven Rostedtmy @ifdeps;
3217b9066f6cSSteven Rostedt
3218b9066f6cSSteven Rostedt# prevent recursion
3219b9066f6cSSteven Rostedtmy %read_kconfigs;
3220b9066f6cSSteven Rostedt
3221ac6974c7SSteven Rostedtsub add_dep {
3222ac6974c7SSteven Rostedt    # $config depends on $dep
3223ac6974c7SSteven Rostedt    my ($config, $dep) = @_;
3224ac6974c7SSteven Rostedt
3225ac6974c7SSteven Rostedt    if (defined($depends{$config})) {
3226ac6974c7SSteven Rostedt	$depends{$config} .= " " . $dep;
3227ac6974c7SSteven Rostedt    } else {
3228ac6974c7SSteven Rostedt	$depends{$config} = $dep;
3229ac6974c7SSteven Rostedt    }
3230ac6974c7SSteven Rostedt
3231ac6974c7SSteven Rostedt    # record the number of configs depending on $dep
3232ac6974c7SSteven Rostedt    if (defined $depcount{$dep}) {
3233ac6974c7SSteven Rostedt	$depcount{$dep}++;
3234ac6974c7SSteven Rostedt    } else {
3235ac6974c7SSteven Rostedt	$depcount{$dep} = 1;
3236ac6974c7SSteven Rostedt    }
3237ac6974c7SSteven Rostedt}
3238ac6974c7SSteven Rostedt
3239b9066f6cSSteven Rostedt# taken from streamline_config.pl
3240b9066f6cSSteven Rostedtsub read_kconfig {
3241b9066f6cSSteven Rostedt    my ($kconfig) = @_;
3242b9066f6cSSteven Rostedt
3243b9066f6cSSteven Rostedt    my $state = "NONE";
3244b9066f6cSSteven Rostedt    my $config;
3245b9066f6cSSteven Rostedt    my @kconfigs;
3246b9066f6cSSteven Rostedt
3247b9066f6cSSteven Rostedt    my $cont = 0;
3248b9066f6cSSteven Rostedt    my $line;
3249b9066f6cSSteven Rostedt
3250b9066f6cSSteven Rostedt
3251b9066f6cSSteven Rostedt    if (! -f $kconfig) {
3252b9066f6cSSteven Rostedt	doprint "file $kconfig does not exist, skipping\n";
3253b9066f6cSSteven Rostedt	return;
3254b9066f6cSSteven Rostedt    }
3255b9066f6cSSteven Rostedt
3256b9066f6cSSteven Rostedt    open(KIN, "$kconfig")
3257b9066f6cSSteven Rostedt	or die "Can't open $kconfig";
3258b9066f6cSSteven Rostedt    while (<KIN>) {
3259b9066f6cSSteven Rostedt	chomp;
3260b9066f6cSSteven Rostedt
3261b9066f6cSSteven Rostedt	# Make sure that lines ending with \ continue
3262b9066f6cSSteven Rostedt	if ($cont) {
3263b9066f6cSSteven Rostedt	    $_ = $line . " " . $_;
3264b9066f6cSSteven Rostedt	}
3265b9066f6cSSteven Rostedt
3266b9066f6cSSteven Rostedt	if (s/\\$//) {
3267b9066f6cSSteven Rostedt	    $cont = 1;
3268b9066f6cSSteven Rostedt	    $line = $_;
3269b9066f6cSSteven Rostedt	    next;
3270b9066f6cSSteven Rostedt	}
3271b9066f6cSSteven Rostedt
3272b9066f6cSSteven Rostedt	$cont = 0;
3273b9066f6cSSteven Rostedt
3274b9066f6cSSteven Rostedt	# collect any Kconfig sources
3275b9066f6cSSteven Rostedt	if (/^source\s*"(.*)"/) {
3276b9066f6cSSteven Rostedt	    $kconfigs[$#kconfigs+1] = $1;
3277b9066f6cSSteven Rostedt	}
3278b9066f6cSSteven Rostedt
3279b9066f6cSSteven Rostedt	# configs found
3280b9066f6cSSteven Rostedt	if (/^\s*(menu)?config\s+(\S+)\s*$/) {
3281b9066f6cSSteven Rostedt	    $state = "NEW";
3282b9066f6cSSteven Rostedt	    $config = $2;
3283b9066f6cSSteven Rostedt
3284b9066f6cSSteven Rostedt	    for (my $i = 0; $i < $iflevel; $i++) {
3285ac6974c7SSteven Rostedt		add_dep $config, $ifdeps[$i];
3286b9066f6cSSteven Rostedt	    }
3287b9066f6cSSteven Rostedt
3288b9066f6cSSteven Rostedt	# collect the depends for the config
3289b9066f6cSSteven Rostedt	} elsif ($state eq "NEW" && /^\s*depends\s+on\s+(.*)$/) {
3290b9066f6cSSteven Rostedt
3291ac6974c7SSteven Rostedt	    add_dep $config, $1;
3292b9066f6cSSteven Rostedt
3293b9066f6cSSteven Rostedt	# Get the configs that select this config
3294ac6974c7SSteven Rostedt	} elsif ($state eq "NEW" && /^\s*select\s+(\S+)/) {
3295ac6974c7SSteven Rostedt
3296ac6974c7SSteven Rostedt	    # selected by depends on config
3297ac6974c7SSteven Rostedt	    add_dep $1, $config;
3298b9066f6cSSteven Rostedt
3299b9066f6cSSteven Rostedt	# Check for if statements
3300b9066f6cSSteven Rostedt	} elsif (/^if\s+(.*\S)\s*$/) {
3301b9066f6cSSteven Rostedt	    my $deps = $1;
3302b9066f6cSSteven Rostedt	    # remove beginning and ending non text
3303b9066f6cSSteven Rostedt	    $deps =~ s/^[^a-zA-Z0-9_]*//;
3304b9066f6cSSteven Rostedt	    $deps =~ s/[^a-zA-Z0-9_]*$//;
3305b9066f6cSSteven Rostedt
3306b9066f6cSSteven Rostedt	    my @deps = split /[^a-zA-Z0-9_]+/, $deps;
3307b9066f6cSSteven Rostedt
3308b9066f6cSSteven Rostedt	    $ifdeps[$iflevel++] = join ':', @deps;
3309b9066f6cSSteven Rostedt
3310b9066f6cSSteven Rostedt	} elsif (/^endif/) {
3311b9066f6cSSteven Rostedt
3312b9066f6cSSteven Rostedt	    $iflevel-- if ($iflevel);
3313b9066f6cSSteven Rostedt
3314b9066f6cSSteven Rostedt	# stop on "help"
3315b9066f6cSSteven Rostedt	} elsif (/^\s*help\s*$/) {
3316b9066f6cSSteven Rostedt	    $state = "NONE";
3317b9066f6cSSteven Rostedt	}
3318b9066f6cSSteven Rostedt    }
3319b9066f6cSSteven Rostedt    close(KIN);
3320b9066f6cSSteven Rostedt
3321b9066f6cSSteven Rostedt    # read in any configs that were found.
3322b9066f6cSSteven Rostedt    foreach $kconfig (@kconfigs) {
3323b9066f6cSSteven Rostedt	if (!defined($read_kconfigs{$kconfig})) {
3324b9066f6cSSteven Rostedt	    $read_kconfigs{$kconfig} = 1;
3325b9066f6cSSteven Rostedt	    read_kconfig("$builddir/$kconfig");
3326b9066f6cSSteven Rostedt	}
3327b9066f6cSSteven Rostedt    }
3328b9066f6cSSteven Rostedt}
3329b9066f6cSSteven Rostedt
3330b9066f6cSSteven Rostedtsub read_depends {
3331b9066f6cSSteven Rostedt    # find out which arch this is by the kconfig file
3332b9066f6cSSteven Rostedt    open (IN, $output_config)
3333b9066f6cSSteven Rostedt	or dodie "Failed to read $output_config";
3334b9066f6cSSteven Rostedt    my $arch;
3335b9066f6cSSteven Rostedt    while (<IN>) {
3336b9066f6cSSteven Rostedt	if (m,Linux/(\S+)\s+\S+\s+Kernel Configuration,) {
3337b9066f6cSSteven Rostedt	    $arch = $1;
3338b9066f6cSSteven Rostedt	    last;
3339b9066f6cSSteven Rostedt	}
3340b9066f6cSSteven Rostedt    }
3341b9066f6cSSteven Rostedt    close IN;
3342b9066f6cSSteven Rostedt
3343b9066f6cSSteven Rostedt    if (!defined($arch)) {
3344b9066f6cSSteven Rostedt	doprint "Could not find arch from config file\n";
3345b9066f6cSSteven Rostedt	doprint "no dependencies used\n";
3346b9066f6cSSteven Rostedt	return;
3347b9066f6cSSteven Rostedt    }
3348b9066f6cSSteven Rostedt
3349b9066f6cSSteven Rostedt    # arch is really the subarch, we need to know
3350b9066f6cSSteven Rostedt    # what directory to look at.
3351b9066f6cSSteven Rostedt    if ($arch eq "i386" || $arch eq "x86_64") {
3352b9066f6cSSteven Rostedt	$arch = "x86";
3353b9066f6cSSteven Rostedt    } elsif ($arch =~ /^tile/) {
3354b9066f6cSSteven Rostedt	$arch = "tile";
3355b9066f6cSSteven Rostedt    }
3356b9066f6cSSteven Rostedt
3357b9066f6cSSteven Rostedt    my $kconfig = "$builddir/arch/$arch/Kconfig";
3358b9066f6cSSteven Rostedt
3359b9066f6cSSteven Rostedt    if (! -f $kconfig && $arch =~ /\d$/) {
3360b9066f6cSSteven Rostedt	my $orig = $arch;
3361b9066f6cSSteven Rostedt 	# some subarchs have numbers, truncate them
3362b9066f6cSSteven Rostedt	$arch =~ s/\d*$//;
3363b9066f6cSSteven Rostedt	$kconfig = "$builddir/arch/$arch/Kconfig";
3364b9066f6cSSteven Rostedt	if (! -f $kconfig) {
3365b9066f6cSSteven Rostedt	    doprint "No idea what arch dir $orig is for\n";
3366b9066f6cSSteven Rostedt	    doprint "no dependencies used\n";
3367b9066f6cSSteven Rostedt	    return;
3368b9066f6cSSteven Rostedt	}
3369b9066f6cSSteven Rostedt    }
3370b9066f6cSSteven Rostedt
3371b9066f6cSSteven Rostedt    read_kconfig($kconfig);
3372b9066f6cSSteven Rostedt}
3373b9066f6cSSteven Rostedt
33744c4ab120SSteven Rostedtsub read_config_list {
33754c4ab120SSteven Rostedt    my ($config) = @_;
33764c4ab120SSteven Rostedt
33774c4ab120SSteven Rostedt    open (IN, $config)
33784c4ab120SSteven Rostedt	or dodie "Failed to read $config";
33794c4ab120SSteven Rostedt
33804c4ab120SSteven Rostedt    while (<IN>) {
33814c4ab120SSteven Rostedt	if (/^((CONFIG\S*)=.*)/) {
33824c4ab120SSteven Rostedt	    if (!defined($config_ignore{$2})) {
33834c4ab120SSteven Rostedt		$config_list{$2} = $1;
33844c4ab120SSteven Rostedt	    }
33854c4ab120SSteven Rostedt	}
33864c4ab120SSteven Rostedt    }
33874c4ab120SSteven Rostedt
33884c4ab120SSteven Rostedt    close(IN);
33894c4ab120SSteven Rostedt}
33904c4ab120SSteven Rostedt
33914c4ab120SSteven Rostedtsub read_output_config {
33924c4ab120SSteven Rostedt    my ($config) = @_;
33934c4ab120SSteven Rostedt
33944c4ab120SSteven Rostedt    assign_configs \%config_ignore, $config;
33954c4ab120SSteven Rostedt}
33964c4ab120SSteven Rostedt
33974c4ab120SSteven Rostedtsub make_new_config {
33984c4ab120SSteven Rostedt    my @configs = @_;
33994c4ab120SSteven Rostedt
34004c4ab120SSteven Rostedt    open (OUT, ">$output_config")
34014c4ab120SSteven Rostedt	or dodie "Failed to write $output_config";
34024c4ab120SSteven Rostedt
34034c4ab120SSteven Rostedt    foreach my $config (@configs) {
34044c4ab120SSteven Rostedt	print OUT "$config\n";
34054c4ab120SSteven Rostedt    }
34064c4ab120SSteven Rostedt    close OUT;
34074c4ab120SSteven Rostedt}
34084c4ab120SSteven Rostedt
3409ac6974c7SSteven Rostedtsub chomp_config {
3410ac6974c7SSteven Rostedt    my ($config) = @_;
3411ac6974c7SSteven Rostedt
3412ac6974c7SSteven Rostedt    $config =~ s/CONFIG_//;
3413ac6974c7SSteven Rostedt
3414ac6974c7SSteven Rostedt    return $config;
3415ac6974c7SSteven Rostedt}
3416ac6974c7SSteven Rostedt
3417b9066f6cSSteven Rostedtsub get_depends {
3418b9066f6cSSteven Rostedt    my ($dep) = @_;
3419b9066f6cSSteven Rostedt
3420ac6974c7SSteven Rostedt    my $kconfig = chomp_config $dep;
3421b9066f6cSSteven Rostedt
3422b9066f6cSSteven Rostedt    $dep = $depends{"$kconfig"};
3423b9066f6cSSteven Rostedt
3424b9066f6cSSteven Rostedt    # the dep string we have saves the dependencies as they
3425b9066f6cSSteven Rostedt    # were found, including expressions like ! && ||. We
3426b9066f6cSSteven Rostedt    # want to split this out into just an array of configs.
3427b9066f6cSSteven Rostedt
3428b9066f6cSSteven Rostedt    my $valid = "A-Za-z_0-9";
3429b9066f6cSSteven Rostedt
3430b9066f6cSSteven Rostedt    my @configs;
3431b9066f6cSSteven Rostedt
3432b9066f6cSSteven Rostedt    while ($dep =~ /[$valid]/) {
3433b9066f6cSSteven Rostedt
3434b9066f6cSSteven Rostedt	if ($dep =~ /^[^$valid]*([$valid]+)/) {
3435b9066f6cSSteven Rostedt	    my $conf = "CONFIG_" . $1;
3436b9066f6cSSteven Rostedt
3437b9066f6cSSteven Rostedt	    $configs[$#configs + 1] = $conf;
3438b9066f6cSSteven Rostedt
3439b9066f6cSSteven Rostedt	    $dep =~ s/^[^$valid]*[$valid]+//;
3440b9066f6cSSteven Rostedt	} else {
3441b9066f6cSSteven Rostedt	    die "this should never happen";
3442b9066f6cSSteven Rostedt	}
3443b9066f6cSSteven Rostedt    }
3444b9066f6cSSteven Rostedt
3445b9066f6cSSteven Rostedt    return @configs;
3446b9066f6cSSteven Rostedt}
3447b9066f6cSSteven Rostedt
3448b9066f6cSSteven Rostedtmy %min_configs;
3449b9066f6cSSteven Rostedtmy %keep_configs;
345043d1b651SSteven Rostedtmy %save_configs;
3451b9066f6cSSteven Rostedtmy %processed_configs;
3452b9066f6cSSteven Rostedtmy %nochange_config;
3453b9066f6cSSteven Rostedt
3454b9066f6cSSteven Rostedtsub test_this_config {
3455b9066f6cSSteven Rostedt    my ($config) = @_;
3456b9066f6cSSteven Rostedt
3457b9066f6cSSteven Rostedt    my $found;
3458b9066f6cSSteven Rostedt
3459b9066f6cSSteven Rostedt    # if we already processed this config, skip it
3460b9066f6cSSteven Rostedt    if (defined($processed_configs{$config})) {
3461b9066f6cSSteven Rostedt	return undef;
3462b9066f6cSSteven Rostedt    }
3463b9066f6cSSteven Rostedt    $processed_configs{$config} = 1;
3464b9066f6cSSteven Rostedt
3465b9066f6cSSteven Rostedt    # if this config failed during this round, skip it
3466b9066f6cSSteven Rostedt    if (defined($nochange_config{$config})) {
3467b9066f6cSSteven Rostedt	return undef;
3468b9066f6cSSteven Rostedt    }
3469b9066f6cSSteven Rostedt
3470ac6974c7SSteven Rostedt    my $kconfig = chomp_config $config;
3471b9066f6cSSteven Rostedt
3472b9066f6cSSteven Rostedt    # Test dependencies first
3473b9066f6cSSteven Rostedt    if (defined($depends{"$kconfig"})) {
3474b9066f6cSSteven Rostedt	my @parents = get_depends $config;
3475b9066f6cSSteven Rostedt	foreach my $parent (@parents) {
3476b9066f6cSSteven Rostedt	    # if the parent is in the min config, check it first
3477b9066f6cSSteven Rostedt	    next if (!defined($min_configs{$parent}));
3478b9066f6cSSteven Rostedt	    $found = test_this_config($parent);
3479b9066f6cSSteven Rostedt	    if (defined($found)) {
3480b9066f6cSSteven Rostedt		return $found;
3481b9066f6cSSteven Rostedt	    }
3482b9066f6cSSteven Rostedt	}
3483b9066f6cSSteven Rostedt    }
3484b9066f6cSSteven Rostedt
3485b9066f6cSSteven Rostedt    # Remove this config from the list of configs
3486fb16d891SAdam Lee    # do a make olddefconfig and then read the resulting
3487b9066f6cSSteven Rostedt    # .config to make sure it is missing the config that
3488b9066f6cSSteven Rostedt    # we had before
3489b9066f6cSSteven Rostedt    my %configs = %min_configs;
3490b9066f6cSSteven Rostedt    delete $configs{$config};
3491b9066f6cSSteven Rostedt    make_new_config ((values %configs), (values %keep_configs));
3492b9066f6cSSteven Rostedt    make_oldconfig;
3493b9066f6cSSteven Rostedt    undef %configs;
3494b9066f6cSSteven Rostedt    assign_configs \%configs, $output_config;
3495b9066f6cSSteven Rostedt
3496b9066f6cSSteven Rostedt    return $config if (!defined($configs{$config}));
3497b9066f6cSSteven Rostedt
3498b9066f6cSSteven Rostedt    doprint "disabling config $config did not change .config\n";
3499b9066f6cSSteven Rostedt
3500b9066f6cSSteven Rostedt    $nochange_config{$config} = 1;
3501b9066f6cSSteven Rostedt
3502b9066f6cSSteven Rostedt    return undef;
3503b9066f6cSSteven Rostedt}
3504b9066f6cSSteven Rostedt
35054c4ab120SSteven Rostedtsub make_min_config {
35064c4ab120SSteven Rostedt    my ($i) = @_;
35074c4ab120SSteven Rostedt
3508ccc513b6SSteven Rostedt    my $type = $minconfig_type;
3509ccc513b6SSteven Rostedt    if ($type ne "boot" && $type ne "test") {
3510ccc513b6SSteven Rostedt	fail "Invalid MIN_CONFIG_TYPE '$minconfig_type'\n" .
3511ccc513b6SSteven Rostedt	    " make_min_config works only with 'boot' and 'test'\n" and return;
3512ccc513b6SSteven Rostedt    }
3513ccc513b6SSteven Rostedt
35144c4ab120SSteven Rostedt    if (!defined($output_minconfig)) {
35154c4ab120SSteven Rostedt	fail "OUTPUT_MIN_CONFIG not defined" and return;
35164c4ab120SSteven Rostedt    }
351735ce5952SSteven Rostedt
351835ce5952SSteven Rostedt    # If output_minconfig exists, and the start_minconfig
351935ce5952SSteven Rostedt    # came from min_config, than ask if we should use
352035ce5952SSteven Rostedt    # that instead.
352135ce5952SSteven Rostedt    if (-f $output_minconfig && !$start_minconfig_defined) {
352235ce5952SSteven Rostedt	print "$output_minconfig exists\n";
352343de3316SSteven Rostedt	if (!defined($use_output_minconfig)) {
352435ce5952SSteven Rostedt	    if (read_yn " Use it as minconfig?") {
352535ce5952SSteven Rostedt		$start_minconfig = $output_minconfig;
352635ce5952SSteven Rostedt	    }
352743de3316SSteven Rostedt	} elsif ($use_output_minconfig > 0) {
352843de3316SSteven Rostedt	    doprint "Using $output_minconfig as MIN_CONFIG\n";
352943de3316SSteven Rostedt	    $start_minconfig = $output_minconfig;
353043de3316SSteven Rostedt	} else {
353143de3316SSteven Rostedt	    doprint "Set to still use MIN_CONFIG as starting point\n";
353243de3316SSteven Rostedt	}
353335ce5952SSteven Rostedt    }
353435ce5952SSteven Rostedt
35354c4ab120SSteven Rostedt    if (!defined($start_minconfig)) {
35364c4ab120SSteven Rostedt	fail "START_MIN_CONFIG or MIN_CONFIG not defined" and return;
35374c4ab120SSteven Rostedt    }
35384c4ab120SSteven Rostedt
353935ce5952SSteven Rostedt    my $temp_config = "$tmpdir/temp_config";
354035ce5952SSteven Rostedt
35414c4ab120SSteven Rostedt    # First things first. We build an allnoconfig to find
35424c4ab120SSteven Rostedt    # out what the defaults are that we can't touch.
35434c4ab120SSteven Rostedt    # Some are selections, but we really can't handle selections.
35444c4ab120SSteven Rostedt
35454c4ab120SSteven Rostedt    my $save_minconfig = $minconfig;
35464c4ab120SSteven Rostedt    undef $minconfig;
35474c4ab120SSteven Rostedt
35484c4ab120SSteven Rostedt    run_command "$make allnoconfig" or return 0;
35494c4ab120SSteven Rostedt
3550b9066f6cSSteven Rostedt    read_depends;
3551b9066f6cSSteven Rostedt
35524c4ab120SSteven Rostedt    process_config_ignore $output_config;
3553b9066f6cSSteven Rostedt
355443d1b651SSteven Rostedt    undef %save_configs;
3555b9066f6cSSteven Rostedt    undef %min_configs;
35564c4ab120SSteven Rostedt
35574c4ab120SSteven Rostedt    if (defined($ignore_config)) {
35584c4ab120SSteven Rostedt	# make sure the file exists
35594c4ab120SSteven Rostedt	`touch $ignore_config`;
356043d1b651SSteven Rostedt	assign_configs \%save_configs, $ignore_config;
35614c4ab120SSteven Rostedt    }
35624c4ab120SSteven Rostedt
356343d1b651SSteven Rostedt    %keep_configs = %save_configs;
356443d1b651SSteven Rostedt
35654c4ab120SSteven Rostedt    doprint "Load initial configs from $start_minconfig\n";
35664c4ab120SSteven Rostedt
35674c4ab120SSteven Rostedt    # Look at the current min configs, and save off all the
35684c4ab120SSteven Rostedt    # ones that were set via the allnoconfig
35694c4ab120SSteven Rostedt    assign_configs \%min_configs, $start_minconfig;
35704c4ab120SSteven Rostedt
35714c4ab120SSteven Rostedt    my @config_keys = keys %min_configs;
35724c4ab120SSteven Rostedt
3573ac6974c7SSteven Rostedt    # All configs need a depcount
3574ac6974c7SSteven Rostedt    foreach my $config (@config_keys) {
3575ac6974c7SSteven Rostedt	my $kconfig = chomp_config $config;
3576ac6974c7SSteven Rostedt	if (!defined $depcount{$kconfig}) {
3577ac6974c7SSteven Rostedt		$depcount{$kconfig} = 0;
3578ac6974c7SSteven Rostedt	}
3579ac6974c7SSteven Rostedt    }
3580ac6974c7SSteven Rostedt
35814c4ab120SSteven Rostedt    # Remove anything that was set by the make allnoconfig
35824c4ab120SSteven Rostedt    # we shouldn't need them as they get set for us anyway.
35834c4ab120SSteven Rostedt    foreach my $config (@config_keys) {
35844c4ab120SSteven Rostedt	# Remove anything in the ignore_config
35854c4ab120SSteven Rostedt	if (defined($keep_configs{$config})) {
35864c4ab120SSteven Rostedt	    my $file = $ignore_config;
35874c4ab120SSteven Rostedt	    $file =~ s,.*/(.*?)$,$1,;
35884c4ab120SSteven Rostedt	    doprint "$config set by $file ... ignored\n";
35894c4ab120SSteven Rostedt	    delete $min_configs{$config};
35904c4ab120SSteven Rostedt	    next;
35914c4ab120SSteven Rostedt	}
35924c4ab120SSteven Rostedt	# But make sure the settings are the same. If a min config
35934c4ab120SSteven Rostedt	# sets a selection, we do not want to get rid of it if
35944c4ab120SSteven Rostedt	# it is not the same as what we have. Just move it into
35954c4ab120SSteven Rostedt	# the keep configs.
35964c4ab120SSteven Rostedt	if (defined($config_ignore{$config})) {
35974c4ab120SSteven Rostedt	    if ($config_ignore{$config} ne $min_configs{$config}) {
35984c4ab120SSteven Rostedt		doprint "$config is in allnoconfig as '$config_ignore{$config}'";
35994c4ab120SSteven Rostedt		doprint " but it is '$min_configs{$config}' in minconfig .. keeping\n";
36004c4ab120SSteven Rostedt		$keep_configs{$config} = $min_configs{$config};
36014c4ab120SSteven Rostedt	    } else {
36024c4ab120SSteven Rostedt		doprint "$config set by allnoconfig ... ignored\n";
36034c4ab120SSteven Rostedt	    }
36044c4ab120SSteven Rostedt	    delete $min_configs{$config};
36054c4ab120SSteven Rostedt	}
36064c4ab120SSteven Rostedt    }
36074c4ab120SSteven Rostedt
36084c4ab120SSteven Rostedt    my $done = 0;
3609b9066f6cSSteven Rostedt    my $take_two = 0;
36104c4ab120SSteven Rostedt
36114c4ab120SSteven Rostedt    while (!$done) {
36124c4ab120SSteven Rostedt
36134c4ab120SSteven Rostedt	my $config;
36144c4ab120SSteven Rostedt	my $found;
36154c4ab120SSteven Rostedt
36164c4ab120SSteven Rostedt	# Now disable each config one by one and do a make oldconfig
36174c4ab120SSteven Rostedt	# till we find a config that changes our list.
36184c4ab120SSteven Rostedt
36194c4ab120SSteven Rostedt	my @test_configs = keys %min_configs;
3620ac6974c7SSteven Rostedt
3621ac6974c7SSteven Rostedt	# Sort keys by who is most dependent on
3622ac6974c7SSteven Rostedt	@test_configs = sort  { $depcount{chomp_config($b)} <=> $depcount{chomp_config($a)} }
3623ac6974c7SSteven Rostedt			  @test_configs ;
3624ac6974c7SSteven Rostedt
3625ac6974c7SSteven Rostedt	# Put configs that did not modify the config at the end.
36264c4ab120SSteven Rostedt	my $reset = 1;
36274c4ab120SSteven Rostedt	for (my $i = 0; $i < $#test_configs; $i++) {
36284c4ab120SSteven Rostedt	    if (!defined($nochange_config{$test_configs[0]})) {
36294c4ab120SSteven Rostedt		$reset = 0;
36304c4ab120SSteven Rostedt		last;
36314c4ab120SSteven Rostedt	    }
36324c4ab120SSteven Rostedt	    # This config didn't change the .config last time.
36334c4ab120SSteven Rostedt	    # Place it at the end
36344c4ab120SSteven Rostedt	    my $config = shift @test_configs;
36354c4ab120SSteven Rostedt	    push @test_configs, $config;
36364c4ab120SSteven Rostedt	}
36374c4ab120SSteven Rostedt
36384c4ab120SSteven Rostedt	# if every test config has failed to modify the .config file
36394c4ab120SSteven Rostedt	# in the past, then reset and start over.
36404c4ab120SSteven Rostedt	if ($reset) {
36414c4ab120SSteven Rostedt	    undef %nochange_config;
36424c4ab120SSteven Rostedt	}
36434c4ab120SSteven Rostedt
3644b9066f6cSSteven Rostedt	undef %processed_configs;
3645b9066f6cSSteven Rostedt
36464c4ab120SSteven Rostedt	foreach my $config (@test_configs) {
36474c4ab120SSteven Rostedt
3648b9066f6cSSteven Rostedt	    $found = test_this_config $config;
36494c4ab120SSteven Rostedt
3650b9066f6cSSteven Rostedt	    last if (defined($found));
36514c4ab120SSteven Rostedt
36524c4ab120SSteven Rostedt	    # oh well, try another config
36534c4ab120SSteven Rostedt	}
36544c4ab120SSteven Rostedt
36554c4ab120SSteven Rostedt	if (!defined($found)) {
3656b9066f6cSSteven Rostedt	    # we could have failed due to the nochange_config hash
3657b9066f6cSSteven Rostedt	    # reset and try again
3658b9066f6cSSteven Rostedt	    if (!$take_two) {
3659b9066f6cSSteven Rostedt		undef %nochange_config;
3660b9066f6cSSteven Rostedt		$take_two = 1;
3661b9066f6cSSteven Rostedt		next;
3662b9066f6cSSteven Rostedt	    }
36634c4ab120SSteven Rostedt	    doprint "No more configs found that we can disable\n";
36644c4ab120SSteven Rostedt	    $done = 1;
36654c4ab120SSteven Rostedt	    last;
36664c4ab120SSteven Rostedt	}
3667b9066f6cSSteven Rostedt	$take_two = 0;
36684c4ab120SSteven Rostedt
36694c4ab120SSteven Rostedt	$config = $found;
36704c4ab120SSteven Rostedt
36714c4ab120SSteven Rostedt	doprint "Test with $config disabled\n";
36724c4ab120SSteven Rostedt
36734c4ab120SSteven Rostedt	# set in_bisect to keep build and monitor from dieing
36744c4ab120SSteven Rostedt	$in_bisect = 1;
36754c4ab120SSteven Rostedt
36764c4ab120SSteven Rostedt	my $failed = 0;
3677bf1c95abSSteven Rostedt	build "oldconfig" or $failed = 1;
3678bf1c95abSSteven Rostedt	if (!$failed) {
36794c4ab120SSteven Rostedt		start_monitor_and_boot or $failed = 1;
3680ccc513b6SSteven Rostedt
3681ccc513b6SSteven Rostedt		if ($type eq "test" && !$failed) {
3682ccc513b6SSteven Rostedt		    do_run_test or $failed = 1;
3683ccc513b6SSteven Rostedt		}
3684ccc513b6SSteven Rostedt
36854c4ab120SSteven Rostedt		end_monitor;
3686bf1c95abSSteven Rostedt	}
36874c4ab120SSteven Rostedt
36884c4ab120SSteven Rostedt	$in_bisect = 0;
36894c4ab120SSteven Rostedt
36904c4ab120SSteven Rostedt	if ($failed) {
3691b9066f6cSSteven Rostedt	    doprint "$min_configs{$config} is needed to boot the box... keeping\n";
36924c4ab120SSteven Rostedt	    # this config is needed, add it to the ignore list.
36934c4ab120SSteven Rostedt	    $keep_configs{$config} = $min_configs{$config};
369443d1b651SSteven Rostedt	    $save_configs{$config} = $min_configs{$config};
36954c4ab120SSteven Rostedt	    delete $min_configs{$config};
369635ce5952SSteven Rostedt
369735ce5952SSteven Rostedt	    # update new ignore configs
369835ce5952SSteven Rostedt	    if (defined($ignore_config)) {
369935ce5952SSteven Rostedt		open (OUT, ">$temp_config")
370035ce5952SSteven Rostedt		    or die "Can't write to $temp_config";
370143d1b651SSteven Rostedt		foreach my $config (keys %save_configs) {
370243d1b651SSteven Rostedt		    print OUT "$save_configs{$config}\n";
370335ce5952SSteven Rostedt		}
370435ce5952SSteven Rostedt		close OUT;
370535ce5952SSteven Rostedt		run_command "mv $temp_config $ignore_config" or
370635ce5952SSteven Rostedt		    dodie "failed to copy update to $ignore_config";
370735ce5952SSteven Rostedt	    }
370835ce5952SSteven Rostedt
37094c4ab120SSteven Rostedt	} else {
37104c4ab120SSteven Rostedt	    # We booted without this config, remove it from the minconfigs.
37114c4ab120SSteven Rostedt	    doprint "$config is not needed, disabling\n";
37124c4ab120SSteven Rostedt
37134c4ab120SSteven Rostedt	    delete $min_configs{$config};
37144c4ab120SSteven Rostedt
37154c4ab120SSteven Rostedt	    # Also disable anything that is not enabled in this config
37164c4ab120SSteven Rostedt	    my %configs;
37174c4ab120SSteven Rostedt	    assign_configs \%configs, $output_config;
37184c4ab120SSteven Rostedt	    my @config_keys = keys %min_configs;
37194c4ab120SSteven Rostedt	    foreach my $config (@config_keys) {
37204c4ab120SSteven Rostedt		if (!defined($configs{$config})) {
37214c4ab120SSteven Rostedt		    doprint "$config is not set, disabling\n";
37224c4ab120SSteven Rostedt		    delete $min_configs{$config};
37234c4ab120SSteven Rostedt		}
37244c4ab120SSteven Rostedt	    }
37254c4ab120SSteven Rostedt
37264c4ab120SSteven Rostedt	    # Save off all the current mandidory configs
372735ce5952SSteven Rostedt	    open (OUT, ">$temp_config")
372835ce5952SSteven Rostedt		or die "Can't write to $temp_config";
37294c4ab120SSteven Rostedt	    foreach my $config (keys %keep_configs) {
37304c4ab120SSteven Rostedt		print OUT "$keep_configs{$config}\n";
37314c4ab120SSteven Rostedt	    }
37324c4ab120SSteven Rostedt	    foreach my $config (keys %min_configs) {
37334c4ab120SSteven Rostedt		print OUT "$min_configs{$config}\n";
37344c4ab120SSteven Rostedt	    }
37354c4ab120SSteven Rostedt	    close OUT;
373635ce5952SSteven Rostedt
373735ce5952SSteven Rostedt	    run_command "mv $temp_config $output_minconfig" or
373835ce5952SSteven Rostedt		dodie "failed to copy update to $output_minconfig";
37394c4ab120SSteven Rostedt	}
37404c4ab120SSteven Rostedt
37414c4ab120SSteven Rostedt	doprint "Reboot and wait $sleep_time seconds\n";
3742bc7c5803SSteven Rostedt	reboot_to_good $sleep_time;
37434c4ab120SSteven Rostedt    }
37444c4ab120SSteven Rostedt
37454c4ab120SSteven Rostedt    success $i;
37464c4ab120SSteven Rostedt    return 1;
37474c4ab120SSteven Rostedt}
37484c4ab120SSteven Rostedt
37494283b169SSteven Rostedt (Red Hat)sub make_warnings_file {
37504283b169SSteven Rostedt (Red Hat)    my ($i) = @_;
37514283b169SSteven Rostedt (Red Hat)
37524283b169SSteven Rostedt (Red Hat)    if (!defined($warnings_file)) {
37534283b169SSteven Rostedt (Red Hat)	dodie "Must define WARNINGS_FILE for make_warnings_file test";
37544283b169SSteven Rostedt (Red Hat)    }
37554283b169SSteven Rostedt (Red Hat)
37564283b169SSteven Rostedt (Red Hat)    if ($build_type eq "nobuild") {
37574283b169SSteven Rostedt (Red Hat)	dodie "BUILD_TYPE can not be 'nobuild' for make_warnings_file test";
37584283b169SSteven Rostedt (Red Hat)    }
37594283b169SSteven Rostedt (Red Hat)
37604283b169SSteven Rostedt (Red Hat)    build $build_type or dodie "Failed to build";
37614283b169SSteven Rostedt (Red Hat)
37624283b169SSteven Rostedt (Red Hat)    open(OUT, ">$warnings_file") or dodie "Can't create $warnings_file";
37634283b169SSteven Rostedt (Red Hat)
37644283b169SSteven Rostedt (Red Hat)    open(IN, $buildlog) or dodie "Can't open $buildlog";
37654283b169SSteven Rostedt (Red Hat)    while (<IN>) {
37664283b169SSteven Rostedt (Red Hat)
37674283b169SSteven Rostedt (Red Hat)	# Some compilers use UTF-8 extended for quotes
37684283b169SSteven Rostedt (Red Hat)	# for distcc heterogeneous systems, this causes issues
37694283b169SSteven Rostedt (Red Hat)	s/$utf8_quote/'/g;
37704283b169SSteven Rostedt (Red Hat)
37714283b169SSteven Rostedt (Red Hat)	if (/$check_build_re/) {
37724283b169SSteven Rostedt (Red Hat)	    print OUT;
37734283b169SSteven Rostedt (Red Hat)	}
37744283b169SSteven Rostedt (Red Hat)    }
37754283b169SSteven Rostedt (Red Hat)    close(IN);
37764283b169SSteven Rostedt (Red Hat)
37774283b169SSteven Rostedt (Red Hat)    close(OUT);
37784283b169SSteven Rostedt (Red Hat)
37794283b169SSteven Rostedt (Red Hat)    success $i;
37804283b169SSteven Rostedt (Red Hat)}
37814283b169SSteven Rostedt (Red Hat)
37828d1491baSSteven Rostedt$#ARGV < 1 or die "ktest.pl version: $VERSION\n   usage: ktest.pl config-file\n";
37832545eb61SSteven Rostedt
37848d1491baSSteven Rostedtif ($#ARGV == 0) {
37858d1491baSSteven Rostedt    $ktest_config = $ARGV[0];
37868d1491baSSteven Rostedt    if (! -f $ktest_config) {
37878d1491baSSteven Rostedt	print "$ktest_config does not exist.\n";
378835ce5952SSteven Rostedt	if (!read_yn "Create it?") {
37898d1491baSSteven Rostedt	    exit 0;
37908d1491baSSteven Rostedt	}
37918d1491baSSteven Rostedt    }
37928d1491baSSteven Rostedt} else {
37938d1491baSSteven Rostedt    $ktest_config = "ktest.conf";
37948d1491baSSteven Rostedt}
37958d1491baSSteven Rostedt
37968d1491baSSteven Rostedtif (! -f $ktest_config) {
3797dbd3783bSSteven Rostedt    $newconfig = 1;
3798c4261d0fSSteven Rostedt    get_test_case;
37998d1491baSSteven Rostedt    open(OUT, ">$ktest_config") or die "Can not create $ktest_config";
38008d1491baSSteven Rostedt    print OUT << "EOF"
38018d1491baSSteven Rostedt# Generated by ktest.pl
38028d1491baSSteven Rostedt#
38030e7a22deSSteven Rostedt
38040e7a22deSSteven Rostedt# PWD is a ktest.pl variable that will result in the process working
38050e7a22deSSteven Rostedt# directory that ktest.pl is executed in.
38060e7a22deSSteven Rostedt
38070e7a22deSSteven Rostedt# THIS_DIR is automatically assigned the PWD of the path that generated
38080e7a22deSSteven Rostedt# the config file. It is best to use this variable when assigning other
38090e7a22deSSteven Rostedt# directory paths within this directory. This allows you to easily
38100e7a22deSSteven Rostedt# move the test cases to other locations or to other machines.
38110e7a22deSSteven Rostedt#
38120e7a22deSSteven RostedtTHIS_DIR := $variable{"PWD"}
38130e7a22deSSteven Rostedt
38148d1491baSSteven Rostedt# Define each test with TEST_START
38158d1491baSSteven Rostedt# The config options below it will override the defaults
38168d1491baSSteven RostedtTEST_START
3817c4261d0fSSteven RostedtTEST_TYPE = $default{"TEST_TYPE"}
38188d1491baSSteven Rostedt
38198d1491baSSteven RostedtDEFAULTS
38208d1491baSSteven RostedtEOF
38218d1491baSSteven Rostedt;
38228d1491baSSteven Rostedt    close(OUT);
38238d1491baSSteven Rostedt}
38248d1491baSSteven Rostedtread_config $ktest_config;
38258d1491baSSteven Rostedt
382623715c3cSSteven Rostedtif (defined($opt{"LOG_FILE"})) {
382704262be3SSteven Rostedt (Red Hat)    $opt{"LOG_FILE"} = eval_option("LOG_FILE", $opt{"LOG_FILE"}, -1);
382823715c3cSSteven Rostedt}
382923715c3cSSteven Rostedt
38308d1491baSSteven Rostedt# Append any configs entered in manually to the config file.
38318d1491baSSteven Rostedtmy @new_configs = keys %entered_configs;
38328d1491baSSteven Rostedtif ($#new_configs >= 0) {
38338d1491baSSteven Rostedt    print "\nAppending entered in configs to $ktest_config\n";
38348d1491baSSteven Rostedt    open(OUT, ">>$ktest_config") or die "Can not append to $ktest_config";
38358d1491baSSteven Rostedt    foreach my $config (@new_configs) {
38368d1491baSSteven Rostedt	print OUT "$config = $entered_configs{$config}\n";
38370e7a22deSSteven Rostedt	$opt{$config} = process_variables($entered_configs{$config});
38388d1491baSSteven Rostedt    }
38398d1491baSSteven Rostedt}
38402545eb61SSteven Rostedt
38412b7d9b21SSteven Rostedtif ($opt{"CLEAR_LOG"} && defined($opt{"LOG_FILE"})) {
38422b7d9b21SSteven Rostedt    unlink $opt{"LOG_FILE"};
38432b7d9b21SSteven Rostedt}
38442545eb61SSteven Rostedt
38452b7d9b21SSteven Rostedtdoprint "\n\nSTARTING AUTOMATED TESTS\n\n";
38462b7d9b21SSteven Rostedt
3847a57419b3SSteven Rostedtfor (my $i = 0, my $repeat = 1; $i <= $opt{"NUM_TESTS"}; $i += $repeat) {
3848a57419b3SSteven Rostedt
3849a57419b3SSteven Rostedt    if (!$i) {
3850a57419b3SSteven Rostedt	doprint "DEFAULT OPTIONS:\n";
3851a57419b3SSteven Rostedt    } else {
3852a57419b3SSteven Rostedt	doprint "\nTEST $i OPTIONS";
3853a57419b3SSteven Rostedt	if (defined($repeat_tests{$i})) {
3854a57419b3SSteven Rostedt	    $repeat = $repeat_tests{$i};
3855a57419b3SSteven Rostedt	    doprint " ITERATE $repeat";
3856a57419b3SSteven Rostedt	}
3857a57419b3SSteven Rostedt	doprint "\n";
3858a57419b3SSteven Rostedt    }
3859a57419b3SSteven Rostedt
38602b7d9b21SSteven Rostedt    foreach my $option (sort keys %opt) {
3861a57419b3SSteven Rostedt
3862a57419b3SSteven Rostedt	if ($option =~ /\[(\d+)\]$/) {
3863a57419b3SSteven Rostedt	    next if ($i != $1);
3864a57419b3SSteven Rostedt	} else {
3865a57419b3SSteven Rostedt	    next if ($i);
3866a57419b3SSteven Rostedt	}
3867a57419b3SSteven Rostedt
38682b7d9b21SSteven Rostedt	doprint "$option = $opt{$option}\n";
38692b7d9b21SSteven Rostedt    }
3870a57419b3SSteven Rostedt}
38712545eb61SSteven Rostedt
38722a62512bSSteven Rostedtsub __set_test_option {
38735a391fbfSSteven Rostedt    my ($name, $i) = @_;
38745a391fbfSSteven Rostedt
38755a391fbfSSteven Rostedt    my $option = "$name\[$i\]";
38765a391fbfSSteven Rostedt
38775a391fbfSSteven Rostedt    if (defined($opt{$option})) {
38785a391fbfSSteven Rostedt	return $opt{$option};
38795a391fbfSSteven Rostedt    }
38805a391fbfSSteven Rostedt
3881a57419b3SSteven Rostedt    foreach my $test (keys %repeat_tests) {
3882a57419b3SSteven Rostedt	if ($i >= $test &&
3883a57419b3SSteven Rostedt	    $i < $test + $repeat_tests{$test}) {
3884a57419b3SSteven Rostedt	    $option = "$name\[$test\]";
3885a57419b3SSteven Rostedt	    if (defined($opt{$option})) {
3886a57419b3SSteven Rostedt		return $opt{$option};
3887a57419b3SSteven Rostedt	    }
3888a57419b3SSteven Rostedt	}
3889a57419b3SSteven Rostedt    }
3890a57419b3SSteven Rostedt
38915a391fbfSSteven Rostedt    if (defined($opt{$name})) {
38925a391fbfSSteven Rostedt	return $opt{$name};
38935a391fbfSSteven Rostedt    }
38945a391fbfSSteven Rostedt
38955a391fbfSSteven Rostedt    return undef;
38965a391fbfSSteven Rostedt}
38975a391fbfSSteven Rostedt
38982a62512bSSteven Rostedtsub set_test_option {
38992a62512bSSteven Rostedt    my ($name, $i) = @_;
39002a62512bSSteven Rostedt
39012a62512bSSteven Rostedt    my $option = __set_test_option($name, $i);
39022a62512bSSteven Rostedt    return $option if (!defined($option));
39032a62512bSSteven Rostedt
390404262be3SSteven Rostedt (Red Hat)    return eval_option($name, $option, $i);
39052a62512bSSteven Rostedt}
39062a62512bSSteven Rostedt
39072545eb61SSteven Rostedt# First we need to do is the builds
3908a75fececSSteven Rostedtfor (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
39092545eb61SSteven Rostedt
39104ab1cce5SSteven Rostedt    # Do not reboot on failing test options
39114ab1cce5SSteven Rostedt    $no_reboot = 1;
3912759a3cc6SSteven Rostedt    $reboot_success = 0;
39134ab1cce5SSteven Rostedt
3914683a3e64SSteven Rostedt    $have_version = 0;
3915683a3e64SSteven Rostedt
3916576f627cSSteven Rostedt    $iteration = $i;
3917576f627cSSteven Rostedt
3918c1434dccSSteven Rostedt    undef %force_config;
3919c1434dccSSteven Rostedt
3920a75fececSSteven Rostedt    my $makecmd = set_test_option("MAKE_CMD", $i);
3921a75fececSSteven Rostedt
39229cc9e091SSteven Rostedt    # Load all the options into their mapped variable names
39239cc9e091SSteven Rostedt    foreach my $opt (keys %option_map) {
39249cc9e091SSteven Rostedt	${$option_map{$opt}} = set_test_option($opt, $i);
39259cc9e091SSteven Rostedt    }
3926b5f4aea6SSteven Rostedt
392735ce5952SSteven Rostedt    $start_minconfig_defined = 1;
392835ce5952SSteven Rostedt
3929921ed4c7SSteven Rostedt    # The first test may override the PRE_KTEST option
3930921ed4c7SSteven Rostedt    if (defined($pre_ktest) && $i == 1) {
3931921ed4c7SSteven Rostedt	doprint "\n";
3932921ed4c7SSteven Rostedt	run_command $pre_ktest;
3933921ed4c7SSteven Rostedt    }
3934921ed4c7SSteven Rostedt
3935921ed4c7SSteven Rostedt    # Any test can override the POST_KTEST option
3936921ed4c7SSteven Rostedt    # The last test takes precedence.
3937921ed4c7SSteven Rostedt    if (defined($post_ktest)) {
3938921ed4c7SSteven Rostedt	$final_post_ktest = $post_ktest;
3939921ed4c7SSteven Rostedt    }
3940921ed4c7SSteven Rostedt
39414c4ab120SSteven Rostedt    if (!defined($start_minconfig)) {
394235ce5952SSteven Rostedt	$start_minconfig_defined = 0;
39434c4ab120SSteven Rostedt	$start_minconfig = $minconfig;
39444c4ab120SSteven Rostedt    }
39454c4ab120SSteven Rostedt
3946a75fececSSteven Rostedt    chdir $builddir || die "can't change directory to $builddir";
3947a75fececSSteven Rostedt
3948a908a665SAndrew Jones    foreach my $dir ($tmpdir, $outputdir) {
3949a908a665SAndrew Jones	if (!-d $dir) {
3950a908a665SAndrew Jones	    mkpath($dir) or
3951a908a665SAndrew Jones		die "can't create $dir";
3952a908a665SAndrew Jones	}
3953a75fececSSteven Rostedt    }
3954a75fececSSteven Rostedt
3955e48c5293SSteven Rostedt    $ENV{"SSH_USER"} = $ssh_user;
3956e48c5293SSteven Rostedt    $ENV{"MACHINE"} = $machine;
3957e48c5293SSteven Rostedt
3958a75fececSSteven Rostedt    $buildlog = "$tmpdir/buildlog-$machine";
3959a9dd5d63SRabin Vincent    $testlog = "$tmpdir/testlog-$machine";
3960a75fececSSteven Rostedt    $dmesg = "$tmpdir/dmesg-$machine";
3961a75fececSSteven Rostedt    $make = "$makecmd O=$outputdir";
396251ad1dd1SSteven Rostedt    $output_config = "$outputdir/.config";
3963a75fececSSteven Rostedt
3964bb8474b1SSteven Rostedt    if (!$buildonly) {
3965bb8474b1SSteven Rostedt	$target = "$ssh_user\@$machine";
3966a75fececSSteven Rostedt	if ($reboot_type eq "grub") {
3967576f627cSSteven Rostedt	    dodie "GRUB_MENU not defined" if (!defined($grub_menu));
3968a15ba913SSteven Rostedt	} elsif ($reboot_type eq "grub2") {
3969a15ba913SSteven Rostedt	    dodie "GRUB_MENU not defined" if (!defined($grub_menu));
3970a15ba913SSteven Rostedt	    dodie "GRUB_FILE not defined" if (!defined($grub_file));
39717786954cSSteven Rostedt	} elsif ($reboot_type eq "syslinux") {
39727786954cSSteven Rostedt	    dodie "SYSLINUX_LABEL not defined" if (!defined($syslinux_label));
3973a75fececSSteven Rostedt	}
3974bb8474b1SSteven Rostedt    }
3975a75fececSSteven Rostedt
3976a75fececSSteven Rostedt    my $run_type = $build_type;
3977a75fececSSteven Rostedt    if ($test_type eq "patchcheck") {
3978b5f4aea6SSteven Rostedt	$run_type = $patchcheck_type;
3979a75fececSSteven Rostedt    } elsif ($test_type eq "bisect") {
3980b5f4aea6SSteven Rostedt	$run_type = $bisect_type;
39810a05c769SSteven Rostedt    } elsif ($test_type eq "config_bisect") {
3982b5f4aea6SSteven Rostedt	$run_type = $config_bisect_type;
39834283b169SSteven Rostedt (Red Hat)    } elsif ($test_type eq "make_min_config") {
39844283b169SSteven Rostedt (Red Hat)	$run_type = "";
39854283b169SSteven Rostedt (Red Hat)    } elsif ($test_type eq "make_warnings_file") {
39864c4ab120SSteven Rostedt	$run_type = "";
39874c4ab120SSteven Rostedt    }
39884c4ab120SSteven Rostedt
3989a75fececSSteven Rostedt    # mistake in config file?
3990a75fececSSteven Rostedt    if (!defined($run_type)) {
3991a75fececSSteven Rostedt	$run_type = "ERROR";
3992a75fececSSteven Rostedt    }
39932545eb61SSteven Rostedt
3994e0a8742eSSteven Rostedt    my $installme = "";
3995e0a8742eSSteven Rostedt    $installme = " no_install" if ($no_install);
3996e0a8742eSSteven Rostedt
39972545eb61SSteven Rostedt    doprint "\n\n";
3998e0a8742eSSteven Rostedt    doprint "RUNNING TEST $i of $opt{NUM_TESTS} with option $test_type $run_type$installme\n\n";
39997faafbd6SSteven Rostedt
4000921ed4c7SSteven Rostedt    if (defined($pre_test)) {
4001921ed4c7SSteven Rostedt	run_command $pre_test;
4002921ed4c7SSteven Rostedt    }
4003921ed4c7SSteven Rostedt
40047faafbd6SSteven Rostedt    unlink $dmesg;
40057faafbd6SSteven Rostedt    unlink $buildlog;
4006a9dd5d63SRabin Vincent    unlink $testlog;
40072545eb61SSteven Rostedt
4008250bae8bSSteven Rostedt    if (defined($addconfig)) {
4009250bae8bSSteven Rostedt	my $min = $minconfig;
40102b7d9b21SSteven Rostedt	if (!defined($minconfig)) {
4011250bae8bSSteven Rostedt	    $min = "";
4012250bae8bSSteven Rostedt	}
4013250bae8bSSteven Rostedt	run_command "cat $addconfig $min > $tmpdir/add_config" or
40142b7d9b21SSteven Rostedt	    dodie "Failed to create temp config";
40159be2e6b5SSteven Rostedt	$minconfig = "$tmpdir/add_config";
40162b7d9b21SSteven Rostedt    }
40172b7d9b21SSteven Rostedt
40186c5ee0beSSteven Rostedt    if (defined($checkout)) {
40196c5ee0beSSteven Rostedt	run_command "git checkout $checkout" or
40206c5ee0beSSteven Rostedt	    die "failed to checkout $checkout";
40216c5ee0beSSteven Rostedt    }
40226c5ee0beSSteven Rostedt
4023759a3cc6SSteven Rostedt    $no_reboot = 0;
4024759a3cc6SSteven Rostedt
4025648a182cSSteven Rostedt    # A test may opt to not reboot the box
4026648a182cSSteven Rostedt    if ($reboot_on_success) {
4027759a3cc6SSteven Rostedt	$reboot_success = 1;
4028648a182cSSteven Rostedt    }
40294ab1cce5SSteven Rostedt
4030a75fececSSteven Rostedt    if ($test_type eq "bisect") {
40315f9b6cedSSteven Rostedt	bisect $i;
40325f9b6cedSSteven Rostedt	next;
40330a05c769SSteven Rostedt    } elsif ($test_type eq "config_bisect") {
40340a05c769SSteven Rostedt	config_bisect $i;
40350a05c769SSteven Rostedt	next;
4036a75fececSSteven Rostedt    } elsif ($test_type eq "patchcheck") {
40376c5ee0beSSteven Rostedt	patchcheck $i;
40386c5ee0beSSteven Rostedt	next;
40394c4ab120SSteven Rostedt    } elsif ($test_type eq "make_min_config") {
40404c4ab120SSteven Rostedt	make_min_config $i;
40414c4ab120SSteven Rostedt	next;
40424283b169SSteven Rostedt (Red Hat)    } elsif ($test_type eq "make_warnings_file") {
40434283b169SSteven Rostedt (Red Hat)	$no_reboot = 1;
40444283b169SSteven Rostedt (Red Hat)	make_warnings_file $i;
40454283b169SSteven Rostedt (Red Hat)	next;
40465f9b6cedSSteven Rostedt    }
40475f9b6cedSSteven Rostedt
40487faafbd6SSteven Rostedt    if ($build_type ne "nobuild") {
40497faafbd6SSteven Rostedt	build $build_type or next;
40504283b169SSteven Rostedt (Red Hat)	check_buildlog or next;
40512545eb61SSteven Rostedt    }
40522545eb61SSteven Rostedt
4053cd8e368fSSteven Rostedt    if ($test_type eq "install") {
4054cd8e368fSSteven Rostedt	get_version;
4055cd8e368fSSteven Rostedt	install;
4056cd8e368fSSteven Rostedt	success $i;
4057cd8e368fSSteven Rostedt	next;
4058cd8e368fSSteven Rostedt    }
4059cd8e368fSSteven Rostedt
4060a75fececSSteven Rostedt    if ($test_type ne "build") {
40617faafbd6SSteven Rostedt	my $failed = 0;
4062ddf607e5SSteven Rostedt	start_monitor_and_boot or $failed = 1;
4063a75fececSSteven Rostedt
4064a75fececSSteven Rostedt	if (!$failed && $test_type ne "boot" && defined($run_test)) {
40657faafbd6SSteven Rostedt	    do_run_test or $failed = 1;
40665a391fbfSSteven Rostedt	}
40677faafbd6SSteven Rostedt	end_monitor;
40687faafbd6SSteven Rostedt	next if ($failed);
4069a75fececSSteven Rostedt    }
40705a391fbfSSteven Rostedt
40715f9b6cedSSteven Rostedt    success $i;
407275c3fda7SSteven Rostedt}
40732545eb61SSteven Rostedt
4074921ed4c7SSteven Rostedtif (defined($final_post_ktest)) {
4075921ed4c7SSteven Rostedt    run_command $final_post_ktest;
4076921ed4c7SSteven Rostedt}
4077921ed4c7SSteven Rostedt
40785c42fc5bSSteven Rostedtif ($opt{"POWEROFF_ON_SUCCESS"}) {
407975c3fda7SSteven Rostedt    halt;
4080759a3cc6SSteven Rostedt} elsif ($opt{"REBOOT_ON_SUCCESS"} && !do_not_reboot && $reboot_success) {
4081bc7c5803SSteven Rostedt    reboot_to_good;
4082648a182cSSteven Rostedt} elsif (defined($switch_to_good)) {
4083648a182cSSteven Rostedt    # still need to get to the good kernel
4084648a182cSSteven Rostedt    run_command $switch_to_good;
40855c42fc5bSSteven Rostedt}
408675c3fda7SSteven Rostedt
4087648a182cSSteven Rostedt
4088e48c5293SSteven Rostedtdoprint "\n    $successes of $opt{NUM_TESTS} tests were successful\n\n";
4089e48c5293SSteven Rostedt
40902545eb61SSteven Rostedtexit 0;
4091