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