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