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