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