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