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