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