xref: /openbmc/linux/tools/testing/ktest/ktest.pl (revision 060f35a317ef09101b128f399dce7ed13d019461)
1#!/usr/bin/perl -w
2# SPDX-License-Identifier: GPL-2.0-only
3#
4# Copyright 2010 - Steven Rostedt <srostedt@redhat.com>, Red Hat Inc.
5#
6
7use strict;
8use IPC::Open2;
9use Fcntl qw(F_GETFL F_SETFL O_NONBLOCK);
10use File::Path qw(mkpath);
11use File::Copy qw(cp);
12use FileHandle;
13use FindBin;
14use IO::Handle;
15
16my $VERSION = "0.2";
17
18$| = 1;
19
20my %opt;
21my %repeat_tests;
22my %repeats;
23my %evals;
24
25#default opts
26my %default = (
27    "MAILER"			=> "sendmail",	# default mailer
28    "EMAIL_ON_ERROR"		=> 1,
29    "EMAIL_WHEN_FINISHED"	=> 1,
30    "EMAIL_WHEN_CANCELED"	=> 0,
31    "EMAIL_WHEN_STARTED"	=> 0,
32    "NUM_TESTS"			=> 1,
33    "TEST_TYPE"			=> "build",
34    "BUILD_TYPE"		=> "oldconfig",
35    "MAKE_CMD"			=> "make",
36    "CLOSE_CONSOLE_SIGNAL"	=> "INT",
37    "TIMEOUT"			=> 120,
38    "TMP_DIR"			=> "/tmp/ktest/\${MACHINE}",
39    "SLEEP_TIME"		=> 60,		# sleep time between tests
40    "BUILD_NOCLEAN"		=> 0,
41    "REBOOT_ON_ERROR"		=> 0,
42    "POWEROFF_ON_ERROR"		=> 0,
43    "REBOOT_ON_SUCCESS"		=> 1,
44    "POWEROFF_ON_SUCCESS"	=> 0,
45    "BUILD_OPTIONS"		=> "",
46    "BISECT_SLEEP_TIME"		=> 60,		# sleep time between bisects
47    "PATCHCHECK_SLEEP_TIME"	=> 60, 		# sleep time between patch checks
48    "CLEAR_LOG"			=> 0,
49    "BISECT_MANUAL"		=> 0,
50    "BISECT_SKIP"		=> 1,
51    "BISECT_TRIES"		=> 1,
52    "MIN_CONFIG_TYPE"		=> "boot",
53    "SUCCESS_LINE"		=> "login:",
54    "DETECT_TRIPLE_FAULT"	=> 1,
55    "NO_INSTALL"		=> 0,
56    "BOOTED_TIMEOUT"		=> 1,
57    "DIE_ON_FAILURE"		=> 1,
58    "SSH_EXEC"			=> "ssh \$SSH_USER\@\$MACHINE \$SSH_COMMAND",
59    "SCP_TO_TARGET"		=> "scp \$SRC_FILE \$SSH_USER\@\$MACHINE:\$DST_FILE",
60    "SCP_TO_TARGET_INSTALL"	=> "\${SCP_TO_TARGET}",
61    "REBOOT"			=> "ssh \$SSH_USER\@\$MACHINE reboot",
62    "REBOOT_RETURN_CODE"	=> 255,
63    "STOP_AFTER_SUCCESS"	=> 10,
64    "STOP_AFTER_FAILURE"	=> 60,
65    "STOP_TEST_AFTER"		=> 600,
66    "MAX_MONITOR_WAIT"		=> 1800,
67    "GRUB_REBOOT"		=> "grub2-reboot",
68    "GRUB_BLS_GET"		=> "grubby --info=ALL",
69    "SYSLINUX"			=> "extlinux",
70    "SYSLINUX_PATH"		=> "/boot/extlinux",
71    "CONNECT_TIMEOUT"		=> 25,
72
73# required, and we will ask users if they don't have them but we keep the default
74# value something that is common.
75    "REBOOT_TYPE"		=> "grub",
76    "LOCALVERSION"		=> "-test",
77    "SSH_USER"			=> "root",
78    "BUILD_TARGET"	 	=> "arch/x86/boot/bzImage",
79    "TARGET_IMAGE"		=> "/boot/vmlinuz-test",
80
81    "LOG_FILE"			=> undef,
82    "IGNORE_UNUSED"		=> 0,
83);
84
85my $test_log_start = 0;
86
87my $ktest_config = "ktest.conf";
88my $version;
89my $have_version = 0;
90my $machine;
91my $last_machine;
92my $ssh_user;
93my $tmpdir;
94my $builddir;
95my $outputdir;
96my $output_config;
97my $test_type;
98my $build_type;
99my $build_options;
100my $final_post_ktest;
101my $pre_ktest;
102my $post_ktest;
103my $pre_test;
104my $pre_test_die;
105my $post_test;
106my $pre_build;
107my $post_build;
108my $pre_build_die;
109my $post_build_die;
110my $reboot_type;
111my $reboot_script;
112my $power_cycle;
113my $reboot;
114my $reboot_return_code;
115my $reboot_on_error;
116my $switch_to_good;
117my $switch_to_test;
118my $poweroff_on_error;
119my $reboot_on_success;
120my $die_on_failure;
121my $powercycle_after_reboot;
122my $poweroff_after_halt;
123my $max_monitor_wait;
124my $ssh_exec;
125my $scp_to_target;
126my $scp_to_target_install;
127my $power_off;
128my $grub_menu;
129my $last_grub_menu;
130my $grub_file;
131my $grub_number;
132my $grub_reboot;
133my $grub_bls_get;
134my $syslinux;
135my $syslinux_path;
136my $syslinux_label;
137my $target;
138my $make;
139my $pre_install;
140my $post_install;
141my $no_install;
142my $noclean;
143my $minconfig;
144my $start_minconfig;
145my $start_minconfig_defined;
146my $output_minconfig;
147my $minconfig_type;
148my $use_output_minconfig;
149my $warnings_file;
150my $ignore_config;
151my $ignore_errors;
152my $addconfig;
153my $in_bisect = 0;
154my $bisect_bad_commit = "";
155my $reverse_bisect;
156my $bisect_manual;
157my $bisect_skip;
158my $bisect_tries;
159my $config_bisect_good;
160my $bisect_ret_good;
161my $bisect_ret_bad;
162my $bisect_ret_skip;
163my $bisect_ret_abort;
164my $bisect_ret_default;
165my $in_patchcheck = 0;
166my $run_test;
167my $buildlog;
168my $testlog;
169my $dmesg;
170my $monitor_fp;
171my $monitor_pid;
172my $monitor_cnt = 0;
173my $sleep_time;
174my $bisect_sleep_time;
175my $patchcheck_sleep_time;
176my $ignore_warnings;
177my $store_failures;
178my $store_successes;
179my $test_name;
180my $timeout;
181my $run_timeout;
182my $connect_timeout;
183my $config_bisect_exec;
184my $booted_timeout;
185my $detect_triplefault;
186my $console;
187my $close_console_signal;
188my $reboot_success_line;
189my $success_line;
190my $stop_after_success;
191my $stop_after_failure;
192my $stop_test_after;
193my $build_target;
194my $target_image;
195my $checkout;
196my $localversion;
197my $iteration = 0;
198my $successes = 0;
199my $stty_orig;
200my $run_command_status = 0;
201
202my $bisect_good;
203my $bisect_bad;
204my $bisect_type;
205my $bisect_start;
206my $bisect_replay;
207my $bisect_files;
208my $bisect_reverse;
209my $bisect_check;
210
211my $config_bisect;
212my $config_bisect_type;
213my $config_bisect_check;
214
215my $patchcheck_type;
216my $patchcheck_start;
217my $patchcheck_cherry;
218my $patchcheck_end;
219
220my $build_time;
221my $install_time;
222my $reboot_time;
223my $test_time;
224
225my $pwd;
226my $dirname = $FindBin::Bin;
227
228my $mailto;
229my $mailer;
230my $mail_path;
231my $mail_max_size;
232my $mail_command;
233my $email_on_error;
234my $email_when_finished;
235my $email_when_started;
236my $email_when_canceled;
237
238my $script_start_time = localtime();
239
240# set when a test is something other that just building or install
241# which would require more options.
242my $buildonly = 1;
243
244# tell build not to worry about warnings, even when WARNINGS_FILE is set
245my $warnings_ok = 0;
246
247# set when creating a new config
248my $newconfig = 0;
249
250my %entered_configs;
251my %config_help;
252my %variable;
253
254# force_config is the list of configs that we force enabled (or disabled)
255# in a .config file. The MIN_CONFIG and ADD_CONFIG configs.
256my %force_config;
257
258# do not force reboots on config problems
259my $no_reboot = 1;
260
261# reboot on success
262my $reboot_success = 0;
263
264my %option_map = (
265    "MAILTO"			=> \$mailto,
266    "MAILER"			=> \$mailer,
267    "MAIL_PATH"			=> \$mail_path,
268    "MAIL_MAX_SIZE"		=> \$mail_max_size,
269    "MAIL_COMMAND"		=> \$mail_command,
270    "EMAIL_ON_ERROR"		=> \$email_on_error,
271    "EMAIL_WHEN_FINISHED"	=> \$email_when_finished,
272    "EMAIL_WHEN_STARTED"	=> \$email_when_started,
273    "EMAIL_WHEN_CANCELED"	=> \$email_when_canceled,
274    "MACHINE"			=> \$machine,
275    "SSH_USER"			=> \$ssh_user,
276    "TMP_DIR"			=> \$tmpdir,
277    "OUTPUT_DIR"		=> \$outputdir,
278    "BUILD_DIR"			=> \$builddir,
279    "TEST_TYPE"			=> \$test_type,
280    "PRE_KTEST"			=> \$pre_ktest,
281    "POST_KTEST"		=> \$post_ktest,
282    "PRE_TEST"			=> \$pre_test,
283    "PRE_TEST_DIE"		=> \$pre_test_die,
284    "POST_TEST"			=> \$post_test,
285    "BUILD_TYPE"		=> \$build_type,
286    "BUILD_OPTIONS"		=> \$build_options,
287    "PRE_BUILD"			=> \$pre_build,
288    "POST_BUILD"		=> \$post_build,
289    "PRE_BUILD_DIE"		=> \$pre_build_die,
290    "POST_BUILD_DIE"		=> \$post_build_die,
291    "POWER_CYCLE"		=> \$power_cycle,
292    "REBOOT"			=> \$reboot,
293    "REBOOT_RETURN_CODE"	=> \$reboot_return_code,
294    "BUILD_NOCLEAN"		=> \$noclean,
295    "MIN_CONFIG"		=> \$minconfig,
296    "OUTPUT_MIN_CONFIG"		=> \$output_minconfig,
297    "START_MIN_CONFIG"		=> \$start_minconfig,
298    "MIN_CONFIG_TYPE"		=> \$minconfig_type,
299    "USE_OUTPUT_MIN_CONFIG"	=> \$use_output_minconfig,
300    "WARNINGS_FILE"		=> \$warnings_file,
301    "IGNORE_CONFIG"		=> \$ignore_config,
302    "TEST"			=> \$run_test,
303    "ADD_CONFIG"		=> \$addconfig,
304    "REBOOT_TYPE"		=> \$reboot_type,
305    "GRUB_MENU"			=> \$grub_menu,
306    "GRUB_FILE"			=> \$grub_file,
307    "GRUB_REBOOT"		=> \$grub_reboot,
308    "GRUB_BLS_GET"		=> \$grub_bls_get,
309    "SYSLINUX"			=> \$syslinux,
310    "SYSLINUX_PATH"		=> \$syslinux_path,
311    "SYSLINUX_LABEL"		=> \$syslinux_label,
312    "PRE_INSTALL"		=> \$pre_install,
313    "POST_INSTALL"		=> \$post_install,
314    "NO_INSTALL"		=> \$no_install,
315    "REBOOT_SCRIPT"		=> \$reboot_script,
316    "REBOOT_ON_ERROR"		=> \$reboot_on_error,
317    "SWITCH_TO_GOOD"		=> \$switch_to_good,
318    "SWITCH_TO_TEST"		=> \$switch_to_test,
319    "POWEROFF_ON_ERROR"		=> \$poweroff_on_error,
320    "REBOOT_ON_SUCCESS"		=> \$reboot_on_success,
321    "DIE_ON_FAILURE"		=> \$die_on_failure,
322    "POWER_OFF"			=> \$power_off,
323    "POWERCYCLE_AFTER_REBOOT"	=> \$powercycle_after_reboot,
324    "POWEROFF_AFTER_HALT"	=> \$poweroff_after_halt,
325    "MAX_MONITOR_WAIT"		=> \$max_monitor_wait,
326    "SLEEP_TIME"		=> \$sleep_time,
327    "BISECT_SLEEP_TIME"		=> \$bisect_sleep_time,
328    "PATCHCHECK_SLEEP_TIME"	=> \$patchcheck_sleep_time,
329    "IGNORE_WARNINGS"		=> \$ignore_warnings,
330    "IGNORE_ERRORS"		=> \$ignore_errors,
331    "BISECT_MANUAL"		=> \$bisect_manual,
332    "BISECT_SKIP"		=> \$bisect_skip,
333    "BISECT_TRIES"		=> \$bisect_tries,
334    "CONFIG_BISECT_GOOD"	=> \$config_bisect_good,
335    "BISECT_RET_GOOD"		=> \$bisect_ret_good,
336    "BISECT_RET_BAD"		=> \$bisect_ret_bad,
337    "BISECT_RET_SKIP"		=> \$bisect_ret_skip,
338    "BISECT_RET_ABORT"		=> \$bisect_ret_abort,
339    "BISECT_RET_DEFAULT"	=> \$bisect_ret_default,
340    "STORE_FAILURES"		=> \$store_failures,
341    "STORE_SUCCESSES"		=> \$store_successes,
342    "TEST_NAME"			=> \$test_name,
343    "TIMEOUT"			=> \$timeout,
344    "RUN_TIMEOUT"		=> \$run_timeout,
345    "CONNECT_TIMEOUT"		=> \$connect_timeout,
346    "CONFIG_BISECT_EXEC"	=> \$config_bisect_exec,
347    "BOOTED_TIMEOUT"		=> \$booted_timeout,
348    "CONSOLE"			=> \$console,
349    "CLOSE_CONSOLE_SIGNAL"	=> \$close_console_signal,
350    "DETECT_TRIPLE_FAULT"	=> \$detect_triplefault,
351    "SUCCESS_LINE"		=> \$success_line,
352    "REBOOT_SUCCESS_LINE"	=> \$reboot_success_line,
353    "STOP_AFTER_SUCCESS"	=> \$stop_after_success,
354    "STOP_AFTER_FAILURE"	=> \$stop_after_failure,
355    "STOP_TEST_AFTER"		=> \$stop_test_after,
356    "BUILD_TARGET"		=> \$build_target,
357    "SSH_EXEC"			=> \$ssh_exec,
358    "SCP_TO_TARGET"		=> \$scp_to_target,
359    "SCP_TO_TARGET_INSTALL"	=> \$scp_to_target_install,
360    "CHECKOUT"			=> \$checkout,
361    "TARGET_IMAGE"		=> \$target_image,
362    "LOCALVERSION"		=> \$localversion,
363
364    "BISECT_GOOD"		=> \$bisect_good,
365    "BISECT_BAD"		=> \$bisect_bad,
366    "BISECT_TYPE"		=> \$bisect_type,
367    "BISECT_START"		=> \$bisect_start,
368    "BISECT_REPLAY"		=> \$bisect_replay,
369    "BISECT_FILES"		=> \$bisect_files,
370    "BISECT_REVERSE"		=> \$bisect_reverse,
371    "BISECT_CHECK"		=> \$bisect_check,
372
373    "CONFIG_BISECT"		=> \$config_bisect,
374    "CONFIG_BISECT_TYPE"	=> \$config_bisect_type,
375    "CONFIG_BISECT_CHECK"	=> \$config_bisect_check,
376
377    "PATCHCHECK_TYPE"		=> \$patchcheck_type,
378    "PATCHCHECK_START"		=> \$patchcheck_start,
379    "PATCHCHECK_CHERRY"		=> \$patchcheck_cherry,
380    "PATCHCHECK_END"		=> \$patchcheck_end,
381);
382
383# Options may be used by other options, record them.
384my %used_options;
385
386# default variables that can be used
387chomp ($variable{"PWD"} = `pwd`);
388$pwd = $variable{"PWD"};
389
390$config_help{"MACHINE"} = << "EOF"
391 The machine hostname that you will test.
392 For build only tests, it is still needed to differentiate log files.
393EOF
394    ;
395$config_help{"SSH_USER"} = << "EOF"
396 The box is expected to have ssh on normal bootup, provide the user
397  (most likely root, since you need privileged operations)
398EOF
399    ;
400$config_help{"BUILD_DIR"} = << "EOF"
401 The directory that contains the Linux source code (full path).
402 You can use \${PWD} that will be the path where ktest.pl is run, or use
403 \${THIS_DIR} which is assigned \${PWD} but may be changed later.
404EOF
405    ;
406$config_help{"OUTPUT_DIR"} = << "EOF"
407 The directory that the objects will be built (full path).
408 (can not be same as BUILD_DIR)
409 You can use \${PWD} that will be the path where ktest.pl is run, or use
410 \${THIS_DIR} which is assigned \${PWD} but may be changed later.
411EOF
412    ;
413$config_help{"BUILD_TARGET"} = << "EOF"
414 The location of the compiled file to copy to the target.
415 (relative to OUTPUT_DIR)
416EOF
417    ;
418$config_help{"BUILD_OPTIONS"} = << "EOF"
419 Options to add to \"make\" when building.
420 i.e.  -j20
421EOF
422    ;
423$config_help{"TARGET_IMAGE"} = << "EOF"
424 The place to put your image on the test machine.
425EOF
426    ;
427$config_help{"POWER_CYCLE"} = << "EOF"
428 A script or command to reboot the box.
429
430 Here is a digital loggers power switch example
431 POWER_CYCLE = wget --no-proxy -O /dev/null -q  --auth-no-challenge 'http://admin:admin\@power/outlet?5=CCL'
432
433 Here is an example to reboot a virtual box on the current host
434 with the name "Guest".
435 POWER_CYCLE = virsh destroy Guest; sleep 5; virsh start Guest
436EOF
437    ;
438$config_help{"CONSOLE"} = << "EOF"
439 The script or command that reads the console
440
441  If you use ttywatch server, something like the following would work.
442CONSOLE = nc -d localhost 3001
443
444 For a virtual machine with guest name "Guest".
445CONSOLE =  virsh console Guest
446EOF
447    ;
448$config_help{"LOCALVERSION"} = << "EOF"
449 Required version ending to differentiate the test
450 from other linux builds on the system.
451EOF
452    ;
453$config_help{"REBOOT_TYPE"} = << "EOF"
454 Way to reboot the box to the test kernel.
455 Only valid options so far are "grub", "grub2", "grub2bls", "syslinux", and "script".
456
457 If you specify grub, it will assume grub version 1
458 and will search in /boot/grub/menu.lst for the title \$GRUB_MENU
459 and select that target to reboot to the kernel. If this is not
460 your setup, then specify "script" and have a command or script
461 specified in REBOOT_SCRIPT to boot to the target.
462
463 The entry in /boot/grub/menu.lst must be entered in manually.
464 The test will not modify that file.
465
466 If you specify grub2, then you also need to specify both \$GRUB_MENU
467 and \$GRUB_FILE.
468
469 If you specify grub2bls, then you also need to specify \$GRUB_MENU.
470
471 If you specify syslinux, then you may use SYSLINUX to define the syslinux
472 command (defaults to extlinux), and SYSLINUX_PATH to specify the path to
473 the syslinux install (defaults to /boot/extlinux). But you have to specify
474 SYSLINUX_LABEL to define the label to boot to for the test kernel.
475EOF
476    ;
477$config_help{"GRUB_MENU"} = << "EOF"
478 The grub title name for the test kernel to boot
479 (Only mandatory if REBOOT_TYPE = grub or grub2)
480
481 Note, ktest.pl will not update the grub menu.lst, you need to
482 manually add an option for the test. ktest.pl will search
483 the grub menu.lst for this option to find what kernel to
484 reboot into.
485
486 For example, if in the /boot/grub/menu.lst the test kernel title has:
487 title Test Kernel
488 kernel vmlinuz-test
489 GRUB_MENU = Test Kernel
490
491 For grub2, a search of \$GRUB_FILE is performed for the lines
492 that begin with "menuentry". It will not detect submenus. The
493 menu must be a non-nested menu. Add the quotes used in the menu
494 to guarantee your selection, as the first menuentry with the content
495 of \$GRUB_MENU that is found will be used.
496
497 For grub2bls, \$GRUB_MENU is searched on the result of \$GRUB_BLS_GET
498 command for the lines that begin with "title".
499EOF
500    ;
501$config_help{"GRUB_FILE"} = << "EOF"
502 If grub2 is used, the full path for the grub.cfg file is placed
503 here. Use something like /boot/grub2/grub.cfg to search.
504EOF
505    ;
506$config_help{"SYSLINUX_LABEL"} = << "EOF"
507 If syslinux is used, the label that boots the target kernel must
508 be specified with SYSLINUX_LABEL.
509EOF
510    ;
511$config_help{"REBOOT_SCRIPT"} = << "EOF"
512 A script to reboot the target into the test kernel
513 (Only mandatory if REBOOT_TYPE = script)
514EOF
515    ;
516
517# used with process_expression()
518my $d = 0;
519
520# defined before get_test_name()
521my $in_die = 0;
522
523# defined before process_warning_line()
524my $check_build_re = ".*:.*(warning|error|Error):.*";
525my $utf8_quote = "\\x{e2}\\x{80}(\\x{98}|\\x{99})";
526
527# defined before child_finished()
528my $child_done;
529
530# config_ignore holds the configs that were set (or unset) for
531# a good config and we will ignore these configs for the rest
532# of a config bisect. These configs stay as they were.
533my %config_ignore;
534
535# config_set holds what all configs were set as.
536my %config_set;
537
538# config_off holds the set of configs that the bad config had disabled.
539# We need to record them and set them in the .config when running
540# olddefconfig, because olddefconfig keeps the defaults.
541my %config_off;
542
543# config_off_tmp holds a set of configs to turn off for now
544my @config_off_tmp;
545
546# config_list is the set of configs that are being tested
547my %config_list;
548my %null_config;
549
550my %dependency;
551
552# found above run_config_bisect()
553my $pass = 1;
554
555# found above add_dep()
556
557my %depends;
558my %depcount;
559my $iflevel = 0;
560my @ifdeps;
561
562# prevent recursion
563my %read_kconfigs;
564
565# found above test_this_config()
566my %min_configs;
567my %keep_configs;
568my %save_configs;
569my %processed_configs;
570my %nochange_config;
571
572#
573# These are first defined here, main function later on
574#
575sub run_command;
576sub start_monitor;
577sub end_monitor;
578sub wait_for_monitor;
579
580sub _logit {
581    if (defined($opt{"LOG_FILE"})) {
582	print LOG @_;
583    }
584}
585
586sub logit {
587    if (defined($opt{"LOG_FILE"})) {
588	_logit @_;
589    } else {
590	print @_;
591    }
592}
593
594sub doprint {
595    print @_;
596    _logit @_;
597}
598
599sub read_prompt {
600    my ($cancel, $prompt) = @_;
601
602    my $ans;
603
604    for (;;) {
605        if ($cancel) {
606	    print "$prompt [y/n/C] ";
607	} else {
608	    print "$prompt [Y/n] ";
609	}
610	$ans = <STDIN>;
611	chomp $ans;
612	if ($ans =~ /^\s*$/) {
613	    if ($cancel) {
614		$ans = "c";
615	    } else {
616		$ans = "y";
617	    }
618	}
619	last if ($ans =~ /^y$/i || $ans =~ /^n$/i);
620	if ($cancel) {
621	    last if ($ans =~ /^c$/i);
622	    print "Please answer either 'y', 'n' or 'c'.\n";
623	} else {
624	    print "Please answer either 'y' or 'n'.\n";
625	}
626    }
627    if ($ans =~ /^c/i) {
628	exit;
629    }
630    if ($ans !~ /^y$/i) {
631	return 0;
632    }
633    return 1;
634}
635
636sub read_yn {
637    my ($prompt) = @_;
638
639    return read_prompt 0, $prompt;
640}
641
642sub read_ync {
643    my ($prompt) = @_;
644
645    return read_prompt 1, $prompt;
646}
647
648sub get_mandatory_config {
649    my ($config) = @_;
650    my $ans;
651
652    return if (defined($opt{$config}));
653
654    if (defined($config_help{$config})) {
655	print "\n";
656	print $config_help{$config};
657    }
658
659    for (;;) {
660	print "$config = ";
661	if (defined($default{$config}) && length($default{$config})) {
662	    print "\[$default{$config}\] ";
663	}
664	$ans = <STDIN>;
665	$ans =~ s/^\s*(.*\S)\s*$/$1/;
666	if ($ans =~ /^\s*$/) {
667	    if ($default{$config}) {
668		$ans = $default{$config};
669	    } else {
670		print "Your answer can not be blank\n";
671		next;
672	    }
673	}
674	$entered_configs{$config} = ${ans};
675	last;
676    }
677}
678
679sub show_time {
680    my ($time) = @_;
681
682    my $hours = 0;
683    my $minutes = 0;
684
685    if ($time > 3600) {
686	$hours = int($time / 3600);
687	$time -= $hours * 3600;
688    }
689    if ($time > 60) {
690	$minutes = int($time / 60);
691	$time -= $minutes * 60;
692    }
693
694    if ($hours > 0) {
695	doprint "$hours hour";
696	doprint "s" if ($hours > 1);
697	doprint " ";
698    }
699
700    if ($minutes > 0) {
701	doprint "$minutes minute";
702	doprint "s" if ($minutes > 1);
703	doprint " ";
704    }
705
706    doprint "$time second";
707    doprint "s" if ($time != 1);
708}
709
710sub print_times {
711    doprint "\n";
712    if ($build_time) {
713	doprint "Build time:   ";
714	show_time($build_time);
715	doprint "\n";
716    }
717    if ($install_time) {
718	doprint "Install time: ";
719	show_time($install_time);
720	doprint "\n";
721    }
722    if ($reboot_time) {
723	doprint "Reboot time:  ";
724	show_time($reboot_time);
725	doprint "\n";
726    }
727    if ($test_time) {
728	doprint "Test time:    ";
729	show_time($test_time);
730	doprint "\n";
731    }
732    # reset for iterations like bisect
733    $build_time = 0;
734    $install_time = 0;
735    $reboot_time = 0;
736    $test_time = 0;
737}
738
739sub get_mandatory_configs {
740    get_mandatory_config("MACHINE");
741    get_mandatory_config("BUILD_DIR");
742    get_mandatory_config("OUTPUT_DIR");
743
744    if ($newconfig) {
745	get_mandatory_config("BUILD_OPTIONS");
746    }
747
748    # options required for other than just building a kernel
749    if (!$buildonly) {
750	get_mandatory_config("POWER_CYCLE");
751	get_mandatory_config("CONSOLE");
752    }
753
754    # options required for install and more
755    if ($buildonly != 1) {
756	get_mandatory_config("SSH_USER");
757	get_mandatory_config("BUILD_TARGET");
758	get_mandatory_config("TARGET_IMAGE");
759    }
760
761    get_mandatory_config("LOCALVERSION");
762
763    return if ($buildonly);
764
765    my $rtype = $opt{"REBOOT_TYPE"};
766
767    if (!defined($rtype)) {
768	if (!defined($opt{"GRUB_MENU"})) {
769	    get_mandatory_config("REBOOT_TYPE");
770	    $rtype = $entered_configs{"REBOOT_TYPE"};
771	} else {
772	    $rtype = "grub";
773	}
774    }
775
776    if (($rtype eq "grub") or ($rtype eq "grub2bls")) {
777	get_mandatory_config("GRUB_MENU");
778    }
779
780    if ($rtype eq "grub2") {
781	get_mandatory_config("GRUB_MENU");
782	get_mandatory_config("GRUB_FILE");
783    }
784
785    if ($rtype eq "syslinux") {
786	get_mandatory_config("SYSLINUX_LABEL");
787    }
788}
789
790sub process_variables {
791    my ($value, $remove_undef) = @_;
792    my $retval = "";
793
794    # We want to check for '\', and it is just easier
795    # to check the previous characet of '$' and not need
796    # to worry if '$' is the first character. By adding
797    # a space to $value, we can just check [^\\]\$ and
798    # it will still work.
799    $value = " $value";
800
801    while ($value =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) {
802	my $begin = $1;
803	my $var = $2;
804	my $end = $3;
805	# append beginning of value to retval
806	$retval = "$retval$begin";
807	if ($var =~ s/^shell\s+//) {
808	    $retval = `$var`;
809	    if ($?) {
810		doprint "WARNING: $var returned an error\n";
811	    } else {
812		chomp $retval;
813	    }
814	} elsif (defined($variable{$var})) {
815	    $retval = "$retval$variable{$var}";
816	} elsif (defined($remove_undef) && $remove_undef) {
817	    # for if statements, any variable that is not defined,
818	    # we simple convert to 0
819	    $retval = "${retval}0";
820	} else {
821	    # put back the origin piece.
822	    $retval = "$retval\$\{$var\}";
823	    # This could be an option that is used later, save
824	    # it so we don't warn if this option is not one of
825	    # ktests options.
826	    $used_options{$var} = 1;
827	}
828	$value = $end;
829    }
830    $retval = "$retval$value";
831
832    # remove the space added in the beginning
833    $retval =~ s/ //;
834
835    return "$retval";
836}
837
838sub set_value {
839    my ($lvalue, $rvalue, $override, $overrides, $name) = @_;
840
841    my $prvalue = process_variables($rvalue);
842
843    if ($lvalue =~ /^(TEST|BISECT|CONFIG_BISECT)_TYPE(\[.*\])?$/ &&
844	$prvalue !~ /^(config_|)bisect$/ &&
845	$prvalue !~ /^build$/ &&
846	$prvalue !~ /^make_warnings_file$/ &&
847	$buildonly) {
848
849	# Note if a test is something other than build, then we
850	# will need other mandatory options.
851	if ($prvalue ne "install") {
852	    $buildonly = 0;
853	} else {
854	    # install still limits some mandatory options.
855	    $buildonly = 2;
856	}
857    }
858
859    if (defined($opt{$lvalue})) {
860	if (!$override || defined(${$overrides}{$lvalue})) {
861	    my $extra = "";
862	    if ($override) {
863		$extra = "In the same override section!\n";
864	    }
865	    die "$name: $.: Option $lvalue defined more than once!\n$extra";
866	}
867	${$overrides}{$lvalue} = $prvalue;
868    }
869
870    $opt{$lvalue} = $prvalue;
871}
872
873sub set_eval {
874    my ($lvalue, $rvalue, $name) = @_;
875
876    my $prvalue = process_variables($rvalue);
877    my $arr;
878
879    if (defined($evals{$lvalue})) {
880	$arr = $evals{$lvalue};
881    } else {
882	$arr = [];
883	$evals{$lvalue} = $arr;
884    }
885
886    push @{$arr}, $rvalue;
887}
888
889sub set_variable {
890    my ($lvalue, $rvalue) = @_;
891
892    if ($rvalue =~ /^\s*$/) {
893	delete $variable{$lvalue};
894    } else {
895	$rvalue = process_variables($rvalue);
896	$variable{$lvalue} = $rvalue;
897    }
898}
899
900sub process_compare {
901    my ($lval, $cmp, $rval) = @_;
902
903    # remove whitespace
904
905    $lval =~ s/^\s*//;
906    $lval =~ s/\s*$//;
907
908    $rval =~ s/^\s*//;
909    $rval =~ s/\s*$//;
910
911    if ($cmp eq "==") {
912	return $lval eq $rval;
913    } elsif ($cmp eq "!=") {
914	return $lval ne $rval;
915    } elsif ($cmp eq "=~") {
916	return $lval =~ m/$rval/;
917    } elsif ($cmp eq "!~") {
918	return $lval !~ m/$rval/;
919    }
920
921    my $statement = "$lval $cmp $rval";
922    my $ret = eval $statement;
923
924    # $@ stores error of eval
925    if ($@) {
926	return -1;
927    }
928
929    return $ret;
930}
931
932sub value_defined {
933    my ($val) = @_;
934
935    return defined($variable{$2}) ||
936	defined($opt{$2});
937}
938
939sub process_expression {
940    my ($name, $val) = @_;
941
942    my $c = $d++;
943
944    while ($val =~ s/\(([^\(]*?)\)/\&\&\&\&VAL\&\&\&\&/) {
945	my $express = $1;
946
947	if (process_expression($name, $express)) {
948	    $val =~ s/\&\&\&\&VAL\&\&\&\&/ 1 /;
949	} else {
950	    $val =~ s/\&\&\&\&VAL\&\&\&\&/ 0 /;
951	}
952    }
953
954    $d--;
955    my $OR = "\\|\\|";
956    my $AND = "\\&\\&";
957
958    while ($val =~ s/^(.*?)($OR|$AND)//) {
959	my $express = $1;
960	my $op = $2;
961
962	if (process_expression($name, $express)) {
963	    if ($op eq "||") {
964		return 1;
965	    }
966	} else {
967	    if ($op eq "&&") {
968		return 0;
969	    }
970	}
971    }
972
973    if ($val =~ /(.*)(==|\!=|>=|<=|>|<|=~|\!~)(.*)/) {
974	my $ret = process_compare($1, $2, $3);
975	if ($ret < 0) {
976	    die "$name: $.: Unable to process comparison\n";
977	}
978	return $ret;
979    }
980
981    if ($val =~ /^\s*(NOT\s*)?DEFINED\s+(\S+)\s*$/) {
982	if (defined $1) {
983	    return !value_defined($2);
984	} else {
985	    return value_defined($2);
986	}
987    }
988
989    if ($val =~ s/^\s*NOT\s+(.*)//) {
990	my $express = $1;
991	my $ret = process_expression($name, $express);
992	return !$ret;
993    }
994
995    if ($val =~ /^\s*0\s*$/) {
996	return 0;
997    } elsif ($val =~ /^\s*\d+\s*$/) {
998	return 1;
999    }
1000
1001    die ("$name: $.: Undefined content $val in if statement\n");
1002}
1003
1004sub process_if {
1005    my ($name, $value) = @_;
1006
1007    # Convert variables and replace undefined ones with 0
1008    my $val = process_variables($value, 1);
1009    my $ret = process_expression $name, $val;
1010
1011    return $ret;
1012}
1013
1014sub __read_config {
1015    my ($config, $current_test_num) = @_;
1016
1017    my $in;
1018    open($in, $config) || die "can't read file $config";
1019
1020    my $name = $config;
1021    $name =~ s,.*/(.*),$1,;
1022
1023    my $test_num = $$current_test_num;
1024    my $default = 1;
1025    my $repeat = 1;
1026    my $num_tests_set = 0;
1027    my $skip = 0;
1028    my $rest;
1029    my $line;
1030    my $test_case = 0;
1031    my $if = 0;
1032    my $if_set = 0;
1033    my $override = 0;
1034
1035    my %overrides;
1036
1037    while (<$in>) {
1038
1039	# ignore blank lines and comments
1040	next if (/^\s*$/ || /\s*\#/);
1041
1042	if (/^\s*(TEST_START|DEFAULTS)\b(.*)/) {
1043
1044	    my $type = $1;
1045	    $rest = $2;
1046	    $line = $2;
1047
1048	    my $old_test_num;
1049	    my $old_repeat;
1050	    $override = 0;
1051
1052	    if ($type eq "TEST_START") {
1053		if ($num_tests_set) {
1054		    die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
1055		}
1056
1057		$old_test_num = $test_num;
1058		$old_repeat = $repeat;
1059
1060		$test_num += $repeat;
1061		$default = 0;
1062		$repeat = 1;
1063	    } else {
1064		$default = 1;
1065	    }
1066
1067	    # If SKIP is anywhere in the line, the command will be skipped
1068	    if ($rest =~ s/\s+SKIP\b//) {
1069		$skip = 1;
1070	    } else {
1071		$test_case = 1;
1072		$skip = 0;
1073	    }
1074
1075	    if ($rest =~ s/\sELSE\b//) {
1076		if (!$if) {
1077		    die "$name: $.: ELSE found with out matching IF section\n$_";
1078		}
1079		$if = 0;
1080
1081		if ($if_set) {
1082		    $skip = 1;
1083		} else {
1084		    $skip = 0;
1085		}
1086	    }
1087
1088	    if ($rest =~ s/\sIF\s+(.*)//) {
1089		if (process_if($name, $1)) {
1090		    $if_set = 1;
1091		} else {
1092		    $skip = 1;
1093		}
1094		$if = 1;
1095	    } else {
1096		$if = 0;
1097		$if_set = 0;
1098	    }
1099
1100	    if (!$skip) {
1101		if ($type eq "TEST_START") {
1102		    if ($rest =~ s/\s+ITERATE\s+(\d+)//) {
1103			$repeat = $1;
1104			$repeat_tests{"$test_num"} = $repeat;
1105		    }
1106		} elsif ($rest =~ s/\sOVERRIDE\b//) {
1107		    # DEFAULT only
1108		    $override = 1;
1109		    # Clear previous overrides
1110		    %overrides = ();
1111		}
1112	    }
1113
1114	    if (!$skip && $rest !~ /^\s*$/) {
1115		die "$name: $.: Garbage found after $type\n$_";
1116	    }
1117
1118	    if ($skip && $type eq "TEST_START") {
1119		$test_num = $old_test_num;
1120		$repeat = $old_repeat;
1121	    }
1122	} elsif (/^\s*ELSE\b(.*)$/) {
1123	    if (!$if) {
1124		die "$name: $.: ELSE found with out matching IF section\n$_";
1125	    }
1126	    $rest = $1;
1127	    if ($if_set) {
1128		$skip = 1;
1129		$rest = "";
1130	    } else {
1131		$skip = 0;
1132
1133		if ($rest =~ /\sIF\s+(.*)/) {
1134		    # May be a ELSE IF section.
1135		    if (process_if($name, $1)) {
1136			$if_set = 1;
1137		    } else {
1138			$skip = 1;
1139		    }
1140		    $rest = "";
1141		} else {
1142		    $if = 0;
1143		}
1144	    }
1145
1146	    if ($rest !~ /^\s*$/) {
1147		die "$name: $.: Garbage found after DEFAULTS\n$_";
1148	    }
1149
1150	} elsif (/^\s*INCLUDE\s+(\S+)/) {
1151
1152	    next if ($skip);
1153
1154	    if (!$default) {
1155		die "$name: $.: INCLUDE can only be done in default sections\n$_";
1156	    }
1157
1158	    my $file = process_variables($1);
1159
1160	    if ($file !~ m,^/,) {
1161		# check the path of the config file first
1162		if ($config =~ m,(.*)/,) {
1163		    if (-f "$1/$file") {
1164			$file = "$1/$file";
1165		    }
1166		}
1167	    }
1168
1169	    if ( ! -r $file ) {
1170		die "$name: $.: Can't read file $file\n$_";
1171	    }
1172
1173	    if (__read_config($file, \$test_num)) {
1174		$test_case = 1;
1175	    }
1176
1177	} elsif (/^\s*([A-Z_\[\]\d]+)\s*=~\s*(.*?)\s*$/) {
1178
1179	    next if ($skip);
1180
1181	    my $lvalue = $1;
1182	    my $rvalue = $2;
1183
1184	    if ($default || $lvalue =~ /\[\d+\]$/) {
1185		set_eval($lvalue, $rvalue, $name);
1186	    } else {
1187		my $val = "$lvalue\[$test_num\]";
1188		set_eval($val, $rvalue, $name);
1189	    }
1190
1191	} elsif (/^\s*([A-Z_\[\]\d]+)\s*=\s*(.*?)\s*$/) {
1192
1193	    next if ($skip);
1194
1195	    my $lvalue = $1;
1196	    my $rvalue = $2;
1197
1198	    if (!$default &&
1199		($lvalue eq "NUM_TESTS" ||
1200		 $lvalue eq "LOG_FILE" ||
1201		 $lvalue eq "CLEAR_LOG")) {
1202		die "$name: $.: $lvalue must be set in DEFAULTS section\n";
1203	    }
1204
1205	    if ($lvalue eq "NUM_TESTS") {
1206		if ($test_num) {
1207		    die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
1208		}
1209		if (!$default) {
1210		    die "$name: $.: NUM_TESTS must be set in default section\n";
1211		}
1212		$num_tests_set = 1;
1213	    }
1214
1215	    if ($default || $lvalue =~ /\[\d+\]$/) {
1216		set_value($lvalue, $rvalue, $override, \%overrides, $name);
1217	    } else {
1218		my $val = "$lvalue\[$test_num\]";
1219		set_value($val, $rvalue, $override, \%overrides, $name);
1220
1221		if ($repeat > 1) {
1222		    $repeats{$val} = $repeat;
1223		}
1224	    }
1225	} elsif (/^\s*([A-Z_\[\]\d]+)\s*:=\s*(.*?)\s*$/) {
1226	    next if ($skip);
1227
1228	    my $lvalue = $1;
1229	    my $rvalue = $2;
1230
1231	    # process config variables.
1232	    # Config variables are only active while reading the
1233	    # config and can be defined anywhere. They also ignore
1234	    # TEST_START and DEFAULTS, but are skipped if they are in
1235	    # on of these sections that have SKIP defined.
1236	    # The save variable can be
1237	    # defined multiple times and the new one simply overrides
1238	    # the previous one.
1239	    set_variable($lvalue, $rvalue);
1240
1241	} else {
1242	    die "$name: $.: Garbage found in config\n$_";
1243	}
1244    }
1245
1246    if ($test_num) {
1247	$test_num += $repeat - 1;
1248	$opt{"NUM_TESTS"} = $test_num;
1249    }
1250
1251    close($in);
1252
1253    $$current_test_num = $test_num;
1254
1255    return $test_case;
1256}
1257
1258sub get_test_case {
1259    print "What test case would you like to run?\n";
1260    print " (build, install or boot)\n";
1261    print " Other tests are available but require editing ktest.conf\n";
1262    print " (see tools/testing/ktest/sample.conf)\n";
1263    my $ans = <STDIN>;
1264    chomp $ans;
1265    $default{"TEST_TYPE"} = $ans;
1266}
1267
1268sub read_config {
1269    my ($config) = @_;
1270
1271    my $test_case;
1272    my $test_num = 0;
1273
1274    $test_case = __read_config $config, \$test_num;
1275
1276    # make sure we have all mandatory configs
1277    get_mandatory_configs;
1278
1279    # was a test specified?
1280    if (!$test_case) {
1281	print "No test case specified.\n";
1282	get_test_case;
1283    }
1284
1285    # set any defaults
1286
1287    foreach my $default (keys %default) {
1288	if (!defined($opt{$default})) {
1289	    $opt{$default} = $default{$default};
1290	}
1291    }
1292
1293    if ($opt{"IGNORE_UNUSED"} == 1) {
1294	return;
1295    }
1296
1297    my %not_used;
1298
1299    # check if there are any stragglers (typos?)
1300    foreach my $option (keys %opt) {
1301	my $op = $option;
1302	# remove per test labels.
1303	$op =~ s/\[.*\]//;
1304	if (!exists($option_map{$op}) &&
1305	    !exists($default{$op}) &&
1306	    !exists($used_options{$op})) {
1307	    $not_used{$op} = 1;
1308	}
1309    }
1310
1311    if (%not_used) {
1312	my $s = "s are";
1313	$s = " is" if (keys %not_used == 1);
1314	print "The following option$s not used; could be a typo:\n";
1315	foreach my $option (keys %not_used) {
1316	    print "$option\n";
1317	}
1318	print "Set IGNORE_UNUSED = 1 to have ktest ignore unused variables\n";
1319	if (!read_yn "Do you want to continue?") {
1320	    exit -1;
1321	}
1322    }
1323}
1324
1325sub __eval_option {
1326    my ($name, $option, $i) = @_;
1327
1328    # Add space to evaluate the character before $
1329    $option = " $option";
1330    my $retval = "";
1331    my $repeated = 0;
1332    my $parent = 0;
1333
1334    foreach my $test (keys %repeat_tests) {
1335	if ($i >= $test &&
1336	    $i < $test + $repeat_tests{$test}) {
1337
1338	    $repeated = 1;
1339	    $parent = $test;
1340	    last;
1341	}
1342    }
1343
1344    while ($option =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) {
1345	my $start = $1;
1346	my $var = $2;
1347	my $end = $3;
1348
1349	# Append beginning of line
1350	$retval = "$retval$start";
1351
1352	# If the iteration option OPT[$i] exists, then use that.
1353	# otherwise see if the default OPT (without [$i]) exists.
1354
1355	my $o = "$var\[$i\]";
1356	my $parento = "$var\[$parent\]";
1357
1358	# If a variable contains itself, use the default var
1359	if (($var eq $name) && defined($opt{$var})) {
1360	    $o = $opt{$var};
1361	    $retval = "$retval$o";
1362	} elsif (defined($opt{$o})) {
1363	    $o = $opt{$o};
1364	    $retval = "$retval$o";
1365	} elsif ($repeated && defined($opt{$parento})) {
1366	    $o = $opt{$parento};
1367	    $retval = "$retval$o";
1368	} elsif (defined($opt{$var})) {
1369	    $o = $opt{$var};
1370	    $retval = "$retval$o";
1371	} elsif ($var eq "KERNEL_VERSION" && defined($make)) {
1372	    # special option KERNEL_VERSION uses kernel version
1373	    get_version();
1374	    $retval = "$retval$version";
1375	} else {
1376	    $retval = "$retval\$\{$var\}";
1377	}
1378
1379	$option = $end;
1380    }
1381
1382    $retval = "$retval$option";
1383
1384    $retval =~ s/^ //;
1385
1386    return $retval;
1387}
1388
1389sub process_evals {
1390    my ($name, $option, $i) = @_;
1391
1392    my $option_name = "$name\[$i\]";
1393    my $ev;
1394
1395    my $old_option = $option;
1396
1397    if (defined($evals{$option_name})) {
1398	$ev = $evals{$option_name};
1399    } elsif (defined($evals{$name})) {
1400	$ev = $evals{$name};
1401    } else {
1402	return $option;
1403    }
1404
1405    for my $e (@{$ev}) {
1406	eval "\$option =~ $e";
1407    }
1408
1409    if ($option ne $old_option) {
1410	doprint("$name changed from '$old_option' to '$option'\n");
1411    }
1412
1413    return $option;
1414}
1415
1416sub eval_option {
1417    my ($name, $option, $i) = @_;
1418
1419    my $prev = "";
1420
1421    # Since an option can evaluate to another option,
1422    # keep iterating until we do not evaluate any more
1423    # options.
1424    my $r = 0;
1425    while ($prev ne $option) {
1426	# Check for recursive evaluations.
1427	# 100 deep should be more than enough.
1428	if ($r++ > 100) {
1429	    die "Over 100 evaluations occurred with $option\n" .
1430		"Check for recursive variables\n";
1431	}
1432	$prev = $option;
1433	$option = __eval_option($name, $option, $i);
1434    }
1435
1436    $option = process_evals($name, $option, $i);
1437
1438    return $option;
1439}
1440
1441sub reboot {
1442    my ($time) = @_;
1443    my $powercycle = 0;
1444
1445    # test if the machine can be connected to within a few seconds
1446    my $stat = run_ssh("echo check machine status", $connect_timeout);
1447    if (!$stat) {
1448	doprint("power cycle\n");
1449	$powercycle = 1;
1450    }
1451
1452    if ($powercycle) {
1453	run_command "$power_cycle";
1454
1455	start_monitor;
1456	# flush out current monitor
1457	# May contain the reboot success line
1458	wait_for_monitor 1;
1459
1460    } else {
1461	# Make sure everything has been written to disk
1462	run_ssh("sync", 10);
1463
1464	if (defined($time)) {
1465	    start_monitor;
1466	    # flush out current monitor
1467	    # May contain the reboot success line
1468	    wait_for_monitor 1;
1469	}
1470
1471	# try to reboot normally
1472	if (run_command $reboot) {
1473	    if (defined($powercycle_after_reboot)) {
1474		sleep $powercycle_after_reboot;
1475		run_command "$power_cycle";
1476	    }
1477	} else {
1478	    # nope? power cycle it.
1479	    run_command "$power_cycle";
1480	}
1481    }
1482
1483    if (defined($time)) {
1484
1485	# We only want to get to the new kernel, don't fail
1486	# if we stumble over a call trace.
1487	my $save_ignore_errors = $ignore_errors;
1488	$ignore_errors = 1;
1489
1490	# Look for the good kernel to boot
1491	if (wait_for_monitor($time, "Linux version")) {
1492	    # reboot got stuck?
1493	    doprint "Reboot did not finish. Forcing power cycle\n";
1494	    run_command "$power_cycle";
1495	}
1496
1497	$ignore_errors = $save_ignore_errors;
1498
1499	# Still need to wait for the reboot to finish
1500	wait_for_monitor($time, $reboot_success_line);
1501    }
1502    if ($powercycle || $time) {
1503	end_monitor;
1504    }
1505}
1506
1507sub reboot_to_good {
1508    my ($time) = @_;
1509
1510    if (defined($switch_to_good)) {
1511	run_command $switch_to_good;
1512    }
1513
1514    reboot $time;
1515}
1516
1517sub do_not_reboot {
1518    my $i = $iteration;
1519
1520    return $test_type eq "build" || $no_reboot ||
1521	($test_type eq "patchcheck" && $opt{"PATCHCHECK_TYPE[$i]"} eq "build") ||
1522	($test_type eq "bisect" && $opt{"BISECT_TYPE[$i]"} eq "build") ||
1523	($test_type eq "config_bisect" && $opt{"CONFIG_BISECT_TYPE[$i]"} eq "build");
1524}
1525
1526sub get_test_name() {
1527    my $name;
1528
1529    if (defined($test_name)) {
1530	$name = "$test_name:$test_type";
1531    } else {
1532	$name = $test_type;
1533    }
1534    return $name;
1535}
1536
1537sub dodie {
1538    # avoid recursion
1539    return if ($in_die);
1540    $in_die = 1;
1541
1542    if ($monitor_cnt) {
1543	# restore terminal settings
1544	system("stty $stty_orig");
1545    }
1546
1547    my $i = $iteration;
1548
1549    doprint "CRITICAL FAILURE... [TEST $i] ", @_, "\n";
1550
1551    if ($reboot_on_error && !do_not_reboot) {
1552	doprint "REBOOTING\n";
1553	reboot_to_good;
1554    } elsif ($poweroff_on_error && defined($power_off)) {
1555	doprint "POWERING OFF\n";
1556	`$power_off`;
1557    }
1558
1559    if (defined($opt{"LOG_FILE"})) {
1560	print " See $opt{LOG_FILE} for more info.\n";
1561    }
1562
1563    if ($email_on_error) {
1564	my $name = get_test_name;
1565	my $log_file;
1566
1567	if (defined($opt{"LOG_FILE"})) {
1568	    my $whence = 2; # End of file
1569	    my $log_size = tell LOG;
1570	    my $size = $log_size - $test_log_start;
1571
1572	    if (defined($mail_max_size)) {
1573		if ($size > $mail_max_size) {
1574		    $size = $mail_max_size;
1575		}
1576	    }
1577	    my $pos = - $size;
1578	    $log_file = "$tmpdir/log";
1579	    open (L, "$opt{LOG_FILE}") or die "Can't open $opt{LOG_FILE} to read)";
1580	    open (O, "> $tmpdir/log") or die "Can't open $tmpdir/log\n";
1581	    seek(L, $pos, $whence);
1582	    while (<L>) {
1583		print O;
1584	    }
1585	    close O;
1586	    close L;
1587	}
1588
1589	send_email("KTEST: critical failure for test $i [$name]",
1590		"Your test started at $script_start_time has failed with:\n@_\n", $log_file);
1591    }
1592
1593    if (defined($post_test)) {
1594	run_command $post_test;
1595    }
1596
1597    die @_, "\n";
1598}
1599
1600sub create_pty {
1601    my ($ptm, $pts) = @_;
1602    my $tmp;
1603    my $TIOCSPTLCK = 0x40045431;
1604    my $TIOCGPTN = 0x80045430;
1605
1606    sysopen($ptm, "/dev/ptmx", O_RDWR | O_NONBLOCK) or
1607	dodie "Can't open /dev/ptmx";
1608
1609    # unlockpt()
1610    $tmp = pack("i", 0);
1611    ioctl($ptm, $TIOCSPTLCK, $tmp) or
1612	dodie "ioctl TIOCSPTLCK for /dev/ptmx failed";
1613
1614    # ptsname()
1615    ioctl($ptm, $TIOCGPTN, $tmp) or
1616	dodie "ioctl TIOCGPTN for /dev/ptmx failed";
1617    $tmp = unpack("i", $tmp);
1618
1619    sysopen($pts, "/dev/pts/$tmp", O_RDWR | O_NONBLOCK) or
1620	dodie "Can't open /dev/pts/$tmp";
1621}
1622
1623sub exec_console {
1624    my ($ptm, $pts) = @_;
1625
1626    close($ptm);
1627
1628    close(\*STDIN);
1629    close(\*STDOUT);
1630    close(\*STDERR);
1631
1632    open(\*STDIN, '<&', $pts);
1633    open(\*STDOUT, '>&', $pts);
1634    open(\*STDERR, '>&', $pts);
1635
1636    close($pts);
1637
1638    exec $console or
1639	dodie "Can't open console $console";
1640}
1641
1642sub open_console {
1643    my ($ptm) = @_;
1644    my $pts = \*PTSFD;
1645    my $pid;
1646
1647    # save terminal settings
1648    $stty_orig = `stty -g`;
1649
1650    # place terminal in cbreak mode so that stdin can be read one character at
1651    # a time without having to wait for a newline
1652    system("stty -icanon -echo -icrnl");
1653
1654    create_pty($ptm, $pts);
1655
1656    $pid = fork;
1657
1658    if (!$pid) {
1659	# child
1660	exec_console($ptm, $pts)
1661    }
1662
1663    # parent
1664    close($pts);
1665
1666    return $pid;
1667
1668    open(PTSFD, "Stop perl from warning about single use of PTSFD");
1669}
1670
1671sub close_console {
1672    my ($fp, $pid) = @_;
1673
1674    doprint "kill child process $pid\n";
1675    kill $close_console_signal, $pid;
1676
1677    doprint "wait for child process $pid to exit\n";
1678    waitpid($pid, 0);
1679
1680    print "closing!\n";
1681    close($fp);
1682
1683    # restore terminal settings
1684    system("stty $stty_orig");
1685}
1686
1687sub start_monitor {
1688    if ($monitor_cnt++) {
1689	return;
1690    }
1691    $monitor_fp = \*MONFD;
1692    $monitor_pid = open_console $monitor_fp;
1693
1694    return;
1695
1696    open(MONFD, "Stop perl from warning about single use of MONFD");
1697}
1698
1699sub end_monitor {
1700    return if (!defined $console);
1701    if (--$monitor_cnt) {
1702	return;
1703    }
1704    close_console($monitor_fp, $monitor_pid);
1705}
1706
1707sub wait_for_monitor {
1708    my ($time, $stop) = @_;
1709    my $full_line = "";
1710    my $line;
1711    my $booted = 0;
1712    my $start_time = time;
1713    my $skip_call_trace = 0;
1714    my $bug = 0;
1715    my $bug_ignored = 0;
1716    my $now;
1717
1718    doprint "** Wait for monitor to settle down **\n";
1719
1720    # read the monitor and wait for the system to calm down
1721    while (!$booted) {
1722	$line = wait_for_input($monitor_fp, $time);
1723	last if (!defined($line));
1724	print "$line";
1725	$full_line .= $line;
1726
1727	if (defined($stop) && $full_line =~ /$stop/) {
1728	    doprint "wait for monitor detected $stop\n";
1729	    $booted = 1;
1730	}
1731
1732	if ($full_line =~ /\[ backtrace testing \]/) {
1733	    $skip_call_trace = 1;
1734	}
1735
1736	if ($full_line =~ /call trace:/i) {
1737	    if (!$bug && !$skip_call_trace) {
1738		if ($ignore_errors) {
1739		    $bug_ignored = 1;
1740		} else {
1741		    $bug = 1;
1742		}
1743	    }
1744	}
1745
1746	if ($full_line =~ /\[ end of backtrace testing \]/) {
1747	    $skip_call_trace = 0;
1748	}
1749
1750	if ($full_line =~ /Kernel panic -/) {
1751	    $bug = 1;
1752	}
1753
1754	if ($line =~ /\n/) {
1755	    $full_line = "";
1756	}
1757	$now = time;
1758	if ($now - $start_time >= $max_monitor_wait) {
1759	    doprint "Exiting monitor flush due to hitting MAX_MONITOR_WAIT\n";
1760	    return 1;
1761	}
1762    }
1763    print "** Monitor flushed **\n";
1764
1765    # if stop is defined but wasn't hit, return error
1766    # used by reboot (which wants to see a reboot)
1767    if (defined($stop) && !$booted) {
1768	$bug = 1;
1769    }
1770    return $bug;
1771}
1772
1773sub save_logs {
1774    my ($result, $basedir) = @_;
1775    my @t = localtime;
1776    my $date = sprintf "%04d%02d%02d%02d%02d%02d",
1777	1900+$t[5],$t[4],$t[3],$t[2],$t[1],$t[0];
1778
1779    my $type = $build_type;
1780    if ($type =~ /useconfig/) {
1781	$type = "useconfig";
1782    }
1783
1784    my $dir = "$machine-$test_type-$type-$result-$date";
1785
1786    $dir = "$basedir/$dir";
1787
1788    if (!-d $dir) {
1789	mkpath($dir) or
1790	    dodie "can't create $dir";
1791    }
1792
1793    my %files = (
1794	"config" => $output_config,
1795	"buildlog" => $buildlog,
1796	"dmesg" => $dmesg,
1797	"testlog" => $testlog,
1798    );
1799
1800    while (my ($name, $source) = each(%files)) {
1801	if (-f "$source") {
1802	    cp "$source", "$dir/$name" or
1803		dodie "failed to copy $source";
1804	}
1805    }
1806
1807    doprint "*** Saved info to $dir ***\n";
1808}
1809
1810sub fail {
1811
1812    if ($die_on_failure) {
1813	dodie @_;
1814    }
1815
1816    doprint "FAILED\n";
1817
1818    my $i = $iteration;
1819
1820    # no need to reboot for just building.
1821    if (!do_not_reboot) {
1822	doprint "REBOOTING\n";
1823	reboot_to_good $sleep_time;
1824    }
1825
1826    my $name = "";
1827
1828    if (defined($test_name)) {
1829	$name = " ($test_name)";
1830    }
1831
1832    print_times;
1833
1834    doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
1835    doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
1836    doprint "KTEST RESULT: TEST $i$name Failed: ", @_, "\n";
1837    doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
1838    doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
1839
1840    if (defined($store_failures)) {
1841	save_logs "fail", $store_failures;
1842    }
1843
1844    if (defined($post_test)) {
1845	run_command $post_test;
1846    }
1847
1848    return 1;
1849}
1850
1851sub run_command {
1852    my ($command, $redirect, $timeout) = @_;
1853    my $start_time;
1854    my $end_time;
1855    my $dolog = 0;
1856    my $dord = 0;
1857    my $dostdout = 0;
1858    my $pid;
1859    my $command_orig = $command;
1860
1861    $command =~ s/\$SSH_USER/$ssh_user/g;
1862    $command =~ s/\$MACHINE/$machine/g;
1863
1864    if (!defined($timeout)) {
1865	$timeout = $run_timeout;
1866    }
1867
1868    if (!defined($timeout)) {
1869	$timeout = -1; # tell wait_for_input to wait indefinitely
1870    }
1871
1872    doprint("$command ... ");
1873    $start_time = time;
1874
1875    $pid = open(CMD, "$command 2>&1 |") or
1876	(fail "unable to exec $command" and return 0);
1877
1878    if (defined($opt{"LOG_FILE"})) {
1879	$dolog = 1;
1880    }
1881
1882    if (defined($redirect)) {
1883	if ($redirect eq 1) {
1884	    $dostdout = 1;
1885	    # Have the output of the command on its own line
1886	    doprint "\n";
1887	} else {
1888	    open (RD, ">$redirect") or
1889		dodie "failed to write to redirect $redirect";
1890	    $dord = 1;
1891	}
1892    }
1893
1894    my $hit_timeout = 0;
1895
1896    while (1) {
1897	my $fp = \*CMD;
1898	my $line = wait_for_input($fp, $timeout);
1899	if (!defined($line)) {
1900	    my $now = time;
1901	    if ($timeout >= 0 && (($now - $start_time) >= $timeout)) {
1902		doprint "Hit timeout of $timeout, killing process\n";
1903		$hit_timeout = 1;
1904		kill 9, $pid;
1905	    }
1906	    last;
1907	}
1908	print LOG $line if ($dolog);
1909	print RD $line if ($dord);
1910	print $line if ($dostdout);
1911    }
1912
1913    waitpid($pid, 0);
1914    # shift 8 for real exit status
1915    $run_command_status = $? >> 8;
1916
1917    if ($command_orig eq $default{REBOOT} &&
1918	$run_command_status == $reboot_return_code) {
1919	$run_command_status = 0;
1920    }
1921
1922    close(CMD);
1923    close(RD)  if ($dord);
1924
1925    $end_time = time;
1926    my $delta = $end_time - $start_time;
1927
1928    if ($delta == 1) {
1929	doprint "[1 second] ";
1930    } else {
1931	doprint "[$delta seconds] ";
1932    }
1933
1934    if ($hit_timeout) {
1935	$run_command_status = 1;
1936    }
1937
1938    if ($run_command_status) {
1939	doprint "FAILED!\n";
1940    } else {
1941	doprint "SUCCESS\n";
1942    }
1943
1944    return !$run_command_status;
1945}
1946
1947sub run_ssh {
1948    my ($cmd, $timeout) = @_;
1949    my $cp_exec = $ssh_exec;
1950
1951    $cp_exec =~ s/\$SSH_COMMAND/$cmd/g;
1952    return run_command "$cp_exec", undef , $timeout;
1953}
1954
1955sub run_scp {
1956    my ($src, $dst, $cp_scp) = @_;
1957
1958    $cp_scp =~ s/\$SRC_FILE/$src/g;
1959    $cp_scp =~ s/\$DST_FILE/$dst/g;
1960
1961    return run_command "$cp_scp";
1962}
1963
1964sub run_scp_install {
1965    my ($src, $dst) = @_;
1966
1967    my $cp_scp = $scp_to_target_install;
1968
1969    return run_scp($src, $dst, $cp_scp);
1970}
1971
1972sub run_scp_mod {
1973    my ($src, $dst) = @_;
1974
1975    my $cp_scp = $scp_to_target;
1976
1977    return run_scp($src, $dst, $cp_scp);
1978}
1979
1980sub _get_grub_index {
1981
1982    my ($command, $target, $skip, $submenu) = @_;
1983
1984    return if (defined($grub_number) && defined($last_grub_menu) &&
1985	$last_grub_menu eq $grub_menu && defined($last_machine) &&
1986	$last_machine eq $machine);
1987
1988    doprint "Find $reboot_type menu ... ";
1989    $grub_number = -1;
1990
1991    my $ssh_grub = $ssh_exec;
1992    $ssh_grub =~ s,\$SSH_COMMAND,$command,g;
1993
1994    open(IN, "$ssh_grub |") or
1995	dodie "unable to execute $command";
1996
1997    my $found = 0;
1998
1999    my $submenu_number = 0;
2000
2001    while (<IN>) {
2002	if (/$target/) {
2003	    $grub_number++;
2004	    $found = 1;
2005	    last;
2006	} elsif (defined($submenu) && /$submenu/) {
2007		$submenu_number++;
2008		$grub_number = -1;
2009	} elsif (/$skip/) {
2010	    $grub_number++;
2011	}
2012    }
2013    close(IN);
2014
2015    dodie "Could not find '$grub_menu' through $command on $machine"
2016	if (!$found);
2017    if ($submenu_number > 0) {
2018	$grub_number = "$submenu_number>$grub_number";
2019    }
2020    doprint "$grub_number\n";
2021    $last_grub_menu = $grub_menu;
2022    $last_machine = $machine;
2023}
2024
2025sub get_grub_index {
2026
2027    my $command;
2028    my $target;
2029    my $skip;
2030    my $submenu;
2031    my $grub_menu_qt;
2032
2033    if ($reboot_type !~ /^grub/) {
2034	return;
2035    }
2036
2037    $grub_menu_qt = quotemeta($grub_menu);
2038
2039    if ($reboot_type eq "grub") {
2040	$command = "cat /boot/grub/menu.lst";
2041	$target = '^\s*title\s+' . $grub_menu_qt . '\s*$';
2042	$skip = '^\s*title\s';
2043    } elsif ($reboot_type eq "grub2") {
2044	$command = "cat $grub_file";
2045	$target = '^\s*menuentry.*' . $grub_menu_qt;
2046	$skip = '^\s*menuentry\s';
2047	$submenu = '^\s*submenu\s';
2048    } elsif ($reboot_type eq "grub2bls") {
2049	$command = $grub_bls_get;
2050	$target = '^title=.*' . $grub_menu_qt;
2051	$skip = '^title=';
2052    } else {
2053	return;
2054    }
2055
2056    _get_grub_index($command, $target, $skip, $submenu);
2057}
2058
2059sub wait_for_input {
2060    my ($fp, $time) = @_;
2061    my $start_time;
2062    my $rin;
2063    my $rout;
2064    my $nr;
2065    my $buf;
2066    my $line;
2067    my $ch;
2068
2069    if (!defined($time)) {
2070	$time = $timeout;
2071    }
2072
2073    if ($time < 0) {
2074	# Negative number means wait indefinitely
2075	undef $time;
2076    }
2077
2078    $rin = '';
2079    vec($rin, fileno($fp), 1) = 1;
2080    vec($rin, fileno(\*STDIN), 1) = 1;
2081
2082    $start_time = time;
2083
2084    while (1) {
2085	$nr = select($rout=$rin, undef, undef, $time);
2086
2087	last if ($nr <= 0);
2088
2089	# copy data from stdin to the console
2090	if (vec($rout, fileno(\*STDIN), 1) == 1) {
2091	    $nr = sysread(\*STDIN, $buf, 1000);
2092	    syswrite($fp, $buf, $nr) if ($nr > 0);
2093	}
2094
2095	# The timeout is based on time waiting for the fp data
2096	if (vec($rout, fileno($fp), 1) != 1) {
2097	    last if (defined($time) && (time - $start_time > $time));
2098	    next;
2099	}
2100
2101	$line = "";
2102
2103	# try to read one char at a time
2104	while (sysread $fp, $ch, 1) {
2105	    $line .= $ch;
2106	    last if ($ch eq "\n");
2107	}
2108
2109	last if (!length($line));
2110
2111	return $line;
2112    }
2113    return undef;
2114}
2115
2116sub reboot_to {
2117    if (defined($switch_to_test)) {
2118	run_command $switch_to_test;
2119    }
2120
2121    if ($reboot_type eq "grub") {
2122	run_ssh "'(echo \"savedefault --default=$grub_number --once\" | grub --batch)'";
2123    } elsif (($reboot_type eq "grub2") or ($reboot_type eq "grub2bls")) {
2124	run_ssh "$grub_reboot \"'$grub_number'\"";
2125    } elsif ($reboot_type eq "syslinux") {
2126	run_ssh "$syslinux --once \\\"$syslinux_label\\\" $syslinux_path";
2127    } elsif (defined $reboot_script) {
2128	run_command "$reboot_script";
2129    }
2130    reboot;
2131}
2132
2133sub get_sha1 {
2134    my ($commit) = @_;
2135
2136    doprint "git rev-list --max-count=1 $commit ... ";
2137    my $sha1 = `git rev-list --max-count=1 $commit`;
2138    my $ret = $?;
2139
2140    logit $sha1;
2141
2142    if ($ret) {
2143	doprint "FAILED\n";
2144	dodie "Failed to get git $commit";
2145    }
2146
2147    print "SUCCESS\n";
2148
2149    chomp $sha1;
2150
2151    return $sha1;
2152}
2153
2154sub monitor {
2155    my $booted = 0;
2156    my $bug = 0;
2157    my $bug_ignored = 0;
2158    my $skip_call_trace = 0;
2159    my $loops;
2160
2161    my $start_time = time;
2162
2163    wait_for_monitor 5;
2164
2165    my $line;
2166    my $full_line = "";
2167
2168    open(DMESG, "> $dmesg") or
2169	dodie "unable to write to $dmesg";
2170
2171    reboot_to;
2172
2173    my $success_start;
2174    my $failure_start;
2175    my $monitor_start = time;
2176    my $done = 0;
2177    my $version_found = 0;
2178
2179    while (!$done) {
2180	if ($bug && defined($stop_after_failure) &&
2181	    $stop_after_failure >= 0) {
2182	    my $time = $stop_after_failure - (time - $failure_start);
2183	    $line = wait_for_input($monitor_fp, $time);
2184	    if (!defined($line)) {
2185		doprint "bug timed out after $booted_timeout seconds\n";
2186		doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
2187		last;
2188	    }
2189	} elsif ($booted) {
2190	    $line = wait_for_input($monitor_fp, $booted_timeout);
2191	    if (!defined($line)) {
2192		my $s = $booted_timeout == 1 ? "" : "s";
2193		doprint "Successful boot found: break after $booted_timeout second$s\n";
2194		last;
2195	    }
2196	} else {
2197	    $line = wait_for_input($monitor_fp);
2198	    if (!defined($line)) {
2199		my $s = $timeout == 1 ? "" : "s";
2200		doprint "Timed out after $timeout second$s\n";
2201		last;
2202	    }
2203	}
2204
2205	doprint $line;
2206	print DMESG $line;
2207
2208	# we are not guaranteed to get a full line
2209	$full_line .= $line;
2210
2211	if ($full_line =~ /$success_line/) {
2212	    $booted = 1;
2213	    $success_start = time;
2214	}
2215
2216	if ($booted && defined($stop_after_success) &&
2217	    $stop_after_success >= 0) {
2218	    my $now = time;
2219	    if ($now - $success_start >= $stop_after_success) {
2220		doprint "Test forced to stop after $stop_after_success seconds after success\n";
2221		last;
2222	    }
2223	}
2224
2225	if ($full_line =~ /\[ backtrace testing \]/) {
2226	    $skip_call_trace = 1;
2227	}
2228
2229	if ($full_line =~ /call trace:/i) {
2230	    if (!$bug && !$skip_call_trace) {
2231		if ($ignore_errors) {
2232		    $bug_ignored = 1;
2233		} else {
2234		    $bug = 1;
2235		    $failure_start = time;
2236		}
2237	    }
2238	}
2239
2240	if ($bug && defined($stop_after_failure) &&
2241	    $stop_after_failure >= 0) {
2242	    my $now = time;
2243	    if ($now - $failure_start >= $stop_after_failure) {
2244		doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
2245		last;
2246	    }
2247	}
2248
2249	if ($full_line =~ /\[ end of backtrace testing \]/) {
2250	    $skip_call_trace = 0;
2251	}
2252
2253	if ($full_line =~ /Kernel panic -/) {
2254	    $failure_start = time;
2255	    $bug = 1;
2256	}
2257
2258	# Detect triple faults by testing the banner
2259	if ($full_line =~ /\bLinux version (\S+).*\n/) {
2260	    if ($1 eq $version) {
2261		$version_found = 1;
2262	    } elsif ($version_found && $detect_triplefault) {
2263		# We already booted into the kernel we are testing,
2264		# but now we booted into another kernel?
2265		# Consider this a triple fault.
2266		doprint "Already booted in Linux kernel $version, but now\n";
2267		doprint "we booted into Linux kernel $1.\n";
2268		doprint "Assuming that this is a triple fault.\n";
2269		doprint "To disable this: set DETECT_TRIPLE_FAULT to 0\n";
2270		last;
2271	    }
2272	}
2273
2274	if ($line =~ /\n/) {
2275	    $full_line = "";
2276	}
2277
2278	if ($stop_test_after > 0 && !$booted && !$bug) {
2279	    if (time - $monitor_start > $stop_test_after) {
2280		doprint "STOP_TEST_AFTER ($stop_test_after seconds) timed out\n";
2281		$done = 1;
2282	    }
2283	}
2284    }
2285
2286    my $end_time = time;
2287    $reboot_time = $end_time - $start_time;
2288
2289    close(DMESG);
2290
2291    if ($bug) {
2292	return 0 if ($in_bisect);
2293	fail "failed - got a bug report" and return 0;
2294    }
2295
2296    if (!$booted) {
2297	return 0 if ($in_bisect);
2298	fail "failed - never got a boot prompt." and return 0;
2299    }
2300
2301    if ($bug_ignored) {
2302	doprint "WARNING: Call Trace detected but ignored due to IGNORE_ERRORS=1\n";
2303    }
2304
2305    return 1;
2306}
2307
2308sub eval_kernel_version {
2309    my ($option) = @_;
2310
2311    $option =~ s/\$KERNEL_VERSION/$version/g;
2312
2313    return $option;
2314}
2315
2316sub do_post_install {
2317
2318    return if (!defined($post_install));
2319
2320    my $cp_post_install = eval_kernel_version $post_install;
2321    run_command "$cp_post_install" or
2322	dodie "Failed to run post install";
2323}
2324
2325# Sometimes the reboot fails, and will hang. We try to ssh to the box
2326# and if we fail, we force another reboot, that should powercycle it.
2327sub test_booted {
2328    if (!run_ssh "echo testing connection") {
2329	reboot $sleep_time;
2330    }
2331}
2332
2333sub install {
2334
2335    return if ($no_install);
2336
2337    my $start_time = time;
2338
2339    if (defined($pre_install)) {
2340	my $cp_pre_install = eval_kernel_version $pre_install;
2341	run_command "$cp_pre_install" or
2342	    dodie "Failed to run pre install";
2343    }
2344
2345    my $cp_target = eval_kernel_version $target_image;
2346
2347    test_booted;
2348
2349    run_scp_install "$outputdir/$build_target", "$cp_target" or
2350	dodie "failed to copy image";
2351
2352    my $install_mods = 0;
2353
2354    # should we process modules?
2355    $install_mods = 0;
2356    open(IN, "$output_config") or dodie("Can't read config file");
2357    while (<IN>) {
2358	if (/CONFIG_MODULES(=y)?/) {
2359	    if (defined($1)) {
2360		$install_mods = 1;
2361		last;
2362	    }
2363	}
2364    }
2365    close(IN);
2366
2367    if (!$install_mods) {
2368	do_post_install;
2369	doprint "No modules needed\n";
2370	my $end_time = time;
2371	$install_time = $end_time - $start_time;
2372	return;
2373    }
2374
2375    run_command "$make INSTALL_MOD_STRIP=1 INSTALL_MOD_PATH=$tmpdir modules_install" or
2376	dodie "Failed to install modules";
2377
2378    my $modlib = "/lib/modules/$version";
2379    my $modtar = "ktest-mods.tar.bz2";
2380
2381    run_ssh "rm -rf $modlib" or
2382	dodie "failed to remove old mods: $modlib";
2383
2384    # would be nice if scp -r did not follow symbolic links
2385    run_command "cd $tmpdir && tar -cjf $modtar lib/modules/$version" or
2386	dodie "making tarball";
2387
2388    run_scp_mod "$tmpdir/$modtar", "/tmp" or
2389	dodie "failed to copy modules";
2390
2391    unlink "$tmpdir/$modtar";
2392
2393    run_ssh "'(cd / && tar xjf /tmp/$modtar)'" or
2394	dodie "failed to tar modules";
2395
2396    run_ssh "rm -f /tmp/$modtar";
2397
2398    do_post_install;
2399
2400    my $end_time = time;
2401    $install_time = $end_time - $start_time;
2402}
2403
2404sub get_version {
2405    # get the release name
2406    return if ($have_version);
2407    doprint "$make kernelrelease ... ";
2408    $version = `$make -s kernelrelease | tail -1`;
2409    if (!length($version)) {
2410	run_command "$make allnoconfig" or return 0;
2411	doprint "$make kernelrelease ... ";
2412	$version = `$make -s kernelrelease | tail -1`;
2413    }
2414    chomp($version);
2415    doprint "$version\n";
2416    $have_version = 1;
2417}
2418
2419sub start_monitor_and_install {
2420    # Make sure the stable kernel has finished booting
2421
2422    # Install bisects, don't need console
2423    if (defined $console) {
2424	start_monitor;
2425	wait_for_monitor 5;
2426	end_monitor;
2427    }
2428
2429    get_grub_index;
2430    get_version;
2431    install;
2432
2433    start_monitor if (defined $console);
2434    return monitor;
2435}
2436
2437sub process_warning_line {
2438    my ($line) = @_;
2439
2440    chomp $line;
2441
2442    # for distcc heterogeneous systems, some compilers
2443    # do things differently causing warning lines
2444    # to be slightly different. This makes an attempt
2445    # to fixe those issues.
2446
2447    # chop off the index into the line
2448    # using distcc, some compilers give different indexes
2449    # depending on white space
2450    $line =~ s/^(\s*\S+:\d+:)\d+/$1/;
2451
2452    # Some compilers use UTF-8 extended for quotes and some don't.
2453    $line =~ s/$utf8_quote/'/g;
2454
2455    return $line;
2456}
2457
2458# Read buildlog and check against warnings file for any
2459# new warnings.
2460#
2461# Returns 1 if OK
2462#         0 otherwise
2463sub check_buildlog {
2464    return 1 if (!defined $warnings_file);
2465
2466    my %warnings_list;
2467
2468    # Failed builds should not reboot the target
2469    my $save_no_reboot = $no_reboot;
2470    $no_reboot = 1;
2471
2472    if (-f $warnings_file) {
2473	open(IN, $warnings_file) or
2474	    dodie "Error opening $warnings_file";
2475
2476	while (<IN>) {
2477	    if (/$check_build_re/) {
2478		my $warning = process_warning_line $_;
2479
2480		$warnings_list{$warning} = 1;
2481	    }
2482	}
2483	close(IN);
2484    }
2485
2486    # If warnings file didn't exist, and WARNINGS_FILE exist,
2487    # then we fail on any warning!
2488
2489    open(IN, $buildlog) or dodie "Can't open $buildlog";
2490    while (<IN>) {
2491	if (/$check_build_re/) {
2492	    my $warning = process_warning_line $_;
2493
2494	    if (!defined $warnings_list{$warning}) {
2495		fail "New warning found (not in $warnings_file)\n$_\n";
2496		$no_reboot = $save_no_reboot;
2497		return 0;
2498	    }
2499	}
2500    }
2501    $no_reboot = $save_no_reboot;
2502    close(IN);
2503}
2504
2505sub check_patch_buildlog {
2506    my ($patch) = @_;
2507
2508    my @files = `git show $patch | diffstat -l`;
2509
2510    foreach my $file (@files) {
2511	chomp $file;
2512    }
2513
2514    open(IN, "git show $patch |") or
2515	dodie "failed to show $patch";
2516    while (<IN>) {
2517	if (m,^--- a/(.*),) {
2518	    chomp $1;
2519	    $files[$#files] = $1;
2520	}
2521    }
2522    close(IN);
2523
2524    open(IN, $buildlog) or dodie "Can't open $buildlog";
2525    while (<IN>) {
2526	if (/^\s*(.*?):.*(warning|error)/) {
2527	    my $err = $1;
2528	    foreach my $file (@files) {
2529		my $fullpath = "$builddir/$file";
2530		if ($file eq $err || $fullpath eq $err) {
2531		    fail "$file built with warnings" and return 0;
2532		}
2533	    }
2534	}
2535    }
2536    close(IN);
2537
2538    return 1;
2539}
2540
2541sub apply_min_config {
2542    my $outconfig = "$output_config.new";
2543
2544    # Read the config file and remove anything that
2545    # is in the force_config hash (from minconfig and others)
2546    # then add the force config back.
2547
2548    doprint "Applying minimum configurations into $output_config.new\n";
2549
2550    open (OUT, ">$outconfig") or
2551	dodie "Can't create $outconfig";
2552
2553    if (-f $output_config) {
2554	open (IN, $output_config) or
2555	    dodie "Failed to open $output_config";
2556	while (<IN>) {
2557	    if (/^(# )?(CONFIG_[^\s=]*)/) {
2558		next if (defined($force_config{$2}));
2559	    }
2560	    print OUT;
2561	}
2562	close IN;
2563    }
2564    foreach my $config (keys %force_config) {
2565	print OUT "$force_config{$config}\n";
2566    }
2567    close OUT;
2568
2569    run_command "mv $outconfig $output_config";
2570}
2571
2572sub make_oldconfig {
2573
2574    my @force_list = keys %force_config;
2575
2576    if ($#force_list >= 0) {
2577	apply_min_config;
2578    }
2579
2580    if (!run_command "$make olddefconfig") {
2581	# Perhaps olddefconfig doesn't exist in this version of the kernel
2582	# try oldnoconfig
2583	doprint "olddefconfig failed, trying make oldnoconfig\n";
2584	if (!run_command "$make oldnoconfig") {
2585	    doprint "oldnoconfig failed, trying yes '' | make oldconfig\n";
2586	    # try a yes '' | oldconfig
2587	    run_command "yes '' | $make oldconfig" or
2588		dodie "failed make config oldconfig";
2589	}
2590    }
2591}
2592
2593# read a config file and use this to force new configs.
2594sub load_force_config {
2595    my ($config) = @_;
2596
2597    doprint "Loading force configs from $config\n";
2598    open(IN, $config) or
2599	dodie "failed to read $config";
2600    while (<IN>) {
2601	chomp;
2602	if (/^(CONFIG[^\s=]*)(\s*=.*)/) {
2603	    $force_config{$1} = $_;
2604	} elsif (/^# (CONFIG_\S*) is not set/) {
2605	    $force_config{$1} = $_;
2606	}
2607    }
2608    close IN;
2609}
2610
2611sub build {
2612    my ($type) = @_;
2613
2614    unlink $buildlog;
2615
2616    my $start_time = time;
2617
2618    # Failed builds should not reboot the target
2619    my $save_no_reboot = $no_reboot;
2620    $no_reboot = 1;
2621
2622    # Calculate a new version from here.
2623    $have_version = 0;
2624
2625    if (defined($pre_build)) {
2626	my $ret = run_command $pre_build;
2627	if (!$ret && defined($pre_build_die) &&
2628	    $pre_build_die) {
2629	    dodie "failed to pre_build\n";
2630	}
2631    }
2632
2633    if ($type =~ /^useconfig:(.*)/) {
2634	run_command "cp $1 $output_config" or
2635	    dodie "could not copy $1 to .config";
2636
2637	$type = "oldconfig";
2638    }
2639
2640    # old config can ask questions
2641    if ($type eq "oldconfig") {
2642	$type = "olddefconfig";
2643
2644	# allow for empty configs
2645	run_command "touch $output_config";
2646
2647	if (!$noclean) {
2648	    run_command "mv $output_config $outputdir/config_temp" or
2649		dodie "moving .config";
2650
2651	    run_command "$make mrproper" or dodie "make mrproper";
2652
2653	    run_command "mv $outputdir/config_temp $output_config" or
2654		dodie "moving config_temp";
2655	}
2656    } elsif (!$noclean) {
2657	unlink "$output_config";
2658	run_command "$make mrproper" or
2659	    dodie "make mrproper";
2660    }
2661
2662    # add something to distinguish this build
2663    open(OUT, "> $outputdir/localversion") or dodie("Can't make localversion file");
2664    print OUT "$localversion\n";
2665    close(OUT);
2666
2667    if (defined($minconfig)) {
2668	load_force_config($minconfig);
2669    }
2670
2671    if ($type ne "olddefconfig") {
2672	run_command "$make $type" or
2673	    dodie "failed make config";
2674    }
2675    # Run old config regardless, to enforce min configurations
2676    make_oldconfig;
2677
2678    if (not defined($build_options)){
2679	$build_options = "";
2680    }
2681    my $build_ret = run_command "$make $build_options", $buildlog;
2682
2683    if (defined($post_build)) {
2684	# Because a post build may change the kernel version
2685	# do it now.
2686	get_version;
2687	my $ret = run_command $post_build;
2688	if (!$ret && defined($post_build_die) &&
2689	    $post_build_die) {
2690	    dodie "failed to post_build\n";
2691	}
2692    }
2693
2694    if (!$build_ret) {
2695	# bisect may need this to pass
2696	if ($in_bisect) {
2697	    $no_reboot = $save_no_reboot;
2698	    return 0;
2699	}
2700	fail "failed build" and return 0;
2701    }
2702
2703    $no_reboot = $save_no_reboot;
2704
2705    my $end_time = time;
2706    $build_time = $end_time - $start_time;
2707
2708    return 1;
2709}
2710
2711sub halt {
2712    if (!run_ssh "halt" or defined($power_off)) {
2713	if (defined($poweroff_after_halt)) {
2714	    sleep $poweroff_after_halt;
2715	    run_command "$power_off";
2716	}
2717    } else {
2718	# nope? the zap it!
2719	run_command "$power_off";
2720    }
2721}
2722
2723sub success {
2724    my ($i) = @_;
2725
2726    $successes++;
2727
2728    my $name = "";
2729
2730    if (defined($test_name)) {
2731	$name = " ($test_name)";
2732    }
2733
2734    print_times;
2735
2736    doprint "\n\n";
2737    doprint "*******************************************\n";
2738    doprint "*******************************************\n";
2739    doprint "KTEST RESULT: TEST $i$name SUCCESS!!!!   **\n";
2740    doprint "*******************************************\n";
2741    doprint "*******************************************\n";
2742
2743    if (defined($store_successes)) {
2744	save_logs "success", $store_successes;
2745    }
2746
2747    if ($i != $opt{"NUM_TESTS"} && !do_not_reboot) {
2748	doprint "Reboot and wait $sleep_time seconds\n";
2749	reboot_to_good $sleep_time;
2750    }
2751
2752    if (defined($post_test)) {
2753	run_command $post_test;
2754    }
2755}
2756
2757sub answer_bisect {
2758    for (;;) {
2759	doprint "Pass, fail, or skip? [p/f/s]";
2760	my $ans = <STDIN>;
2761	chomp $ans;
2762	if ($ans eq "p" || $ans eq "P") {
2763	    return 1;
2764	} elsif ($ans eq "f" || $ans eq "F") {
2765	    return 0;
2766	} elsif ($ans eq "s" || $ans eq "S") {
2767	    return -1;
2768	} else {
2769	    print "Please answer 'p', 'f', or 's'\n";
2770	}
2771    }
2772}
2773
2774sub child_run_test {
2775
2776    # child should have no power
2777    $reboot_on_error = 0;
2778    $poweroff_on_error = 0;
2779    $die_on_failure = 1;
2780
2781    run_command $run_test, $testlog;
2782
2783    exit $run_command_status;
2784}
2785
2786sub child_finished {
2787    $child_done = 1;
2788}
2789
2790sub do_run_test {
2791    my $child_pid;
2792    my $child_exit;
2793    my $line;
2794    my $full_line;
2795    my $bug = 0;
2796    my $bug_ignored = 0;
2797
2798    my $start_time = time;
2799
2800    wait_for_monitor 1;
2801
2802    doprint "run test $run_test\n";
2803
2804    $child_done = 0;
2805
2806    $SIG{CHLD} = qw(child_finished);
2807
2808    $child_pid = fork;
2809
2810    child_run_test if (!$child_pid);
2811
2812    $full_line = "";
2813
2814    do {
2815	$line = wait_for_input($monitor_fp, 1);
2816	if (defined($line)) {
2817
2818	    # we are not guaranteed to get a full line
2819	    $full_line .= $line;
2820	    doprint $line;
2821
2822	    if ($full_line =~ /call trace:/i) {
2823		if ($ignore_errors) {
2824		    $bug_ignored = 1;
2825		} else {
2826		    $bug = 1;
2827		}
2828	    }
2829
2830	    if ($full_line =~ /Kernel panic -/) {
2831		$bug = 1;
2832	    }
2833
2834	    if ($line =~ /\n/) {
2835		$full_line = "";
2836	    }
2837	}
2838    } while (!$child_done && !$bug);
2839
2840    if (!$bug && $bug_ignored) {
2841	doprint "WARNING: Call Trace detected but ignored due to IGNORE_ERRORS=1\n";
2842    }
2843
2844    if ($bug) {
2845	my $failure_start = time;
2846	my $now;
2847	do {
2848	    $line = wait_for_input($monitor_fp, 1);
2849	    if (defined($line)) {
2850		doprint $line;
2851	    }
2852	    $now = time;
2853	    if ($now - $failure_start >= $stop_after_failure) {
2854		last;
2855	    }
2856	} while (defined($line));
2857
2858	doprint "Detected kernel crash!\n";
2859	# kill the child with extreme prejudice
2860	kill 9, $child_pid;
2861    }
2862
2863    waitpid $child_pid, 0;
2864    $child_exit = $? >> 8;
2865
2866    my $end_time = time;
2867    $test_time = $end_time - $start_time;
2868
2869    if (!$bug && $in_bisect) {
2870	if (defined($bisect_ret_good)) {
2871	    if ($child_exit == $bisect_ret_good) {
2872		return 1;
2873	    }
2874	}
2875	if (defined($bisect_ret_skip)) {
2876	    if ($child_exit == $bisect_ret_skip) {
2877		return -1;
2878	    }
2879	}
2880	if (defined($bisect_ret_abort)) {
2881	    if ($child_exit == $bisect_ret_abort) {
2882		fail "test abort" and return -2;
2883	    }
2884	}
2885	if (defined($bisect_ret_bad)) {
2886	    if ($child_exit == $bisect_ret_skip) {
2887		return 0;
2888	    }
2889	}
2890	if (defined($bisect_ret_default)) {
2891	    if ($bisect_ret_default eq "good") {
2892		return 1;
2893	    } elsif ($bisect_ret_default eq "bad") {
2894		return 0;
2895	    } elsif ($bisect_ret_default eq "skip") {
2896		return -1;
2897	    } elsif ($bisect_ret_default eq "abort") {
2898		return -2;
2899	    } else {
2900		fail "unknown default action: $bisect_ret_default"
2901		    and return -2;
2902	    }
2903	}
2904    }
2905
2906    if ($bug || $child_exit) {
2907	return 0 if $in_bisect;
2908	fail "test failed" and return 0;
2909    }
2910    return 1;
2911}
2912
2913sub run_git_bisect {
2914    my ($command) = @_;
2915
2916    doprint "$command ... ";
2917
2918    my $output = `$command 2>&1`;
2919    my $ret = $?;
2920
2921    logit $output;
2922
2923    if ($ret) {
2924	doprint "FAILED\n";
2925	dodie "Failed to git bisect";
2926    }
2927
2928    doprint "SUCCESS\n";
2929    if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\))\s+\[([[:xdigit:]]+)\]/) {
2930	doprint "$1 [$2]\n";
2931    } elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) {
2932	$bisect_bad_commit = $1;
2933	doprint "Found bad commit... $1\n";
2934	return 0;
2935    } else {
2936	# we already logged it, just print it now.
2937	print $output;
2938    }
2939
2940    return 1;
2941}
2942
2943sub bisect_reboot {
2944    doprint "Reboot and sleep $bisect_sleep_time seconds\n";
2945    reboot_to_good $bisect_sleep_time;
2946}
2947
2948# returns 1 on success, 0 on failure, -1 on skip
2949sub run_bisect_test {
2950    my ($type, $buildtype) = @_;
2951
2952    my $failed = 0;
2953    my $result;
2954
2955    $in_bisect = 1;
2956
2957    build $buildtype or $failed = 1;
2958
2959    if ($type ne "build") {
2960	if ($failed && $bisect_skip) {
2961	    $in_bisect = 0;
2962	    return -1;
2963	}
2964	dodie "Failed on build" if $failed;
2965
2966	# Now boot the box
2967	start_monitor_and_install or $failed = 1;
2968
2969	if ($type ne "boot") {
2970	    if ($failed && $bisect_skip) {
2971		end_monitor;
2972		bisect_reboot;
2973		$in_bisect = 0;
2974		return -1;
2975	    }
2976	    dodie "Failed on boot" if $failed;
2977
2978	    do_run_test or $failed = 1;
2979	}
2980	end_monitor;
2981    }
2982
2983    if ($failed) {
2984	$result = 0;
2985    } else {
2986	$result = 1;
2987    }
2988
2989    # reboot the box to a kernel we can ssh to
2990    if ($type ne "build") {
2991	bisect_reboot;
2992    }
2993    $in_bisect = 0;
2994
2995    return $result;
2996}
2997
2998sub run_bisect {
2999    my ($type) = @_;
3000    my $buildtype = "oldconfig";
3001
3002    # We should have a minconfig to use?
3003    if (defined($minconfig)) {
3004	$buildtype = "useconfig:$minconfig";
3005    }
3006
3007    # If the user sets bisect_tries to less than 1, then no tries
3008    # is a success.
3009    my $ret = 1;
3010
3011    # Still let the user manually decide that though.
3012    if ($bisect_tries < 1 && $bisect_manual) {
3013	$ret = answer_bisect;
3014    }
3015
3016    for (my $i = 0; $i < $bisect_tries; $i++) {
3017	if ($bisect_tries > 1) {
3018	    my $t = $i + 1;
3019	    doprint("Running bisect trial $t of $bisect_tries:\n");
3020	}
3021	$ret = run_bisect_test $type, $buildtype;
3022
3023	if ($bisect_manual) {
3024	    $ret = answer_bisect;
3025	}
3026
3027	last if (!$ret);
3028    }
3029
3030    # Are we looking for where it worked, not failed?
3031    if ($reverse_bisect && $ret >= 0) {
3032	$ret = !$ret;
3033    }
3034
3035    if ($ret > 0) {
3036	return "good";
3037    } elsif ($ret == 0) {
3038	return  "bad";
3039    } elsif ($bisect_skip) {
3040	doprint "HIT A BAD COMMIT ... SKIPPING\n";
3041	return "skip";
3042    }
3043}
3044
3045sub update_bisect_replay {
3046    my $tmp_log = "$tmpdir/ktest_bisect_log";
3047    run_command "git bisect log > $tmp_log" or
3048	dodie "can't create bisect log";
3049    return $tmp_log;
3050}
3051
3052sub bisect {
3053    my ($i) = @_;
3054
3055    my $result;
3056
3057    dodie "BISECT_GOOD[$i] not defined\n"	if (!defined($bisect_good));
3058    dodie "BISECT_BAD[$i] not defined\n"	if (!defined($bisect_bad));
3059    dodie "BISECT_TYPE[$i] not defined\n"	if (!defined($bisect_type));
3060
3061    my $good = $bisect_good;
3062    my $bad = $bisect_bad;
3063    my $type = $bisect_type;
3064    my $start = $bisect_start;
3065    my $replay = $bisect_replay;
3066    my $start_files = $bisect_files;
3067
3068    if (defined($start_files)) {
3069	$start_files = " -- " . $start_files;
3070    } else {
3071	$start_files = "";
3072    }
3073
3074    # convert to true sha1's
3075    $good = get_sha1($good);
3076    $bad = get_sha1($bad);
3077
3078    if (defined($bisect_reverse) && $bisect_reverse == 1) {
3079	doprint "Performing a reverse bisect (bad is good, good is bad!)\n";
3080	$reverse_bisect = 1;
3081    } else {
3082	$reverse_bisect = 0;
3083    }
3084
3085    # Can't have a test without having a test to run
3086    if ($type eq "test" && !defined($run_test)) {
3087	$type = "boot";
3088    }
3089
3090    # Check if a bisect was running
3091    my $bisect_start_file = "$builddir/.git/BISECT_START";
3092
3093    my $check = $bisect_check;
3094    my $do_check = defined($check) && $check ne "0";
3095
3096    if ( -f $bisect_start_file ) {
3097	print "Bisect in progress found\n";
3098	if ($do_check) {
3099	    print " If you say yes, then no checks of good or bad will be done\n";
3100	}
3101	if (defined($replay)) {
3102	    print "** BISECT_REPLAY is defined in config file **";
3103	    print " Ignore config option and perform new git bisect log?\n";
3104	    if (read_ync " (yes, no, or cancel) ") {
3105		$replay = update_bisect_replay;
3106		$do_check = 0;
3107	    }
3108	} elsif (read_yn "read git log and continue?") {
3109	    $replay = update_bisect_replay;
3110	    $do_check = 0;
3111	}
3112    }
3113
3114    if ($do_check) {
3115	# get current HEAD
3116	my $head = get_sha1("HEAD");
3117
3118	if ($check ne "good") {
3119	    doprint "TESTING BISECT BAD [$bad]\n";
3120	    run_command "git checkout $bad" or
3121		dodie "Failed to checkout $bad";
3122
3123	    $result = run_bisect $type;
3124
3125	    if ($result ne "bad") {
3126		fail "Tested BISECT_BAD [$bad] and it succeeded" and return 0;
3127	    }
3128	}
3129
3130	if ($check ne "bad") {
3131	    doprint "TESTING BISECT GOOD [$good]\n";
3132	    run_command "git checkout $good" or
3133		dodie "Failed to checkout $good";
3134
3135	    $result = run_bisect $type;
3136
3137	    if ($result ne "good") {
3138		fail "Tested BISECT_GOOD [$good] and it failed" and return 0;
3139	    }
3140	}
3141
3142	# checkout where we started
3143	run_command "git checkout $head" or
3144	    dodie "Failed to checkout $head";
3145    }
3146
3147    run_command "git bisect start$start_files" or
3148	dodie "could not start bisect";
3149
3150    if (defined($replay)) {
3151	run_command "git bisect replay $replay" or
3152	    dodie "failed to run replay";
3153    } else {
3154	run_command "git bisect good $good" or
3155	    dodie "could not set bisect good to $good";
3156
3157	run_git_bisect "git bisect bad $bad" or
3158	    dodie "could not set bisect bad to $bad";
3159    }
3160
3161    if (defined($start)) {
3162	run_command "git checkout $start" or
3163	    dodie "failed to checkout $start";
3164    }
3165
3166    my $test;
3167    do {
3168	$result = run_bisect $type;
3169	$test = run_git_bisect "git bisect $result";
3170	print_times;
3171    } while ($test);
3172
3173    run_command "git bisect log" or
3174	dodie "could not capture git bisect log";
3175
3176    run_command "git bisect reset" or
3177	dodie "could not reset git bisect";
3178
3179    doprint "Bad commit was [$bisect_bad_commit]\n";
3180
3181    success $i;
3182}
3183
3184sub assign_configs {
3185    my ($hash, $config) = @_;
3186
3187    doprint "Reading configs from $config\n";
3188
3189    open (IN, $config) or
3190	dodie "Failed to read $config";
3191
3192    while (<IN>) {
3193	chomp;
3194	if (/^((CONFIG\S*)=.*)/) {
3195	    ${$hash}{$2} = $1;
3196	} elsif (/^(# (CONFIG\S*) is not set)/) {
3197	    ${$hash}{$2} = $1;
3198	}
3199    }
3200
3201    close(IN);
3202}
3203
3204sub process_config_ignore {
3205    my ($config) = @_;
3206
3207    assign_configs \%config_ignore, $config;
3208}
3209
3210sub get_dependencies {
3211    my ($config) = @_;
3212
3213    my $arr = $dependency{$config};
3214    if (!defined($arr)) {
3215	return ();
3216    }
3217
3218    my @deps = @{$arr};
3219
3220    foreach my $dep (@{$arr}) {
3221	print "ADD DEP $dep\n";
3222	@deps = (@deps, get_dependencies $dep);
3223    }
3224
3225    return @deps;
3226}
3227
3228sub save_config {
3229    my ($pc, $file) = @_;
3230
3231    my %configs = %{$pc};
3232
3233    doprint "Saving configs into $file\n";
3234
3235    open(OUT, ">$file") or dodie "Can not write to $file";
3236
3237    foreach my $config (keys %configs) {
3238	print OUT "$configs{$config}\n";
3239    }
3240    close(OUT);
3241}
3242
3243sub create_config {
3244    my ($name, $pc) = @_;
3245
3246    doprint "Creating old config from $name configs\n";
3247
3248    save_config $pc, $output_config;
3249
3250    make_oldconfig;
3251}
3252
3253sub run_config_bisect_test {
3254    my ($type) = @_;
3255
3256    my $ret = run_bisect_test $type, "oldconfig";
3257
3258    if ($bisect_manual) {
3259	$ret = answer_bisect;
3260    }
3261
3262    return $ret;
3263}
3264
3265sub config_bisect_end {
3266    my ($good, $bad) = @_;
3267    my $diffexec = "diff -u";
3268
3269    if (-f "$builddir/scripts/diffconfig") {
3270	$diffexec = "$builddir/scripts/diffconfig";
3271    }
3272    doprint "\n\n***************************************\n";
3273    doprint "No more config bisecting possible.\n";
3274    run_command "$diffexec $good $bad", 1;
3275    doprint "***************************************\n\n";
3276}
3277
3278sub run_config_bisect {
3279    my ($good, $bad, $last_result) = @_;
3280    my $reset = "";
3281    my $cmd;
3282    my $ret;
3283
3284    if (!length($last_result)) {
3285	$reset = "-r";
3286    }
3287    run_command "$config_bisect_exec $reset -b $outputdir $good $bad $last_result", 1;
3288
3289    # config-bisect returns:
3290    #   0 if there is more to bisect
3291    #   1 for finding a good config
3292    #   2 if it can not find any more configs
3293    #  -1 (255) on error
3294    if ($run_command_status) {
3295	return $run_command_status;
3296    }
3297
3298    $ret = run_config_bisect_test $config_bisect_type;
3299    if ($ret) {
3300	doprint "NEW GOOD CONFIG ($pass)\n";
3301	system("cp $output_config $tmpdir/good_config.tmp.$pass");
3302	$pass++;
3303	# Return 3 for good config
3304	return 3;
3305    } else {
3306	doprint "NEW BAD CONFIG ($pass)\n";
3307	system("cp $output_config $tmpdir/bad_config.tmp.$pass");
3308	$pass++;
3309	# Return 4 for bad config
3310	return 4;
3311    }
3312}
3313
3314sub config_bisect {
3315    my ($i) = @_;
3316
3317    my $good_config;
3318    my $bad_config;
3319
3320    my $type = $config_bisect_type;
3321    my $ret;
3322
3323    $bad_config = $config_bisect;
3324
3325    if (defined($config_bisect_good)) {
3326	$good_config = $config_bisect_good;
3327    } elsif (defined($minconfig)) {
3328	$good_config = $minconfig;
3329    } else {
3330	doprint "No config specified, checking if defconfig works";
3331	$ret = run_bisect_test $type, "defconfig";
3332	if (!$ret) {
3333	    fail "Have no good config to compare with, please set CONFIG_BISECT_GOOD";
3334	    return 1;
3335	}
3336	$good_config = $output_config;
3337    }
3338
3339    if (!defined($config_bisect_exec)) {
3340	# First check the location that ktest.pl ran
3341	my @locations = (
3342		"$pwd/config-bisect.pl",
3343		"$dirname/config-bisect.pl",
3344		"$builddir/tools/testing/ktest/config-bisect.pl",
3345		undef );
3346	foreach my $loc (@locations) {
3347	    doprint "loc = $loc\n";
3348	    $config_bisect_exec = $loc;
3349	    last if (defined($config_bisect_exec && -x $config_bisect_exec));
3350	}
3351	if (!defined($config_bisect_exec)) {
3352	    fail "Could not find an executable config-bisect.pl\n",
3353		"  Set CONFIG_BISECT_EXEC to point to config-bisect.pl";
3354	    return 1;
3355	}
3356    }
3357
3358    # we don't want min configs to cause issues here.
3359    doprint "Disabling 'MIN_CONFIG' for this test\n";
3360    undef $minconfig;
3361
3362    my %good_configs;
3363    my %bad_configs;
3364    my %tmp_configs;
3365
3366    if (-f "$tmpdir/good_config.tmp" || -f "$tmpdir/bad_config.tmp") {
3367	if (read_yn "Interrupted config-bisect. Continue (n - will start new)?") {
3368	    if (-f "$tmpdir/good_config.tmp") {
3369		$good_config = "$tmpdir/good_config.tmp";
3370	    } else {
3371		$good_config = "$tmpdir/good_config";
3372	    }
3373	    if (-f "$tmpdir/bad_config.tmp") {
3374		$bad_config = "$tmpdir/bad_config.tmp";
3375	    } else {
3376		$bad_config = "$tmpdir/bad_config";
3377	    }
3378	}
3379    }
3380    doprint "Run good configs through make oldconfig\n";
3381    assign_configs \%tmp_configs, $good_config;
3382    create_config "$good_config", \%tmp_configs;
3383    $good_config = "$tmpdir/good_config";
3384    system("cp $output_config $good_config") == 0 or dodie "cp good config";
3385
3386    doprint "Run bad configs through make oldconfig\n";
3387    assign_configs \%tmp_configs, $bad_config;
3388    create_config "$bad_config", \%tmp_configs;
3389    $bad_config = "$tmpdir/bad_config";
3390    system("cp $output_config $bad_config") == 0 or dodie "cp bad config";
3391
3392    if (defined($config_bisect_check) && $config_bisect_check ne "0") {
3393	if ($config_bisect_check ne "good") {
3394	    doprint "Testing bad config\n";
3395
3396	    $ret = run_bisect_test $type, "useconfig:$bad_config";
3397	    if ($ret) {
3398		fail "Bad config succeeded when expected to fail!";
3399		return 0;
3400	    }
3401	}
3402	if ($config_bisect_check ne "bad") {
3403	    doprint "Testing good config\n";
3404
3405	    $ret = run_bisect_test $type, "useconfig:$good_config";
3406	    if (!$ret) {
3407		fail "Good config failed when expected to succeed!";
3408		return 0;
3409	    }
3410	}
3411    }
3412
3413    my $last_run = "";
3414
3415    do {
3416	$ret = run_config_bisect $good_config, $bad_config, $last_run;
3417	if ($ret == 3) {
3418	    $last_run = "good";
3419	} elsif ($ret == 4) {
3420	    $last_run = "bad";
3421	}
3422	print_times;
3423    } while ($ret == 3 || $ret == 4);
3424
3425    if ($ret == 2) {
3426	config_bisect_end "$good_config.tmp", "$bad_config.tmp";
3427    }
3428
3429    return $ret if ($ret < 0);
3430
3431    success $i;
3432}
3433
3434sub patchcheck_reboot {
3435    doprint "Reboot and sleep $patchcheck_sleep_time seconds\n";
3436    reboot_to_good $patchcheck_sleep_time;
3437}
3438
3439sub patchcheck {
3440    my ($i) = @_;
3441
3442    dodie "PATCHCHECK_START[$i] not defined\n"
3443	if (!defined($patchcheck_start));
3444    dodie "PATCHCHECK_TYPE[$i] not defined\n"
3445	if (!defined($patchcheck_type));
3446
3447    my $start = $patchcheck_start;
3448
3449    my $cherry = $patchcheck_cherry;
3450    if (!defined($cherry)) {
3451	$cherry = 0;
3452    }
3453
3454    my $end = "HEAD";
3455    if (defined($patchcheck_end)) {
3456	$end = $patchcheck_end;
3457    } elsif ($cherry) {
3458	dodie "PATCHCHECK_END must be defined with PATCHCHECK_CHERRY\n";
3459    }
3460
3461    # Get the true sha1's since we can use things like HEAD~3
3462    $start = get_sha1($start);
3463    $end = get_sha1($end);
3464
3465    my $type = $patchcheck_type;
3466
3467    # Can't have a test without having a test to run
3468    if ($type eq "test" && !defined($run_test)) {
3469	$type = "boot";
3470    }
3471
3472    if ($cherry) {
3473	open (IN, "git cherry -v $start $end|") or
3474	    dodie "could not get git list";
3475    } else {
3476	open (IN, "git log --pretty=oneline $end|") or
3477	    dodie "could not get git list";
3478    }
3479
3480    my @list;
3481
3482    while (<IN>) {
3483	chomp;
3484	# git cherry adds a '+' we want to remove
3485	s/^\+ //;
3486	$list[$#list+1] = $_;
3487	last if (/^$start/);
3488    }
3489    close(IN);
3490
3491    if (!$cherry) {
3492	if ($list[$#list] !~ /^$start/) {
3493	    fail "SHA1 $start not found";
3494	}
3495
3496	# go backwards in the list
3497	@list = reverse @list;
3498    }
3499
3500    doprint("Going to test the following commits:\n");
3501    foreach my $l (@list) {
3502	doprint "$l\n";
3503    }
3504
3505    my $save_clean = $noclean;
3506    my %ignored_warnings;
3507
3508    if (defined($ignore_warnings)) {
3509	foreach my $sha1 (split /\s+/, $ignore_warnings) {
3510	    $ignored_warnings{$sha1} = 1;
3511	}
3512    }
3513
3514    $in_patchcheck = 1;
3515    foreach my $item (@list) {
3516	my $sha1 = $item;
3517	$sha1 =~ s/^([[:xdigit:]]+).*/$1/;
3518
3519	doprint "\nProcessing commit \"$item\"\n\n";
3520
3521	run_command "git checkout $sha1" or
3522	    dodie "Failed to checkout $sha1";
3523
3524	# only clean on the first and last patch
3525	if ($item eq $list[0] ||
3526	    $item eq $list[$#list]) {
3527	    $noclean = $save_clean;
3528	} else {
3529	    $noclean = 1;
3530	}
3531
3532	if (defined($minconfig)) {
3533	    build "useconfig:$minconfig" or return 0;
3534	} else {
3535	    # ?? no config to use?
3536	    build "oldconfig" or return 0;
3537	}
3538
3539	# No need to do per patch checking if warnings file exists
3540	if (!defined($warnings_file) && !defined($ignored_warnings{$sha1})) {
3541	    check_patch_buildlog $sha1 or return 0;
3542	}
3543
3544	check_buildlog or return 0;
3545
3546	next if ($type eq "build");
3547
3548	my $failed = 0;
3549
3550	start_monitor_and_install or $failed = 1;
3551
3552	if (!$failed && $type ne "boot"){
3553	    do_run_test or $failed = 1;
3554	}
3555	end_monitor;
3556	if ($failed) {
3557	    print_times;
3558	    return 0;
3559	}
3560	patchcheck_reboot;
3561	print_times;
3562    }
3563    $in_patchcheck = 0;
3564    success $i;
3565
3566    return 1;
3567}
3568
3569sub add_dep {
3570    # $config depends on $dep
3571    my ($config, $dep) = @_;
3572
3573    if (defined($depends{$config})) {
3574	$depends{$config} .= " " . $dep;
3575    } else {
3576	$depends{$config} = $dep;
3577    }
3578
3579    # record the number of configs depending on $dep
3580    if (defined $depcount{$dep}) {
3581	$depcount{$dep}++;
3582    } else {
3583	$depcount{$dep} = 1;
3584    }
3585}
3586
3587# taken from streamline_config.pl
3588sub read_kconfig {
3589    my ($kconfig) = @_;
3590
3591    my $state = "NONE";
3592    my $config;
3593    my @kconfigs;
3594
3595    my $cont = 0;
3596    my $line;
3597
3598    if (! -f $kconfig) {
3599	doprint "file $kconfig does not exist, skipping\n";
3600	return;
3601    }
3602
3603    open(KIN, "$kconfig")
3604	or dodie "Can't open $kconfig";
3605    while (<KIN>) {
3606	chomp;
3607
3608	# Make sure that lines ending with \ continue
3609	if ($cont) {
3610	    $_ = $line . " " . $_;
3611	}
3612
3613	if (s/\\$//) {
3614	    $cont = 1;
3615	    $line = $_;
3616	    next;
3617	}
3618
3619	$cont = 0;
3620
3621	# collect any Kconfig sources
3622	if (/^source\s*"(.*)"/) {
3623	    $kconfigs[$#kconfigs+1] = $1;
3624	}
3625
3626	# configs found
3627	if (/^\s*(menu)?config\s+(\S+)\s*$/) {
3628	    $state = "NEW";
3629	    $config = $2;
3630
3631	    for (my $i = 0; $i < $iflevel; $i++) {
3632		add_dep $config, $ifdeps[$i];
3633	    }
3634
3635	# collect the depends for the config
3636	} elsif ($state eq "NEW" && /^\s*depends\s+on\s+(.*)$/) {
3637
3638	    add_dep $config, $1;
3639
3640	# Get the configs that select this config
3641	} elsif ($state eq "NEW" && /^\s*select\s+(\S+)/) {
3642
3643	    # selected by depends on config
3644	    add_dep $1, $config;
3645
3646	# Check for if statements
3647	} elsif (/^if\s+(.*\S)\s*$/) {
3648	    my $deps = $1;
3649	    # remove beginning and ending non text
3650	    $deps =~ s/^[^a-zA-Z0-9_]*//;
3651	    $deps =~ s/[^a-zA-Z0-9_]*$//;
3652
3653	    my @deps = split /[^a-zA-Z0-9_]+/, $deps;
3654
3655	    $ifdeps[$iflevel++] = join ':', @deps;
3656
3657	} elsif (/^endif/) {
3658
3659	    $iflevel-- if ($iflevel);
3660
3661	# stop on "help"
3662	} elsif (/^\s*help\s*$/) {
3663	    $state = "NONE";
3664	}
3665    }
3666    close(KIN);
3667
3668    # read in any configs that were found.
3669    foreach $kconfig (@kconfigs) {
3670	if (!defined($read_kconfigs{$kconfig})) {
3671	    $read_kconfigs{$kconfig} = 1;
3672	    read_kconfig("$builddir/$kconfig");
3673	}
3674    }
3675}
3676
3677sub read_depends {
3678    # find out which arch this is by the kconfig file
3679    open (IN, $output_config) or
3680	dodie "Failed to read $output_config";
3681    my $arch;
3682    while (<IN>) {
3683	if (m,Linux/(\S+)\s+\S+\s+Kernel Configuration,) {
3684	    $arch = $1;
3685	    last;
3686	}
3687    }
3688    close IN;
3689
3690    if (!defined($arch)) {
3691	doprint "Could not find arch from config file\n";
3692	doprint "no dependencies used\n";
3693	return;
3694    }
3695
3696    # arch is really the subarch, we need to know
3697    # what directory to look at.
3698    if ($arch eq "i386" || $arch eq "x86_64") {
3699	$arch = "x86";
3700    }
3701
3702    my $kconfig = "$builddir/arch/$arch/Kconfig";
3703
3704    if (! -f $kconfig && $arch =~ /\d$/) {
3705	my $orig = $arch;
3706	# some subarchs have numbers, truncate them
3707	$arch =~ s/\d*$//;
3708	$kconfig = "$builddir/arch/$arch/Kconfig";
3709	if (! -f $kconfig) {
3710	    doprint "No idea what arch dir $orig is for\n";
3711	    doprint "no dependencies used\n";
3712	    return;
3713	}
3714    }
3715
3716    read_kconfig($kconfig);
3717}
3718
3719sub make_new_config {
3720    my @configs = @_;
3721
3722    open (OUT, ">$output_config")
3723	or dodie "Failed to write $output_config";
3724
3725    foreach my $config (@configs) {
3726	print OUT "$config\n";
3727    }
3728    close OUT;
3729}
3730
3731sub chomp_config {
3732    my ($config) = @_;
3733
3734    $config =~ s/CONFIG_//;
3735
3736    return $config;
3737}
3738
3739sub get_depends {
3740    my ($dep) = @_;
3741
3742    my $kconfig = chomp_config $dep;
3743
3744    $dep = $depends{"$kconfig"};
3745
3746    # the dep string we have saves the dependencies as they
3747    # were found, including expressions like ! && ||. We
3748    # want to split this out into just an array of configs.
3749
3750    my $valid = "A-Za-z_0-9";
3751
3752    my @configs;
3753
3754    while ($dep =~ /[$valid]/) {
3755	if ($dep =~ /^[^$valid]*([$valid]+)/) {
3756	    my $conf = "CONFIG_" . $1;
3757
3758	    $configs[$#configs + 1] = $conf;
3759
3760	    $dep =~ s/^[^$valid]*[$valid]+//;
3761	} else {
3762	    dodie "this should never happen";
3763	}
3764    }
3765
3766    return @configs;
3767}
3768
3769sub test_this_config {
3770    my ($config) = @_;
3771
3772    my $found;
3773
3774    # if we already processed this config, skip it
3775    if (defined($processed_configs{$config})) {
3776	return undef;
3777    }
3778    $processed_configs{$config} = 1;
3779
3780    # if this config failed during this round, skip it
3781    if (defined($nochange_config{$config})) {
3782	return undef;
3783    }
3784
3785    my $kconfig = chomp_config $config;
3786
3787    # Test dependencies first
3788    if (defined($depends{"$kconfig"})) {
3789	my @parents = get_depends $config;
3790	foreach my $parent (@parents) {
3791	    # if the parent is in the min config, check it first
3792	    next if (!defined($min_configs{$parent}));
3793	    $found = test_this_config($parent);
3794	    if (defined($found)) {
3795		return $found;
3796	    }
3797	}
3798    }
3799
3800    # Remove this config from the list of configs
3801    # do a make olddefconfig and then read the resulting
3802    # .config to make sure it is missing the config that
3803    # we had before
3804    my %configs = %min_configs;
3805    $configs{$config} = "# $config is not set";
3806    make_new_config ((values %configs), (values %keep_configs));
3807    make_oldconfig;
3808    delete $configs{$config};
3809    undef %configs;
3810    assign_configs \%configs, $output_config;
3811
3812    if (!defined($configs{$config}) || $configs{$config} =~ /^#/) {
3813	return $config;
3814    }
3815
3816    doprint "disabling config $config did not change .config\n";
3817
3818    $nochange_config{$config} = 1;
3819
3820    return undef;
3821}
3822
3823sub make_min_config {
3824    my ($i) = @_;
3825
3826    my $type = $minconfig_type;
3827    if ($type ne "boot" && $type ne "test") {
3828	fail "Invalid MIN_CONFIG_TYPE '$minconfig_type'\n" .
3829	    " make_min_config works only with 'boot' and 'test'\n" and return;
3830    }
3831
3832    if (!defined($output_minconfig)) {
3833	fail "OUTPUT_MIN_CONFIG not defined" and return;
3834    }
3835
3836    # If output_minconfig exists, and the start_minconfig
3837    # came from min_config, than ask if we should use
3838    # that instead.
3839    if (-f $output_minconfig && !$start_minconfig_defined) {
3840	print "$output_minconfig exists\n";
3841	if (!defined($use_output_minconfig)) {
3842	    if (read_yn " Use it as minconfig?") {
3843		$start_minconfig = $output_minconfig;
3844	    }
3845	} elsif ($use_output_minconfig > 0) {
3846	    doprint "Using $output_minconfig as MIN_CONFIG\n";
3847	    $start_minconfig = $output_minconfig;
3848	} else {
3849	    doprint "Set to still use MIN_CONFIG as starting point\n";
3850	}
3851    }
3852
3853    if (!defined($start_minconfig)) {
3854	fail "START_MIN_CONFIG or MIN_CONFIG not defined" and return;
3855    }
3856
3857    my $temp_config = "$tmpdir/temp_config";
3858
3859    # First things first. We build an allnoconfig to find
3860    # out what the defaults are that we can't touch.
3861    # Some are selections, but we really can't handle selections.
3862
3863    my $save_minconfig = $minconfig;
3864    undef $minconfig;
3865
3866    run_command "$make allnoconfig" or return 0;
3867
3868    read_depends;
3869
3870    process_config_ignore $output_config;
3871
3872    undef %save_configs;
3873    undef %min_configs;
3874
3875    if (defined($ignore_config)) {
3876	# make sure the file exists
3877	`touch $ignore_config`;
3878	assign_configs \%save_configs, $ignore_config;
3879    }
3880
3881    %keep_configs = %save_configs;
3882
3883    doprint "Load initial configs from $start_minconfig\n";
3884
3885    # Look at the current min configs, and save off all the
3886    # ones that were set via the allnoconfig
3887    assign_configs \%min_configs, $start_minconfig;
3888
3889    my @config_keys = keys %min_configs;
3890
3891    # All configs need a depcount
3892    foreach my $config (@config_keys) {
3893	my $kconfig = chomp_config $config;
3894	if (!defined $depcount{$kconfig}) {
3895	    $depcount{$kconfig} = 0;
3896	}
3897    }
3898
3899    # Remove anything that was set by the make allnoconfig
3900    # we shouldn't need them as they get set for us anyway.
3901    foreach my $config (@config_keys) {
3902	# Remove anything in the ignore_config
3903	if (defined($keep_configs{$config})) {
3904	    my $file = $ignore_config;
3905	    $file =~ s,.*/(.*?)$,$1,;
3906	    doprint "$config set by $file ... ignored\n";
3907	    delete $min_configs{$config};
3908	    next;
3909	}
3910	# But make sure the settings are the same. If a min config
3911	# sets a selection, we do not want to get rid of it if
3912	# it is not the same as what we have. Just move it into
3913	# the keep configs.
3914	if (defined($config_ignore{$config})) {
3915	    if ($config_ignore{$config} ne $min_configs{$config}) {
3916		doprint "$config is in allnoconfig as '$config_ignore{$config}'";
3917		doprint " but it is '$min_configs{$config}' in minconfig .. keeping\n";
3918		$keep_configs{$config} = $min_configs{$config};
3919	    } else {
3920		doprint "$config set by allnoconfig ... ignored\n";
3921	    }
3922	    delete $min_configs{$config};
3923	}
3924    }
3925
3926    my $done = 0;
3927    my $take_two = 0;
3928
3929    while (!$done) {
3930	my $config;
3931	my $found;
3932
3933	# Now disable each config one by one and do a make oldconfig
3934	# till we find a config that changes our list.
3935
3936	my @test_configs = keys %min_configs;
3937
3938	# Sort keys by who is most dependent on
3939	@test_configs = sort  { $depcount{chomp_config($b)} <=> $depcount{chomp_config($a)} }
3940	    @test_configs ;
3941
3942	# Put configs that did not modify the config at the end.
3943	my $reset = 1;
3944	for (my $i = 0; $i < $#test_configs; $i++) {
3945	    if (!defined($nochange_config{$test_configs[0]})) {
3946		$reset = 0;
3947		last;
3948	    }
3949	    # This config didn't change the .config last time.
3950	    # Place it at the end
3951	    my $config = shift @test_configs;
3952	    push @test_configs, $config;
3953	}
3954
3955	# if every test config has failed to modify the .config file
3956	# in the past, then reset and start over.
3957	if ($reset) {
3958	    undef %nochange_config;
3959	}
3960
3961	undef %processed_configs;
3962
3963	foreach my $config (@test_configs) {
3964
3965	    $found = test_this_config $config;
3966
3967	    last if (defined($found));
3968
3969	    # oh well, try another config
3970	}
3971
3972	if (!defined($found)) {
3973	    # we could have failed due to the nochange_config hash
3974	    # reset and try again
3975	    if (!$take_two) {
3976		undef %nochange_config;
3977		$take_two = 1;
3978		next;
3979	    }
3980	    doprint "No more configs found that we can disable\n";
3981	    $done = 1;
3982	    last;
3983	}
3984	$take_two = 0;
3985
3986	$config = $found;
3987
3988	doprint "Test with $config disabled\n";
3989
3990	# set in_bisect to keep build and monitor from dieing
3991	$in_bisect = 1;
3992
3993	my $failed = 0;
3994	build "oldconfig" or $failed = 1;
3995	if (!$failed) {
3996	    start_monitor_and_install or $failed = 1;
3997
3998	    if ($type eq "test" && !$failed) {
3999		do_run_test or $failed = 1;
4000	    }
4001
4002	    end_monitor;
4003	}
4004
4005	$in_bisect = 0;
4006
4007	if ($failed) {
4008	    doprint "$min_configs{$config} is needed to boot the box... keeping\n";
4009	    # this config is needed, add it to the ignore list.
4010	    $keep_configs{$config} = $min_configs{$config};
4011	    $save_configs{$config} = $min_configs{$config};
4012	    delete $min_configs{$config};
4013
4014	    # update new ignore configs
4015	    if (defined($ignore_config)) {
4016		open (OUT, ">$temp_config") or
4017		    dodie "Can't write to $temp_config";
4018		foreach my $config (keys %save_configs) {
4019		    print OUT "$save_configs{$config}\n";
4020		}
4021		close OUT;
4022		run_command "mv $temp_config $ignore_config" or
4023		    dodie "failed to copy update to $ignore_config";
4024	    }
4025
4026	} else {
4027	    # We booted without this config, remove it from the minconfigs.
4028	    doprint "$config is not needed, disabling\n";
4029
4030	    delete $min_configs{$config};
4031
4032	    # Also disable anything that is not enabled in this config
4033	    my %configs;
4034	    assign_configs \%configs, $output_config;
4035	    my @config_keys = keys %min_configs;
4036	    foreach my $config (@config_keys) {
4037		if (!defined($configs{$config})) {
4038		    doprint "$config is not set, disabling\n";
4039		    delete $min_configs{$config};
4040		}
4041	    }
4042
4043	    # Save off all the current mandatory configs
4044	    open (OUT, ">$temp_config") or
4045		dodie "Can't write to $temp_config";
4046	    foreach my $config (keys %keep_configs) {
4047		print OUT "$keep_configs{$config}\n";
4048	    }
4049	    foreach my $config (keys %min_configs) {
4050		print OUT "$min_configs{$config}\n";
4051	    }
4052	    close OUT;
4053
4054	    run_command "mv $temp_config $output_minconfig" or
4055		dodie "failed to copy update to $output_minconfig";
4056	}
4057
4058	doprint "Reboot and wait $sleep_time seconds\n";
4059	reboot_to_good $sleep_time;
4060    }
4061
4062    success $i;
4063    return 1;
4064}
4065
4066sub make_warnings_file {
4067    my ($i) = @_;
4068
4069    if (!defined($warnings_file)) {
4070	dodie "Must define WARNINGS_FILE for make_warnings_file test";
4071    }
4072
4073    if ($build_type eq "nobuild") {
4074	dodie "BUILD_TYPE can not be 'nobuild' for make_warnings_file test";
4075    }
4076
4077    build $build_type or dodie "Failed to build";
4078
4079    open(OUT, ">$warnings_file") or dodie "Can't create $warnings_file";
4080
4081    open(IN, $buildlog) or dodie "Can't open $buildlog";
4082    while (<IN>) {
4083	# Some compilers use UTF-8 extended for quotes
4084	# for distcc heterogeneous systems, this causes issues
4085	s/$utf8_quote/'/g;
4086
4087	if (/$check_build_re/) {
4088	    print OUT;
4089	}
4090    }
4091    close(IN);
4092
4093    close(OUT);
4094
4095    success $i;
4096}
4097
4098sub option_defined {
4099    my ($option) = @_;
4100
4101    if (defined($opt{$option}) && $opt{$option} !~ /^\s*$/) {
4102	return 1;
4103    }
4104
4105    return 0;
4106}
4107
4108sub __set_test_option {
4109    my ($name, $i) = @_;
4110
4111    my $option = "$name\[$i\]";
4112
4113    if (option_defined($option)) {
4114	return $opt{$option};
4115    }
4116
4117    foreach my $test (keys %repeat_tests) {
4118	if ($i >= $test &&
4119	    $i < $test + $repeat_tests{$test}) {
4120	    $option = "$name\[$test\]";
4121	    if (option_defined($option)) {
4122		return $opt{$option};
4123	    }
4124	}
4125    }
4126
4127    if (option_defined($name)) {
4128	return $opt{$name};
4129    }
4130
4131    return undef;
4132}
4133
4134sub set_test_option {
4135    my ($name, $i) = @_;
4136
4137    my $option = __set_test_option($name, $i);
4138    return $option if (!defined($option));
4139
4140    return eval_option($name, $option, $i);
4141}
4142
4143sub find_mailer {
4144    my ($mailer) = @_;
4145
4146    my @paths = split /:/, $ENV{PATH};
4147
4148    # sendmail is usually in /usr/sbin
4149    $paths[$#paths + 1] = "/usr/sbin";
4150
4151    foreach my $path (@paths) {
4152	if (-x "$path/$mailer") {
4153	    return $path;
4154	}
4155    }
4156
4157    return undef;
4158}
4159
4160sub do_send_mail {
4161    my ($subject, $message, $file) = @_;
4162
4163    if (!defined($mail_path)) {
4164	# find the mailer
4165	$mail_path = find_mailer $mailer;
4166	if (!defined($mail_path)) {
4167	    die "\nCan not find $mailer in PATH\n";
4168	}
4169    }
4170
4171    my $header_file = "$tmpdir/header";
4172    open (HEAD, ">$header_file") or die "Can not create $header_file\n";
4173    print HEAD "To: $mailto\n";
4174    print HEAD "Subject: $subject\n\n";
4175    print HEAD "$message\n";
4176    close HEAD;
4177
4178    if (!defined($mail_command)) {
4179	if ($mailer eq "mail" || $mailer eq "mailx") {
4180	    $mail_command = "cat \$HEADER_FILE \$BODY_FILE | \$MAIL_PATH/\$MAILER -s \'\$SUBJECT\' \$MAILTO";
4181	} elsif ($mailer eq "sendmail" ) {
4182	    $mail_command =  "cat \$HEADER_FILE \$BODY_FILE | \$MAIL_PATH/\$MAILER -t \$MAILTO";
4183	} else {
4184	    die "\nYour mailer: $mailer is not supported.\n";
4185	}
4186    }
4187
4188    if (defined($file)) {
4189	$mail_command =~ s/\$BODY_FILE/$file/g;
4190    } else {
4191	$mail_command =~ s/\$BODY_FILE//g;
4192    }
4193
4194    $mail_command =~ s/\$HEADER_FILE/$header_file/g;
4195    $mail_command =~ s/\$MAILER/$mailer/g;
4196    $mail_command =~ s/\$MAIL_PATH/$mail_path/g;
4197    $mail_command =~ s/\$MAILTO/$mailto/g;
4198    $mail_command =~ s/\$SUBJECT/$subject/g;
4199    $mail_command =~ s/\$MESSAGE/$message/g;
4200
4201    my $ret = run_command $mail_command;
4202    if (!$ret && defined($file)) {
4203	# try again without the file
4204	$message .= "\n\n*** FAILED TO SEND LOG ***\n\n";
4205	do_send_email($subject, $message);
4206    }
4207}
4208
4209sub send_email {
4210    if (defined($mailto)) {
4211	if (!defined($mailer)) {
4212	    doprint "No email sent: email or mailer not specified in config.\n";
4213	    return;
4214	}
4215	do_send_mail @_;
4216    }
4217}
4218
4219sub cancel_test {
4220    if ($monitor_cnt) {
4221	end_monitor;
4222    }
4223    if ($email_when_canceled) {
4224	my $name = get_test_name;
4225	send_email("KTEST: Your [$name] test was cancelled",
4226	    "Your test started at $script_start_time was cancelled: sig int");
4227    }
4228    die "\nCaught Sig Int, test interrupted: $!\n"
4229}
4230
4231$#ARGV < 1 or die "ktest.pl version: $VERSION\n   usage: ktest.pl [config-file]\n";
4232
4233if ($#ARGV == 0) {
4234    $ktest_config = $ARGV[0];
4235    if (! -f $ktest_config) {
4236	print "$ktest_config does not exist.\n";
4237	if (!read_yn "Create it?") {
4238	    exit 0;
4239	}
4240    }
4241}
4242
4243if (! -f $ktest_config) {
4244    $newconfig = 1;
4245    get_test_case;
4246    open(OUT, ">$ktest_config") or die "Can not create $ktest_config";
4247    print OUT << "EOF"
4248# Generated by ktest.pl
4249#
4250
4251# PWD is a ktest.pl variable that will result in the process working
4252# directory that ktest.pl is executed in.
4253
4254# THIS_DIR is automatically assigned the PWD of the path that generated
4255# the config file. It is best to use this variable when assigning other
4256# directory paths within this directory. This allows you to easily
4257# move the test cases to other locations or to other machines.
4258#
4259THIS_DIR := $variable{"PWD"}
4260
4261# Define each test with TEST_START
4262# The config options below it will override the defaults
4263TEST_START
4264TEST_TYPE = $default{"TEST_TYPE"}
4265
4266DEFAULTS
4267EOF
4268;
4269    close(OUT);
4270}
4271read_config $ktest_config;
4272
4273if (defined($opt{"LOG_FILE"})) {
4274    $opt{"LOG_FILE"} = eval_option("LOG_FILE", $opt{"LOG_FILE"}, -1);
4275}
4276
4277# Append any configs entered in manually to the config file.
4278my @new_configs = keys %entered_configs;
4279if ($#new_configs >= 0) {
4280    print "\nAppending entered in configs to $ktest_config\n";
4281    open(OUT, ">>$ktest_config") or die "Can not append to $ktest_config";
4282    foreach my $config (@new_configs) {
4283	print OUT "$config = $entered_configs{$config}\n";
4284	$opt{$config} = process_variables($entered_configs{$config});
4285    }
4286}
4287
4288if (defined($opt{"LOG_FILE"})) {
4289    if ($opt{"CLEAR_LOG"}) {
4290	unlink $opt{"LOG_FILE"};
4291    }
4292    open(LOG, ">> $opt{LOG_FILE}") or die "Can't write to $opt{LOG_FILE}";
4293    LOG->autoflush(1);
4294}
4295
4296doprint "\n\nSTARTING AUTOMATED TESTS\n\n";
4297
4298for (my $i = 0, my $repeat = 1; $i <= $opt{"NUM_TESTS"}; $i += $repeat) {
4299
4300    if (!$i) {
4301	doprint "DEFAULT OPTIONS:\n";
4302    } else {
4303	doprint "\nTEST $i OPTIONS";
4304	if (defined($repeat_tests{$i})) {
4305	    $repeat = $repeat_tests{$i};
4306	    doprint " ITERATE $repeat";
4307	}
4308	doprint "\n";
4309    }
4310
4311    foreach my $option (sort keys %opt) {
4312	if ($option =~ /\[(\d+)\]$/) {
4313	    next if ($i != $1);
4314	} else {
4315	    next if ($i);
4316	}
4317
4318	doprint "$option = $opt{$option}\n";
4319    }
4320}
4321
4322$SIG{INT} = qw(cancel_test);
4323
4324# First we need to do is the builds
4325for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
4326
4327    # Do not reboot on failing test options
4328    $no_reboot = 1;
4329    $reboot_success = 0;
4330
4331    $have_version = 0;
4332
4333    $iteration = $i;
4334
4335    $build_time = 0;
4336    $install_time = 0;
4337    $reboot_time = 0;
4338    $test_time = 0;
4339
4340    undef %force_config;
4341
4342    my $makecmd = set_test_option("MAKE_CMD", $i);
4343
4344    $outputdir = set_test_option("OUTPUT_DIR", $i);
4345    $builddir = set_test_option("BUILD_DIR", $i);
4346
4347    chdir $builddir || dodie "can't change directory to $builddir";
4348
4349    if (!-d $outputdir) {
4350	mkpath($outputdir) or
4351	    dodie "can't create $outputdir";
4352    }
4353
4354    $make = "$makecmd O=$outputdir";
4355
4356    # Load all the options into their mapped variable names
4357    foreach my $opt (keys %option_map) {
4358	${$option_map{$opt}} = set_test_option($opt, $i);
4359    }
4360
4361    $start_minconfig_defined = 1;
4362
4363    # The first test may override the PRE_KTEST option
4364    if ($i == 1) {
4365	if (defined($pre_ktest)) {
4366	    doprint "\n";
4367	    run_command $pre_ktest;
4368	}
4369	if ($email_when_started) {
4370	    my $name = get_test_name;
4371	    send_email("KTEST: Your [$name] test was started",
4372		"Your test was started on $script_start_time");
4373	}
4374    }
4375
4376    # Any test can override the POST_KTEST option
4377    # The last test takes precedence.
4378    if (defined($post_ktest)) {
4379	$final_post_ktest = $post_ktest;
4380    }
4381
4382    if (!defined($start_minconfig)) {
4383	$start_minconfig_defined = 0;
4384	$start_minconfig = $minconfig;
4385    }
4386
4387    if (!-d $tmpdir) {
4388	mkpath($tmpdir) or
4389	    dodie "can't create $tmpdir";
4390    }
4391
4392    $ENV{"SSH_USER"} = $ssh_user;
4393    $ENV{"MACHINE"} = $machine;
4394
4395    $buildlog = "$tmpdir/buildlog-$machine";
4396    $testlog = "$tmpdir/testlog-$machine";
4397    $dmesg = "$tmpdir/dmesg-$machine";
4398    $output_config = "$outputdir/.config";
4399
4400    if (!$buildonly) {
4401	$target = "$ssh_user\@$machine";
4402	if (($reboot_type eq "grub") or ($reboot_type eq "grub2bls")) {
4403	    dodie "GRUB_MENU not defined" if (!defined($grub_menu));
4404	} elsif ($reboot_type eq "grub2") {
4405	    dodie "GRUB_MENU not defined" if (!defined($grub_menu));
4406	    dodie "GRUB_FILE not defined" if (!defined($grub_file));
4407	} elsif ($reboot_type eq "syslinux") {
4408	    dodie "SYSLINUX_LABEL not defined" if (!defined($syslinux_label));
4409	}
4410    }
4411
4412    my $run_type = $build_type;
4413    if ($test_type eq "patchcheck") {
4414	$run_type = $patchcheck_type;
4415    } elsif ($test_type eq "bisect") {
4416	$run_type = $bisect_type;
4417    } elsif ($test_type eq "config_bisect") {
4418	$run_type = $config_bisect_type;
4419    } elsif ($test_type eq "make_min_config") {
4420	$run_type = "";
4421    } elsif ($test_type eq "make_warnings_file") {
4422	$run_type = "";
4423    }
4424
4425    # mistake in config file?
4426    if (!defined($run_type)) {
4427	$run_type = "ERROR";
4428    }
4429
4430    my $installme = "";
4431    $installme = " no_install" if ($no_install);
4432
4433    my $name = "";
4434
4435    if (defined($test_name)) {
4436	$name = " ($test_name)";
4437    }
4438
4439    doprint "\n\n";
4440
4441    if (defined($opt{"LOG_FILE"})) {
4442	$test_log_start = tell(LOG);
4443    }
4444
4445    doprint "RUNNING TEST $i of $opt{NUM_TESTS}$name with option $test_type $run_type$installme\n\n";
4446
4447    if (defined($pre_test)) {
4448	my $ret = run_command $pre_test;
4449	if (!$ret && defined($pre_test_die) &&
4450	    $pre_test_die) {
4451		dodie "failed to pre_test\n";
4452	}
4453    }
4454
4455    unlink $dmesg;
4456    unlink $buildlog;
4457    unlink $testlog;
4458
4459    if (defined($addconfig)) {
4460	my $min = $minconfig;
4461	if (!defined($minconfig)) {
4462	    $min = "";
4463	}
4464	run_command "cat $addconfig $min > $tmpdir/add_config" or
4465	    dodie "Failed to create temp config";
4466	$minconfig = "$tmpdir/add_config";
4467    }
4468
4469    if (defined($checkout)) {
4470	run_command "git checkout $checkout" or
4471	    dodie "failed to checkout $checkout";
4472    }
4473
4474    $no_reboot = 0;
4475
4476    # A test may opt to not reboot the box
4477    if ($reboot_on_success) {
4478	$reboot_success = 1;
4479    }
4480
4481    if ($test_type eq "bisect") {
4482	bisect $i;
4483	next;
4484    } elsif ($test_type eq "config_bisect") {
4485	config_bisect $i;
4486	next;
4487    } elsif ($test_type eq "patchcheck") {
4488	patchcheck $i;
4489	next;
4490    } elsif ($test_type eq "make_min_config") {
4491	make_min_config $i;
4492	next;
4493    } elsif ($test_type eq "make_warnings_file") {
4494	$no_reboot = 1;
4495	make_warnings_file $i;
4496	next;
4497    }
4498
4499    if ($build_type ne "nobuild") {
4500	build $build_type or next;
4501	check_buildlog or next;
4502    }
4503
4504    if ($test_type eq "install") {
4505	get_version;
4506	install;
4507	success $i;
4508	next;
4509    }
4510
4511    if ($test_type ne "build") {
4512	my $failed = 0;
4513	start_monitor_and_install or $failed = 1;
4514
4515	if (!$failed && $test_type ne "boot" && defined($run_test)) {
4516	    do_run_test or $failed = 1;
4517	}
4518	end_monitor;
4519	if ($failed) {
4520	    print_times;
4521	    next;
4522	}
4523    }
4524
4525    print_times;
4526
4527    success $i;
4528}
4529
4530if (defined($final_post_ktest)) {
4531
4532    my $cp_final_post_ktest = eval_kernel_version $final_post_ktest;
4533    run_command $cp_final_post_ktest;
4534}
4535
4536if ($opt{"POWEROFF_ON_SUCCESS"}) {
4537    halt;
4538} elsif ($opt{"REBOOT_ON_SUCCESS"} && !do_not_reboot && $reboot_success) {
4539    reboot_to_good;
4540} elsif (defined($switch_to_good)) {
4541    # still need to get to the good kernel
4542    run_command $switch_to_good;
4543}
4544
4545doprint "\n    $successes of $opt{NUM_TESTS} tests were successful\n\n";
4546
4547if ($email_when_finished) {
4548    send_email("KTEST: Your test has finished!",
4549	"$successes of $opt{NUM_TESTS} tests started at $script_start_time were successful!");
4550}
4551
4552if (defined($opt{"LOG_FILE"})) {
4553    print "\n See $opt{LOG_FILE} for the record of results.\n\n";
4554    close LOG;
4555}
4556
4557exit 0;
4558
4559##
4560# The following are here to standardize tabs/spaces/etc across the most likely editors
4561###
4562
4563# Local Variables:
4564# mode: perl
4565# End:
4566# vim: softtabstop=4
4567