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