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