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