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