]> git.karo-electronics.de Git - mv-sheeva.git/blob - tools/testing/ktest/ktest.pl
ktest: Reboot to good kernel after every bisect run
[mv-sheeva.git] / tools / testing / ktest / ktest.pl
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
7 use strict;
8 use IPC::Open2;
9 use Fcntl qw(F_GETFL F_SETFL O_NONBLOCK);
10 use File::Path qw(mkpath);
11 use File::Copy qw(cp);
12 use FileHandle;
13
14 my $VERSION = "0.2";
15
16 $| = 1;
17
18 my %opt;
19 my %repeat_tests;
20 my %repeats;
21 my %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
53 my $ktest_config;
54 my $version;
55 my $machine;
56 my $ssh_user;
57 my $tmpdir;
58 my $builddir;
59 my $outputdir;
60 my $output_config;
61 my $test_type;
62 my $build_type;
63 my $build_options;
64 my $reboot_type;
65 my $reboot_script;
66 my $power_cycle;
67 my $reboot;
68 my $reboot_on_error;
69 my $poweroff_on_error;
70 my $die_on_failure;
71 my $powercycle_after_reboot;
72 my $poweroff_after_halt;
73 my $ssh_exec;
74 my $scp_to_target;
75 my $power_off;
76 my $grub_menu;
77 my $grub_number;
78 my $target;
79 my $make;
80 my $post_install;
81 my $noclean;
82 my $minconfig;
83 my $addconfig;
84 my $in_bisect = 0;
85 my $bisect_bad = "";
86 my $reverse_bisect;
87 my $bisect_manual;
88 my $bisect_skip;
89 my $in_patchcheck = 0;
90 my $run_test;
91 my $redirect;
92 my $buildlog;
93 my $dmesg;
94 my $monitor_fp;
95 my $monitor_pid;
96 my $monitor_cnt = 0;
97 my $sleep_time;
98 my $bisect_sleep_time;
99 my $store_failures;
100 my $timeout;
101 my $booted_timeout;
102 my $console;
103 my $success_line;
104 my $stop_after_success;
105 my $stop_after_failure;
106 my $stop_test_after;
107 my $build_target;
108 my $target_image;
109 my $localversion;
110 my $iteration = 0;
111 my $successes = 0;
112
113 my %entered_configs;
114 my %config_help;
115
116 $config_help{"MACHINE"} = << "EOF"
117  The machine hostname that you will test.
118 EOF
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)
123 EOF
124     ;
125 $config_help{"BUILD_DIR"} = << "EOF"
126  The directory that contains the Linux source code (full path).
127 EOF
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)
132 EOF
133     ;
134 $config_help{"BUILD_TARGET"} = << "EOF"
135  The location of the compiled file to copy to the target.
136  (relative to OUTPUT_DIR)
137 EOF
138     ;
139 $config_help{"TARGET_IMAGE"} = << "EOF"
140  The place to put your image on the test machine.
141 EOF
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
152 EOF
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.
158 CONSOLE = nc -d localhost 3001
159
160  For a virtual machine with guest name "Guest".
161 CONSOLE =  virsh console Guest
162 EOF
163     ;
164 $config_help{"LOCALVERSION"} = << "EOF"
165  Required version ending to differentiate the test
166  from other linux builds on the system.
167 EOF
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.
181 EOF
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
196 EOF
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)
201 EOF
202     ;
203
204
205 sub 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
234 sub 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
263 sub 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
276 sub 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
412 sub _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
420 sub logit {
421     if (defined($opt{"LOG_FILE"})) {
422         _logit @_;
423     } else {
424         print @_;
425     }
426 }
427
428 sub doprint {
429     print @_;
430     _logit @_;
431 }
432
433 sub run_command;
434
435 sub 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
448 sub 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
456 sub 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
478 sub 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
494 sub 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
504 sub 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
516 sub end_monitor {
517     if (--$monitor_cnt) {
518         return;
519     }
520     close_console($monitor_fp, $monitor_pid);
521 }
522
523 sub 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
537 sub 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
598 sub 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
645 sub 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
653 sub 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
663 sub 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
694 sub 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
725 sub 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
734 sub 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
755 sub 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
862 sub 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
916 sub 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
948 sub 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
960 sub 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
1024 sub 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
1036 sub 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
1056 sub 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
1064 sub 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
1079 sub 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
1091 my $child_done;
1092
1093 sub child_finished {
1094     $child_done = 1;
1095 }
1096
1097 sub 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
1169 sub 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
1199 sub 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
1208 sub 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
1264 sub 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
1294 sub 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
1404 my %config_ignore;
1405 my %config_set;
1406
1407 my %config_list;
1408 my %null_config;
1409
1410 my %dependency;
1411
1412 sub 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
1427 sub 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
1448 sub 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
1466 sub 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
1488 sub 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
1508 sub run_config_bisect_test {
1509     my ($type) = @_;
1510
1511     return run_bisect_test $type, "oldconfig";
1512 }
1513
1514 sub 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
1531 sub process_failed {
1532     my ($config) = @_;
1533
1534     doprint "\n\n***************************************\n";
1535     doprint "Found bad config: $config\n";
1536     doprint "***************************************\n\n";
1537 }
1538
1539 sub 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
1650 sub 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
1767 sub 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
1867 if ($#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
1890 if (! -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
1897 TEST_START
1898
1899 DEFAULTS
1900 EOF
1901 ;
1902     close(OUT);
1903 }
1904 read_config $ktest_config;
1905
1906 # Append any configs entered in manually to the config file.
1907 my @new_configs = keys %entered_configs;
1908 if ($#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
1917 if ($opt{"CLEAR_LOG"} && defined($opt{"LOG_FILE"})) {
1918     unlink $opt{"LOG_FILE"};
1919 }
1920
1921 doprint "\n\nSTARTING AUTOMATED TESTS\n\n";
1922
1923 for (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
1948 sub 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
1975 for (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
2115 if ($opt{"POWEROFF_ON_SUCCESS"}) {
2116     halt;
2117 } elsif ($opt{"REBOOT_ON_SUCCESS"} && !do_not_reboot) {
2118     reboot;
2119 }
2120
2121 doprint "\n    $successes of $opt{NUM_TESTS} tests were successful\n\n";
2122
2123 exit 0;