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