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