xref: /linux/tools/testing/ktest/ktest.pl (revision 66a7974a395fe0ab8fb9f6acd013343bc6bad83a)
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]+1,$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    if (defined($opt{"LOG_FILE"})) {
1882	if (-f $opt{"LOG_FILE"}) {
1883	    cp $opt{"LOG_FILE"}, "$dir/logfile";
1884	}
1885    }
1886
1887    while (my ($name, $source) = each(%files)) {
1888	if (-f "$source") {
1889	    cp "$source", "$dir/$name" or
1890		dodie "failed to copy $source";
1891	}
1892    }
1893
1894    doprint "*** Saved info to $dir ***\n";
1895}
1896
1897sub fail {
1898
1899    if ($die_on_failure) {
1900	dodie @_;
1901    }
1902
1903    doprint "FAILED\n";
1904
1905    my $i = $iteration;
1906
1907    # no need to reboot for just building.
1908    if (!do_not_reboot) {
1909	doprint "REBOOTING\n";
1910	reboot_to_good $sleep_time;
1911    }
1912
1913    my $name = "";
1914
1915    if (defined($test_name)) {
1916	$name = " ($test_name)";
1917    }
1918
1919    print_times;
1920
1921    doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
1922    doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
1923    doprint "KTEST RESULT: TEST $i$name Failed: ", @_, "\n";
1924    doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
1925    doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
1926
1927    if (defined($store_failures)) {
1928	save_logs "fail", $store_failures;
1929    }
1930
1931    if (defined($post_test)) {
1932	run_command $post_test;
1933    }
1934
1935    return 1;
1936}
1937
1938sub run_command {
1939    my ($command, $redirect, $timeout) = @_;
1940    my $start_time;
1941    my $end_time;
1942    my $dolog = 0;
1943    my $dord = 0;
1944    my $dostdout = 0;
1945    my $pid;
1946    my $command_orig = $command;
1947
1948    $command =~ s/\$SSH_USER/$ssh_user/g;
1949    $command =~ s/\$MACHINE/$machine/g;
1950
1951    if (!defined($timeout)) {
1952	$timeout = $run_timeout;
1953    }
1954
1955    if (!defined($timeout)) {
1956	$timeout = -1; # tell wait_for_input to wait indefinitely
1957    }
1958
1959    doprint("$command ... ");
1960    $start_time = time;
1961
1962    $pid = open(CMD, "-|",
1963		"sh", "-c",
1964		'command=$1; shift; exec 2>&1; eval "$command"',
1965		"sh", $command) or
1966	(fail "unable to exec $command" and return 0);
1967
1968    if (defined($opt{"LOG_FILE"})) {
1969	$dolog = 1;
1970    }
1971
1972    if (defined($redirect)) {
1973	if ($redirect eq 1) {
1974	    $dostdout = 1;
1975	    # Have the output of the command on its own line
1976	    doprint "\n";
1977	} else {
1978	    open (RD, ">$redirect") or
1979		dodie "failed to write to redirect $redirect";
1980	    $dord = 1;
1981	}
1982    }
1983
1984    my $hit_timeout = 0;
1985
1986    while (1) {
1987	my $fp = \*CMD;
1988	my $line = wait_for_input($fp, $timeout);
1989	if (!defined($line)) {
1990	    my $now = time;
1991	    if ($timeout >= 0 && (($now - $start_time) >= $timeout)) {
1992		doprint "Hit timeout of $timeout, killing process\n";
1993		$hit_timeout = 1;
1994		kill 9, $pid;
1995	    }
1996	    last;
1997	}
1998	print LOG $line if ($dolog);
1999	print RD $line if ($dord);
2000	print $line if ($dostdout);
2001    }
2002
2003    waitpid($pid, 0);
2004    # shift 8 for real exit status
2005    $run_command_status = $? >> 8;
2006
2007    if ($command_orig eq $default{REBOOT} &&
2008	$run_command_status == $reboot_return_code) {
2009	$run_command_status = 0;
2010    }
2011
2012    close(CMD);
2013    close(RD)  if ($dord);
2014
2015    $end_time = time;
2016    my $delta = $end_time - $start_time;
2017
2018    if ($delta == 1) {
2019	doprint "[1 second] ";
2020    } else {
2021	doprint "[$delta seconds] ";
2022    }
2023
2024    if ($hit_timeout) {
2025	$run_command_status = 1;
2026    }
2027
2028    if ($run_command_status) {
2029	doprint "FAILED!\n";
2030    } else {
2031	doprint "SUCCESS\n";
2032    }
2033
2034    return !$run_command_status;
2035}
2036
2037sub run_ssh {
2038    my ($cmd, $timeout) = @_;
2039    my $cp_exec = $ssh_exec;
2040
2041    $cp_exec =~ s/\$SSH_COMMAND/$cmd/g;
2042    return run_command "$cp_exec", undef , $timeout;
2043}
2044
2045sub run_scp {
2046    my ($src, $dst, $cp_scp) = @_;
2047
2048    $cp_scp =~ s/\$SRC_FILE/$src/g;
2049    $cp_scp =~ s/\$DST_FILE/$dst/g;
2050
2051    return run_command "$cp_scp";
2052}
2053
2054sub run_scp_install {
2055    my ($src, $dst) = @_;
2056
2057    my $cp_scp = $scp_to_target_install;
2058
2059    return run_scp($src, $dst, $cp_scp);
2060}
2061
2062sub run_scp_mod {
2063    my ($src, $dst) = @_;
2064
2065    my $cp_scp = $scp_to_target;
2066
2067    return run_scp($src, $dst, $cp_scp);
2068}
2069
2070sub _get_grub_index {
2071
2072    my ($command, $target, $skip, $submenu) = @_;
2073
2074    return if (defined($grub_number) && defined($last_grub_menu) &&
2075	$last_grub_menu eq $grub_menu && defined($last_machine) &&
2076	$last_machine eq $machine);
2077
2078    doprint "Find $reboot_type menu ... ";
2079    $grub_number = -1;
2080
2081    my $ssh_grub = $ssh_exec;
2082    $ssh_grub =~ s,\$SSH_COMMAND,$command,g;
2083
2084    open(IN, "$ssh_grub |") or
2085	dodie "unable to execute $command";
2086
2087    my $found = 0;
2088
2089    my $submenu_number = 0;
2090
2091    while (<IN>) {
2092	if (/$target/) {
2093	    $grub_number++;
2094	    $found = 1;
2095	    last;
2096	} elsif (defined($submenu) && /$submenu/) {
2097		$submenu_number++;
2098		$grub_number = -1;
2099	} elsif (/$skip/) {
2100	    $grub_number++;
2101	}
2102    }
2103    close(IN);
2104
2105    dodie "Could not find '$grub_menu' through $command on $machine"
2106	if (!$found);
2107    if ($submenu_number > 0) {
2108	$grub_number = "$submenu_number>$grub_number";
2109    }
2110    doprint "$grub_number\n";
2111    $last_grub_menu = $grub_menu;
2112    $last_machine = $machine;
2113}
2114
2115sub get_grub_index {
2116
2117    my $command;
2118    my $target;
2119    my $skip;
2120    my $submenu;
2121    my $grub_menu_qt;
2122
2123    if ($reboot_type !~ /^grub/) {
2124	return;
2125    }
2126
2127    $grub_menu_qt = quotemeta($grub_menu);
2128
2129    if ($reboot_type eq "grub") {
2130	$command = "cat /boot/grub/menu.lst";
2131	$target = '^\s*title\s+' . $grub_menu_qt . '\s*$';
2132	$skip = '^\s*title\s';
2133    } elsif ($reboot_type eq "grub2") {
2134	$command = "cat $grub_file";
2135	$target = '^\s*menuentry.*' . $grub_menu_qt;
2136	$skip = '^\s*menuentry\s';
2137	$submenu = '^\s*submenu\s';
2138    } elsif ($reboot_type eq "grub2bls") {
2139	$command = $grub_bls_get;
2140	$target = '^title=.*' . $grub_menu_qt;
2141	$skip = '^title=';
2142    } else {
2143	return;
2144    }
2145
2146    _get_grub_index($command, $target, $skip, $submenu);
2147}
2148
2149sub wait_for_input {
2150    my ($fp, $time) = @_;
2151    my $start_time;
2152    my $rin;
2153    my $rout;
2154    my $nr;
2155    my $buf;
2156    my $line;
2157    my $ch;
2158
2159    if (!defined($time)) {
2160	$time = $timeout;
2161    }
2162
2163    if ($time < 0) {
2164	# Negative number means wait indefinitely
2165	undef $time;
2166    }
2167
2168    $rin = '';
2169    vec($rin, fileno($fp), 1) = 1;
2170    vec($rin, fileno(\*STDIN), 1) = 1;
2171
2172    $start_time = time;
2173
2174    while (1) {
2175	$nr = select($rout=$rin, undef, undef, $time);
2176
2177	last if ($nr <= 0);
2178
2179	# copy data from stdin to the console
2180	if (vec($rout, fileno(\*STDIN), 1) == 1) {
2181	    $nr = sysread(\*STDIN, $buf, 1000);
2182	    syswrite($fp, $buf, $nr) if ($nr > 0);
2183	}
2184
2185	# The timeout is based on time waiting for the fp data
2186	if (vec($rout, fileno($fp), 1) != 1) {
2187	    last if (defined($time) && (time - $start_time > $time));
2188	    next;
2189	}
2190
2191	$line = "";
2192
2193	# try to read one char at a time
2194	while (sysread $fp, $ch, 1) {
2195	    $line .= $ch;
2196	    last if ($ch eq "\n");
2197	}
2198
2199	last if (!length($line));
2200
2201	return $line;
2202    }
2203    return undef;
2204}
2205
2206sub reboot_to {
2207    if (defined($switch_to_test)) {
2208	run_command $switch_to_test;
2209    }
2210
2211    if ($reboot_type eq "grub") {
2212	run_ssh "'(echo \"savedefault --default=$grub_number --once\" | grub --batch)'";
2213    } elsif (($reboot_type eq "grub2") or ($reboot_type eq "grub2bls")) {
2214	run_ssh "$grub_reboot \"'$grub_number'\"";
2215    } elsif ($reboot_type eq "syslinux") {
2216	run_ssh "$syslinux --once \\\"$syslinux_label\\\" $syslinux_path";
2217    } elsif (defined $reboot_script) {
2218	run_command "$reboot_script";
2219    }
2220    reboot;
2221}
2222
2223sub get_sha1 {
2224    my ($commit) = @_;
2225
2226    doprint "git rev-list --max-count=1 $commit ... ";
2227    my $sha1 = `git rev-list --max-count=1 $commit`;
2228    my $ret = $?;
2229
2230    logit $sha1;
2231
2232    if ($ret) {
2233	doprint "FAILED\n";
2234	dodie "Failed to get git $commit";
2235    }
2236
2237    print "SUCCESS\n";
2238
2239    chomp $sha1;
2240
2241    return $sha1;
2242}
2243
2244sub monitor {
2245    my $booted = 0;
2246    my $bug = 0;
2247    my $bug_ignored = 0;
2248    my $skip_call_trace = 0;
2249    my $loops;
2250
2251    my $start_time = time;
2252
2253    wait_for_monitor 5;
2254
2255    my $line;
2256    my $full_line = "";
2257
2258    open(DMESG, "> $dmesg") or
2259	dodie "unable to write to $dmesg";
2260
2261    reboot_to;
2262
2263    my $success_start;
2264    my $failure_start;
2265    my $monitor_start = time;
2266    my $done = 0;
2267    my $version_found = 0;
2268
2269    while (!$done) {
2270	if ($bug && defined($stop_after_failure) &&
2271	    $stop_after_failure >= 0) {
2272	    my $time = $stop_after_failure - (time - $failure_start);
2273	    $line = wait_for_input($monitor_fp, $time);
2274	    if (!defined($line)) {
2275		doprint "bug timed out after $booted_timeout seconds\n";
2276		doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
2277		last;
2278	    }
2279	} elsif ($booted) {
2280	    $line = wait_for_input($monitor_fp, $booted_timeout);
2281	    if (!defined($line)) {
2282		my $s = $booted_timeout == 1 ? "" : "s";
2283		doprint "Successful boot found: break after $booted_timeout second$s\n";
2284		last;
2285	    }
2286	} else {
2287	    $line = wait_for_input($monitor_fp);
2288	    if (!defined($line)) {
2289		my $s = $timeout == 1 ? "" : "s";
2290		doprint "Timed out after $timeout second$s\n";
2291		last;
2292	    }
2293	}
2294
2295	doprint $line;
2296	print DMESG $line;
2297
2298	# we are not guaranteed to get a full line
2299	$full_line .= $line;
2300
2301	if ($full_line =~ /$success_line/) {
2302	    $booted = 1;
2303	    $success_start = time;
2304	}
2305
2306	if ($booted && defined($stop_after_success) &&
2307	    $stop_after_success >= 0) {
2308	    my $now = time;
2309	    if ($now - $success_start >= $stop_after_success) {
2310		doprint "Test forced to stop after $stop_after_success seconds after success\n";
2311		last;
2312	    }
2313	}
2314
2315	if ($full_line =~ /\[ backtrace testing \]/) {
2316	    $skip_call_trace = 1;
2317	}
2318
2319	if ($full_line =~ /call trace:/i) {
2320	    if (!$bug && !$skip_call_trace) {
2321		if ($ignore_errors) {
2322		    $bug_ignored = 1;
2323		} else {
2324		    $bug = 1;
2325		    $failure_start = time;
2326		}
2327	    }
2328	}
2329
2330	if ($bug && defined($stop_after_failure) &&
2331	    $stop_after_failure >= 0) {
2332	    my $now = time;
2333	    if ($now - $failure_start >= $stop_after_failure) {
2334		doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
2335		last;
2336	    }
2337	}
2338
2339	if ($full_line =~ /\[ end of backtrace testing \]/) {
2340	    $skip_call_trace = 0;
2341	}
2342
2343	if ($full_line =~ /Kernel panic -/) {
2344	    $failure_start = time;
2345	    $bug = 1;
2346	}
2347
2348	# Detect triple faults by testing the banner
2349	if ($full_line =~ /\bLinux version (\S+).*\n/) {
2350	    if ($1 eq $version) {
2351		$version_found = 1;
2352	    } elsif ($version_found && $detect_triplefault) {
2353		# We already booted into the kernel we are testing,
2354		# but now we booted into another kernel?
2355		# Consider this a triple fault.
2356		doprint "Already booted in Linux kernel $version, but now\n";
2357		doprint "we booted into Linux kernel $1.\n";
2358		doprint "Assuming that this is a triple fault.\n";
2359		doprint "To disable this: set DETECT_TRIPLE_FAULT to 0\n";
2360		last;
2361	    }
2362	}
2363
2364	if ($line =~ /\n/) {
2365	    $full_line = "";
2366	}
2367
2368	if ($stop_test_after > 0 && !$booted && !$bug) {
2369	    if (time - $monitor_start > $stop_test_after) {
2370		doprint "STOP_TEST_AFTER ($stop_test_after seconds) timed out\n";
2371		$done = 1;
2372	    }
2373	}
2374    }
2375
2376    my $end_time = time;
2377    $reboot_time = $end_time - $start_time;
2378
2379    close(DMESG);
2380
2381    if ($bug) {
2382	return 0 if ($in_bisect);
2383	fail "failed - got a bug report" and return 0;
2384    }
2385
2386    if (!$booted) {
2387	return 0 if ($in_bisect);
2388	fail "failed - never got a boot prompt." and return 0;
2389    }
2390
2391    if ($bug_ignored) {
2392	doprint "WARNING: Call Trace detected but ignored due to IGNORE_ERRORS=1\n";
2393    }
2394
2395    return 1;
2396}
2397
2398sub eval_kernel_version {
2399    my ($option) = @_;
2400
2401    $option =~ s/\$KERNEL_VERSION/$version/g;
2402
2403    return $option;
2404}
2405
2406sub do_post_install {
2407
2408    return if (!defined($post_install));
2409
2410    my $cp_post_install = eval_kernel_version $post_install;
2411    run_command "$cp_post_install" or
2412	dodie "Failed to run post install";
2413}
2414
2415# Sometimes the reboot fails, and will hang. We try to ssh to the box
2416# and if we fail, we force another reboot, that should powercycle it.
2417sub test_booted {
2418    if (!run_ssh "echo testing connection") {
2419	reboot $sleep_time;
2420    }
2421}
2422
2423sub install {
2424
2425    return if ($no_install);
2426
2427    my $start_time = time;
2428
2429    if (defined($pre_install)) {
2430	my $cp_pre_install = eval_kernel_version $pre_install;
2431	run_command "$cp_pre_install" or
2432	    dodie "Failed to run pre install";
2433    }
2434
2435    my $cp_target = eval_kernel_version $target_image;
2436
2437    test_booted;
2438
2439    run_scp_install "$outputdir/$build_target", "$cp_target" or
2440	dodie "failed to copy image";
2441
2442    my $install_mods = 0;
2443
2444    # should we process modules?
2445    $install_mods = 0;
2446    open(IN, "$output_config") or dodie("Can't read config file");
2447    while (<IN>) {
2448	if (/CONFIG_MODULES(=y)?/) {
2449	    if (defined($1)) {
2450		$install_mods = 1;
2451		last;
2452	    }
2453	}
2454    }
2455    close(IN);
2456
2457    if (!$install_mods) {
2458	do_post_install;
2459	doprint "No modules needed\n";
2460	my $end_time = time;
2461	$install_time = $end_time - $start_time;
2462	return;
2463    }
2464
2465    run_command "$make INSTALL_MOD_STRIP=1 INSTALL_MOD_PATH=$tmpdir modules_install" or
2466	dodie "Failed to install modules";
2467
2468    my $modlib = "/lib/modules/$version";
2469    my $modtar = "ktest-mods.tar.bz2";
2470
2471    run_ssh "rm -rf $modlib" or
2472	dodie "failed to remove old mods: $modlib";
2473
2474    # would be nice if scp -r did not follow symbolic links
2475    run_command "cd $tmpdir && tar -cjf $modtar lib/modules/$version" or
2476	dodie "making tarball";
2477
2478    run_scp_mod "$tmpdir/$modtar", "/tmp" or
2479	dodie "failed to copy modules";
2480
2481    unlink "$tmpdir/$modtar";
2482
2483    run_ssh "'(cd / && tar xjf /tmp/$modtar)'" or
2484	dodie "failed to tar modules";
2485
2486    run_ssh "rm -f /tmp/$modtar";
2487
2488    do_post_install;
2489
2490    my $end_time = time;
2491    $install_time = $end_time - $start_time;
2492}
2493
2494sub get_version {
2495    # get the release name
2496    return if ($have_version);
2497    doprint "$make kernelrelease ... ";
2498    $version = `$make -s kernelrelease | tail -1`;
2499    if (!length($version)) {
2500	run_command "$make allnoconfig" or return 0;
2501	doprint "$make kernelrelease ... ";
2502	$version = `$make -s kernelrelease | tail -1`;
2503    }
2504    chomp($version);
2505    doprint "$version\n";
2506    $have_version = 1;
2507}
2508
2509sub start_monitor_and_install {
2510    # Make sure the stable kernel has finished booting
2511
2512    # Install bisects, don't need console
2513    if (defined $console) {
2514	start_monitor;
2515	wait_for_monitor 5;
2516	end_monitor;
2517    }
2518
2519    get_grub_index;
2520    get_version;
2521    install;
2522
2523    start_monitor if (defined $console);
2524    return monitor;
2525}
2526
2527sub process_warning_line {
2528    my ($line) = @_;
2529
2530    chomp $line;
2531
2532    # for distcc heterogeneous systems, some compilers
2533    # do things differently causing warning lines
2534    # to be slightly different. This makes an attempt
2535    # to fixe those issues.
2536
2537    # chop off the index into the line
2538    # using distcc, some compilers give different indexes
2539    # depending on white space
2540    $line =~ s/^(\s*\S+:\d+:)\d+/$1/;
2541
2542    # Some compilers use UTF-8 extended for quotes and some don't.
2543    $line =~ s/$utf8_quote/'/g;
2544
2545    return $line;
2546}
2547
2548# Read buildlog and check against warnings file for any
2549# new warnings.
2550#
2551# Returns 1 if OK
2552#         0 otherwise
2553sub check_buildlog {
2554    my %warnings_list;
2555
2556    # Failed builds should not reboot the target
2557    my $save_no_reboot = $no_reboot;
2558    $no_reboot = 1;
2559
2560    if (defined($warnings_file) && -f $warnings_file) {
2561	open(IN, $warnings_file) or
2562	    dodie "Error opening $warnings_file";
2563
2564	while (<IN>) {
2565	    if (/$check_build_re/) {
2566		my $warning = process_warning_line $_;
2567
2568		$warnings_list{$warning} = 1;
2569	    }
2570	}
2571	close(IN);
2572    }
2573
2574    open(IN, $buildlog) or dodie "Can't open $buildlog";
2575    while (<IN>) {
2576	if (/$check_build_re/) {
2577	    my $warning = process_warning_line $_;
2578
2579	    if (!defined $warnings_list{$warning}) {
2580		$warning_found++;
2581
2582		# If warnings file didn't exist, and WARNINGS_FILE exist,
2583		# then we fail on any warning!
2584		if (defined $warnings_file) {
2585		    fail "New warning found (not in $warnings_file)\n$_\n";
2586		    $no_reboot = $save_no_reboot;
2587		    return 0;
2588		}
2589	    }
2590	}
2591    }
2592    $no_reboot = $save_no_reboot;
2593    close(IN);
2594}
2595
2596sub check_patch_buildlog {
2597    my ($patch) = @_;
2598
2599    my @files = `git show $patch | diffstat -l`;
2600
2601    foreach my $file (@files) {
2602	chomp $file;
2603    }
2604
2605    open(IN, "git show $patch |") or
2606	dodie "failed to show $patch";
2607    while (<IN>) {
2608	if (m,^--- a/(.*),) {
2609	    chomp $1;
2610	    $files[$#files] = $1;
2611	}
2612    }
2613    close(IN);
2614
2615    open(IN, $buildlog) or dodie "Can't open $buildlog";
2616    while (<IN>) {
2617	if (/^\s*(.*?):.*(warning|error)/) {
2618	    my $err = $1;
2619	    foreach my $file (@files) {
2620		my $fullpath = "$builddir/$file";
2621		if ($file eq $err || $fullpath eq $err) {
2622		    fail "$file built with warnings" and return 0;
2623		}
2624	    }
2625	}
2626    }
2627    close(IN);
2628
2629    return 1;
2630}
2631
2632sub apply_min_config {
2633    my $outconfig = "$output_config.new";
2634
2635    # Read the config file and remove anything that
2636    # is in the force_config hash (from minconfig and others)
2637    # then add the force config back.
2638
2639    doprint "Applying minimum configurations into $output_config.new\n";
2640
2641    open (OUT, ">$outconfig") or
2642	dodie "Can't create $outconfig";
2643
2644    if (-f $output_config) {
2645	open (IN, $output_config) or
2646	    dodie "Failed to open $output_config";
2647	while (<IN>) {
2648	    if (/^(# )?(CONFIG_[^\s=]*)/) {
2649		next if (defined($force_config{$2}));
2650	    }
2651	    print OUT;
2652	}
2653	close IN;
2654    }
2655    foreach my $config (keys %force_config) {
2656	print OUT "$force_config{$config}\n";
2657    }
2658    close OUT;
2659
2660    run_command "mv $outconfig $output_config";
2661}
2662
2663sub make_oldconfig {
2664
2665    my @force_list = keys %force_config;
2666
2667    if ($#force_list >= 0) {
2668	apply_min_config;
2669    }
2670
2671    if (!run_command "$make olddefconfig") {
2672	# Perhaps olddefconfig doesn't exist in this version of the kernel
2673	# try oldnoconfig
2674	doprint "olddefconfig failed, trying make oldnoconfig\n";
2675	if (!run_command "$make oldnoconfig") {
2676	    doprint "oldnoconfig failed, trying yes '' | make oldconfig\n";
2677	    # try a yes '' | oldconfig
2678	    run_command "yes '' | $make oldconfig" or
2679		dodie "failed make config oldconfig";
2680	}
2681    }
2682}
2683
2684# read a config file and use this to force new configs.
2685sub load_force_config {
2686    my ($config) = @_;
2687
2688    doprint "Loading force configs from $config\n";
2689    open(IN, $config) or
2690	dodie "failed to read $config";
2691    while (<IN>) {
2692	chomp;
2693	if (/^(CONFIG[^\s=]*)(\s*=.*)/) {
2694	    $force_config{$1} = $_;
2695	} elsif (/^# (CONFIG_\S*) is not set/) {
2696	    $force_config{$1} = $_;
2697	}
2698    }
2699    close IN;
2700}
2701
2702sub build {
2703    my ($type) = @_;
2704
2705    unlink $buildlog;
2706
2707    my $start_time = time;
2708
2709    # Failed builds should not reboot the target
2710    my $save_no_reboot = $no_reboot;
2711    $no_reboot = 1;
2712
2713    # Calculate a new version from here.
2714    $have_version = 0;
2715
2716    if (defined($pre_build)) {
2717	my $ret = run_command $pre_build;
2718	if (!$ret && defined($pre_build_die) &&
2719	    $pre_build_die) {
2720	    dodie "failed to pre_build\n";
2721	}
2722    }
2723
2724    if ($type =~ /^useconfig:(.*)/) {
2725	run_command "cp $1 $output_config" or
2726	    dodie "could not copy $1 to .config";
2727
2728	$type = "oldconfig";
2729    }
2730
2731    # old config can ask questions
2732    if ($type eq "oldconfig") {
2733	$type = "olddefconfig";
2734
2735	# allow for empty configs
2736	run_command "touch $output_config";
2737
2738	if (!$noclean) {
2739	    run_command "mv $output_config $outputdir/config_temp" or
2740		dodie "moving .config";
2741
2742	    run_command "$make mrproper" or dodie "make mrproper";
2743
2744	    run_command "mv $outputdir/config_temp $output_config" or
2745		dodie "moving config_temp";
2746	}
2747    } elsif (!$noclean) {
2748	unlink "$output_config";
2749	run_command "$make mrproper" or
2750	    dodie "make mrproper";
2751    }
2752
2753    # add something to distinguish this build
2754    open(OUT, "> $outputdir/localversion") or dodie("Can't make localversion file");
2755    print OUT "$localversion\n";
2756    close(OUT);
2757
2758    if (defined($minconfig)) {
2759	load_force_config($minconfig);
2760    }
2761
2762    if ($type ne "olddefconfig") {
2763	run_command "$make $type" or
2764	    dodie "failed make config";
2765    }
2766    # Run old config regardless, to enforce min configurations
2767    make_oldconfig;
2768
2769    if (not defined($build_options)){
2770	$build_options = "";
2771    }
2772    my $build_ret = run_command "$make $build_options", $buildlog;
2773
2774    if (defined($post_build)) {
2775	# Because a post build may change the kernel version
2776	# do it now.
2777	get_version;
2778	my $ret = run_command $post_build;
2779	if (!$ret && defined($post_build_die) &&
2780	    $post_build_die) {
2781	    dodie "failed to post_build\n";
2782	}
2783    }
2784
2785    if (!$build_ret) {
2786	# bisect may need this to pass
2787	if ($in_bisect) {
2788	    $no_reboot = $save_no_reboot;
2789	    return 0;
2790	}
2791	fail "failed build" and return 0;
2792    }
2793
2794    $no_reboot = $save_no_reboot;
2795
2796    my $end_time = time;
2797    $build_time = $end_time - $start_time;
2798
2799    return 1;
2800}
2801
2802sub halt {
2803    if (!run_ssh "halt" or defined($power_off)) {
2804	if (defined($poweroff_after_halt)) {
2805	    sleep $poweroff_after_halt;
2806	    run_command "$power_off";
2807	}
2808    } else {
2809	# nope? the zap it!
2810	run_command "$power_off";
2811    }
2812}
2813
2814sub success {
2815    my ($i) = @_;
2816
2817    $successes++;
2818
2819    my $name = "";
2820
2821    if (defined($test_name)) {
2822	$name = " ($test_name)";
2823    }
2824
2825    print_times;
2826
2827    doprint "\n\n";
2828    doprint "*******************************************\n";
2829    doprint "*******************************************\n";
2830    doprint "KTEST RESULT: TEST $i$name SUCCESS!!!!   **\n";
2831    doprint "*******************************************\n";
2832    doprint "*******************************************\n";
2833
2834    if (defined($store_successes)) {
2835	save_logs "success", $store_successes;
2836    }
2837
2838    if ($i != $opt{"NUM_TESTS"} && !do_not_reboot) {
2839	doprint "Reboot and wait $sleep_time seconds\n";
2840	reboot_to_good $sleep_time;
2841    }
2842
2843    if (defined($post_test)) {
2844	run_command $post_test;
2845    }
2846}
2847
2848sub answer_bisect {
2849    for (;;) {
2850	doprint "Pass, fail, or skip? [p/f/s]";
2851	my $ans = <STDIN>;
2852	chomp $ans;
2853	if ($ans eq "p" || $ans eq "P") {
2854	    return 1;
2855	} elsif ($ans eq "f" || $ans eq "F") {
2856	    return 0;
2857	} elsif ($ans eq "s" || $ans eq "S") {
2858	    return -1;
2859	} else {
2860	    print "Please answer 'p', 'f', or 's'\n";
2861	}
2862    }
2863}
2864
2865sub child_run_test {
2866
2867    # child should have no power
2868    $reboot_on_error = 0;
2869    $poweroff_on_error = 0;
2870    $die_on_failure = 1;
2871
2872    run_command $run_test, $testlog;
2873
2874    exit $run_command_status;
2875}
2876
2877sub child_finished {
2878    $child_done = 1;
2879}
2880
2881sub do_run_test {
2882    my $child_pid;
2883    my $child_exit;
2884    my $line;
2885    my $full_line;
2886    my $bug = 0;
2887    my $bug_ignored = 0;
2888
2889    my $start_time = time;
2890
2891    wait_for_monitor 1;
2892
2893    doprint "run test $run_test\n";
2894
2895    $child_done = 0;
2896
2897    $SIG{CHLD} = qw(child_finished);
2898
2899    $child_pid = fork;
2900
2901    child_run_test if (!$child_pid);
2902
2903    $full_line = "";
2904
2905    do {
2906	$line = wait_for_input($monitor_fp, 1);
2907	if (defined($line)) {
2908
2909	    # we are not guaranteed to get a full line
2910	    $full_line .= $line;
2911	    doprint $line;
2912
2913	    if ($full_line =~ /call trace:/i) {
2914		if ($ignore_errors) {
2915		    $bug_ignored = 1;
2916		} else {
2917		    $bug = 1;
2918		}
2919	    }
2920
2921	    if ($full_line =~ /Kernel panic -/) {
2922		$bug = 1;
2923	    }
2924
2925	    if ($line =~ /\n/) {
2926		$full_line = "";
2927	    }
2928	}
2929    } while (!$child_done && !$bug);
2930
2931    if (!$bug && $bug_ignored) {
2932	doprint "WARNING: Call Trace detected but ignored due to IGNORE_ERRORS=1\n";
2933    }
2934
2935    if ($bug) {
2936	my $failure_start = time;
2937	my $now;
2938	do {
2939	    $line = wait_for_input($monitor_fp, 1);
2940	    if (defined($line)) {
2941		doprint $line;
2942	    }
2943	    $now = time;
2944	    if ($now - $failure_start >= $stop_after_failure) {
2945		last;
2946	    }
2947	} while (defined($line));
2948
2949	doprint "Detected kernel crash!\n";
2950	# kill the child with extreme prejudice
2951	kill 9, $child_pid;
2952    }
2953
2954    waitpid $child_pid, 0;
2955    $child_exit = $? >> 8;
2956
2957    my $end_time = time;
2958    $test_time = $end_time - $start_time;
2959
2960    if (!$bug && $in_bisect) {
2961	if (defined($bisect_ret_good)) {
2962	    if ($child_exit == $bisect_ret_good) {
2963		return 1;
2964	    }
2965	}
2966	if (defined($bisect_ret_skip)) {
2967	    if ($child_exit == $bisect_ret_skip) {
2968		return -1;
2969	    }
2970	}
2971	if (defined($bisect_ret_abort)) {
2972	    if ($child_exit == $bisect_ret_abort) {
2973		fail "test abort" and return -2;
2974	    }
2975	}
2976	if (defined($bisect_ret_bad)) {
2977	    if ($child_exit == $bisect_ret_skip) {
2978		return 0;
2979	    }
2980	}
2981	if (defined($bisect_ret_default)) {
2982	    if ($bisect_ret_default eq "good") {
2983		return 1;
2984	    } elsif ($bisect_ret_default eq "bad") {
2985		return 0;
2986	    } elsif ($bisect_ret_default eq "skip") {
2987		return -1;
2988	    } elsif ($bisect_ret_default eq "abort") {
2989		return -2;
2990	    } else {
2991		fail "unknown default action: $bisect_ret_default"
2992		    and return -2;
2993	    }
2994	}
2995    }
2996
2997    if ($bug || $child_exit) {
2998	return 0 if $in_bisect;
2999	fail "test failed" and return 0;
3000    }
3001    return 1;
3002}
3003
3004sub run_git_bisect {
3005    my ($command) = @_;
3006
3007    doprint "$command ... ";
3008
3009    my $output = `$command 2>&1`;
3010    my $ret = $?;
3011
3012    logit $output;
3013
3014    if ($ret) {
3015	doprint "FAILED\n";
3016	dodie "Failed to git bisect";
3017    }
3018
3019    doprint "SUCCESS\n";
3020    if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\))\s+\[([[:xdigit:]]+)\]/) {
3021	doprint "$1 [$2]\n";
3022    } elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) {
3023	$bisect_bad_commit = $1;
3024	doprint "Found bad commit... $1\n";
3025	return 0;
3026    } else {
3027	# we already logged it, just print it now.
3028	print $output;
3029    }
3030
3031    return 1;
3032}
3033
3034sub bisect_reboot {
3035    doprint "Reboot and sleep $bisect_sleep_time seconds\n";
3036    reboot_to_good $bisect_sleep_time;
3037}
3038
3039# returns 1 on success, 0 on failure, -1 on skip
3040sub run_bisect_test {
3041    my ($type, $buildtype) = @_;
3042
3043    my $failed = 0;
3044    my $result;
3045
3046    $in_bisect = 1;
3047
3048    build $buildtype or $failed = 1;
3049
3050    if ($type ne "build") {
3051	if ($failed && $bisect_skip) {
3052	    $in_bisect = 0;
3053	    return -1;
3054	}
3055	dodie "Failed on build" if $failed;
3056
3057	# Now boot the box
3058	start_monitor_and_install or $failed = 1;
3059
3060	if ($type ne "boot") {
3061	    if ($failed && $bisect_skip) {
3062		end_monitor;
3063		bisect_reboot;
3064		$in_bisect = 0;
3065		return -1;
3066	    }
3067	    dodie "Failed on boot" if $failed;
3068
3069	    do_run_test or $failed = 1;
3070	}
3071	end_monitor;
3072    }
3073
3074    if ($failed) {
3075	$result = 0;
3076    } else {
3077	$result = 1;
3078    }
3079
3080    # reboot the box to a kernel we can ssh to
3081    if ($type ne "build") {
3082	bisect_reboot;
3083    }
3084    $in_bisect = 0;
3085
3086    return $result;
3087}
3088
3089sub run_bisect {
3090    my ($type) = @_;
3091    my $buildtype = "oldconfig";
3092
3093    # We should have a minconfig to use?
3094    if (defined($minconfig)) {
3095	$buildtype = "useconfig:$minconfig";
3096    }
3097
3098    # If the user sets bisect_tries to less than 1, then no tries
3099    # is a success.
3100    my $ret = 1;
3101
3102    # Still let the user manually decide that though.
3103    if ($bisect_tries < 1 && $bisect_manual) {
3104	$ret = answer_bisect;
3105    }
3106
3107    for (my $i = 0; $i < $bisect_tries; $i++) {
3108	if ($bisect_tries > 1) {
3109	    my $t = $i + 1;
3110	    doprint("Running bisect trial $t of $bisect_tries:\n");
3111	}
3112	$ret = run_bisect_test $type, $buildtype;
3113
3114	if ($bisect_manual) {
3115	    $ret = answer_bisect;
3116	}
3117
3118	last if (!$ret);
3119    }
3120
3121    # Are we looking for where it worked, not failed?
3122    if ($reverse_bisect && $ret >= 0) {
3123	$ret = !$ret;
3124    }
3125
3126    if ($ret > 0) {
3127	return "good";
3128    } elsif ($ret == 0) {
3129	return  "bad";
3130    } elsif ($bisect_skip) {
3131	doprint "HIT A BAD COMMIT ... SKIPPING\n";
3132	return "skip";
3133    }
3134}
3135
3136sub update_bisect_replay {
3137    my $tmp_log = "$tmpdir/ktest_bisect_log";
3138    run_command "git bisect log > $tmp_log" or
3139	dodie "can't create bisect log";
3140    return $tmp_log;
3141}
3142
3143sub bisect {
3144    my ($i) = @_;
3145
3146    my $result;
3147
3148    dodie "BISECT_GOOD[$i] not defined\n"	if (!defined($bisect_good));
3149    dodie "BISECT_BAD[$i] not defined\n"	if (!defined($bisect_bad));
3150    dodie "BISECT_TYPE[$i] not defined\n"	if (!defined($bisect_type));
3151
3152    my $good = $bisect_good;
3153    my $bad = $bisect_bad;
3154    my $type = $bisect_type;
3155    my $start = $bisect_start;
3156    my $replay = $bisect_replay;
3157    my $start_files = $bisect_files;
3158
3159    if (defined($start_files)) {
3160	$start_files = " -- " . $start_files;
3161    } else {
3162	$start_files = "";
3163    }
3164
3165    # convert to true sha1's
3166    $good = get_sha1($good);
3167    $bad = get_sha1($bad);
3168
3169    if (defined($bisect_reverse) && $bisect_reverse == 1) {
3170	doprint "Performing a reverse bisect (bad is good, good is bad!)\n";
3171	$reverse_bisect = 1;
3172    } else {
3173	$reverse_bisect = 0;
3174    }
3175
3176    # Can't have a test without having a test to run
3177    if ($type eq "test" && !defined($run_test)) {
3178	$type = "boot";
3179    }
3180
3181    # Check if a bisect was running
3182    my $bisect_start_file = "$builddir/.git/BISECT_START";
3183
3184    my $check = $bisect_check;
3185    my $do_check = defined($check) && $check ne "0";
3186
3187    if ( -f $bisect_start_file ) {
3188	print "Bisect in progress found\n";
3189	if ($do_check) {
3190	    print " If you say yes, then no checks of good or bad will be done\n";
3191	}
3192	if (defined($replay)) {
3193	    print "** BISECT_REPLAY is defined in config file **";
3194	    print " Ignore config option and perform new git bisect log?\n";
3195	    if (read_ync " (yes, no, or cancel) ") {
3196		$replay = update_bisect_replay;
3197		$do_check = 0;
3198	    }
3199	} elsif (read_yn "read git log and continue?") {
3200	    $replay = update_bisect_replay;
3201	    $do_check = 0;
3202	}
3203    }
3204
3205    if ($do_check) {
3206	# get current HEAD
3207	my $head = get_sha1("HEAD");
3208
3209	if ($check ne "good") {
3210	    doprint "TESTING BISECT BAD [$bad]\n";
3211	    run_command "git checkout $bad" or
3212		dodie "Failed to checkout $bad";
3213
3214	    $result = run_bisect $type;
3215
3216	    if ($result ne "bad") {
3217		fail "Tested BISECT_BAD [$bad] and it succeeded" and return 0;
3218	    }
3219	}
3220
3221	if ($check ne "bad") {
3222	    doprint "TESTING BISECT GOOD [$good]\n";
3223	    run_command "git checkout $good" or
3224		dodie "Failed to checkout $good";
3225
3226	    $result = run_bisect $type;
3227
3228	    if ($result ne "good") {
3229		fail "Tested BISECT_GOOD [$good] and it failed" and return 0;
3230	    }
3231	}
3232
3233	# checkout where we started
3234	run_command "git checkout $head" or
3235	    dodie "Failed to checkout $head";
3236    }
3237
3238    run_command "git bisect start$start_files" or
3239	dodie "could not start bisect";
3240
3241    if (defined($replay)) {
3242	run_command "git bisect replay $replay" or
3243	    dodie "failed to run replay";
3244    } else {
3245	run_command "git bisect good $good" or
3246	    dodie "could not set bisect good to $good";
3247
3248	run_git_bisect "git bisect bad $bad" or
3249	    dodie "could not set bisect bad to $bad";
3250    }
3251
3252    if (defined($start)) {
3253	run_command "git checkout $start" or
3254	    dodie "failed to checkout $start";
3255    }
3256
3257    my $test;
3258    do {
3259	$result = run_bisect $type;
3260	$test = run_git_bisect "git bisect $result";
3261	print_times;
3262    } while ($test);
3263
3264    run_command "git bisect log" or
3265	dodie "could not capture git bisect log";
3266
3267    run_command "git bisect reset" or
3268	dodie "could not reset git bisect";
3269
3270    doprint "Bad commit was [$bisect_bad_commit]\n";
3271
3272    success $i;
3273}
3274
3275sub assign_configs {
3276    my ($hash, $config) = @_;
3277
3278    doprint "Reading configs from $config\n";
3279
3280    open (IN, $config) or
3281	dodie "Failed to read $config";
3282
3283    while (<IN>) {
3284	chomp;
3285	if (/^((CONFIG\S*)=.*)/) {
3286	    ${$hash}{$2} = $1;
3287	} elsif (/^(# (CONFIG\S*) is not set)/) {
3288	    ${$hash}{$2} = $1;
3289	}
3290    }
3291
3292    close(IN);
3293}
3294
3295sub process_config_ignore {
3296    my ($config) = @_;
3297
3298    assign_configs \%config_ignore, $config;
3299}
3300
3301sub get_dependencies {
3302    my ($config) = @_;
3303
3304    my $arr = $dependency{$config};
3305    if (!defined($arr)) {
3306	return ();
3307    }
3308
3309    my @deps = @{$arr};
3310
3311    foreach my $dep (@{$arr}) {
3312	print "ADD DEP $dep\n";
3313	@deps = (@deps, get_dependencies $dep);
3314    }
3315
3316    return @deps;
3317}
3318
3319sub save_config {
3320    my ($pc, $file) = @_;
3321
3322    my %configs = %{$pc};
3323
3324    doprint "Saving configs into $file\n";
3325
3326    open(OUT, ">$file") or dodie "Can not write to $file";
3327
3328    foreach my $config (keys %configs) {
3329	print OUT "$configs{$config}\n";
3330    }
3331    close(OUT);
3332}
3333
3334sub create_config {
3335    my ($name, $pc) = @_;
3336
3337    doprint "Creating old config from $name configs\n";
3338
3339    save_config $pc, $output_config;
3340
3341    make_oldconfig;
3342}
3343
3344sub run_config_bisect_test {
3345    my ($type) = @_;
3346
3347    my $ret = run_bisect_test $type, "oldconfig";
3348
3349    if ($bisect_manual) {
3350	$ret = answer_bisect;
3351    }
3352
3353    return $ret;
3354}
3355
3356sub config_bisect_end {
3357    my ($good, $bad) = @_;
3358    my $diffexec = "diff -u";
3359
3360    if (-f "$builddir/scripts/diffconfig") {
3361	$diffexec = "$builddir/scripts/diffconfig";
3362    }
3363    doprint "\n\n***************************************\n";
3364    doprint "No more config bisecting possible.\n";
3365    run_command "$diffexec $good $bad", 1;
3366    doprint "***************************************\n\n";
3367}
3368
3369sub run_config_bisect {
3370    my ($good, $bad, $last_result) = @_;
3371    my $reset = "";
3372    my $cmd;
3373    my $ret;
3374
3375    if (!length($last_result)) {
3376	$reset = "-r";
3377    }
3378    run_command "$config_bisect_exec $reset -b $outputdir $good $bad $last_result", 1;
3379
3380    # config-bisect returns:
3381    #   0 if there is more to bisect
3382    #   1 for finding a good config
3383    #   2 if it can not find any more configs
3384    #  -1 (255) on error
3385    if ($run_command_status) {
3386	return $run_command_status;
3387    }
3388
3389    $ret = run_config_bisect_test $config_bisect_type;
3390    if ($ret) {
3391	doprint "NEW GOOD CONFIG ($pass)\n";
3392	system("cp $output_config $tmpdir/good_config.tmp.$pass");
3393	$pass++;
3394	# Return 3 for good config
3395	return 3;
3396    } else {
3397	doprint "NEW BAD CONFIG ($pass)\n";
3398	system("cp $output_config $tmpdir/bad_config.tmp.$pass");
3399	$pass++;
3400	# Return 4 for bad config
3401	return 4;
3402    }
3403}
3404
3405sub config_bisect {
3406    my ($i) = @_;
3407
3408    my $good_config;
3409    my $bad_config;
3410
3411    my $type = $config_bisect_type;
3412    my $ret;
3413
3414    $bad_config = $config_bisect;
3415
3416    if (defined($config_bisect_good)) {
3417	$good_config = $config_bisect_good;
3418    } elsif (defined($minconfig)) {
3419	$good_config = $minconfig;
3420    } else {
3421	doprint "No config specified, checking if defconfig works";
3422	$ret = run_bisect_test $type, "defconfig";
3423	if (!$ret) {
3424	    fail "Have no good config to compare with, please set CONFIG_BISECT_GOOD";
3425	    return 1;
3426	}
3427	$good_config = $output_config;
3428    }
3429
3430    if (!defined($config_bisect_exec)) {
3431	# First check the location that ktest.pl ran
3432	my @locations = (
3433		"$pwd/config-bisect.pl",
3434		"$dirname/config-bisect.pl",
3435		"$builddir/tools/testing/ktest/config-bisect.pl",
3436		undef );
3437	foreach my $loc (@locations) {
3438	    doprint "loc = $loc\n";
3439	    $config_bisect_exec = $loc;
3440	    last if (defined($config_bisect_exec && -x $config_bisect_exec));
3441	}
3442	if (!defined($config_bisect_exec)) {
3443	    fail "Could not find an executable config-bisect.pl\n",
3444		"  Set CONFIG_BISECT_EXEC to point to config-bisect.pl";
3445	    return 1;
3446	}
3447    }
3448
3449    # we don't want min configs to cause issues here.
3450    doprint "Disabling 'MIN_CONFIG' for this test\n";
3451    undef $minconfig;
3452
3453    my %good_configs;
3454    my %bad_configs;
3455    my %tmp_configs;
3456
3457    if (-f "$tmpdir/good_config.tmp" || -f "$tmpdir/bad_config.tmp") {
3458	if (read_yn "Interrupted config-bisect. Continue (n - will start new)?") {
3459	    if (-f "$tmpdir/good_config.tmp") {
3460		$good_config = "$tmpdir/good_config.tmp";
3461	    } else {
3462		$good_config = "$tmpdir/good_config";
3463	    }
3464	    if (-f "$tmpdir/bad_config.tmp") {
3465		$bad_config = "$tmpdir/bad_config.tmp";
3466	    } else {
3467		$bad_config = "$tmpdir/bad_config";
3468	    }
3469	}
3470    }
3471    doprint "Run good configs through make oldconfig\n";
3472    assign_configs \%tmp_configs, $good_config;
3473    create_config "$good_config", \%tmp_configs;
3474    $good_config = "$tmpdir/good_config";
3475    system("cp $output_config $good_config") == 0 or dodie "cp good config";
3476
3477    doprint "Run bad configs through make oldconfig\n";
3478    assign_configs \%tmp_configs, $bad_config;
3479    create_config "$bad_config", \%tmp_configs;
3480    $bad_config = "$tmpdir/bad_config";
3481    system("cp $output_config $bad_config") == 0 or dodie "cp bad config";
3482
3483    if (defined($config_bisect_check) && $config_bisect_check ne "0") {
3484	if ($config_bisect_check ne "good") {
3485	    doprint "Testing bad config\n";
3486
3487	    $ret = run_bisect_test $type, "useconfig:$bad_config";
3488	    if ($ret) {
3489		fail "Bad config succeeded when expected to fail!";
3490		return 0;
3491	    }
3492	}
3493	if ($config_bisect_check ne "bad") {
3494	    doprint "Testing good config\n";
3495
3496	    $ret = run_bisect_test $type, "useconfig:$good_config";
3497	    if (!$ret) {
3498		fail "Good config failed when expected to succeed!";
3499		return 0;
3500	    }
3501	}
3502    }
3503
3504    my $last_run = "";
3505
3506    do {
3507	$ret = run_config_bisect $good_config, $bad_config, $last_run;
3508	if ($ret == 3) {
3509	    $last_run = "good";
3510	} elsif ($ret == 4) {
3511	    $last_run = "bad";
3512	}
3513	print_times;
3514    } while ($ret == 3 || $ret == 4);
3515
3516    if ($ret == 2) {
3517	config_bisect_end "$good_config.tmp", "$bad_config.tmp";
3518    }
3519
3520    return $ret if ($ret < 0);
3521
3522    success $i;
3523}
3524
3525sub patchcheck_reboot {
3526    doprint "Reboot and sleep $patchcheck_sleep_time seconds\n";
3527    reboot_to_good $patchcheck_sleep_time;
3528}
3529
3530sub patchcheck {
3531    my ($i) = @_;
3532
3533    dodie "PATCHCHECK_START[$i] not defined\n"
3534	if (!defined($patchcheck_start));
3535    dodie "PATCHCHECK_TYPE[$i] not defined\n"
3536	if (!defined($patchcheck_type));
3537
3538    my $start = $patchcheck_start;
3539
3540    my $cherry = $patchcheck_cherry;
3541    if (!defined($cherry)) {
3542	$cherry = 0;
3543    }
3544
3545    my $end = "HEAD";
3546    if (defined($patchcheck_end)) {
3547	$end = $patchcheck_end;
3548    } elsif ($cherry) {
3549	dodie "PATCHCHECK_END must be defined with PATCHCHECK_CHERRY\n";
3550    }
3551
3552    # Get the true sha1's since we can use things like HEAD~3
3553    $start = get_sha1($start);
3554    $end = get_sha1($end);
3555
3556    my $type = $patchcheck_type;
3557
3558    # Can't have a test without having a test to run
3559    if ($type eq "test" && !defined($run_test)) {
3560	$type = "boot";
3561    }
3562
3563    if ($cherry) {
3564	open (IN, "git cherry -v $start $end|") or
3565	    dodie "could not get git list";
3566    } else {
3567	open (IN, "git log --pretty=oneline $end|") or
3568	    dodie "could not get git list";
3569    }
3570
3571    my @list;
3572
3573    while (<IN>) {
3574	chomp;
3575	# git cherry adds a '+' we want to remove
3576	s/^\+ //;
3577	$list[$#list+1] = $_;
3578	last if (/^$start/);
3579    }
3580    close(IN);
3581
3582    if (!$cherry) {
3583	if ($list[$#list] !~ /^$start/) {
3584	    fail "SHA1 $start not found";
3585	}
3586
3587	# go backwards in the list
3588	@list = reverse @list;
3589    }
3590
3591    my %skip_list;
3592    my $will_skip = 0;
3593
3594    if (defined($patchcheck_skip)) {
3595	foreach my $s (split /\s+/, $patchcheck_skip) {
3596	    $s = `git log --pretty=oneline $s~1..$s`;
3597	    $s =~ s/^(\S+).*/$1/;
3598	    chomp $s;
3599	    $skip_list{$s} = 1;
3600	    $will_skip++;
3601	}
3602    }
3603
3604    doprint("Going to test the following commits:\n");
3605    foreach my $l (@list) {
3606	my $sha1 = $l;
3607	$sha1 =~ s/^([[:xdigit:]]+).*/$1/;
3608	next if (defined($skip_list{$sha1}));
3609	doprint "$l\n";
3610    }
3611
3612    if ($will_skip) {
3613	doprint("\nSkipping the following commits:\n");
3614	foreach my $l (@list) {
3615	    my $sha1 = $l;
3616	    $sha1 =~ s/^([[:xdigit:]]+).*/$1/;
3617	    next if (!defined($skip_list{$sha1}));
3618	    doprint "$l\n";
3619	}
3620    }
3621
3622    my $save_clean = $noclean;
3623    my %ignored_warnings;
3624
3625    if (defined($ignore_warnings)) {
3626	foreach my $sha1 (split /\s+/, $ignore_warnings) {
3627	    $ignored_warnings{$sha1} = 1;
3628	}
3629    }
3630
3631    $in_patchcheck = 1;
3632    foreach my $item (@list) {
3633	my $sha1 = $item;
3634	$sha1 =~ s/^([[:xdigit:]]+).*/$1/;
3635
3636	if (defined($skip_list{$sha1})) {
3637	    doprint "\nSkipping \"$item\"\n\n";
3638	    next;
3639	}
3640
3641	doprint "\nProcessing commit \"$item\"\n\n";
3642
3643	run_command "git checkout $sha1" or
3644	    dodie "Failed to checkout $sha1";
3645
3646	# only clean on the first and last patch
3647	if ($item eq $list[0] ||
3648	    $item eq $list[$#list]) {
3649	    $noclean = $save_clean;
3650	} else {
3651	    $noclean = 1;
3652	}
3653
3654	if (defined($minconfig)) {
3655	    build "useconfig:$minconfig" or return 0;
3656	} else {
3657	    # ?? no config to use?
3658	    build "oldconfig" or return 0;
3659	}
3660
3661	# No need to do per patch checking if warnings file exists
3662	if (!defined($warnings_file) && !defined($ignored_warnings{$sha1})) {
3663	    check_patch_buildlog $sha1 or return 0;
3664	}
3665
3666	check_buildlog or return 0;
3667
3668	next if ($type eq "build");
3669
3670	my $failed = 0;
3671
3672	start_monitor_and_install or $failed = 1;
3673
3674	if (!$failed && $type ne "boot"){
3675	    do_run_test or $failed = 1;
3676	}
3677	end_monitor;
3678	if ($failed) {
3679	    print_times;
3680	    return 0;
3681	}
3682	patchcheck_reboot;
3683	print_times;
3684    }
3685    $in_patchcheck = 0;
3686    success $i;
3687
3688    return 1;
3689}
3690
3691sub add_dep {
3692    # $config depends on $dep
3693    my ($config, $dep) = @_;
3694
3695    if (defined($depends{$config})) {
3696	$depends{$config} .= " " . $dep;
3697    } else {
3698	$depends{$config} = $dep;
3699    }
3700
3701    # record the number of configs depending on $dep
3702    if (defined $depcount{$dep}) {
3703	$depcount{$dep}++;
3704    } else {
3705	$depcount{$dep} = 1;
3706    }
3707}
3708
3709# taken from streamline_config.pl
3710sub read_kconfig {
3711    my ($kconfig) = @_;
3712
3713    my $state = "NONE";
3714    my $config;
3715    my @kconfigs;
3716
3717    my $cont = 0;
3718    my $line;
3719
3720    if (! -f $kconfig) {
3721	doprint "file $kconfig does not exist, skipping\n";
3722	return;
3723    }
3724
3725    open(KIN, "$kconfig")
3726	or dodie "Can't open $kconfig";
3727    while (<KIN>) {
3728	chomp;
3729
3730	# Make sure that lines ending with \ continue
3731	if ($cont) {
3732	    $_ = $line . " " . $_;
3733	}
3734
3735	if (s/\\$//) {
3736	    $cont = 1;
3737	    $line = $_;
3738	    next;
3739	}
3740
3741	$cont = 0;
3742
3743	# collect any Kconfig sources
3744	if (/^source\s*"(.*)"/) {
3745	    $kconfigs[$#kconfigs+1] = $1;
3746	}
3747
3748	# configs found
3749	if (/^\s*(menu)?config\s+(\S+)\s*$/) {
3750	    $state = "NEW";
3751	    $config = $2;
3752
3753	    for (my $i = 0; $i < $iflevel; $i++) {
3754		add_dep $config, $ifdeps[$i];
3755	    }
3756
3757	# collect the depends for the config
3758	} elsif ($state eq "NEW" && /^\s*depends\s+on\s+(.*)$/) {
3759
3760	    add_dep $config, $1;
3761
3762	# Get the configs that select this config
3763	} elsif ($state eq "NEW" && /^\s*select\s+(\S+)/) {
3764
3765	    # selected by depends on config
3766	    add_dep $1, $config;
3767
3768	# Check for if statements
3769	} elsif (/^if\s+(.*\S)\s*$/) {
3770	    my $deps = $1;
3771	    # remove beginning and ending non text
3772	    $deps =~ s/^[^a-zA-Z0-9_]*//;
3773	    $deps =~ s/[^a-zA-Z0-9_]*$//;
3774
3775	    my @deps = split /[^a-zA-Z0-9_]+/, $deps;
3776
3777	    $ifdeps[$iflevel++] = join ':', @deps;
3778
3779	} elsif (/^endif/) {
3780
3781	    $iflevel-- if ($iflevel);
3782
3783	# stop on "help"
3784	} elsif (/^\s*help\s*$/) {
3785	    $state = "NONE";
3786	}
3787    }
3788    close(KIN);
3789
3790    # read in any configs that were found.
3791    foreach $kconfig (@kconfigs) {
3792	if (!defined($read_kconfigs{$kconfig})) {
3793	    $read_kconfigs{$kconfig} = 1;
3794	    read_kconfig("$builddir/$kconfig");
3795	}
3796    }
3797}
3798
3799sub read_depends {
3800    # find out which arch this is by the kconfig file
3801    open (IN, $output_config) or
3802	dodie "Failed to read $output_config";
3803    my $arch;
3804    while (<IN>) {
3805	if (m,Linux/(\S+)\s+\S+\s+Kernel Configuration,) {
3806	    $arch = $1;
3807	    last;
3808	}
3809    }
3810    close IN;
3811
3812    if (!defined($arch)) {
3813	doprint "Could not find arch from config file\n";
3814	doprint "no dependencies used\n";
3815	return;
3816    }
3817
3818    # arch is really the subarch, we need to know
3819    # what directory to look at.
3820    if ($arch eq "i386" || $arch eq "x86_64") {
3821	$arch = "x86";
3822    }
3823
3824    my $kconfig = "$builddir/arch/$arch/Kconfig";
3825
3826    if (! -f $kconfig && $arch =~ /\d$/) {
3827	my $orig = $arch;
3828	# some subarchs have numbers, truncate them
3829	$arch =~ s/\d*$//;
3830	$kconfig = "$builddir/arch/$arch/Kconfig";
3831	if (! -f $kconfig) {
3832	    doprint "No idea what arch dir $orig is for\n";
3833	    doprint "no dependencies used\n";
3834	    return;
3835	}
3836    }
3837
3838    read_kconfig($kconfig);
3839}
3840
3841sub make_new_config {
3842    my @configs = @_;
3843
3844    open (OUT, ">$output_config")
3845	or dodie "Failed to write $output_config";
3846
3847    foreach my $config (@configs) {
3848	print OUT "$config\n";
3849    }
3850    close OUT;
3851}
3852
3853sub chomp_config {
3854    my ($config) = @_;
3855
3856    $config =~ s/CONFIG_//;
3857
3858    return $config;
3859}
3860
3861sub get_depends {
3862    my ($dep) = @_;
3863
3864    my $kconfig = chomp_config $dep;
3865
3866    $dep = $depends{"$kconfig"};
3867
3868    # the dep string we have saves the dependencies as they
3869    # were found, including expressions like ! && ||. We
3870    # want to split this out into just an array of configs.
3871
3872    my $valid = "A-Za-z_0-9";
3873
3874    my @configs;
3875
3876    while ($dep =~ /[$valid]/) {
3877	if ($dep =~ /^[^$valid]*([$valid]+)/) {
3878	    my $conf = "CONFIG_" . $1;
3879
3880	    $configs[$#configs + 1] = $conf;
3881
3882	    $dep =~ s/^[^$valid]*[$valid]+//;
3883	} else {
3884	    dodie "this should never happen";
3885	}
3886    }
3887
3888    return @configs;
3889}
3890
3891sub test_this_config {
3892    my ($config) = @_;
3893
3894    my $found;
3895
3896    # if we already processed this config, skip it
3897    if (defined($processed_configs{$config})) {
3898	return undef;
3899    }
3900    $processed_configs{$config} = 1;
3901
3902    # if this config failed during this round, skip it
3903    if (defined($nochange_config{$config})) {
3904	return undef;
3905    }
3906
3907    my $kconfig = chomp_config $config;
3908
3909    # Test dependencies first
3910    if (defined($depends{"$kconfig"})) {
3911	my @parents = get_depends $config;
3912	foreach my $parent (@parents) {
3913	    # if the parent is in the min config, check it first
3914	    next if (!defined($min_configs{$parent}));
3915	    $found = test_this_config($parent);
3916	    if (defined($found)) {
3917		return $found;
3918	    }
3919	}
3920    }
3921
3922    # Remove this config from the list of configs
3923    # do a make olddefconfig and then read the resulting
3924    # .config to make sure it is missing the config that
3925    # we had before
3926    my %configs = %min_configs;
3927    $configs{$config} = "# $config is not set";
3928    make_new_config ((values %configs), (values %keep_configs));
3929    make_oldconfig;
3930    delete $configs{$config};
3931    undef %configs;
3932    assign_configs \%configs, $output_config;
3933
3934    if (!defined($configs{$config}) || $configs{$config} =~ /^#/) {
3935	return $config;
3936    }
3937
3938    doprint "disabling config $config did not change .config\n";
3939
3940    $nochange_config{$config} = 1;
3941
3942    return undef;
3943}
3944
3945sub make_min_config {
3946    my ($i) = @_;
3947
3948    my $type = $minconfig_type;
3949    if ($type ne "boot" && $type ne "test") {
3950	fail "Invalid MIN_CONFIG_TYPE '$minconfig_type'\n" .
3951	    " make_min_config works only with 'boot' and 'test'\n" and return;
3952    }
3953
3954    if (!defined($output_minconfig)) {
3955	fail "OUTPUT_MIN_CONFIG not defined" and return;
3956    }
3957
3958    # If output_minconfig exists, and the start_minconfig
3959    # came from min_config, than ask if we should use
3960    # that instead.
3961    if (-f $output_minconfig && !$start_minconfig_defined) {
3962	print "$output_minconfig exists\n";
3963	if (!defined($use_output_minconfig)) {
3964	    if (read_yn " Use it as minconfig?") {
3965		$start_minconfig = $output_minconfig;
3966	    }
3967	} elsif ($use_output_minconfig > 0) {
3968	    doprint "Using $output_minconfig as MIN_CONFIG\n";
3969	    $start_minconfig = $output_minconfig;
3970	} else {
3971	    doprint "Set to still use MIN_CONFIG as starting point\n";
3972	}
3973    }
3974
3975    if (!defined($start_minconfig)) {
3976	fail "START_MIN_CONFIG or MIN_CONFIG not defined" and return;
3977    }
3978
3979    my $temp_config = "$tmpdir/temp_config";
3980
3981    # First things first. We build an allnoconfig to find
3982    # out what the defaults are that we can't touch.
3983    # Some are selections, but we really can't handle selections.
3984
3985    my $save_minconfig = $minconfig;
3986    undef $minconfig;
3987
3988    run_command "$make allnoconfig" or return 0;
3989
3990    read_depends;
3991
3992    process_config_ignore $output_config;
3993
3994    undef %save_configs;
3995    undef %min_configs;
3996
3997    if (defined($ignore_config)) {
3998	# make sure the file exists
3999	`touch $ignore_config`;
4000	assign_configs \%save_configs, $ignore_config;
4001    }
4002
4003    %keep_configs = %save_configs;
4004
4005    doprint "Load initial configs from $start_minconfig\n";
4006
4007    # Look at the current min configs, and save off all the
4008    # ones that were set via the allnoconfig
4009    assign_configs \%min_configs, $start_minconfig;
4010
4011    my @config_keys = keys %min_configs;
4012
4013    # All configs need a depcount
4014    foreach my $config (@config_keys) {
4015	my $kconfig = chomp_config $config;
4016	if (!defined $depcount{$kconfig}) {
4017	    $depcount{$kconfig} = 0;
4018	}
4019    }
4020
4021    # Remove anything that was set by the make allnoconfig
4022    # we shouldn't need them as they get set for us anyway.
4023    foreach my $config (@config_keys) {
4024	# Remove anything in the ignore_config
4025	if (defined($keep_configs{$config})) {
4026	    my $file = $ignore_config;
4027	    $file =~ s,.*/(.*?)$,$1,;
4028	    doprint "$config set by $file ... ignored\n";
4029	    delete $min_configs{$config};
4030	    next;
4031	}
4032	# But make sure the settings are the same. If a min config
4033	# sets a selection, we do not want to get rid of it if
4034	# it is not the same as what we have. Just move it into
4035	# the keep configs.
4036	if (defined($config_ignore{$config})) {
4037	    if ($config_ignore{$config} ne $min_configs{$config}) {
4038		doprint "$config is in allnoconfig as '$config_ignore{$config}'";
4039		doprint " but it is '$min_configs{$config}' in minconfig .. keeping\n";
4040		$keep_configs{$config} = $min_configs{$config};
4041	    } else {
4042		doprint "$config set by allnoconfig ... ignored\n";
4043	    }
4044	    delete $min_configs{$config};
4045	}
4046    }
4047
4048    my $done = 0;
4049    my $take_two = 0;
4050
4051    while (!$done) {
4052	my $config;
4053	my $found;
4054
4055	# Now disable each config one by one and do a make oldconfig
4056	# till we find a config that changes our list.
4057
4058	my @test_configs = keys %min_configs;
4059
4060	# Sort keys by who is most dependent on
4061	@test_configs = sort  { $depcount{chomp_config($b)} <=> $depcount{chomp_config($a)} }
4062	    @test_configs ;
4063
4064	# Put configs that did not modify the config at the end.
4065	my $reset = 1;
4066	for (my $i = 0; $i < $#test_configs; $i++) {
4067	    if (!defined($nochange_config{$test_configs[0]})) {
4068		$reset = 0;
4069		last;
4070	    }
4071	    # This config didn't change the .config last time.
4072	    # Place it at the end
4073	    my $config = shift @test_configs;
4074	    push @test_configs, $config;
4075	}
4076
4077	# if every test config has failed to modify the .config file
4078	# in the past, then reset and start over.
4079	if ($reset) {
4080	    undef %nochange_config;
4081	}
4082
4083	undef %processed_configs;
4084
4085	foreach my $config (@test_configs) {
4086
4087	    $found = test_this_config $config;
4088
4089	    last if (defined($found));
4090
4091	    # oh well, try another config
4092	}
4093
4094	if (!defined($found)) {
4095	    # we could have failed due to the nochange_config hash
4096	    # reset and try again
4097	    if (!$take_two) {
4098		undef %nochange_config;
4099		$take_two = 1;
4100		next;
4101	    }
4102	    doprint "No more configs found that we can disable\n";
4103	    $done = 1;
4104	    last;
4105	}
4106	$take_two = 0;
4107
4108	$config = $found;
4109
4110	doprint "Test with $config disabled\n";
4111
4112	# set in_bisect to keep build and monitor from dieing
4113	$in_bisect = 1;
4114
4115	my $failed = 0;
4116	build "oldconfig" or $failed = 1;
4117	if (!$failed) {
4118	    start_monitor_and_install or $failed = 1;
4119
4120	    if ($type eq "test" && !$failed) {
4121		do_run_test or $failed = 1;
4122	    }
4123
4124	    end_monitor;
4125	}
4126
4127	$in_bisect = 0;
4128
4129	if ($failed) {
4130	    doprint "$min_configs{$config} is needed to boot the box... keeping\n";
4131	    # this config is needed, add it to the ignore list.
4132	    $keep_configs{$config} = $min_configs{$config};
4133	    $save_configs{$config} = $min_configs{$config};
4134	    delete $min_configs{$config};
4135
4136	    # update new ignore configs
4137	    if (defined($ignore_config)) {
4138		open (OUT, ">$temp_config") or
4139		    dodie "Can't write to $temp_config";
4140		foreach my $config (keys %save_configs) {
4141		    print OUT "$save_configs{$config}\n";
4142		}
4143		close OUT;
4144		run_command "mv $temp_config $ignore_config" or
4145		    dodie "failed to copy update to $ignore_config";
4146	    }
4147
4148	} else {
4149	    # We booted without this config, remove it from the minconfigs.
4150	    doprint "$config is not needed, disabling\n";
4151
4152	    delete $min_configs{$config};
4153
4154	    # Also disable anything that is not enabled in this config
4155	    my %configs;
4156	    assign_configs \%configs, $output_config;
4157	    my @config_keys = keys %min_configs;
4158	    foreach my $config (@config_keys) {
4159		if (!defined($configs{$config})) {
4160		    doprint "$config is not set, disabling\n";
4161		    delete $min_configs{$config};
4162		}
4163	    }
4164
4165	    # Save off all the current mandatory configs
4166	    open (OUT, ">$temp_config") or
4167		dodie "Can't write to $temp_config";
4168	    foreach my $config (keys %keep_configs) {
4169		print OUT "$keep_configs{$config}\n";
4170	    }
4171	    foreach my $config (keys %min_configs) {
4172		print OUT "$min_configs{$config}\n";
4173	    }
4174	    close OUT;
4175
4176	    run_command "mv $temp_config $output_minconfig" or
4177		dodie "failed to copy update to $output_minconfig";
4178	}
4179
4180	doprint "Reboot and wait $sleep_time seconds\n";
4181	reboot_to_good $sleep_time;
4182    }
4183
4184    success $i;
4185    return 1;
4186}
4187
4188sub make_warnings_file {
4189    my ($i) = @_;
4190
4191    if (!defined($warnings_file)) {
4192	dodie "Must define WARNINGS_FILE for make_warnings_file test";
4193    }
4194
4195    if ($build_type eq "nobuild") {
4196	dodie "BUILD_TYPE can not be 'nobuild' for make_warnings_file test";
4197    }
4198
4199    build $build_type or dodie "Failed to build";
4200
4201    open(OUT, ">$warnings_file") or dodie "Can't create $warnings_file";
4202
4203    open(IN, $buildlog) or dodie "Can't open $buildlog";
4204    while (<IN>) {
4205	# Some compilers use UTF-8 extended for quotes
4206	# for distcc heterogeneous systems, this causes issues
4207	s/$utf8_quote/'/g;
4208
4209	if (/$check_build_re/) {
4210	    print OUT;
4211	}
4212    }
4213    close(IN);
4214
4215    close(OUT);
4216
4217    success $i;
4218}
4219
4220sub option_defined {
4221    my ($option) = @_;
4222
4223    if (defined($opt{$option}) && $opt{$option} !~ /^\s*$/) {
4224	return 1;
4225    }
4226
4227    return 0;
4228}
4229
4230sub __set_test_option {
4231    my ($name, $i) = @_;
4232
4233    my $option = "$name\[$i\]";
4234
4235    if (exists($opt{$option})) {
4236	return undef if (!option_defined($option));
4237	return $opt{$option};
4238    }
4239
4240    foreach my $test (keys %repeat_tests) {
4241	if ($i >= $test &&
4242	    $i < $test + $repeat_tests{$test}) {
4243	    $option = "$name\[$test\]";
4244	    if (exists($opt{$option})) {
4245		return undef if (!option_defined($option));
4246		return $opt{$option};
4247	    }
4248	}
4249    }
4250
4251    if (option_defined($name)) {
4252	return $opt{$name};
4253    }
4254
4255    return undef;
4256}
4257
4258sub set_test_option {
4259    my ($name, $i) = @_;
4260
4261    my $option = __set_test_option($name, $i);
4262    return $option if (!defined($option));
4263
4264    return eval_option($name, $option, $i);
4265}
4266
4267sub print_test_preamble {
4268    my ($resolved) = @_;
4269
4270    doprint "\n\nSTARTING AUTOMATED TESTS\n\n";
4271
4272    for (my $i = 0, my $repeat = 1; $i <= $opt{"NUM_TESTS"}; $i += $repeat) {
4273
4274	if (!$i) {
4275	    doprint "DEFAULT OPTIONS:\n";
4276	} else {
4277	    doprint "\nTEST $i OPTIONS";
4278	    if (defined($repeat_tests{$i})) {
4279		$repeat = $repeat_tests{$i};
4280		doprint " ITERATE $repeat";
4281	    }
4282	    doprint "\n";
4283	}
4284
4285	foreach my $option (sort keys %opt) {
4286	    my $value;
4287
4288	    if ($option =~ /\[(\d+)\]$/) {
4289		next if ($i != $1);
4290
4291		if ($resolved) {
4292		    my $name = $option;
4293		    $name =~ s/\[\d+\]$//;
4294		    $value = set_test_option($name, $i);
4295		} else {
4296		    $value = $opt{$option};
4297		}
4298	    } else {
4299		next if ($i);
4300
4301		if ($resolved) {
4302		    $value = set_test_option($option, 0);
4303		} else {
4304		    $value = $opt{$option};
4305		}
4306	    }
4307
4308	    $value = "" if (!defined($value));
4309	    doprint "$option = $value\n";
4310	}
4311    }
4312}
4313
4314sub find_mailer {
4315    my ($mailer) = @_;
4316
4317    my @paths = split /:/, $ENV{PATH};
4318
4319    # sendmail is usually in /usr/sbin
4320    $paths[$#paths + 1] = "/usr/sbin";
4321
4322    foreach my $path (@paths) {
4323	if (-x "$path/$mailer") {
4324	    return $path;
4325	}
4326    }
4327
4328    return undef;
4329}
4330
4331sub do_send_mail {
4332    my ($subject, $message, $file) = @_;
4333
4334    if (!defined($mail_path)) {
4335	# find the mailer
4336	$mail_path = find_mailer $mailer;
4337	if (!defined($mail_path)) {
4338	    die "\nCan not find $mailer in PATH\n";
4339	}
4340    }
4341
4342    my $header_file = "$tmpdir/header";
4343    open (HEAD, ">$header_file") or die "Can not create $header_file\n";
4344    print HEAD "To: $mailto\n";
4345    print HEAD "Subject: $subject\n\n";
4346    print HEAD "$message\n";
4347    close HEAD;
4348
4349    if (!defined($mail_command)) {
4350	if ($mailer eq "mail" || $mailer eq "mailx") {
4351	    $mail_command = "cat \$HEADER_FILE \$BODY_FILE | \$MAIL_PATH/\$MAILER -s \'\$SUBJECT\' \$MAILTO";
4352	} elsif ($mailer eq "sendmail" ) {
4353	    $mail_command =  "cat \$HEADER_FILE \$BODY_FILE | \$MAIL_PATH/\$MAILER -t \$MAILTO";
4354	} else {
4355	    die "\nYour mailer: $mailer is not supported.\n";
4356	}
4357    }
4358
4359    if (defined($file)) {
4360	$mail_command =~ s/\$BODY_FILE/$file/g;
4361    } else {
4362	$mail_command =~ s/\$BODY_FILE//g;
4363    }
4364
4365    $mail_command =~ s/\$HEADER_FILE/$header_file/g;
4366    $mail_command =~ s/\$MAILER/$mailer/g;
4367    $mail_command =~ s/\$MAIL_PATH/$mail_path/g;
4368    $mail_command =~ s/\$MAILTO/$mailto/g;
4369    $mail_command =~ s/\$SUBJECT/$subject/g;
4370    $mail_command =~ s/\$MESSAGE/$message/g;
4371
4372    my $ret = run_command $mail_command;
4373    if (!$ret && defined($file)) {
4374	# try again without the file
4375	$message .= "\n\n*** FAILED TO SEND LOG ***\n\n";
4376	do_send_email($subject, $message);
4377    }
4378}
4379
4380sub send_email {
4381    if (defined($mailto)) {
4382	if (!defined($mailer)) {
4383	    doprint "No email sent: email or mailer not specified in config.\n";
4384	    return;
4385	}
4386	do_send_mail @_;
4387    }
4388}
4389
4390sub cancel_test {
4391    if ($monitor_cnt) {
4392	end_monitor;
4393    }
4394    if ($email_when_canceled) {
4395	my $name = get_test_name;
4396	send_email("KTEST: Your [$name] test was cancelled",
4397	    "Your test started at $script_start_time was cancelled: sig int");
4398    }
4399    run_post_ktest;
4400    die "\nCaught Sig Int, test interrupted: $!\n"
4401}
4402
4403sub die_usage {
4404    die << "EOF"
4405ktest.pl version: $VERSION
4406   usage: ktest.pl [options] [config-file]
4407    [options]:
4408       -D value: Where value can act as an option override.
4409                -D BUILD_NOCLEAN=1
4410                    Sets global BUILD_NOCLEAN to 1
4411                -D TEST_TYPE[2]=build
4412                    Sets TEST_TYPE of test 2 to "build"
4413       --dry-run
4414                Print resolved test options and exit without running tests.
4415
4416	        It can also override all temp variables.
4417                 -D USE_TEMP_DIR:=1
4418                    Will override all variables that use
4419                    "USE_TEMP_DIR="
4420
4421EOF
4422;
4423}
4424
4425while ( $#ARGV >= 0 ) {
4426    if ( $ARGV[0] eq "-D" ) {
4427	shift;
4428	die_usage if ($#ARGV < 1);
4429	my $val = shift;
4430
4431	if ($val =~ m/(.*?):=(.*)$/) {
4432	    set_variable($1, $2, 1);
4433	} else {
4434	    $command_vars[$#command_vars + 1] = $val;
4435	}
4436
4437    } elsif ( $ARGV[0] =~ m/^-D(.*)/) {
4438	my $val = $1;
4439	shift;
4440
4441	if ($val =~ m/(.*?):=(.*)$/) {
4442	    set_variable($1, $2, 1);
4443	} else {
4444	    $command_vars[$#command_vars + 1] = $val;
4445	}
4446    } elsif ( $ARGV[0] eq "--dry-run" ) {
4447	$dry_run = 1;
4448	shift;
4449    } elsif ( $ARGV[0] eq "-h" ) {
4450	die_usage;
4451    } else {
4452	last;
4453    }
4454}
4455
4456$#ARGV < 1 or die_usage;
4457if ($#ARGV == 0) {
4458    $ktest_config = $ARGV[0];
4459    if (! -f $ktest_config) {
4460	print "$ktest_config does not exist.\n";
4461	if (!read_yn "Create it?") {
4462	    exit 0;
4463	}
4464    }
4465}
4466
4467if (! -f $ktest_config) {
4468    $newconfig = 1;
4469    get_test_case;
4470    open(OUT, ">$ktest_config") or die "Can not create $ktest_config";
4471    print OUT << "EOF"
4472# Generated by ktest.pl
4473#
4474
4475# PWD is a ktest.pl variable that will result in the process working
4476# directory that ktest.pl is executed in.
4477
4478# THIS_DIR is automatically assigned the PWD of the path that generated
4479# the config file. It is best to use this variable when assigning other
4480# directory paths within this directory. This allows you to easily
4481# move the test cases to other locations or to other machines.
4482#
4483THIS_DIR := $variable{"PWD"}
4484
4485# Define each test with TEST_START
4486# The config options below it will override the defaults
4487TEST_START
4488TEST_TYPE = $default{"TEST_TYPE"}
4489
4490DEFAULTS
4491EOF
4492;
4493    close(OUT);
4494}
4495read_config $ktest_config;
4496
4497if ($dry_run) {
4498    print_test_preamble 1;
4499    exit 0;
4500}
4501
4502if (defined($opt{"LOG_FILE"})) {
4503    $opt{"LOG_FILE"} = set_test_option("LOG_FILE", 1);
4504}
4505
4506# Append any configs entered in manually to the config file.
4507my @new_configs = keys %entered_configs;
4508if ($#new_configs >= 0) {
4509    print "\nAppending entered in configs to $ktest_config\n";
4510    open(OUT, ">>$ktest_config") or die "Can not append to $ktest_config";
4511    foreach my $config (@new_configs) {
4512	print OUT "$config = $entered_configs{$config}\n";
4513	$opt{$config} = process_variables($entered_configs{$config});
4514    }
4515}
4516
4517if (defined($opt{"LOG_FILE"})) {
4518    if ($opt{"CLEAR_LOG"}) {
4519	unlink $opt{"LOG_FILE"};
4520    }
4521
4522    if (! -e $opt{"LOG_FILE"} && $opt{"LOG_FILE"} =~ m,^(.*/),) {
4523        my $dir = $1;
4524        if (! -d $dir) {
4525            mkpath($dir) or die "Failed to create directories '$dir': $!";
4526            print "\nThe log directory $dir did not exist, so it was created.\n";
4527        }
4528    }
4529    open(LOG, ">> $opt{LOG_FILE}") or die "Can't write to $opt{LOG_FILE}";
4530    LOG->autoflush(1);
4531}
4532
4533print_test_preamble 0;
4534
4535$SIG{INT} = qw(cancel_test);
4536
4537# First we need to do is the builds
4538for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
4539
4540    # Do not reboot on failing test options
4541    $no_reboot = 1;
4542    $reboot_success = 0;
4543
4544    $have_version = 0;
4545
4546    $iteration = $i;
4547
4548    $build_time = 0;
4549    $install_time = 0;
4550    $reboot_time = 0;
4551    $test_time = 0;
4552
4553    undef %force_config;
4554
4555    my $makecmd = set_test_option("MAKE_CMD", $i);
4556
4557    $outputdir = set_test_option("OUTPUT_DIR", $i);
4558    $builddir = set_test_option("BUILD_DIR", $i);
4559
4560    chdir $builddir || dodie "can't change directory to $builddir";
4561
4562    if (!-d $outputdir) {
4563	mkpath($outputdir) or
4564	    dodie "can't create $outputdir";
4565    }
4566
4567    $make = "$makecmd O=$outputdir";
4568
4569    # Load all the options into their mapped variable names
4570    foreach my $opt (keys %option_map) {
4571	${$option_map{$opt}} = set_test_option($opt, $i);
4572    }
4573
4574    $start_minconfig_defined = 1;
4575
4576    # The first test may override the PRE_KTEST option
4577    if ($i == 1) {
4578	if (defined($pre_ktest)) {
4579	    doprint "\n";
4580	    my $ret = run_command $pre_ktest;
4581	    if (!$ret && defined($pre_ktest_die) &&
4582		$pre_ktest_die) {
4583		dodie "failed to pre_ktest\n";
4584	    }
4585	}
4586	if ($email_when_started) {
4587	    my $name = get_test_name;
4588	    send_email("KTEST: Your [$name] test was started",
4589		"Your test was started on $script_start_time");
4590	}
4591    }
4592
4593    # Any test can override the POST_KTEST option
4594    # The last test takes precedence.
4595    if (defined($post_ktest)) {
4596	$final_post_ktest = $post_ktest;
4597    }
4598
4599    if (!defined($start_minconfig)) {
4600	$start_minconfig_defined = 0;
4601	$start_minconfig = $minconfig;
4602    }
4603
4604    if (!-d $tmpdir) {
4605	mkpath($tmpdir) or
4606	    dodie "can't create $tmpdir";
4607    }
4608
4609    $ENV{"SSH_USER"} = $ssh_user;
4610    $ENV{"MACHINE"} = $machine;
4611
4612    $buildlog = "$tmpdir/buildlog-$machine";
4613    $testlog = "$tmpdir/testlog-$machine";
4614    $dmesg = "$tmpdir/dmesg-$machine";
4615    $output_config = "$outputdir/.config";
4616
4617    if (!$buildonly) {
4618	$target = "$ssh_user\@$machine";
4619	if (($reboot_type eq "grub") or ($reboot_type eq "grub2bls")) {
4620	    dodie "GRUB_MENU not defined" if (!defined($grub_menu));
4621	} elsif ($reboot_type eq "grub2") {
4622	    dodie "GRUB_MENU not defined" if (!defined($grub_menu));
4623	    dodie "GRUB_FILE not defined" if (!defined($grub_file));
4624	} elsif ($reboot_type eq "syslinux") {
4625	    dodie "SYSLINUX_LABEL not defined" if (!defined($syslinux_label));
4626	}
4627    }
4628
4629    my $run_type = $build_type;
4630    if ($test_type eq "patchcheck") {
4631	$run_type = $patchcheck_type;
4632    } elsif ($test_type eq "bisect") {
4633	$run_type = $bisect_type;
4634    } elsif ($test_type eq "config_bisect") {
4635	$run_type = $config_bisect_type;
4636    } elsif ($test_type eq "make_min_config") {
4637	$run_type = "";
4638    } elsif ($test_type eq "make_warnings_file") {
4639	$run_type = "";
4640    }
4641
4642    # mistake in config file?
4643    if (!defined($run_type)) {
4644	$run_type = "ERROR";
4645    }
4646
4647    my $installme = "";
4648    $installme = " no_install" if ($no_install);
4649
4650    my $name = "";
4651
4652    if (defined($test_name)) {
4653	$name = " ($test_name)";
4654    }
4655
4656    doprint "\n\n";
4657
4658    if (defined($opt{"LOG_FILE"})) {
4659	$test_log_start = tell(LOG);
4660    }
4661
4662    doprint "RUNNING TEST $i of $opt{NUM_TESTS}$name with option $test_type $run_type$installme\n\n";
4663
4664    # Always show which build directory and output directory is being used
4665    doprint "BUILD_DIR=$builddir\n";
4666    doprint "OUTPUT_DIR=$outputdir\n\n";
4667
4668    if (defined($pre_test)) {
4669	my $ret = run_command $pre_test;
4670	if (!$ret && defined($pre_test_die) &&
4671	    $pre_test_die) {
4672		dodie "failed to pre_test\n";
4673	}
4674    }
4675
4676    unlink $dmesg;
4677    unlink $buildlog;
4678    unlink $testlog;
4679
4680    if (defined($addconfig)) {
4681	my $min = $minconfig;
4682	if (!defined($minconfig)) {
4683	    $min = "";
4684	}
4685	run_command "cat $addconfig $min > $tmpdir/add_config" or
4686	    dodie "Failed to create temp config";
4687	$minconfig = "$tmpdir/add_config";
4688    }
4689
4690    if (defined($checkout)) {
4691	run_command "git checkout $checkout" or
4692	    dodie "failed to checkout $checkout";
4693    }
4694
4695    $no_reboot = 0;
4696
4697    # A test may opt to not reboot the box
4698    if ($reboot_on_success) {
4699	$reboot_success = 1;
4700    }
4701
4702    if ($test_type eq "bisect") {
4703	bisect $i;
4704	next;
4705    } elsif ($test_type eq "config_bisect") {
4706	config_bisect $i;
4707	next;
4708    } elsif ($test_type eq "patchcheck") {
4709	patchcheck $i;
4710	next;
4711    } elsif ($test_type eq "make_min_config") {
4712	make_min_config $i;
4713	next;
4714    } elsif ($test_type eq "make_warnings_file") {
4715	$no_reboot = 1;
4716	make_warnings_file $i;
4717	next;
4718    }
4719
4720    if ($build_type ne "nobuild") {
4721	build $build_type or next;
4722	check_buildlog or next;
4723    }
4724
4725    if ($test_type eq "install") {
4726	get_version;
4727	install;
4728	success $i;
4729	next;
4730    }
4731
4732    if ($test_type ne "build") {
4733	my $failed = 0;
4734	start_monitor_and_install or $failed = 1;
4735
4736	if (!$failed && $test_type ne "boot" && defined($run_test)) {
4737	    do_run_test or $failed = 1;
4738	}
4739	end_monitor;
4740	if ($failed) {
4741	    print_times;
4742	    next;
4743	}
4744    }
4745
4746    print_times;
4747
4748    success $i;
4749}
4750
4751run_post_ktest;
4752
4753if ($opt{"POWEROFF_ON_SUCCESS"}) {
4754    halt;
4755} elsif ($opt{"REBOOT_ON_SUCCESS"} && !do_not_reboot && $reboot_success) {
4756    reboot_to_good;
4757} elsif (defined($switch_to_good)) {
4758    # still need to get to the good kernel
4759    run_command $switch_to_good;
4760}
4761
4762doprint "\n    $successes of $opt{NUM_TESTS} tests were successful\n\n";
4763
4764if ($email_when_finished) {
4765    send_email("KTEST: Your test has finished!",
4766	"$successes of $opt{NUM_TESTS} tests started at $script_start_time were successful!");
4767}
4768
4769if (defined($opt{"LOG_FILE"})) {
4770    print "\n See $opt{LOG_FILE} for the record of results.\n\n";
4771    close LOG;
4772}
4773
4774exit 0;
4775
4776##
4777# The following are here to standardize tabs/spaces/etc across the most likely editors
4778###
4779
4780# Local Variables:
4781# mode: perl
4782# End:
4783# vim: softtabstop=4
4784