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