xref: /linux/tools/testing/ktest/ktest.pl (revision 4025bc62dd045d326d8a26a50fc86fd163aec89f)
1#!/usr/bin/perl -w
2#
3# Copyright 2010 - Steven Rostedt <srostedt@redhat.com>, Red Hat Inc.
4# Licensed under the terms of the GNU GPL License version 2
5#
6
7use strict;
8use IPC::Open2;
9use Fcntl qw(F_GETFL F_SETFL O_NONBLOCK);
10use File::Path qw(mkpath);
11use File::Copy qw(cp);
12use FileHandle;
13
14my $VERSION = "0.2";
15
16$| = 1;
17
18my %opt;
19my %repeat_tests;
20my %repeats;
21my %default;
22
23#default opts
24$default{"NUM_TESTS"}		= 1;
25$default{"REBOOT_TYPE"}		= "grub";
26$default{"TEST_TYPE"}		= "test";
27$default{"BUILD_TYPE"}		= "randconfig";
28$default{"MAKE_CMD"}		= "make";
29$default{"TIMEOUT"}		= 120;
30$default{"TMP_DIR"}		= "/tmp/ktest";
31$default{"SLEEP_TIME"}		= 60;	# sleep time between tests
32$default{"BUILD_NOCLEAN"}	= 0;
33$default{"REBOOT_ON_ERROR"}	= 0;
34$default{"POWEROFF_ON_ERROR"}	= 0;
35$default{"REBOOT_ON_SUCCESS"}	= 1;
36$default{"POWEROFF_ON_SUCCESS"}	= 0;
37$default{"BUILD_OPTIONS"}	= "";
38$default{"BISECT_SLEEP_TIME"}	= 60;   # sleep time between bisects
39$default{"CLEAR_LOG"}		= 0;
40$default{"BISECT_MANUAL"}	= 0;
41$default{"BISECT_SKIP"}		= 1;
42$default{"SUCCESS_LINE"}	= "login:";
43$default{"BOOTED_TIMEOUT"}	= 1;
44$default{"DIE_ON_FAILURE"}	= 1;
45$default{"SSH_EXEC"}		= "ssh \$SSH_USER\@\$MACHINE \$SSH_COMMAND";
46$default{"SCP_TO_TARGET"}	= "scp \$SRC_FILE \$SSH_USER\@\$MACHINE:\$DST_FILE";
47$default{"REBOOT"}		= "ssh \$SSH_USER\@\$MACHINE reboot";
48$default{"STOP_AFTER_SUCCESS"}	= 10;
49$default{"STOP_AFTER_FAILURE"}	= 60;
50$default{"STOP_TEST_AFTER"}	= 600;
51$default{"LOCALVERSION"}	= "-test";
52
53my $ktest_config;
54my $version;
55my $machine;
56my $ssh_user;
57my $tmpdir;
58my $builddir;
59my $outputdir;
60my $output_config;
61my $test_type;
62my $build_type;
63my $build_options;
64my $reboot_type;
65my $reboot_script;
66my $power_cycle;
67my $reboot;
68my $reboot_on_error;
69my $poweroff_on_error;
70my $die_on_failure;
71my $powercycle_after_reboot;
72my $poweroff_after_halt;
73my $ssh_exec;
74my $scp_to_target;
75my $power_off;
76my $grub_menu;
77my $grub_number;
78my $target;
79my $make;
80my $post_install;
81my $noclean;
82my $minconfig;
83my $addconfig;
84my $in_bisect = 0;
85my $bisect_bad = "";
86my $reverse_bisect;
87my $bisect_manual;
88my $bisect_skip;
89my $in_patchcheck = 0;
90my $run_test;
91my $redirect;
92my $buildlog;
93my $dmesg;
94my $monitor_fp;
95my $monitor_pid;
96my $monitor_cnt = 0;
97my $sleep_time;
98my $bisect_sleep_time;
99my $store_failures;
100my $timeout;
101my $booted_timeout;
102my $console;
103my $success_line;
104my $stop_after_success;
105my $stop_after_failure;
106my $stop_test_after;
107my $build_target;
108my $target_image;
109my $localversion;
110my $iteration = 0;
111my $successes = 0;
112
113my %entered_configs;
114my %config_help;
115
116$config_help{"MACHINE"} = << "EOF"
117 The machine hostname that you will test.
118EOF
119    ;
120$config_help{"SSH_USER"} = << "EOF"
121 The box is expected to have ssh on normal bootup, provide the user
122  (most likely root, since you need privileged operations)
123EOF
124    ;
125$config_help{"BUILD_DIR"} = << "EOF"
126 The directory that contains the Linux source code (full path).
127EOF
128    ;
129$config_help{"OUTPUT_DIR"} = << "EOF"
130 The directory that the objects will be built (full path).
131 (can not be same as BUILD_DIR)
132EOF
133    ;
134$config_help{"BUILD_TARGET"} = << "EOF"
135 The location of the compiled file to copy to the target.
136 (relative to OUTPUT_DIR)
137EOF
138    ;
139$config_help{"TARGET_IMAGE"} = << "EOF"
140 The place to put your image on the test machine.
141EOF
142    ;
143$config_help{"POWER_CYCLE"} = << "EOF"
144 A script or command to reboot the box.
145
146 Here is a digital loggers power switch example
147 POWER_CYCLE = wget --no-proxy -O /dev/null -q  --auth-no-challenge 'http://admin:admin\@power/outlet?5=CCL'
148
149 Here is an example to reboot a virtual box on the current host
150 with the name "Guest".
151 POWER_CYCLE = virsh destroy Guest; sleep 5; virsh start Guest
152EOF
153    ;
154$config_help{"CONSOLE"} = << "EOF"
155 The script or command that reads the console
156
157  If you use ttywatch server, something like the following would work.
158CONSOLE = nc -d localhost 3001
159
160 For a virtual machine with guest name "Guest".
161CONSOLE =  virsh console Guest
162EOF
163    ;
164$config_help{"LOCALVERSION"} = << "EOF"
165 Required version ending to differentiate the test
166 from other linux builds on the system.
167EOF
168    ;
169$config_help{"REBOOT_TYPE"} = << "EOF"
170 Way to reboot the box to the test kernel.
171 Only valid options so far are "grub" and "script".
172
173 If you specify grub, it will assume grub version 1
174 and will search in /boot/grub/menu.lst for the title \$GRUB_MENU
175 and select that target to reboot to the kernel. If this is not
176 your setup, then specify "script" and have a command or script
177 specified in REBOOT_SCRIPT to boot to the target.
178
179 The entry in /boot/grub/menu.lst must be entered in manually.
180 The test will not modify that file.
181EOF
182    ;
183$config_help{"GRUB_MENU"} = << "EOF"
184 The grub title name for the test kernel to boot
185 (Only mandatory if REBOOT_TYPE = grub)
186
187 Note, ktest.pl will not update the grub menu.lst, you need to
188 manually add an option for the test. ktest.pl will search
189 the grub menu.lst for this option to find what kernel to
190 reboot into.
191
192 For example, if in the /boot/grub/menu.lst the test kernel title has:
193 title Test Kernel
194 kernel vmlinuz-test
195 GRUB_MENU = Test Kernel
196EOF
197    ;
198$config_help{"REBOOT_SCRIPT"} = << "EOF"
199 A script to reboot the target into the test kernel
200 (Only mandatory if REBOOT_TYPE = script)
201EOF
202    ;
203
204
205sub get_ktest_config {
206    my ($config) = @_;
207
208    return if (defined($opt{$config}));
209
210    if (defined($config_help{$config})) {
211	print "\n";
212	print $config_help{$config};
213    }
214
215    for (;;) {
216	print "$config = ";
217	if (defined($default{$config})) {
218	    print "\[$default{$config}\] ";
219	}
220	$entered_configs{$config} = <STDIN>;
221	$entered_configs{$config} =~ s/^\s*(.*\S)\s*$/$1/;
222	if ($entered_configs{$config} =~ /^\s*$/) {
223	    if ($default{$config}) {
224		$entered_configs{$config} = $default{$config};
225	    } else {
226		print "Your answer can not be blank\n";
227		next;
228	    }
229	}
230	last;
231    }
232}
233
234sub get_ktest_configs {
235    get_ktest_config("MACHINE");
236    get_ktest_config("SSH_USER");
237    get_ktest_config("BUILD_DIR");
238    get_ktest_config("OUTPUT_DIR");
239    get_ktest_config("BUILD_TARGET");
240    get_ktest_config("TARGET_IMAGE");
241    get_ktest_config("POWER_CYCLE");
242    get_ktest_config("CONSOLE");
243    get_ktest_config("LOCALVERSION");
244
245    my $rtype = $opt{"REBOOT_TYPE"};
246
247    if (!defined($rtype)) {
248	if (!defined($opt{"GRUB_MENU"})) {
249	    get_ktest_config("REBOOT_TYPE");
250	    $rtype = $entered_configs{"REBOOT_TYPE"};
251	} else {
252	    $rtype = "grub";
253	}
254    }
255
256    if ($rtype eq "grub") {
257	get_ktest_config("GRUB_MENU");
258    } else {
259	get_ktest_config("REBOOT_SCRIPT");
260    }
261}
262
263sub set_value {
264    my ($lvalue, $rvalue) = @_;
265
266    if (defined($opt{$lvalue})) {
267	die "Error: Option $lvalue defined more than once!\n";
268    }
269    if ($rvalue =~ /^\s*$/) {
270	delete $opt{$lvalue};
271    } else {
272	$opt{$lvalue} = $rvalue;
273    }
274}
275
276sub read_config {
277    my ($config) = @_;
278
279    open(IN, $config) || die "can't read file $config";
280
281    my $name = $config;
282    $name =~ s,.*/(.*),$1,;
283
284    my $test_num = 0;
285    my $default = 1;
286    my $repeat = 1;
287    my $num_tests_set = 0;
288    my $skip = 0;
289    my $rest;
290
291    while (<IN>) {
292
293	# ignore blank lines and comments
294	next if (/^\s*$/ || /\s*\#/);
295
296	if (/^\s*TEST_START(.*)/) {
297
298	    $rest = $1;
299
300	    if ($num_tests_set) {
301		die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
302	    }
303
304	    my $old_test_num = $test_num;
305	    my $old_repeat = $repeat;
306
307	    $test_num += $repeat;
308	    $default = 0;
309	    $repeat = 1;
310
311	    if ($rest =~ /\s+SKIP(.*)/) {
312		$rest = $1;
313		$skip = 1;
314	    } else {
315		$skip = 0;
316	    }
317
318	    if ($rest =~ /\s+ITERATE\s+(\d+)(.*)$/) {
319		$repeat = $1;
320		$rest = $2;
321		$repeat_tests{"$test_num"} = $repeat;
322	    }
323
324	    if ($rest =~ /\s+SKIP(.*)/) {
325		$rest = $1;
326		$skip = 1;
327	    }
328
329	    if ($rest !~ /^\s*$/) {
330		die "$name: $.: Gargbage found after TEST_START\n$_";
331	    }
332
333	    if ($skip) {
334		$test_num = $old_test_num;
335		$repeat = $old_repeat;
336	    }
337
338	} elsif (/^\s*DEFAULTS(.*)$/) {
339	    $default = 1;
340
341	    $rest = $1;
342
343	    if ($rest =~ /\s+SKIP(.*)/) {
344		$rest = $1;
345		$skip = 1;
346	    } else {
347		$skip = 0;
348	    }
349
350	    if ($rest !~ /^\s*$/) {
351		die "$name: $.: Gargbage found after DEFAULTS\n$_";
352	    }
353
354	} elsif (/^\s*([A-Z_\[\]\d]+)\s*=\s*(.*?)\s*$/) {
355
356	    next if ($skip);
357
358	    my $lvalue = $1;
359	    my $rvalue = $2;
360
361	    if (!$default &&
362		($lvalue eq "NUM_TESTS" ||
363		 $lvalue eq "LOG_FILE" ||
364		 $lvalue eq "CLEAR_LOG")) {
365		die "$name: $.: $lvalue must be set in DEFAULTS section\n";
366	    }
367
368	    if ($lvalue eq "NUM_TESTS") {
369		if ($test_num) {
370		    die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
371		}
372		if (!$default) {
373		    die "$name: $.: NUM_TESTS must be set in default section\n";
374		}
375		$num_tests_set = 1;
376	    }
377
378	    if ($default || $lvalue =~ /\[\d+\]$/) {
379		set_value($lvalue, $rvalue);
380	    } else {
381		my $val = "$lvalue\[$test_num\]";
382		set_value($val, $rvalue);
383
384		if ($repeat > 1) {
385		    $repeats{$val} = $repeat;
386		}
387	    }
388	} else {
389	    die "$name: $.: Garbage found in config\n$_";
390	}
391    }
392
393    close(IN);
394
395    if ($test_num) {
396	$test_num += $repeat - 1;
397	$opt{"NUM_TESTS"} = $test_num;
398    }
399
400    # make sure we have all mandatory configs
401    get_ktest_configs;
402
403    # set any defaults
404
405    foreach my $default (keys %default) {
406	if (!defined($opt{$default})) {
407	    $opt{$default} = $default{$default};
408	}
409    }
410}
411
412sub _logit {
413    if (defined($opt{"LOG_FILE"})) {
414	open(OUT, ">> $opt{LOG_FILE}") or die "Can't write to $opt{LOG_FILE}";
415	print OUT @_;
416	close(OUT);
417    }
418}
419
420sub logit {
421    if (defined($opt{"LOG_FILE"})) {
422	_logit @_;
423    } else {
424	print @_;
425    }
426}
427
428sub doprint {
429    print @_;
430    _logit @_;
431}
432
433sub run_command;
434
435sub reboot {
436    # try to reboot normally
437    if (run_command $reboot) {
438	if (defined($powercycle_after_reboot)) {
439	    sleep $powercycle_after_reboot;
440	    run_command "$power_cycle";
441	}
442    } else {
443	# nope? power cycle it.
444	run_command "$power_cycle";
445    }
446}
447
448sub do_not_reboot {
449    my $i = $iteration;
450
451    return $test_type eq "build" ||
452	($test_type eq "patchcheck" && $opt{"PATCHCHECK_TYPE[$i]"} eq "build") ||
453	($test_type eq "bisect" && $opt{"BISECT_TYPE[$i]"} eq "build");
454}
455
456sub dodie {
457    doprint "CRITICAL FAILURE... ", @_, "\n";
458
459    my $i = $iteration;
460
461    if ($reboot_on_error && !do_not_reboot) {
462
463	doprint "REBOOTING\n";
464	reboot;
465
466    } elsif ($poweroff_on_error && defined($power_off)) {
467	doprint "POWERING OFF\n";
468	`$power_off`;
469    }
470
471    if (defined($opt{"LOG_FILE"})) {
472	print " See $opt{LOG_FILE} for more info.\n";
473    }
474
475    die @_, "\n";
476}
477
478sub open_console {
479    my ($fp) = @_;
480
481    my $flags;
482
483    my $pid = open($fp, "$console|") or
484	dodie "Can't open console $console";
485
486    $flags = fcntl($fp, F_GETFL, 0) or
487	dodie "Can't get flags for the socket: $!";
488    $flags = fcntl($fp, F_SETFL, $flags | O_NONBLOCK) or
489	dodie "Can't set flags for the socket: $!";
490
491    return $pid;
492}
493
494sub close_console {
495    my ($fp, $pid) = @_;
496
497    doprint "kill child process $pid\n";
498    kill 2, $pid;
499
500    print "closing!\n";
501    close($fp);
502}
503
504sub start_monitor {
505    if ($monitor_cnt++) {
506	return;
507    }
508    $monitor_fp = \*MONFD;
509    $monitor_pid = open_console $monitor_fp;
510
511    return;
512
513    open(MONFD, "Stop perl from warning about single use of MONFD");
514}
515
516sub end_monitor {
517    if (--$monitor_cnt) {
518	return;
519    }
520    close_console($monitor_fp, $monitor_pid);
521}
522
523sub wait_for_monitor {
524    my ($time) = @_;
525    my $line;
526
527    doprint "** Wait for monitor to settle down **\n";
528
529    # read the monitor and wait for the system to calm down
530    do {
531	$line = wait_for_input($monitor_fp, $time);
532	print "$line" if (defined($line));
533    } while (defined($line));
534    print "** Monitor flushed **\n";
535}
536
537sub fail {
538
539	if ($die_on_failure) {
540		dodie @_;
541	}
542
543	doprint "FAILED\n";
544
545	my $i = $iteration;
546
547	# no need to reboot for just building.
548	if (!do_not_reboot) {
549	    doprint "REBOOTING\n";
550	    reboot;
551	    start_monitor;
552	    wait_for_monitor $sleep_time;
553	    end_monitor;
554	}
555
556	doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
557	doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
558	doprint "KTEST RESULT: TEST $i Failed: ", @_, "\n";
559	doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
560	doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
561
562	return 1 if (!defined($store_failures));
563
564	my @t = localtime;
565	my $date = sprintf "%04d%02d%02d%02d%02d%02d",
566		1900+$t[5],$t[4],$t[3],$t[2],$t[1],$t[0];
567
568	my $type = $build_type;
569	if ($type =~ /useconfig/) {
570	    $type = "useconfig";
571	}
572
573	my $dir = "$machine-$test_type-$type-fail-$date";
574	my $faildir = "$store_failures/$dir";
575
576	if (!-d $faildir) {
577	    mkpath($faildir) or
578		die "can't create $faildir";
579	}
580	if (-f "$output_config") {
581	    cp "$output_config", "$faildir/config" or
582		die "failed to copy .config";
583	}
584	if (-f $buildlog) {
585	    cp $buildlog, "$faildir/buildlog" or
586		die "failed to move $buildlog";
587	}
588	if (-f $dmesg) {
589	    cp $dmesg, "$faildir/dmesg" or
590		die "failed to move $dmesg";
591	}
592
593	doprint "*** Saved info to $faildir ***\n";
594
595	return 1;
596}
597
598sub run_command {
599    my ($command) = @_;
600    my $dolog = 0;
601    my $dord = 0;
602    my $pid;
603
604    $command =~ s/\$SSH_USER/$ssh_user/g;
605    $command =~ s/\$MACHINE/$machine/g;
606
607    doprint("$command ... ");
608
609    $pid = open(CMD, "$command 2>&1 |") or
610	(fail "unable to exec $command" and return 0);
611
612    if (defined($opt{"LOG_FILE"})) {
613	open(LOG, ">>$opt{LOG_FILE}") or
614	    dodie "failed to write to log";
615	$dolog = 1;
616    }
617
618    if (defined($redirect)) {
619	open (RD, ">$redirect") or
620	    dodie "failed to write to redirect $redirect";
621	$dord = 1;
622    }
623
624    while (<CMD>) {
625	print LOG if ($dolog);
626	print RD  if ($dord);
627    }
628
629    waitpid($pid, 0);
630    my $failed = $?;
631
632    close(CMD);
633    close(LOG) if ($dolog);
634    close(RD)  if ($dord);
635
636    if ($failed) {
637	doprint "FAILED!\n";
638    } else {
639	doprint "SUCCESS\n";
640    }
641
642    return !$failed;
643}
644
645sub run_ssh {
646    my ($cmd) = @_;
647    my $cp_exec = $ssh_exec;
648
649    $cp_exec =~ s/\$SSH_COMMAND/$cmd/g;
650    return run_command "$cp_exec";
651}
652
653sub run_scp {
654    my ($src, $dst) = @_;
655    my $cp_scp = $scp_to_target;
656
657    $cp_scp =~ s/\$SRC_FILE/$src/g;
658    $cp_scp =~ s/\$DST_FILE/$dst/g;
659
660    return run_command "$cp_scp";
661}
662
663sub get_grub_index {
664
665    if ($reboot_type ne "grub") {
666	return;
667    }
668    return if (defined($grub_number));
669
670    doprint "Find grub menu ... ";
671    $grub_number = -1;
672
673    my $ssh_grub = $ssh_exec;
674    $ssh_grub =~ s,\$SSH_COMMAND,cat /boot/grub/menu.lst,g;
675
676    open(IN, "$ssh_grub |")
677	or die "unable to get menu.lst";
678
679    while (<IN>) {
680	if (/^\s*title\s+$grub_menu\s*$/) {
681	    $grub_number++;
682	    last;
683	} elsif (/^\s*title\s/) {
684	    $grub_number++;
685	}
686    }
687    close(IN);
688
689    die "Could not find '$grub_menu' in /boot/grub/menu on $machine"
690	if ($grub_number < 0);
691    doprint "$grub_number\n";
692}
693
694sub wait_for_input
695{
696    my ($fp, $time) = @_;
697    my $rin;
698    my $ready;
699    my $line;
700    my $ch;
701
702    if (!defined($time)) {
703	$time = $timeout;
704    }
705
706    $rin = '';
707    vec($rin, fileno($fp), 1) = 1;
708    $ready = select($rin, undef, undef, $time);
709
710    $line = "";
711
712    # try to read one char at a time
713    while (sysread $fp, $ch, 1) {
714	$line .= $ch;
715	last if ($ch eq "\n");
716    }
717
718    if (!length($line)) {
719	return undef;
720    }
721
722    return $line;
723}
724
725sub reboot_to {
726    if ($reboot_type eq "grub") {
727	run_ssh "'(echo \"savedefault --default=$grub_number --once\" | grub --batch; reboot)'";
728	return;
729    }
730
731    run_command "$reboot_script";
732}
733
734sub get_sha1 {
735    my ($commit) = @_;
736
737    doprint "git rev-list --max-count=1 $commit ... ";
738    my $sha1 = `git rev-list --max-count=1 $commit`;
739    my $ret = $?;
740
741    logit $sha1;
742
743    if ($ret) {
744	doprint "FAILED\n";
745	dodie "Failed to get git $commit";
746    }
747
748    print "SUCCESS\n";
749
750    chomp $sha1;
751
752    return $sha1;
753}
754
755sub monitor {
756    my $booted = 0;
757    my $bug = 0;
758    my $skip_call_trace = 0;
759    my $loops;
760
761    wait_for_monitor 5;
762
763    my $line;
764    my $full_line = "";
765
766    open(DMESG, "> $dmesg") or
767	die "unable to write to $dmesg";
768
769    reboot_to;
770
771    my $success_start;
772    my $failure_start;
773    my $monitor_start = time;
774    my $done = 0;
775
776    while (!$done) {
777
778	if ($booted) {
779	    $line = wait_for_input($monitor_fp, $booted_timeout);
780	} else {
781	    $line = wait_for_input($monitor_fp);
782	}
783
784	last if (!defined($line));
785
786	doprint $line;
787	print DMESG $line;
788
789	# we are not guaranteed to get a full line
790	$full_line .= $line;
791
792	if ($full_line =~ /$success_line/) {
793	    $booted = 1;
794	    $success_start = time;
795	}
796
797	if ($booted && defined($stop_after_success) &&
798	    $stop_after_success >= 0) {
799	    my $now = time;
800	    if ($now - $success_start >= $stop_after_success) {
801		doprint "Test forced to stop after $stop_after_success seconds after success\n";
802		last;
803	    }
804	}
805
806	if ($full_line =~ /\[ backtrace testing \]/) {
807	    $skip_call_trace = 1;
808	}
809
810	if ($full_line =~ /call trace:/i) {
811	    if (!$bug && !$skip_call_trace) {
812		$bug = 1;
813		$failure_start = time;
814	    }
815	}
816
817	if ($bug && defined($stop_after_failure) &&
818	    $stop_after_failure >= 0) {
819	    my $now = time;
820	    if ($now - $failure_start >= $stop_after_failure) {
821		doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
822		last;
823	    }
824	}
825
826	if ($full_line =~ /\[ end of backtrace testing \]/) {
827	    $skip_call_trace = 0;
828	}
829
830	if ($full_line =~ /Kernel panic -/) {
831	    $failure_start = time;
832	    $bug = 1;
833	}
834
835	if ($line =~ /\n/) {
836	    $full_line = "";
837	}
838
839	if ($stop_test_after > 0 && !$booted && !$bug) {
840	    if (time - $monitor_start > $stop_test_after) {
841		doprint "STOP_TEST_AFTER ($stop_test_after seconds) timed out\n";
842		$done = 1;
843	    }
844	}
845    }
846
847    close(DMESG);
848
849    if ($bug) {
850	return 0 if ($in_bisect);
851	fail "failed - got a bug report" and return 0;
852    }
853
854    if (!$booted) {
855	return 0 if ($in_bisect);
856	fail "failed - never got a boot prompt." and return 0;
857    }
858
859    return 1;
860}
861
862sub install {
863
864    run_scp "$outputdir/$build_target", "$target_image" or
865	dodie "failed to copy image";
866
867    my $install_mods = 0;
868
869    # should we process modules?
870    $install_mods = 0;
871    open(IN, "$output_config") or dodie("Can't read config file");
872    while (<IN>) {
873	if (/CONFIG_MODULES(=y)?/) {
874	    $install_mods = 1 if (defined($1));
875	    last;
876	}
877    }
878    close(IN);
879
880    if (!$install_mods) {
881	doprint "No modules needed\n";
882	return;
883    }
884
885    run_command "$make INSTALL_MOD_PATH=$tmpdir modules_install" or
886	dodie "Failed to install modules";
887
888    my $modlib = "/lib/modules/$version";
889    my $modtar = "ktest-mods.tar.bz2";
890
891    run_ssh "rm -rf $modlib" or
892	dodie "failed to remove old mods: $modlib";
893
894    # would be nice if scp -r did not follow symbolic links
895    run_command "cd $tmpdir && tar -cjf $modtar lib/modules/$version" or
896	dodie "making tarball";
897
898    run_scp "$tmpdir/$modtar", "/tmp" or
899	dodie "failed to copy modules";
900
901    unlink "$tmpdir/$modtar";
902
903    run_ssh "'(cd / && tar xf /tmp/$modtar)'" or
904	dodie "failed to tar modules";
905
906    run_ssh "rm -f /tmp/$modtar";
907
908    return if (!defined($post_install));
909
910    my $cp_post_install = $post_install;
911    $cp_post_install =~ s/\$KERNEL_VERSION/$version/g;
912    run_command "$cp_post_install" or
913	dodie "Failed to run post install";
914}
915
916sub check_buildlog {
917    my ($patch) = @_;
918
919    my @files = `git show $patch | diffstat -l`;
920
921    open(IN, "git show $patch |") or
922	dodie "failed to show $patch";
923    while (<IN>) {
924	if (m,^--- a/(.*),) {
925	    chomp $1;
926	    $files[$#files] = $1;
927	}
928    }
929    close(IN);
930
931    open(IN, $buildlog) or dodie "Can't open $buildlog";
932    while (<IN>) {
933	if (/^\s*(.*?):.*(warning|error)/) {
934	    my $err = $1;
935	    foreach my $file (@files) {
936		my $fullpath = "$builddir/$file";
937		if ($file eq $err || $fullpath eq $err) {
938		    fail "$file built with warnings" and return 0;
939		}
940	    }
941	}
942    }
943    close(IN);
944
945    return 1;
946}
947
948sub make_oldconfig {
949    my ($defconfig) = @_;
950
951    if (!run_command "$defconfig $make oldnoconfig") {
952	# Perhaps oldnoconfig doesn't exist in this version of the kernel
953	# try a yes '' | oldconfig
954	doprint "oldnoconfig failed, trying yes '' | make oldconfig\n";
955	run_command "yes '' | $defconfig $make oldconfig" or
956	    dodie "failed make config oldconfig";
957    }
958}
959
960sub build {
961    my ($type) = @_;
962    my $defconfig = "";
963
964    unlink $buildlog;
965
966    if ($type =~ /^useconfig:(.*)/) {
967	run_command "cp $1 $output_config" or
968	    dodie "could not copy $1 to .config";
969
970	$type = "oldconfig";
971    }
972
973    # old config can ask questions
974    if ($type eq "oldconfig") {
975	$type = "oldnoconfig";
976
977	# allow for empty configs
978	run_command "touch $output_config";
979
980	run_command "mv $output_config $outputdir/config_temp" or
981	    dodie "moving .config";
982
983	if (!$noclean && !run_command "$make mrproper") {
984	    dodie "make mrproper";
985	}
986
987	run_command "mv $outputdir/config_temp $output_config" or
988	    dodie "moving config_temp";
989
990    } elsif (!$noclean) {
991	unlink "$output_config";
992	run_command "$make mrproper" or
993	    dodie "make mrproper";
994    }
995
996    # add something to distinguish this build
997    open(OUT, "> $outputdir/localversion") or dodie("Can't make localversion file");
998    print OUT "$localversion\n";
999    close(OUT);
1000
1001    if (defined($minconfig)) {
1002	$defconfig = "KCONFIG_ALLCONFIG=$minconfig";
1003    }
1004
1005    if ($type eq "oldnoconfig") {
1006	make_oldconfig $defconfig;
1007    } else {
1008	run_command "$defconfig $make $type" or
1009	    dodie "failed make config";
1010    }
1011
1012    $redirect = "$buildlog";
1013    if (!run_command "$make $build_options") {
1014	undef $redirect;
1015	# bisect may need this to pass
1016	return 0 if ($in_bisect);
1017	fail "failed build" and return 0;
1018    }
1019    undef $redirect;
1020
1021    return 1;
1022}
1023
1024sub halt {
1025    if (!run_ssh "halt" or defined($power_off)) {
1026	if (defined($poweroff_after_halt)) {
1027	    sleep $poweroff_after_halt;
1028	    run_command "$power_off";
1029	}
1030    } else {
1031	# nope? the zap it!
1032	run_command "$power_off";
1033    }
1034}
1035
1036sub success {
1037    my ($i) = @_;
1038
1039    $successes++;
1040
1041    doprint "\n\n*******************************************\n";
1042    doprint     "*******************************************\n";
1043    doprint     "KTEST RESULT: TEST $i SUCCESS!!!!         **\n";
1044    doprint     "*******************************************\n";
1045    doprint     "*******************************************\n";
1046
1047    if ($i != $opt{"NUM_TESTS"} && !do_not_reboot) {
1048	doprint "Reboot and wait $sleep_time seconds\n";
1049	reboot;
1050	start_monitor;
1051	wait_for_monitor $sleep_time;
1052	end_monitor;
1053    }
1054}
1055
1056sub get_version {
1057    # get the release name
1058    doprint "$make kernelrelease ... ";
1059    $version = `$make kernelrelease | tail -1`;
1060    chomp($version);
1061    doprint "$version\n";
1062}
1063
1064sub answer_bisect {
1065    for (;;) {
1066	doprint "Pass or fail? [p/f]";
1067	my $ans = <STDIN>;
1068	chomp $ans;
1069	if ($ans eq "p" || $ans eq "P") {
1070	    return 1;
1071	} elsif ($ans eq "f" || $ans eq "F") {
1072	    return 0;
1073	} else {
1074	    print "Please answer 'P' or 'F'\n";
1075	}
1076    }
1077}
1078
1079sub child_run_test {
1080    my $failed = 0;
1081
1082    # child should have no power
1083    $reboot_on_error = 0;
1084    $poweroff_on_error = 0;
1085    $die_on_failure = 1;
1086
1087    run_command $run_test or $failed = 1;
1088    exit $failed;
1089}
1090
1091my $child_done;
1092
1093sub child_finished {
1094    $child_done = 1;
1095}
1096
1097sub do_run_test {
1098    my $child_pid;
1099    my $child_exit;
1100    my $line;
1101    my $full_line;
1102    my $bug = 0;
1103
1104    wait_for_monitor 1;
1105
1106    doprint "run test $run_test\n";
1107
1108    $child_done = 0;
1109
1110    $SIG{CHLD} = qw(child_finished);
1111
1112    $child_pid = fork;
1113
1114    child_run_test if (!$child_pid);
1115
1116    $full_line = "";
1117
1118    do {
1119	$line = wait_for_input($monitor_fp, 1);
1120	if (defined($line)) {
1121
1122	    # we are not guaranteed to get a full line
1123	    $full_line .= $line;
1124	    doprint $line;
1125
1126	    if ($full_line =~ /call trace:/i) {
1127		$bug = 1;
1128	    }
1129
1130	    if ($full_line =~ /Kernel panic -/) {
1131		$bug = 1;
1132	    }
1133
1134	    if ($line =~ /\n/) {
1135		$full_line = "";
1136	    }
1137	}
1138    } while (!$child_done && !$bug);
1139
1140    if ($bug) {
1141	my $failure_start = time;
1142	my $now;
1143	do {
1144	    $line = wait_for_input($monitor_fp, 1);
1145	    if (defined($line)) {
1146		doprint $line;
1147	    }
1148	    $now = time;
1149	    if ($now - $failure_start >= $stop_after_failure) {
1150		last;
1151	    }
1152	} while (defined($line));
1153
1154	doprint "Detected kernel crash!\n";
1155	# kill the child with extreme prejudice
1156	kill 9, $child_pid;
1157    }
1158
1159    waitpid $child_pid, 0;
1160    $child_exit = $?;
1161
1162    if ($bug || $child_exit) {
1163	return 0 if $in_bisect;
1164	fail "test failed" and return 0;
1165    }
1166    return 1;
1167}
1168
1169sub run_git_bisect {
1170    my ($command) = @_;
1171
1172    doprint "$command ... ";
1173
1174    my $output = `$command 2>&1`;
1175    my $ret = $?;
1176
1177    logit $output;
1178
1179    if ($ret) {
1180	doprint "FAILED\n";
1181	dodie "Failed to git bisect";
1182    }
1183
1184    doprint "SUCCESS\n";
1185    if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\))\s+\[([[:xdigit:]]+)\]/) {
1186	doprint "$1 [$2]\n";
1187    } elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) {
1188	$bisect_bad = $1;
1189	doprint "Found bad commit... $1\n";
1190	return 0;
1191    } else {
1192	# we already logged it, just print it now.
1193	print $output;
1194    }
1195
1196    return 1;
1197}
1198
1199sub bisect_reboot {
1200    doprint "Reboot and sleep $bisect_sleep_time seconds\n";
1201    reboot;
1202    start_monitor;
1203    wait_for_monitor $bisect_sleep_time;
1204    end_monitor;
1205}
1206
1207# returns 1 on success, 0 on failure, -1 on skip
1208sub run_bisect_test {
1209    my ($type, $buildtype) = @_;
1210
1211    my $failed = 0;
1212    my $result;
1213    my $output;
1214    my $ret;
1215
1216    $in_bisect = 1;
1217
1218    build $buildtype or $failed = 1;
1219
1220    if ($type ne "build") {
1221	if ($failed && $bisect_skip) {
1222	    $in_bisect = 0;
1223	    return -1;
1224	}
1225	dodie "Failed on build" if $failed;
1226
1227	# Now boot the box
1228	get_grub_index;
1229	get_version;
1230	install;
1231
1232	start_monitor;
1233	monitor or $failed = 1;
1234
1235	if ($type ne "boot") {
1236	    if ($failed && $bisect_skip) {
1237		end_monitor;
1238		bisect_reboot;
1239		$in_bisect = 0;
1240		return -1;
1241	    }
1242	    dodie "Failed on boot" if $failed;
1243
1244	    do_run_test or $failed = 1;
1245	}
1246	end_monitor;
1247    }
1248
1249    if ($failed) {
1250	$result = 0;
1251    } else {
1252	$result = 1;
1253    }
1254
1255    # reboot the box to a kernel we can ssh to
1256    if ($type ne "build") {
1257	bisect_reboot;
1258    }
1259    $in_bisect = 0;
1260
1261    return $result;
1262}
1263
1264sub run_bisect {
1265    my ($type) = @_;
1266    my $buildtype = "oldconfig";
1267
1268    # We should have a minconfig to use?
1269    if (defined($minconfig)) {
1270	$buildtype = "useconfig:$minconfig";
1271    }
1272
1273    my $ret = run_bisect_test $type, $buildtype;
1274
1275    if ($bisect_manual) {
1276	$ret = answer_bisect;
1277    }
1278
1279    # Are we looking for where it worked, not failed?
1280    if ($reverse_bisect) {
1281	$ret = !$ret;
1282    }
1283
1284    if ($ret > 0) {
1285	return "good";
1286    } elsif ($ret == 0) {
1287	return  "bad";
1288    } elsif ($bisect_skip) {
1289	doprint "HIT A BAD COMMIT ... SKIPPING\n";
1290	return "skip";
1291    }
1292}
1293
1294sub bisect {
1295    my ($i) = @_;
1296
1297    my $result;
1298
1299    die "BISECT_GOOD[$i] not defined\n"	if (!defined($opt{"BISECT_GOOD[$i]"}));
1300    die "BISECT_BAD[$i] not defined\n"	if (!defined($opt{"BISECT_BAD[$i]"}));
1301    die "BISECT_TYPE[$i] not defined\n"	if (!defined($opt{"BISECT_TYPE[$i]"}));
1302
1303    my $good = $opt{"BISECT_GOOD[$i]"};
1304    my $bad = $opt{"BISECT_BAD[$i]"};
1305    my $type = $opt{"BISECT_TYPE[$i]"};
1306    my $start = $opt{"BISECT_START[$i]"};
1307    my $replay = $opt{"BISECT_REPLAY[$i]"};
1308    my $start_files = $opt{"BISECT_FILES[$i]"};
1309
1310    if (defined($start_files)) {
1311	$start_files = " -- " . $start_files;
1312    } else {
1313	$start_files = "";
1314    }
1315
1316    # convert to true sha1's
1317    $good = get_sha1($good);
1318    $bad = get_sha1($bad);
1319
1320    if (defined($opt{"BISECT_REVERSE[$i]"}) &&
1321	$opt{"BISECT_REVERSE[$i]"} == 1) {
1322	doprint "Performing a reverse bisect (bad is good, good is bad!)\n";
1323	$reverse_bisect = 1;
1324    } else {
1325	$reverse_bisect = 0;
1326    }
1327
1328    # Can't have a test without having a test to run
1329    if ($type eq "test" && !defined($run_test)) {
1330	$type = "boot";
1331    }
1332
1333    my $check = $opt{"BISECT_CHECK[$i]"};
1334    if (defined($check) && $check ne "0") {
1335
1336	# get current HEAD
1337	my $head = get_sha1("HEAD");
1338
1339	if ($check ne "good") {
1340	    doprint "TESTING BISECT BAD [$bad]\n";
1341	    run_command "git checkout $bad" or
1342		die "Failed to checkout $bad";
1343
1344	    $result = run_bisect $type;
1345
1346	    if ($result ne "bad") {
1347		fail "Tested BISECT_BAD [$bad] and it succeeded" and return 0;
1348	    }
1349	}
1350
1351	if ($check ne "bad") {
1352	    doprint "TESTING BISECT GOOD [$good]\n";
1353	    run_command "git checkout $good" or
1354		die "Failed to checkout $good";
1355
1356	    $result = run_bisect $type;
1357
1358	    if ($result ne "good") {
1359		fail "Tested BISECT_GOOD [$good] and it failed" and return 0;
1360	    }
1361	}
1362
1363	# checkout where we started
1364	run_command "git checkout $head" or
1365	    die "Failed to checkout $head";
1366    }
1367
1368    run_command "git bisect start$start_files" or
1369	dodie "could not start bisect";
1370
1371    run_command "git bisect good $good" or
1372	dodie "could not set bisect good to $good";
1373
1374    run_git_bisect "git bisect bad $bad" or
1375	dodie "could not set bisect bad to $bad";
1376
1377    if (defined($replay)) {
1378	run_command "git bisect replay $replay" or
1379	    dodie "failed to run replay";
1380    }
1381
1382    if (defined($start)) {
1383	run_command "git checkout $start" or
1384	    dodie "failed to checkout $start";
1385    }
1386
1387    my $test;
1388    do {
1389	$result = run_bisect $type;
1390	$test = run_git_bisect "git bisect $result";
1391    } while ($test);
1392
1393    run_command "git bisect log" or
1394	dodie "could not capture git bisect log";
1395
1396    run_command "git bisect reset" or
1397	dodie "could not reset git bisect";
1398
1399    doprint "Bad commit was [$bisect_bad]\n";
1400
1401    success $i;
1402}
1403
1404my %config_ignore;
1405my %config_set;
1406
1407my %config_list;
1408my %null_config;
1409
1410my %dependency;
1411
1412sub process_config_ignore {
1413    my ($config) = @_;
1414
1415    open (IN, $config)
1416	or dodie "Failed to read $config";
1417
1418    while (<IN>) {
1419	if (/^(.*?(CONFIG\S*)(=.*| is not set))/) {
1420	    $config_ignore{$2} = $1;
1421	}
1422    }
1423
1424    close(IN);
1425}
1426
1427sub read_current_config {
1428    my ($config_ref) = @_;
1429
1430    %{$config_ref} = ();
1431    undef %{$config_ref};
1432
1433    my @key = keys %{$config_ref};
1434    if ($#key >= 0) {
1435	print "did not delete!\n";
1436	exit;
1437    }
1438    open (IN, "$output_config");
1439
1440    while (<IN>) {
1441	if (/^(CONFIG\S+)=(.*)/) {
1442	    ${$config_ref}{$1} = $2;
1443	}
1444    }
1445    close(IN);
1446}
1447
1448sub get_dependencies {
1449    my ($config) = @_;
1450
1451    my $arr = $dependency{$config};
1452    if (!defined($arr)) {
1453	return ();
1454    }
1455
1456    my @deps = @{$arr};
1457
1458    foreach my $dep (@{$arr}) {
1459	print "ADD DEP $dep\n";
1460	@deps = (@deps, get_dependencies $dep);
1461    }
1462
1463    return @deps;
1464}
1465
1466sub create_config {
1467    my @configs = @_;
1468
1469    open(OUT, ">$output_config") or dodie "Can not write to $output_config";
1470
1471    foreach my $config (@configs) {
1472	print OUT "$config_set{$config}\n";
1473	my @deps = get_dependencies $config;
1474	foreach my $dep (@deps) {
1475	    print OUT "$config_set{$dep}\n";
1476	}
1477    }
1478
1479    foreach my $config (keys %config_ignore) {
1480	print OUT "$config_ignore{$config}\n";
1481    }
1482    close(OUT);
1483
1484#    exit;
1485    make_oldconfig "";
1486}
1487
1488sub compare_configs {
1489    my (%a, %b) = @_;
1490
1491    foreach my $item (keys %a) {
1492	if (!defined($b{$item})) {
1493	    print "diff $item\n";
1494	    return 1;
1495	}
1496	delete $b{$item};
1497    }
1498
1499    my @keys = keys %b;
1500    if ($#keys) {
1501	print "diff2 $keys[0]\n";
1502    }
1503    return -1 if ($#keys >= 0);
1504
1505    return 0;
1506}
1507
1508sub run_config_bisect_test {
1509    my ($type) = @_;
1510
1511    return run_bisect_test $type, "oldconfig";
1512}
1513
1514sub process_passed {
1515    my (%configs) = @_;
1516
1517    doprint "These configs had no failure: (Enabling them for further compiles)\n";
1518    # Passed! All these configs are part of a good compile.
1519    # Add them to the min options.
1520    foreach my $config (keys %configs) {
1521	if (defined($config_list{$config})) {
1522	    doprint " removing $config\n";
1523	    $config_ignore{$config} = $config_list{$config};
1524	    delete $config_list{$config};
1525	}
1526    }
1527    doprint "config copied to $outputdir/config_good\n";
1528    run_command "cp -f $output_config $outputdir/config_good";
1529}
1530
1531sub process_failed {
1532    my ($config) = @_;
1533
1534    doprint "\n\n***************************************\n";
1535    doprint "Found bad config: $config\n";
1536    doprint "***************************************\n\n";
1537}
1538
1539sub run_config_bisect {
1540
1541    my @start_list = keys %config_list;
1542
1543    if ($#start_list < 0) {
1544	doprint "No more configs to test!!!\n";
1545	return -1;
1546    }
1547
1548    doprint "***** RUN TEST ***\n";
1549    my $type = $opt{"CONFIG_BISECT_TYPE[$iteration]"};
1550    my $ret;
1551    my %current_config;
1552
1553    my $count = $#start_list + 1;
1554    doprint "  $count configs to test\n";
1555
1556    my $half = int($#start_list / 2);
1557
1558    do {
1559	my @tophalf = @start_list[0 .. $half];
1560
1561	create_config @tophalf;
1562	read_current_config \%current_config;
1563
1564	$count = $#tophalf + 1;
1565	doprint "Testing $count configs\n";
1566	my $found = 0;
1567	# make sure we test something
1568	foreach my $config (@tophalf) {
1569	    if (defined($current_config{$config})) {
1570		logit " $config\n";
1571		$found = 1;
1572	    }
1573	}
1574	if (!$found) {
1575	    # try the other half
1576	    doprint "Top half produced no set configs, trying bottom half\n";
1577	    @tophalf = @start_list[$half .. $#start_list];
1578	    create_config @tophalf;
1579	    read_current_config \%current_config;
1580	    foreach my $config (@tophalf) {
1581		if (defined($current_config{$config})) {
1582		    logit " $config\n";
1583		    $found = 1;
1584		}
1585	    }
1586	    if (!$found) {
1587		doprint "Failed: Can't make new config with current configs\n";
1588		foreach my $config (@start_list) {
1589		    doprint "  CONFIG: $config\n";
1590		}
1591		return -1;
1592	    }
1593	    $count = $#tophalf + 1;
1594	    doprint "Testing $count configs\n";
1595	}
1596
1597	$ret = run_config_bisect_test $type;
1598	if ($bisect_manual) {
1599	    $ret = answer_bisect;
1600	}
1601	if ($ret) {
1602	    process_passed %current_config;
1603	    return 0;
1604	}
1605
1606	doprint "This config had a failure.\n";
1607	doprint "Removing these configs that were not set in this config:\n";
1608	doprint "config copied to $outputdir/config_bad\n";
1609	run_command "cp -f $output_config $outputdir/config_bad";
1610
1611	# A config exists in this group that was bad.
1612	foreach my $config (keys %config_list) {
1613	    if (!defined($current_config{$config})) {
1614		doprint " removing $config\n";
1615		delete $config_list{$config};
1616	    }
1617	}
1618
1619	@start_list = @tophalf;
1620
1621	if ($#start_list == 0) {
1622	    process_failed $start_list[0];
1623	    return 1;
1624	}
1625
1626	# remove half the configs we are looking at and see if
1627	# they are good.
1628	$half = int($#start_list / 2);
1629    } while ($half > 0);
1630
1631    # we found a single config, try it again unless we are running manually
1632
1633    if ($bisect_manual) {
1634	process_failed $start_list[0];
1635	return 1;
1636    }
1637
1638    my @tophalf = @start_list[0 .. 0];
1639
1640    $ret = run_config_bisect_test $type;
1641    if ($ret) {
1642	process_passed %current_config;
1643	return 0;
1644    }
1645
1646    process_failed $start_list[0];
1647    return 1;
1648}
1649
1650sub config_bisect {
1651    my ($i) = @_;
1652
1653    my $start_config = $opt{"CONFIG_BISECT[$i]"};
1654
1655    my $tmpconfig = "$tmpdir/use_config";
1656
1657    # Make the file with the bad config and the min config
1658    if (defined($minconfig)) {
1659	# read the min config for things to ignore
1660	run_command "cp $minconfig $tmpconfig" or
1661	    dodie "failed to copy $minconfig to $tmpconfig";
1662    } else {
1663	unlink $tmpconfig;
1664    }
1665
1666    # Add other configs
1667    if (defined($addconfig)) {
1668	run_command "cat $addconfig >> $tmpconfig" or
1669	    dodie "failed to append $addconfig";
1670    }
1671
1672    my $defconfig = "";
1673    if (-f $tmpconfig) {
1674	$defconfig = "KCONFIG_ALLCONFIG=$tmpconfig";
1675	process_config_ignore $tmpconfig;
1676    }
1677
1678    # now process the start config
1679    run_command "cp $start_config $output_config" or
1680	dodie "failed to copy $start_config to $output_config";
1681
1682    # read directly what we want to check
1683    my %config_check;
1684    open (IN, $output_config)
1685	or dodie "faied to open $output_config";
1686
1687    while (<IN>) {
1688	if (/^((CONFIG\S*)=.*)/) {
1689	    $config_check{$2} = $1;
1690	}
1691    }
1692    close(IN);
1693
1694    # Now run oldconfig with the minconfig (and addconfigs)
1695    make_oldconfig $defconfig;
1696
1697    # check to see what we lost (or gained)
1698    open (IN, $output_config)
1699	or dodie "Failed to read $start_config";
1700
1701    my %removed_configs;
1702    my %added_configs;
1703
1704    while (<IN>) {
1705	if (/^((CONFIG\S*)=.*)/) {
1706	    # save off all options
1707	    $config_set{$2} = $1;
1708	    if (defined($config_check{$2})) {
1709		if (defined($config_ignore{$2})) {
1710		    $removed_configs{$2} = $1;
1711		} else {
1712		    $config_list{$2} = $1;
1713		}
1714	    } elsif (!defined($config_ignore{$2})) {
1715		$added_configs{$2} = $1;
1716		$config_list{$2} = $1;
1717	    }
1718	}
1719    }
1720    close(IN);
1721
1722    my @confs = keys %removed_configs;
1723    if ($#confs >= 0) {
1724	doprint "Configs overridden by default configs and removed from check:\n";
1725	foreach my $config (@confs) {
1726	    doprint " $config\n";
1727	}
1728    }
1729    @confs = keys %added_configs;
1730    if ($#confs >= 0) {
1731	doprint "Configs appearing in make oldconfig and added:\n";
1732	foreach my $config (@confs) {
1733	    doprint " $config\n";
1734	}
1735    }
1736
1737    my %config_test;
1738    my $once = 0;
1739
1740    # Sometimes kconfig does weird things. We must make sure
1741    # that the config we autocreate has everything we need
1742    # to test, otherwise we may miss testing configs, or
1743    # may not be able to create a new config.
1744    # Here we create a config with everything set.
1745    create_config (keys %config_list);
1746    read_current_config \%config_test;
1747    foreach my $config (keys %config_list) {
1748	if (!defined($config_test{$config})) {
1749	    if (!$once) {
1750		$once = 1;
1751		doprint "Configs not produced by kconfig (will not be checked):\n";
1752	    }
1753	    doprint "  $config\n";
1754	    delete $config_list{$config};
1755	}
1756    }
1757    my $ret;
1758    do {
1759	$ret = run_config_bisect;
1760    } while (!$ret);
1761
1762    return $ret if ($ret < 0);
1763
1764    success $i;
1765}
1766
1767sub patchcheck {
1768    my ($i) = @_;
1769
1770    die "PATCHCHECK_START[$i] not defined\n"
1771	if (!defined($opt{"PATCHCHECK_START[$i]"}));
1772    die "PATCHCHECK_TYPE[$i] not defined\n"
1773	if (!defined($opt{"PATCHCHECK_TYPE[$i]"}));
1774
1775    my $start = $opt{"PATCHCHECK_START[$i]"};
1776
1777    my $end = "HEAD";
1778    if (defined($opt{"PATCHCHECK_END[$i]"})) {
1779	$end = $opt{"PATCHCHECK_END[$i]"};
1780    }
1781
1782    # Get the true sha1's since we can use things like HEAD~3
1783    $start = get_sha1($start);
1784    $end = get_sha1($end);
1785
1786    my $type = $opt{"PATCHCHECK_TYPE[$i]"};
1787
1788    # Can't have a test without having a test to run
1789    if ($type eq "test" && !defined($run_test)) {
1790	$type = "boot";
1791    }
1792
1793    open (IN, "git log --pretty=oneline $end|") or
1794	dodie "could not get git list";
1795
1796    my @list;
1797
1798    while (<IN>) {
1799	chomp;
1800	$list[$#list+1] = $_;
1801	last if (/^$start/);
1802    }
1803    close(IN);
1804
1805    if ($list[$#list] !~ /^$start/) {
1806	fail "SHA1 $start not found";
1807    }
1808
1809    # go backwards in the list
1810    @list = reverse @list;
1811
1812    my $save_clean = $noclean;
1813
1814    $in_patchcheck = 1;
1815    foreach my $item (@list) {
1816	my $sha1 = $item;
1817	$sha1 =~ s/^([[:xdigit:]]+).*/$1/;
1818
1819	doprint "\nProcessing commit $item\n\n";
1820
1821	run_command "git checkout $sha1" or
1822	    die "Failed to checkout $sha1";
1823
1824	# only clean on the first and last patch
1825	if ($item eq $list[0] ||
1826	    $item eq $list[$#list]) {
1827	    $noclean = $save_clean;
1828	} else {
1829	    $noclean = 1;
1830	}
1831
1832	if (defined($minconfig)) {
1833	    build "useconfig:$minconfig" or return 0;
1834	} else {
1835	    # ?? no config to use?
1836	    build "oldconfig" or return 0;
1837	}
1838
1839	check_buildlog $sha1 or return 0;
1840
1841	next if ($type eq "build");
1842
1843	get_grub_index;
1844	get_version;
1845	install;
1846
1847	my $failed = 0;
1848
1849	start_monitor;
1850	monitor or $failed = 1;
1851
1852	if (!$failed && $type ne "boot"){
1853	    do_run_test or $failed = 1;
1854	}
1855	end_monitor;
1856	return 0 if ($failed);
1857
1858    }
1859    $in_patchcheck = 0;
1860    success $i;
1861
1862    return 1;
1863}
1864
1865$#ARGV < 1 or die "ktest.pl version: $VERSION\n   usage: ktest.pl config-file\n";
1866
1867if ($#ARGV == 0) {
1868    $ktest_config = $ARGV[0];
1869    if (! -f $ktest_config) {
1870	print "$ktest_config does not exist.\n";
1871	my $ans;
1872        for (;;) {
1873	    print "Create it? [Y/n] ";
1874	    $ans = <STDIN>;
1875	    chomp $ans;
1876	    if ($ans =~ /^\s*$/) {
1877		$ans = "y";
1878	    }
1879	    last if ($ans =~ /^y$/i || $ans =~ /^n$/i);
1880	    print "Please answer either 'y' or 'n'.\n";
1881	}
1882	if ($ans !~ /^y$/i) {
1883	    exit 0;
1884	}
1885    }
1886} else {
1887    $ktest_config = "ktest.conf";
1888}
1889
1890if (! -f $ktest_config) {
1891    open(OUT, ">$ktest_config") or die "Can not create $ktest_config";
1892    print OUT << "EOF"
1893# Generated by ktest.pl
1894#
1895# Define each test with TEST_START
1896# The config options below it will override the defaults
1897TEST_START
1898
1899DEFAULTS
1900EOF
1901;
1902    close(OUT);
1903}
1904read_config $ktest_config;
1905
1906# Append any configs entered in manually to the config file.
1907my @new_configs = keys %entered_configs;
1908if ($#new_configs >= 0) {
1909    print "\nAppending entered in configs to $ktest_config\n";
1910    open(OUT, ">>$ktest_config") or die "Can not append to $ktest_config";
1911    foreach my $config (@new_configs) {
1912	print OUT "$config = $entered_configs{$config}\n";
1913	$opt{$config} = $entered_configs{$config};
1914    }
1915}
1916
1917if ($opt{"CLEAR_LOG"} && defined($opt{"LOG_FILE"})) {
1918    unlink $opt{"LOG_FILE"};
1919}
1920
1921doprint "\n\nSTARTING AUTOMATED TESTS\n\n";
1922
1923for (my $i = 0, my $repeat = 1; $i <= $opt{"NUM_TESTS"}; $i += $repeat) {
1924
1925    if (!$i) {
1926	doprint "DEFAULT OPTIONS:\n";
1927    } else {
1928	doprint "\nTEST $i OPTIONS";
1929	if (defined($repeat_tests{$i})) {
1930	    $repeat = $repeat_tests{$i};
1931	    doprint " ITERATE $repeat";
1932	}
1933	doprint "\n";
1934    }
1935
1936    foreach my $option (sort keys %opt) {
1937
1938	if ($option =~ /\[(\d+)\]$/) {
1939	    next if ($i != $1);
1940	} else {
1941	    next if ($i);
1942	}
1943
1944	doprint "$option = $opt{$option}\n";
1945    }
1946}
1947
1948sub set_test_option {
1949    my ($name, $i) = @_;
1950
1951    my $option = "$name\[$i\]";
1952
1953    if (defined($opt{$option})) {
1954	return $opt{$option};
1955    }
1956
1957    foreach my $test (keys %repeat_tests) {
1958	if ($i >= $test &&
1959	    $i < $test + $repeat_tests{$test}) {
1960	    $option = "$name\[$test\]";
1961	    if (defined($opt{$option})) {
1962		return $opt{$option};
1963	    }
1964	}
1965    }
1966
1967    if (defined($opt{$name})) {
1968	return $opt{$name};
1969    }
1970
1971    return undef;
1972}
1973
1974# First we need to do is the builds
1975for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
1976
1977    $iteration = $i;
1978
1979    my $makecmd = set_test_option("MAKE_CMD", $i);
1980
1981    $machine = set_test_option("MACHINE", $i);
1982    $ssh_user = set_test_option("SSH_USER", $i);
1983    $tmpdir = set_test_option("TMP_DIR", $i);
1984    $outputdir = set_test_option("OUTPUT_DIR", $i);
1985    $builddir = set_test_option("BUILD_DIR", $i);
1986    $test_type = set_test_option("TEST_TYPE", $i);
1987    $build_type = set_test_option("BUILD_TYPE", $i);
1988    $build_options = set_test_option("BUILD_OPTIONS", $i);
1989    $power_cycle = set_test_option("POWER_CYCLE", $i);
1990    $reboot = set_test_option("REBOOT", $i);
1991    $noclean = set_test_option("BUILD_NOCLEAN", $i);
1992    $minconfig = set_test_option("MIN_CONFIG", $i);
1993    $run_test = set_test_option("TEST", $i);
1994    $addconfig = set_test_option("ADD_CONFIG", $i);
1995    $reboot_type = set_test_option("REBOOT_TYPE", $i);
1996    $grub_menu = set_test_option("GRUB_MENU", $i);
1997    $post_install = set_test_option("POST_INSTALL", $i);
1998    $reboot_script = set_test_option("REBOOT_SCRIPT", $i);
1999    $reboot_on_error = set_test_option("REBOOT_ON_ERROR", $i);
2000    $poweroff_on_error = set_test_option("POWEROFF_ON_ERROR", $i);
2001    $die_on_failure = set_test_option("DIE_ON_FAILURE", $i);
2002    $power_off = set_test_option("POWER_OFF", $i);
2003    $powercycle_after_reboot = set_test_option("POWERCYCLE_AFTER_REBOOT", $i);
2004    $poweroff_after_halt = set_test_option("POWEROFF_AFTER_HALT", $i);
2005    $sleep_time = set_test_option("SLEEP_TIME", $i);
2006    $bisect_sleep_time = set_test_option("BISECT_SLEEP_TIME", $i);
2007    $bisect_manual = set_test_option("BISECT_MANUAL", $i);
2008    $bisect_skip = set_test_option("BISECT_SKIP", $i);
2009    $store_failures = set_test_option("STORE_FAILURES", $i);
2010    $timeout = set_test_option("TIMEOUT", $i);
2011    $booted_timeout = set_test_option("BOOTED_TIMEOUT", $i);
2012    $console = set_test_option("CONSOLE", $i);
2013    $success_line = set_test_option("SUCCESS_LINE", $i);
2014    $stop_after_success = set_test_option("STOP_AFTER_SUCCESS", $i);
2015    $stop_after_failure = set_test_option("STOP_AFTER_FAILURE", $i);
2016    $stop_test_after = set_test_option("STOP_TEST_AFTER", $i);
2017    $build_target = set_test_option("BUILD_TARGET", $i);
2018    $ssh_exec = set_test_option("SSH_EXEC", $i);
2019    $scp_to_target = set_test_option("SCP_TO_TARGET", $i);
2020    $target_image = set_test_option("TARGET_IMAGE", $i);
2021    $localversion = set_test_option("LOCALVERSION", $i);
2022
2023    chdir $builddir || die "can't change directory to $builddir";
2024
2025    if (!-d $tmpdir) {
2026	mkpath($tmpdir) or
2027	    die "can't create $tmpdir";
2028    }
2029
2030    $ENV{"SSH_USER"} = $ssh_user;
2031    $ENV{"MACHINE"} = $machine;
2032
2033    $target = "$ssh_user\@$machine";
2034
2035    $buildlog = "$tmpdir/buildlog-$machine";
2036    $dmesg = "$tmpdir/dmesg-$machine";
2037    $make = "$makecmd O=$outputdir";
2038    $output_config = "$outputdir/.config";
2039
2040    if ($reboot_type eq "grub") {
2041	dodie "GRUB_MENU not defined" if (!defined($grub_menu));
2042    } elsif (!defined($reboot_script)) {
2043	dodie "REBOOT_SCRIPT not defined"
2044    }
2045
2046    my $run_type = $build_type;
2047    if ($test_type eq "patchcheck") {
2048	$run_type = $opt{"PATCHCHECK_TYPE[$i]"};
2049    } elsif ($test_type eq "bisect") {
2050	$run_type = $opt{"BISECT_TYPE[$i]"};
2051    } elsif ($test_type eq "config_bisect") {
2052	$run_type = $opt{"CONFIG_BISECT_TYPE[$i]"};
2053    }
2054
2055    # mistake in config file?
2056    if (!defined($run_type)) {
2057	$run_type = "ERROR";
2058    }
2059
2060    doprint "\n\n";
2061    doprint "RUNNING TEST $i of $opt{NUM_TESTS} with option $test_type $run_type\n\n";
2062
2063    unlink $dmesg;
2064    unlink $buildlog;
2065
2066    if (!defined($minconfig)) {
2067	$minconfig = $addconfig;
2068
2069    } elsif (defined($addconfig)) {
2070	run_command "cat $addconfig $minconfig > $tmpdir/add_config" or
2071	    dodie "Failed to create temp config";
2072	$minconfig = "$tmpdir/add_config";
2073    }
2074
2075    my $checkout = $opt{"CHECKOUT[$i]"};
2076    if (defined($checkout)) {
2077	run_command "git checkout $checkout" or
2078	    die "failed to checkout $checkout";
2079    }
2080
2081    if ($test_type eq "bisect") {
2082	bisect $i;
2083	next;
2084    } elsif ($test_type eq "config_bisect") {
2085	config_bisect $i;
2086	next;
2087    } elsif ($test_type eq "patchcheck") {
2088	patchcheck $i;
2089	next;
2090    }
2091
2092    if ($build_type ne "nobuild") {
2093	build $build_type or next;
2094    }
2095
2096    if ($test_type ne "build") {
2097	get_grub_index;
2098	get_version;
2099	install;
2100
2101	my $failed = 0;
2102	start_monitor;
2103	monitor or $failed = 1;;
2104
2105	if (!$failed && $test_type ne "boot" && defined($run_test)) {
2106	    do_run_test or $failed = 1;
2107	}
2108	end_monitor;
2109	next if ($failed);
2110    }
2111
2112    success $i;
2113}
2114
2115if ($opt{"POWEROFF_ON_SUCCESS"}) {
2116    halt;
2117} elsif ($opt{"REBOOT_ON_SUCCESS"} && !do_not_reboot) {
2118    reboot;
2119}
2120
2121doprint "\n    $successes of $opt{NUM_TESTS} tests were successful\n\n";
2122
2123exit 0;
2124