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