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