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