Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/roland...
[zen-stable.git] / tools / testing / ktest / ktest.pl
blob8b4c2535b266a2abe17d3ad495b3a0fdfa8855a9
1 #!/usr/bin/perl -w
3 # Copyright 2010 - Steven Rostedt <srostedt@redhat.com>, Red Hat Inc.
4 # Licensed under the terms of the GNU GPL License version 2
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;
14 my $VERSION = "0.2";
16 $| = 1;
18 my %opt;
19 my %repeat_tests;
20 my %repeats;
21 my %default;
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";
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;
131 my %entered_configs;
132 my %config_help;
133 my %variable;
134 my %force_config;
136 # do not force reboots on config problems
137 my $no_reboot = 1;
139 # default variables that can be used
140 chomp ($variable{"PWD"} = `pwd`);
142 $config_help{"MACHINE"} = << "EOF"
143 The machine hostname that you will test.
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)
151 $config_help{"BUILD_DIR"} = << "EOF"
152 The directory that contains the Linux source code (full path).
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)
160 $config_help{"BUILD_TARGET"} = << "EOF"
161 The location of the compiled file to copy to the target.
162 (relative to OUTPUT_DIR)
165 $config_help{"TARGET_IMAGE"} = << "EOF"
166 The place to put your image on the test machine.
169 $config_help{"POWER_CYCLE"} = << "EOF"
170 A script or command to reboot the box.
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'
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
180 $config_help{"CONSOLE"} = << "EOF"
181 The script or command that reads the console
183 If you use ttywatch server, something like the following would work.
184 CONSOLE = nc -d localhost 3001
186 For a virtual machine with guest name "Guest".
187 CONSOLE = virsh console Guest
190 $config_help{"LOCALVERSION"} = << "EOF"
191 Required version ending to differentiate the test
192 from other linux builds on the system.
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".
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.
205 The entry in /boot/grub/menu.lst must be entered in manually.
206 The test will not modify that file.
209 $config_help{"GRUB_MENU"} = << "EOF"
210 The grub title name for the test kernel to boot
211 (Only mandatory if REBOOT_TYPE = grub)
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.
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
224 $config_help{"REBOOT_SCRIPT"} = << "EOF"
225 A script to reboot the target into the test kernel
226 (Only mandatory if REBOOT_TYPE = script)
230 sub read_yn {
231 my ($prompt) = @_;
233 my $ans;
235 for (;;) {
236 print "$prompt [Y/n] ";
237 $ans = <STDIN>;
238 chomp $ans;
239 if ($ans =~ /^\s*$/) {
240 $ans = "y";
242 last if ($ans =~ /^y$/i || $ans =~ /^n$/i);
243 print "Please answer either 'y' or 'n'.\n";
245 if ($ans !~ /^y$/i) {
246 return 0;
248 return 1;
251 sub get_ktest_config {
252 my ($config) = @_;
253 my $ans;
255 return if (defined($opt{$config}));
257 if (defined($config_help{$config})) {
258 print "\n";
259 print $config_help{$config};
262 for (;;) {
263 print "$config = ";
264 if (defined($default{$config})) {
265 print "\[$default{$config}\] ";
267 $ans = <STDIN>;
268 $ans =~ s/^\s*(.*\S)\s*$/$1/;
269 if ($ans =~ /^\s*$/) {
270 if ($default{$config}) {
271 $ans = $default{$config};
272 } else {
273 print "Your answer can not be blank\n";
274 next;
277 $entered_configs{$config} = process_variables($ans);
278 last;
282 sub get_ktest_configs {
283 get_ktest_config("MACHINE");
284 get_ktest_config("SSH_USER");
285 get_ktest_config("BUILD_DIR");
286 get_ktest_config("OUTPUT_DIR");
287 get_ktest_config("BUILD_TARGET");
288 get_ktest_config("TARGET_IMAGE");
289 get_ktest_config("POWER_CYCLE");
290 get_ktest_config("CONSOLE");
291 get_ktest_config("LOCALVERSION");
293 my $rtype = $opt{"REBOOT_TYPE"};
295 if (!defined($rtype)) {
296 if (!defined($opt{"GRUB_MENU"})) {
297 get_ktest_config("REBOOT_TYPE");
298 $rtype = $entered_configs{"REBOOT_TYPE"};
299 } else {
300 $rtype = "grub";
304 if ($rtype eq "grub") {
305 get_ktest_config("GRUB_MENU");
306 } else {
307 get_ktest_config("REBOOT_SCRIPT");
311 sub process_variables {
312 my ($value, $remove_undef) = @_;
313 my $retval = "";
315 # We want to check for '\', and it is just easier
316 # to check the previous characet of '$' and not need
317 # to worry if '$' is the first character. By adding
318 # a space to $value, we can just check [^\\]\$ and
319 # it will still work.
320 $value = " $value";
322 while ($value =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) {
323 my $begin = $1;
324 my $var = $2;
325 my $end = $3;
326 # append beginning of value to retval
327 $retval = "$retval$begin";
328 if (defined($variable{$var})) {
329 $retval = "$retval$variable{$var}";
330 } elsif (defined($remove_undef) && $remove_undef) {
331 # for if statements, any variable that is not defined,
332 # we simple convert to 0
333 $retval = "${retval}0";
334 } else {
335 # put back the origin piece.
336 $retval = "$retval\$\{$var\}";
338 $value = $end;
340 $retval = "$retval$value";
342 # remove the space added in the beginning
343 $retval =~ s/ //;
345 return "$retval"
348 sub set_value {
349 my ($lvalue, $rvalue, $override, $overrides, $name) = @_;
351 if (defined($opt{$lvalue})) {
352 if (!$override || defined(${$overrides}{$lvalue})) {
353 my $extra = "";
354 if ($override) {
355 $extra = "In the same override section!\n";
357 die "$name: $.: Option $lvalue defined more than once!\n$extra";
359 ${$overrides}{$lvalue} = $rvalue;
361 if ($rvalue =~ /^\s*$/) {
362 delete $opt{$lvalue};
363 } else {
364 $rvalue = process_variables($rvalue);
365 $opt{$lvalue} = $rvalue;
369 sub set_variable {
370 my ($lvalue, $rvalue) = @_;
372 if ($rvalue =~ /^\s*$/) {
373 delete $variable{$lvalue};
374 } else {
375 $rvalue = process_variables($rvalue);
376 $variable{$lvalue} = $rvalue;
380 sub process_compare {
381 my ($lval, $cmp, $rval) = @_;
383 # remove whitespace
385 $lval =~ s/^\s*//;
386 $lval =~ s/\s*$//;
388 $rval =~ s/^\s*//;
389 $rval =~ s/\s*$//;
391 if ($cmp eq "==") {
392 return $lval eq $rval;
393 } elsif ($cmp eq "!=") {
394 return $lval ne $rval;
397 my $statement = "$lval $cmp $rval";
398 my $ret = eval $statement;
400 # $@ stores error of eval
401 if ($@) {
402 return -1;
405 return $ret;
408 sub value_defined {
409 my ($val) = @_;
411 return defined($variable{$2}) ||
412 defined($opt{$2});
415 my $d = 0;
416 sub process_expression {
417 my ($name, $val) = @_;
419 my $c = $d++;
421 while ($val =~ s/\(([^\(]*?)\)/\&\&\&\&VAL\&\&\&\&/) {
422 my $express = $1;
424 if (process_expression($name, $express)) {
425 $val =~ s/\&\&\&\&VAL\&\&\&\&/ 1 /;
426 } else {
427 $val =~ s/\&\&\&\&VAL\&\&\&\&/ 0 /;
431 $d--;
432 my $OR = "\\|\\|";
433 my $AND = "\\&\\&";
435 while ($val =~ s/^(.*?)($OR|$AND)//) {
436 my $express = $1;
437 my $op = $2;
439 if (process_expression($name, $express)) {
440 if ($op eq "||") {
441 return 1;
443 } else {
444 if ($op eq "&&") {
445 return 0;
450 if ($val =~ /(.*)(==|\!=|>=|<=|>|<)(.*)/) {
451 my $ret = process_compare($1, $2, $3);
452 if ($ret < 0) {
453 die "$name: $.: Unable to process comparison\n";
455 return $ret;
458 if ($val =~ /^\s*(NOT\s*)?DEFINED\s+(\S+)\s*$/) {
459 if (defined $1) {
460 return !value_defined($2);
461 } else {
462 return value_defined($2);
466 if ($val =~ /^\s*0\s*$/) {
467 return 0;
468 } elsif ($val =~ /^\s*\d+\s*$/) {
469 return 1;
472 die ("$name: $.: Undefined content $val in if statement\n");
475 sub process_if {
476 my ($name, $value) = @_;
478 # Convert variables and replace undefined ones with 0
479 my $val = process_variables($value, 1);
480 my $ret = process_expression $name, $val;
482 return $ret;
485 sub __read_config {
486 my ($config, $current_test_num) = @_;
488 my $in;
489 open($in, $config) || die "can't read file $config";
491 my $name = $config;
492 $name =~ s,.*/(.*),$1,;
494 my $test_num = $$current_test_num;
495 my $default = 1;
496 my $repeat = 1;
497 my $num_tests_set = 0;
498 my $skip = 0;
499 my $rest;
500 my $line;
501 my $test_case = 0;
502 my $if = 0;
503 my $if_set = 0;
504 my $override = 0;
506 my %overrides;
508 while (<$in>) {
510 # ignore blank lines and comments
511 next if (/^\s*$/ || /\s*\#/);
513 if (/^\s*(TEST_START|DEFAULTS)\b(.*)/) {
515 my $type = $1;
516 $rest = $2;
517 $line = $2;
519 my $old_test_num;
520 my $old_repeat;
521 $override = 0;
523 if ($type eq "TEST_START") {
525 if ($num_tests_set) {
526 die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
529 $old_test_num = $test_num;
530 $old_repeat = $repeat;
532 $test_num += $repeat;
533 $default = 0;
534 $repeat = 1;
535 } else {
536 $default = 1;
539 # If SKIP is anywhere in the line, the command will be skipped
540 if ($rest =~ s/\s+SKIP\b//) {
541 $skip = 1;
542 } else {
543 $test_case = 1;
544 $skip = 0;
547 if ($rest =~ s/\sELSE\b//) {
548 if (!$if) {
549 die "$name: $.: ELSE found with out matching IF section\n$_";
551 $if = 0;
553 if ($if_set) {
554 $skip = 1;
555 } else {
556 $skip = 0;
560 if ($rest =~ s/\sIF\s+(.*)//) {
561 if (process_if($name, $1)) {
562 $if_set = 1;
563 } else {
564 $skip = 1;
566 $if = 1;
567 } else {
568 $if = 0;
569 $if_set = 0;
572 if (!$skip) {
573 if ($type eq "TEST_START") {
574 if ($rest =~ s/\s+ITERATE\s+(\d+)//) {
575 $repeat = $1;
576 $repeat_tests{"$test_num"} = $repeat;
578 } elsif ($rest =~ s/\sOVERRIDE\b//) {
579 # DEFAULT only
580 $override = 1;
581 # Clear previous overrides
582 %overrides = ();
586 if (!$skip && $rest !~ /^\s*$/) {
587 die "$name: $.: Gargbage found after $type\n$_";
590 if ($skip && $type eq "TEST_START") {
591 $test_num = $old_test_num;
592 $repeat = $old_repeat;
595 } elsif (/^\s*ELSE\b(.*)$/) {
596 if (!$if) {
597 die "$name: $.: ELSE found with out matching IF section\n$_";
599 $rest = $1;
600 if ($if_set) {
601 $skip = 1;
602 $rest = "";
603 } else {
604 $skip = 0;
606 if ($rest =~ /\sIF\s+(.*)/) {
607 # May be a ELSE IF section.
608 if (!process_if($name, $1)) {
609 $skip = 1;
611 $rest = "";
612 } else {
613 $if = 0;
617 if ($rest !~ /^\s*$/) {
618 die "$name: $.: Gargbage found after DEFAULTS\n$_";
621 } elsif (/^\s*INCLUDE\s+(\S+)/) {
623 next if ($skip);
625 if (!$default) {
626 die "$name: $.: INCLUDE can only be done in default sections\n$_";
629 my $file = process_variables($1);
631 if ($file !~ m,^/,) {
632 # check the path of the config file first
633 if ($config =~ m,(.*)/,) {
634 if (-f "$1/$file") {
635 $file = "$1/$file";
640 if ( ! -r $file ) {
641 die "$name: $.: Can't read file $file\n$_";
644 if (__read_config($file, \$test_num)) {
645 $test_case = 1;
648 } elsif (/^\s*([A-Z_\[\]\d]+)\s*=\s*(.*?)\s*$/) {
650 next if ($skip);
652 my $lvalue = $1;
653 my $rvalue = $2;
655 if (!$default &&
656 ($lvalue eq "NUM_TESTS" ||
657 $lvalue eq "LOG_FILE" ||
658 $lvalue eq "CLEAR_LOG")) {
659 die "$name: $.: $lvalue must be set in DEFAULTS section\n";
662 if ($lvalue eq "NUM_TESTS") {
663 if ($test_num) {
664 die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
666 if (!$default) {
667 die "$name: $.: NUM_TESTS must be set in default section\n";
669 $num_tests_set = 1;
672 if ($default || $lvalue =~ /\[\d+\]$/) {
673 set_value($lvalue, $rvalue, $override, \%overrides, $name);
674 } else {
675 my $val = "$lvalue\[$test_num\]";
676 set_value($val, $rvalue, $override, \%overrides, $name);
678 if ($repeat > 1) {
679 $repeats{$val} = $repeat;
682 } elsif (/^\s*([A-Z_\[\]\d]+)\s*:=\s*(.*?)\s*$/) {
683 next if ($skip);
685 my $lvalue = $1;
686 my $rvalue = $2;
688 # process config variables.
689 # Config variables are only active while reading the
690 # config and can be defined anywhere. They also ignore
691 # TEST_START and DEFAULTS, but are skipped if they are in
692 # on of these sections that have SKIP defined.
693 # The save variable can be
694 # defined multiple times and the new one simply overrides
695 # the prevous one.
696 set_variable($lvalue, $rvalue);
698 } else {
699 die "$name: $.: Garbage found in config\n$_";
703 if ($test_num) {
704 $test_num += $repeat - 1;
705 $opt{"NUM_TESTS"} = $test_num;
708 close($in);
710 $$current_test_num = $test_num;
712 return $test_case;
715 sub read_config {
716 my ($config) = @_;
718 my $test_case;
719 my $test_num = 0;
721 $test_case = __read_config $config, \$test_num;
723 # make sure we have all mandatory configs
724 get_ktest_configs;
726 # was a test specified?
727 if (!$test_case) {
728 print "No test case specified.\n";
729 print "What test case would you like to run?\n";
730 my $ans = <STDIN>;
731 chomp $ans;
732 $default{"TEST_TYPE"} = $ans;
735 # set any defaults
737 foreach my $default (keys %default) {
738 if (!defined($opt{$default})) {
739 $opt{$default} = $default{$default};
744 sub __eval_option {
745 my ($option, $i) = @_;
747 # Add space to evaluate the character before $
748 $option = " $option";
749 my $retval = "";
750 my $repeated = 0;
751 my $parent = 0;
753 foreach my $test (keys %repeat_tests) {
754 if ($i >= $test &&
755 $i < $test + $repeat_tests{$test}) {
757 $repeated = 1;
758 $parent = $test;
759 last;
763 while ($option =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) {
764 my $start = $1;
765 my $var = $2;
766 my $end = $3;
768 # Append beginning of line
769 $retval = "$retval$start";
771 # If the iteration option OPT[$i] exists, then use that.
772 # otherwise see if the default OPT (without [$i]) exists.
774 my $o = "$var\[$i\]";
775 my $parento = "$var\[$parent\]";
777 if (defined($opt{$o})) {
778 $o = $opt{$o};
779 $retval = "$retval$o";
780 } elsif ($repeated && defined($opt{$parento})) {
781 $o = $opt{$parento};
782 $retval = "$retval$o";
783 } elsif (defined($opt{$var})) {
784 $o = $opt{$var};
785 $retval = "$retval$o";
786 } else {
787 $retval = "$retval\$\{$var\}";
790 $option = $end;
793 $retval = "$retval$option";
795 $retval =~ s/^ //;
797 return $retval;
800 sub eval_option {
801 my ($option, $i) = @_;
803 my $prev = "";
805 # Since an option can evaluate to another option,
806 # keep iterating until we do not evaluate any more
807 # options.
808 my $r = 0;
809 while ($prev ne $option) {
810 # Check for recursive evaluations.
811 # 100 deep should be more than enough.
812 if ($r++ > 100) {
813 die "Over 100 evaluations accurred with $option\n" .
814 "Check for recursive variables\n";
816 $prev = $option;
817 $option = __eval_option($option, $i);
820 return $option;
823 sub _logit {
824 if (defined($opt{"LOG_FILE"})) {
825 open(OUT, ">> $opt{LOG_FILE}") or die "Can't write to $opt{LOG_FILE}";
826 print OUT @_;
827 close(OUT);
831 sub logit {
832 if (defined($opt{"LOG_FILE"})) {
833 _logit @_;
834 } else {
835 print @_;
839 sub doprint {
840 print @_;
841 _logit @_;
844 sub run_command;
845 sub start_monitor;
846 sub end_monitor;
847 sub wait_for_monitor;
849 sub reboot {
850 my ($time) = @_;
852 if (defined($time)) {
853 start_monitor;
854 # flush out current monitor
855 # May contain the reboot success line
856 wait_for_monitor 1;
859 # try to reboot normally
860 if (run_command $reboot) {
861 if (defined($powercycle_after_reboot)) {
862 sleep $powercycle_after_reboot;
863 run_command "$power_cycle";
865 } else {
866 # nope? power cycle it.
867 run_command "$power_cycle";
870 if (defined($time)) {
871 wait_for_monitor($time, $reboot_success_line);
872 end_monitor;
876 sub do_not_reboot {
877 my $i = $iteration;
879 return $test_type eq "build" || $no_reboot ||
880 ($test_type eq "patchcheck" && $opt{"PATCHCHECK_TYPE[$i]"} eq "build") ||
881 ($test_type eq "bisect" && $opt{"BISECT_TYPE[$i]"} eq "build");
884 sub dodie {
885 doprint "CRITICAL FAILURE... ", @_, "\n";
887 my $i = $iteration;
889 if ($reboot_on_error && !do_not_reboot) {
891 doprint "REBOOTING\n";
892 reboot;
894 } elsif ($poweroff_on_error && defined($power_off)) {
895 doprint "POWERING OFF\n";
896 `$power_off`;
899 if (defined($opt{"LOG_FILE"})) {
900 print " See $opt{LOG_FILE} for more info.\n";
903 die @_, "\n";
906 sub open_console {
907 my ($fp) = @_;
909 my $flags;
911 my $pid = open($fp, "$console|") or
912 dodie "Can't open console $console";
914 $flags = fcntl($fp, F_GETFL, 0) or
915 dodie "Can't get flags for the socket: $!";
916 $flags = fcntl($fp, F_SETFL, $flags | O_NONBLOCK) or
917 dodie "Can't set flags for the socket: $!";
919 return $pid;
922 sub close_console {
923 my ($fp, $pid) = @_;
925 doprint "kill child process $pid\n";
926 kill 2, $pid;
928 print "closing!\n";
929 close($fp);
932 sub start_monitor {
933 if ($monitor_cnt++) {
934 return;
936 $monitor_fp = \*MONFD;
937 $monitor_pid = open_console $monitor_fp;
939 return;
941 open(MONFD, "Stop perl from warning about single use of MONFD");
944 sub end_monitor {
945 if (--$monitor_cnt) {
946 return;
948 close_console($monitor_fp, $monitor_pid);
951 sub wait_for_monitor {
952 my ($time, $stop) = @_;
953 my $full_line = "";
954 my $line;
955 my $booted = 0;
957 doprint "** Wait for monitor to settle down **\n";
959 # read the monitor and wait for the system to calm down
960 while (!$booted) {
961 $line = wait_for_input($monitor_fp, $time);
962 last if (!defined($line));
963 print "$line";
964 $full_line .= $line;
966 if (defined($stop) && $full_line =~ /$stop/) {
967 doprint "wait for monitor detected $stop\n";
968 $booted = 1;
971 if ($line =~ /\n/) {
972 $full_line = "";
975 print "** Monitor flushed **\n";
978 sub fail {
980 if ($die_on_failure) {
981 dodie @_;
984 doprint "FAILED\n";
986 my $i = $iteration;
988 # no need to reboot for just building.
989 if (!do_not_reboot) {
990 doprint "REBOOTING\n";
991 reboot $sleep_time;
994 my $name = "";
996 if (defined($test_name)) {
997 $name = " ($test_name)";
1000 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
1001 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
1002 doprint "KTEST RESULT: TEST $i$name Failed: ", @_, "\n";
1003 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
1004 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
1006 return 1 if (!defined($store_failures));
1008 my @t = localtime;
1009 my $date = sprintf "%04d%02d%02d%02d%02d%02d",
1010 1900+$t[5],$t[4],$t[3],$t[2],$t[1],$t[0];
1012 my $type = $build_type;
1013 if ($type =~ /useconfig/) {
1014 $type = "useconfig";
1017 my $dir = "$machine-$test_type-$type-fail-$date";
1018 my $faildir = "$store_failures/$dir";
1020 if (!-d $faildir) {
1021 mkpath($faildir) or
1022 die "can't create $faildir";
1024 if (-f "$output_config") {
1025 cp "$output_config", "$faildir/config" or
1026 die "failed to copy .config";
1028 if (-f $buildlog) {
1029 cp $buildlog, "$faildir/buildlog" or
1030 die "failed to move $buildlog";
1032 if (-f $dmesg) {
1033 cp $dmesg, "$faildir/dmesg" or
1034 die "failed to move $dmesg";
1037 doprint "*** Saved info to $faildir ***\n";
1039 return 1;
1042 sub run_command {
1043 my ($command) = @_;
1044 my $dolog = 0;
1045 my $dord = 0;
1046 my $pid;
1048 $command =~ s/\$SSH_USER/$ssh_user/g;
1049 $command =~ s/\$MACHINE/$machine/g;
1051 doprint("$command ... ");
1053 $pid = open(CMD, "$command 2>&1 |") or
1054 (fail "unable to exec $command" and return 0);
1056 if (defined($opt{"LOG_FILE"})) {
1057 open(LOG, ">>$opt{LOG_FILE}") or
1058 dodie "failed to write to log";
1059 $dolog = 1;
1062 if (defined($redirect)) {
1063 open (RD, ">$redirect") or
1064 dodie "failed to write to redirect $redirect";
1065 $dord = 1;
1068 while (<CMD>) {
1069 print LOG if ($dolog);
1070 print RD if ($dord);
1073 waitpid($pid, 0);
1074 my $failed = $?;
1076 close(CMD);
1077 close(LOG) if ($dolog);
1078 close(RD) if ($dord);
1080 if ($failed) {
1081 doprint "FAILED!\n";
1082 } else {
1083 doprint "SUCCESS\n";
1086 return !$failed;
1089 sub run_ssh {
1090 my ($cmd) = @_;
1091 my $cp_exec = $ssh_exec;
1093 $cp_exec =~ s/\$SSH_COMMAND/$cmd/g;
1094 return run_command "$cp_exec";
1097 sub run_scp {
1098 my ($src, $dst) = @_;
1099 my $cp_scp = $scp_to_target;
1101 $cp_scp =~ s/\$SRC_FILE/$src/g;
1102 $cp_scp =~ s/\$DST_FILE/$dst/g;
1104 return run_command "$cp_scp";
1107 sub get_grub_index {
1109 if ($reboot_type ne "grub") {
1110 return;
1112 return if (defined($grub_number));
1114 doprint "Find grub menu ... ";
1115 $grub_number = -1;
1117 my $ssh_grub = $ssh_exec;
1118 $ssh_grub =~ s,\$SSH_COMMAND,cat /boot/grub/menu.lst,g;
1120 open(IN, "$ssh_grub |")
1121 or die "unable to get menu.lst";
1123 my $found = 0;
1125 while (<IN>) {
1126 if (/^\s*title\s+$grub_menu\s*$/) {
1127 $grub_number++;
1128 $found = 1;
1129 last;
1130 } elsif (/^\s*title\s/) {
1131 $grub_number++;
1134 close(IN);
1136 die "Could not find '$grub_menu' in /boot/grub/menu on $machine"
1137 if (!$found);
1138 doprint "$grub_number\n";
1141 sub wait_for_input
1143 my ($fp, $time) = @_;
1144 my $rin;
1145 my $ready;
1146 my $line;
1147 my $ch;
1149 if (!defined($time)) {
1150 $time = $timeout;
1153 $rin = '';
1154 vec($rin, fileno($fp), 1) = 1;
1155 $ready = select($rin, undef, undef, $time);
1157 $line = "";
1159 # try to read one char at a time
1160 while (sysread $fp, $ch, 1) {
1161 $line .= $ch;
1162 last if ($ch eq "\n");
1165 if (!length($line)) {
1166 return undef;
1169 return $line;
1172 sub reboot_to {
1173 if ($reboot_type eq "grub") {
1174 run_ssh "'(echo \"savedefault --default=$grub_number --once\" | grub --batch)'";
1175 reboot;
1176 return;
1179 run_command "$reboot_script";
1182 sub get_sha1 {
1183 my ($commit) = @_;
1185 doprint "git rev-list --max-count=1 $commit ... ";
1186 my $sha1 = `git rev-list --max-count=1 $commit`;
1187 my $ret = $?;
1189 logit $sha1;
1191 if ($ret) {
1192 doprint "FAILED\n";
1193 dodie "Failed to get git $commit";
1196 print "SUCCESS\n";
1198 chomp $sha1;
1200 return $sha1;
1203 sub monitor {
1204 my $booted = 0;
1205 my $bug = 0;
1206 my $skip_call_trace = 0;
1207 my $loops;
1209 wait_for_monitor 5;
1211 my $line;
1212 my $full_line = "";
1214 open(DMESG, "> $dmesg") or
1215 die "unable to write to $dmesg";
1217 reboot_to;
1219 my $success_start;
1220 my $failure_start;
1221 my $monitor_start = time;
1222 my $done = 0;
1223 my $version_found = 0;
1225 while (!$done) {
1227 if ($bug && defined($stop_after_failure) &&
1228 $stop_after_failure >= 0) {
1229 my $time = $stop_after_failure - (time - $failure_start);
1230 $line = wait_for_input($monitor_fp, $time);
1231 if (!defined($line)) {
1232 doprint "bug timed out after $booted_timeout seconds\n";
1233 doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
1234 last;
1236 } elsif ($booted) {
1237 $line = wait_for_input($monitor_fp, $booted_timeout);
1238 if (!defined($line)) {
1239 my $s = $booted_timeout == 1 ? "" : "s";
1240 doprint "Successful boot found: break after $booted_timeout second$s\n";
1241 last;
1243 } else {
1244 $line = wait_for_input($monitor_fp);
1245 if (!defined($line)) {
1246 my $s = $timeout == 1 ? "" : "s";
1247 doprint "Timed out after $timeout second$s\n";
1248 last;
1252 doprint $line;
1253 print DMESG $line;
1255 # we are not guaranteed to get a full line
1256 $full_line .= $line;
1258 if ($full_line =~ /$success_line/) {
1259 $booted = 1;
1260 $success_start = time;
1263 if ($booted && defined($stop_after_success) &&
1264 $stop_after_success >= 0) {
1265 my $now = time;
1266 if ($now - $success_start >= $stop_after_success) {
1267 doprint "Test forced to stop after $stop_after_success seconds after success\n";
1268 last;
1272 if ($full_line =~ /\[ backtrace testing \]/) {
1273 $skip_call_trace = 1;
1276 if ($full_line =~ /call trace:/i) {
1277 if (!$bug && !$skip_call_trace) {
1278 $bug = 1;
1279 $failure_start = time;
1283 if ($bug && defined($stop_after_failure) &&
1284 $stop_after_failure >= 0) {
1285 my $now = time;
1286 if ($now - $failure_start >= $stop_after_failure) {
1287 doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
1288 last;
1292 if ($full_line =~ /\[ end of backtrace testing \]/) {
1293 $skip_call_trace = 0;
1296 if ($full_line =~ /Kernel panic -/) {
1297 $failure_start = time;
1298 $bug = 1;
1301 # Detect triple faults by testing the banner
1302 if ($full_line =~ /\bLinux version (\S+).*\n/) {
1303 if ($1 eq $version) {
1304 $version_found = 1;
1305 } elsif ($version_found && $detect_triplefault) {
1306 # We already booted into the kernel we are testing,
1307 # but now we booted into another kernel?
1308 # Consider this a triple fault.
1309 doprint "Aleady booted in Linux kernel $version, but now\n";
1310 doprint "we booted into Linux kernel $1.\n";
1311 doprint "Assuming that this is a triple fault.\n";
1312 doprint "To disable this: set DETECT_TRIPLE_FAULT to 0\n";
1313 last;
1317 if ($line =~ /\n/) {
1318 $full_line = "";
1321 if ($stop_test_after > 0 && !$booted && !$bug) {
1322 if (time - $monitor_start > $stop_test_after) {
1323 doprint "STOP_TEST_AFTER ($stop_test_after seconds) timed out\n";
1324 $done = 1;
1329 close(DMESG);
1331 if ($bug) {
1332 return 0 if ($in_bisect);
1333 fail "failed - got a bug report" and return 0;
1336 if (!$booted) {
1337 return 0 if ($in_bisect);
1338 fail "failed - never got a boot prompt." and return 0;
1341 return 1;
1344 sub do_post_install {
1346 return if (!defined($post_install));
1348 my $cp_post_install = $post_install;
1349 $cp_post_install =~ s/\$KERNEL_VERSION/$version/g;
1350 run_command "$cp_post_install" or
1351 dodie "Failed to run post install";
1354 sub install {
1356 return if ($no_install);
1358 run_scp "$outputdir/$build_target", "$target_image" or
1359 dodie "failed to copy image";
1361 my $install_mods = 0;
1363 # should we process modules?
1364 $install_mods = 0;
1365 open(IN, "$output_config") or dodie("Can't read config file");
1366 while (<IN>) {
1367 if (/CONFIG_MODULES(=y)?/) {
1368 $install_mods = 1 if (defined($1));
1369 last;
1372 close(IN);
1374 if (!$install_mods) {
1375 do_post_install;
1376 doprint "No modules needed\n";
1377 return;
1380 run_command "$make INSTALL_MOD_PATH=$tmpdir modules_install" or
1381 dodie "Failed to install modules";
1383 my $modlib = "/lib/modules/$version";
1384 my $modtar = "ktest-mods.tar.bz2";
1386 run_ssh "rm -rf $modlib" or
1387 dodie "failed to remove old mods: $modlib";
1389 # would be nice if scp -r did not follow symbolic links
1390 run_command "cd $tmpdir && tar -cjf $modtar lib/modules/$version" or
1391 dodie "making tarball";
1393 run_scp "$tmpdir/$modtar", "/tmp" or
1394 dodie "failed to copy modules";
1396 unlink "$tmpdir/$modtar";
1398 run_ssh "'(cd / && tar xjf /tmp/$modtar)'" or
1399 dodie "failed to tar modules";
1401 run_ssh "rm -f /tmp/$modtar";
1403 do_post_install;
1406 sub get_version {
1407 # get the release name
1408 doprint "$make kernelrelease ... ";
1409 $version = `$make kernelrelease | tail -1`;
1410 chomp($version);
1411 doprint "$version\n";
1414 sub start_monitor_and_boot {
1415 # Make sure the stable kernel has finished booting
1416 start_monitor;
1417 wait_for_monitor 5;
1418 end_monitor;
1420 get_grub_index;
1421 get_version;
1422 install;
1424 start_monitor;
1425 return monitor;
1428 sub check_buildlog {
1429 my ($patch) = @_;
1431 my @files = `git show $patch | diffstat -l`;
1433 open(IN, "git show $patch |") or
1434 dodie "failed to show $patch";
1435 while (<IN>) {
1436 if (m,^--- a/(.*),) {
1437 chomp $1;
1438 $files[$#files] = $1;
1441 close(IN);
1443 open(IN, $buildlog) or dodie "Can't open $buildlog";
1444 while (<IN>) {
1445 if (/^\s*(.*?):.*(warning|error)/) {
1446 my $err = $1;
1447 foreach my $file (@files) {
1448 my $fullpath = "$builddir/$file";
1449 if ($file eq $err || $fullpath eq $err) {
1450 fail "$file built with warnings" and return 0;
1455 close(IN);
1457 return 1;
1460 sub apply_min_config {
1461 my $outconfig = "$output_config.new";
1463 # Read the config file and remove anything that
1464 # is in the force_config hash (from minconfig and others)
1465 # then add the force config back.
1467 doprint "Applying minimum configurations into $output_config.new\n";
1469 open (OUT, ">$outconfig") or
1470 dodie "Can't create $outconfig";
1472 if (-f $output_config) {
1473 open (IN, $output_config) or
1474 dodie "Failed to open $output_config";
1475 while (<IN>) {
1476 if (/^(# )?(CONFIG_[^\s=]*)/) {
1477 next if (defined($force_config{$2}));
1479 print OUT;
1481 close IN;
1483 foreach my $config (keys %force_config) {
1484 print OUT "$force_config{$config}\n";
1486 close OUT;
1488 run_command "mv $outconfig $output_config";
1491 sub make_oldconfig {
1493 my @force_list = keys %force_config;
1495 if ($#force_list >= 0) {
1496 apply_min_config;
1499 if (!run_command "$make oldnoconfig") {
1500 # Perhaps oldnoconfig doesn't exist in this version of the kernel
1501 # try a yes '' | oldconfig
1502 doprint "oldnoconfig failed, trying yes '' | make oldconfig\n";
1503 run_command "yes '' | $make oldconfig" or
1504 dodie "failed make config oldconfig";
1508 # read a config file and use this to force new configs.
1509 sub load_force_config {
1510 my ($config) = @_;
1512 open(IN, $config) or
1513 dodie "failed to read $config";
1514 while (<IN>) {
1515 chomp;
1516 if (/^(CONFIG[^\s=]*)(\s*=.*)/) {
1517 $force_config{$1} = $_;
1518 } elsif (/^# (CONFIG_\S*) is not set/) {
1519 $force_config{$1} = $_;
1522 close IN;
1525 sub build {
1526 my ($type) = @_;
1528 unlink $buildlog;
1530 # Failed builds should not reboot the target
1531 my $save_no_reboot = $no_reboot;
1532 $no_reboot = 1;
1534 if (defined($pre_build)) {
1535 my $ret = run_command $pre_build;
1536 if (!$ret && defined($pre_build_die) &&
1537 $pre_build_die) {
1538 dodie "failed to pre_build\n";
1542 if ($type =~ /^useconfig:(.*)/) {
1543 run_command "cp $1 $output_config" or
1544 dodie "could not copy $1 to .config";
1546 $type = "oldconfig";
1549 # old config can ask questions
1550 if ($type eq "oldconfig") {
1551 $type = "oldnoconfig";
1553 # allow for empty configs
1554 run_command "touch $output_config";
1556 if (!$noclean) {
1557 run_command "mv $output_config $outputdir/config_temp" or
1558 dodie "moving .config";
1560 run_command "$make mrproper" or dodie "make mrproper";
1562 run_command "mv $outputdir/config_temp $output_config" or
1563 dodie "moving config_temp";
1566 } elsif (!$noclean) {
1567 unlink "$output_config";
1568 run_command "$make mrproper" or
1569 dodie "make mrproper";
1572 # add something to distinguish this build
1573 open(OUT, "> $outputdir/localversion") or dodie("Can't make localversion file");
1574 print OUT "$localversion\n";
1575 close(OUT);
1577 if (defined($minconfig)) {
1578 load_force_config($minconfig);
1581 if ($type ne "oldnoconfig") {
1582 run_command "$make $type" or
1583 dodie "failed make config";
1585 # Run old config regardless, to enforce min configurations
1586 make_oldconfig;
1588 $redirect = "$buildlog";
1589 my $build_ret = run_command "$make $build_options";
1590 undef $redirect;
1592 if (defined($post_build)) {
1593 my $ret = run_command $post_build;
1594 if (!$ret && defined($post_build_die) &&
1595 $post_build_die) {
1596 dodie "failed to post_build\n";
1600 if (!$build_ret) {
1601 # bisect may need this to pass
1602 if ($in_bisect) {
1603 $no_reboot = $save_no_reboot;
1604 return 0;
1606 fail "failed build" and return 0;
1609 $no_reboot = $save_no_reboot;
1611 return 1;
1614 sub halt {
1615 if (!run_ssh "halt" or defined($power_off)) {
1616 if (defined($poweroff_after_halt)) {
1617 sleep $poweroff_after_halt;
1618 run_command "$power_off";
1620 } else {
1621 # nope? the zap it!
1622 run_command "$power_off";
1626 sub success {
1627 my ($i) = @_;
1629 $successes++;
1631 my $name = "";
1633 if (defined($test_name)) {
1634 $name = " ($test_name)";
1637 doprint "\n\n*******************************************\n";
1638 doprint "*******************************************\n";
1639 doprint "KTEST RESULT: TEST $i$name SUCCESS!!!! **\n";
1640 doprint "*******************************************\n";
1641 doprint "*******************************************\n";
1643 if ($i != $opt{"NUM_TESTS"} && !do_not_reboot) {
1644 doprint "Reboot and wait $sleep_time seconds\n";
1645 reboot $sleep_time;
1649 sub answer_bisect {
1650 for (;;) {
1651 doprint "Pass or fail? [p/f]";
1652 my $ans = <STDIN>;
1653 chomp $ans;
1654 if ($ans eq "p" || $ans eq "P") {
1655 return 1;
1656 } elsif ($ans eq "f" || $ans eq "F") {
1657 return 0;
1658 } else {
1659 print "Please answer 'P' or 'F'\n";
1664 sub child_run_test {
1665 my $failed = 0;
1667 # child should have no power
1668 $reboot_on_error = 0;
1669 $poweroff_on_error = 0;
1670 $die_on_failure = 1;
1672 run_command $run_test or $failed = 1;
1673 exit $failed;
1676 my $child_done;
1678 sub child_finished {
1679 $child_done = 1;
1682 sub do_run_test {
1683 my $child_pid;
1684 my $child_exit;
1685 my $line;
1686 my $full_line;
1687 my $bug = 0;
1689 wait_for_monitor 1;
1691 doprint "run test $run_test\n";
1693 $child_done = 0;
1695 $SIG{CHLD} = qw(child_finished);
1697 $child_pid = fork;
1699 child_run_test if (!$child_pid);
1701 $full_line = "";
1703 do {
1704 $line = wait_for_input($monitor_fp, 1);
1705 if (defined($line)) {
1707 # we are not guaranteed to get a full line
1708 $full_line .= $line;
1709 doprint $line;
1711 if ($full_line =~ /call trace:/i) {
1712 $bug = 1;
1715 if ($full_line =~ /Kernel panic -/) {
1716 $bug = 1;
1719 if ($line =~ /\n/) {
1720 $full_line = "";
1723 } while (!$child_done && !$bug);
1725 if ($bug) {
1726 my $failure_start = time;
1727 my $now;
1728 do {
1729 $line = wait_for_input($monitor_fp, 1);
1730 if (defined($line)) {
1731 doprint $line;
1733 $now = time;
1734 if ($now - $failure_start >= $stop_after_failure) {
1735 last;
1737 } while (defined($line));
1739 doprint "Detected kernel crash!\n";
1740 # kill the child with extreme prejudice
1741 kill 9, $child_pid;
1744 waitpid $child_pid, 0;
1745 $child_exit = $?;
1747 if ($bug || $child_exit) {
1748 return 0 if $in_bisect;
1749 fail "test failed" and return 0;
1751 return 1;
1754 sub run_git_bisect {
1755 my ($command) = @_;
1757 doprint "$command ... ";
1759 my $output = `$command 2>&1`;
1760 my $ret = $?;
1762 logit $output;
1764 if ($ret) {
1765 doprint "FAILED\n";
1766 dodie "Failed to git bisect";
1769 doprint "SUCCESS\n";
1770 if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\))\s+\[([[:xdigit:]]+)\]/) {
1771 doprint "$1 [$2]\n";
1772 } elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) {
1773 $bisect_bad = $1;
1774 doprint "Found bad commit... $1\n";
1775 return 0;
1776 } else {
1777 # we already logged it, just print it now.
1778 print $output;
1781 return 1;
1784 sub bisect_reboot {
1785 doprint "Reboot and sleep $bisect_sleep_time seconds\n";
1786 reboot $bisect_sleep_time;
1789 # returns 1 on success, 0 on failure, -1 on skip
1790 sub run_bisect_test {
1791 my ($type, $buildtype) = @_;
1793 my $failed = 0;
1794 my $result;
1795 my $output;
1796 my $ret;
1798 $in_bisect = 1;
1800 build $buildtype or $failed = 1;
1802 if ($type ne "build") {
1803 if ($failed && $bisect_skip) {
1804 $in_bisect = 0;
1805 return -1;
1807 dodie "Failed on build" if $failed;
1809 # Now boot the box
1810 start_monitor_and_boot or $failed = 1;
1812 if ($type ne "boot") {
1813 if ($failed && $bisect_skip) {
1814 end_monitor;
1815 bisect_reboot;
1816 $in_bisect = 0;
1817 return -1;
1819 dodie "Failed on boot" if $failed;
1821 do_run_test or $failed = 1;
1823 end_monitor;
1826 if ($failed) {
1827 $result = 0;
1828 } else {
1829 $result = 1;
1832 # reboot the box to a kernel we can ssh to
1833 if ($type ne "build") {
1834 bisect_reboot;
1836 $in_bisect = 0;
1838 return $result;
1841 sub run_bisect {
1842 my ($type) = @_;
1843 my $buildtype = "oldconfig";
1845 # We should have a minconfig to use?
1846 if (defined($minconfig)) {
1847 $buildtype = "useconfig:$minconfig";
1850 my $ret = run_bisect_test $type, $buildtype;
1852 if ($bisect_manual) {
1853 $ret = answer_bisect;
1856 # Are we looking for where it worked, not failed?
1857 if ($reverse_bisect) {
1858 $ret = !$ret;
1861 if ($ret > 0) {
1862 return "good";
1863 } elsif ($ret == 0) {
1864 return "bad";
1865 } elsif ($bisect_skip) {
1866 doprint "HIT A BAD COMMIT ... SKIPPING\n";
1867 return "skip";
1871 sub bisect {
1872 my ($i) = @_;
1874 my $result;
1876 die "BISECT_GOOD[$i] not defined\n" if (!defined($opt{"BISECT_GOOD[$i]"}));
1877 die "BISECT_BAD[$i] not defined\n" if (!defined($opt{"BISECT_BAD[$i]"}));
1878 die "BISECT_TYPE[$i] not defined\n" if (!defined($opt{"BISECT_TYPE[$i]"}));
1880 my $good = $opt{"BISECT_GOOD[$i]"};
1881 my $bad = $opt{"BISECT_BAD[$i]"};
1882 my $type = $opt{"BISECT_TYPE[$i]"};
1883 my $start = $opt{"BISECT_START[$i]"};
1884 my $replay = $opt{"BISECT_REPLAY[$i]"};
1885 my $start_files = $opt{"BISECT_FILES[$i]"};
1887 if (defined($start_files)) {
1888 $start_files = " -- " . $start_files;
1889 } else {
1890 $start_files = "";
1893 # convert to true sha1's
1894 $good = get_sha1($good);
1895 $bad = get_sha1($bad);
1897 if (defined($opt{"BISECT_REVERSE[$i]"}) &&
1898 $opt{"BISECT_REVERSE[$i]"} == 1) {
1899 doprint "Performing a reverse bisect (bad is good, good is bad!)\n";
1900 $reverse_bisect = 1;
1901 } else {
1902 $reverse_bisect = 0;
1905 # Can't have a test without having a test to run
1906 if ($type eq "test" && !defined($run_test)) {
1907 $type = "boot";
1910 my $check = $opt{"BISECT_CHECK[$i]"};
1911 if (defined($check) && $check ne "0") {
1913 # get current HEAD
1914 my $head = get_sha1("HEAD");
1916 if ($check ne "good") {
1917 doprint "TESTING BISECT BAD [$bad]\n";
1918 run_command "git checkout $bad" or
1919 die "Failed to checkout $bad";
1921 $result = run_bisect $type;
1923 if ($result ne "bad") {
1924 fail "Tested BISECT_BAD [$bad] and it succeeded" and return 0;
1928 if ($check ne "bad") {
1929 doprint "TESTING BISECT GOOD [$good]\n";
1930 run_command "git checkout $good" or
1931 die "Failed to checkout $good";
1933 $result = run_bisect $type;
1935 if ($result ne "good") {
1936 fail "Tested BISECT_GOOD [$good] and it failed" and return 0;
1940 # checkout where we started
1941 run_command "git checkout $head" or
1942 die "Failed to checkout $head";
1945 run_command "git bisect start$start_files" or
1946 dodie "could not start bisect";
1948 run_command "git bisect good $good" or
1949 dodie "could not set bisect good to $good";
1951 run_git_bisect "git bisect bad $bad" or
1952 dodie "could not set bisect bad to $bad";
1954 if (defined($replay)) {
1955 run_command "git bisect replay $replay" or
1956 dodie "failed to run replay";
1959 if (defined($start)) {
1960 run_command "git checkout $start" or
1961 dodie "failed to checkout $start";
1964 my $test;
1965 do {
1966 $result = run_bisect $type;
1967 $test = run_git_bisect "git bisect $result";
1968 } while ($test);
1970 run_command "git bisect log" or
1971 dodie "could not capture git bisect log";
1973 run_command "git bisect reset" or
1974 dodie "could not reset git bisect";
1976 doprint "Bad commit was [$bisect_bad]\n";
1978 success $i;
1981 my %config_ignore;
1982 my %config_set;
1984 my %config_list;
1985 my %null_config;
1987 my %dependency;
1989 sub assign_configs {
1990 my ($hash, $config) = @_;
1992 open (IN, $config)
1993 or dodie "Failed to read $config";
1995 while (<IN>) {
1996 if (/^((CONFIG\S*)=.*)/) {
1997 ${$hash}{$2} = $1;
2001 close(IN);
2004 sub process_config_ignore {
2005 my ($config) = @_;
2007 assign_configs \%config_ignore, $config;
2010 sub read_current_config {
2011 my ($config_ref) = @_;
2013 %{$config_ref} = ();
2014 undef %{$config_ref};
2016 my @key = keys %{$config_ref};
2017 if ($#key >= 0) {
2018 print "did not delete!\n";
2019 exit;
2021 open (IN, "$output_config");
2023 while (<IN>) {
2024 if (/^(CONFIG\S+)=(.*)/) {
2025 ${$config_ref}{$1} = $2;
2028 close(IN);
2031 sub get_dependencies {
2032 my ($config) = @_;
2034 my $arr = $dependency{$config};
2035 if (!defined($arr)) {
2036 return ();
2039 my @deps = @{$arr};
2041 foreach my $dep (@{$arr}) {
2042 print "ADD DEP $dep\n";
2043 @deps = (@deps, get_dependencies $dep);
2046 return @deps;
2049 sub create_config {
2050 my @configs = @_;
2052 open(OUT, ">$output_config") or dodie "Can not write to $output_config";
2054 foreach my $config (@configs) {
2055 print OUT "$config_set{$config}\n";
2056 my @deps = get_dependencies $config;
2057 foreach my $dep (@deps) {
2058 print OUT "$config_set{$dep}\n";
2062 foreach my $config (keys %config_ignore) {
2063 print OUT "$config_ignore{$config}\n";
2065 close(OUT);
2067 # exit;
2068 make_oldconfig;
2071 sub compare_configs {
2072 my (%a, %b) = @_;
2074 foreach my $item (keys %a) {
2075 if (!defined($b{$item})) {
2076 print "diff $item\n";
2077 return 1;
2079 delete $b{$item};
2082 my @keys = keys %b;
2083 if ($#keys) {
2084 print "diff2 $keys[0]\n";
2086 return -1 if ($#keys >= 0);
2088 return 0;
2091 sub run_config_bisect_test {
2092 my ($type) = @_;
2094 return run_bisect_test $type, "oldconfig";
2097 sub process_passed {
2098 my (%configs) = @_;
2100 doprint "These configs had no failure: (Enabling them for further compiles)\n";
2101 # Passed! All these configs are part of a good compile.
2102 # Add them to the min options.
2103 foreach my $config (keys %configs) {
2104 if (defined($config_list{$config})) {
2105 doprint " removing $config\n";
2106 $config_ignore{$config} = $config_list{$config};
2107 delete $config_list{$config};
2110 doprint "config copied to $outputdir/config_good\n";
2111 run_command "cp -f $output_config $outputdir/config_good";
2114 sub process_failed {
2115 my ($config) = @_;
2117 doprint "\n\n***************************************\n";
2118 doprint "Found bad config: $config\n";
2119 doprint "***************************************\n\n";
2122 sub run_config_bisect {
2124 my @start_list = keys %config_list;
2126 if ($#start_list < 0) {
2127 doprint "No more configs to test!!!\n";
2128 return -1;
2131 doprint "***** RUN TEST ***\n";
2132 my $type = $opt{"CONFIG_BISECT_TYPE[$iteration]"};
2133 my $ret;
2134 my %current_config;
2136 my $count = $#start_list + 1;
2137 doprint " $count configs to test\n";
2139 my $half = int($#start_list / 2);
2141 do {
2142 my @tophalf = @start_list[0 .. $half];
2144 create_config @tophalf;
2145 read_current_config \%current_config;
2147 $count = $#tophalf + 1;
2148 doprint "Testing $count configs\n";
2149 my $found = 0;
2150 # make sure we test something
2151 foreach my $config (@tophalf) {
2152 if (defined($current_config{$config})) {
2153 logit " $config\n";
2154 $found = 1;
2157 if (!$found) {
2158 # try the other half
2159 doprint "Top half produced no set configs, trying bottom half\n";
2160 @tophalf = @start_list[$half + 1 .. $#start_list];
2161 create_config @tophalf;
2162 read_current_config \%current_config;
2163 foreach my $config (@tophalf) {
2164 if (defined($current_config{$config})) {
2165 logit " $config\n";
2166 $found = 1;
2169 if (!$found) {
2170 doprint "Failed: Can't make new config with current configs\n";
2171 foreach my $config (@start_list) {
2172 doprint " CONFIG: $config\n";
2174 return -1;
2176 $count = $#tophalf + 1;
2177 doprint "Testing $count configs\n";
2180 $ret = run_config_bisect_test $type;
2181 if ($bisect_manual) {
2182 $ret = answer_bisect;
2184 if ($ret) {
2185 process_passed %current_config;
2186 return 0;
2189 doprint "This config had a failure.\n";
2190 doprint "Removing these configs that were not set in this config:\n";
2191 doprint "config copied to $outputdir/config_bad\n";
2192 run_command "cp -f $output_config $outputdir/config_bad";
2194 # A config exists in this group that was bad.
2195 foreach my $config (keys %config_list) {
2196 if (!defined($current_config{$config})) {
2197 doprint " removing $config\n";
2198 delete $config_list{$config};
2202 @start_list = @tophalf;
2204 if ($#start_list == 0) {
2205 process_failed $start_list[0];
2206 return 1;
2209 # remove half the configs we are looking at and see if
2210 # they are good.
2211 $half = int($#start_list / 2);
2212 } while ($#start_list > 0);
2214 # we found a single config, try it again unless we are running manually
2216 if ($bisect_manual) {
2217 process_failed $start_list[0];
2218 return 1;
2221 my @tophalf = @start_list[0 .. 0];
2223 $ret = run_config_bisect_test $type;
2224 if ($ret) {
2225 process_passed %current_config;
2226 return 0;
2229 process_failed $start_list[0];
2230 return 1;
2233 sub config_bisect {
2234 my ($i) = @_;
2236 my $start_config = $opt{"CONFIG_BISECT[$i]"};
2238 my $tmpconfig = "$tmpdir/use_config";
2240 if (defined($config_bisect_good)) {
2241 process_config_ignore $config_bisect_good;
2244 # Make the file with the bad config and the min config
2245 if (defined($minconfig)) {
2246 # read the min config for things to ignore
2247 run_command "cp $minconfig $tmpconfig" or
2248 dodie "failed to copy $minconfig to $tmpconfig";
2249 } else {
2250 unlink $tmpconfig;
2253 if (-f $tmpconfig) {
2254 load_force_config($tmpconfig);
2255 process_config_ignore $tmpconfig;
2258 # now process the start config
2259 run_command "cp $start_config $output_config" or
2260 dodie "failed to copy $start_config to $output_config";
2262 # read directly what we want to check
2263 my %config_check;
2264 open (IN, $output_config)
2265 or dodie "faied to open $output_config";
2267 while (<IN>) {
2268 if (/^((CONFIG\S*)=.*)/) {
2269 $config_check{$2} = $1;
2272 close(IN);
2274 # Now run oldconfig with the minconfig
2275 make_oldconfig;
2277 # check to see what we lost (or gained)
2278 open (IN, $output_config)
2279 or dodie "Failed to read $start_config";
2281 my %removed_configs;
2282 my %added_configs;
2284 while (<IN>) {
2285 if (/^((CONFIG\S*)=.*)/) {
2286 # save off all options
2287 $config_set{$2} = $1;
2288 if (defined($config_check{$2})) {
2289 if (defined($config_ignore{$2})) {
2290 $removed_configs{$2} = $1;
2291 } else {
2292 $config_list{$2} = $1;
2294 } elsif (!defined($config_ignore{$2})) {
2295 $added_configs{$2} = $1;
2296 $config_list{$2} = $1;
2300 close(IN);
2302 my @confs = keys %removed_configs;
2303 if ($#confs >= 0) {
2304 doprint "Configs overridden by default configs and removed from check:\n";
2305 foreach my $config (@confs) {
2306 doprint " $config\n";
2309 @confs = keys %added_configs;
2310 if ($#confs >= 0) {
2311 doprint "Configs appearing in make oldconfig and added:\n";
2312 foreach my $config (@confs) {
2313 doprint " $config\n";
2317 my %config_test;
2318 my $once = 0;
2320 # Sometimes kconfig does weird things. We must make sure
2321 # that the config we autocreate has everything we need
2322 # to test, otherwise we may miss testing configs, or
2323 # may not be able to create a new config.
2324 # Here we create a config with everything set.
2325 create_config (keys %config_list);
2326 read_current_config \%config_test;
2327 foreach my $config (keys %config_list) {
2328 if (!defined($config_test{$config})) {
2329 if (!$once) {
2330 $once = 1;
2331 doprint "Configs not produced by kconfig (will not be checked):\n";
2333 doprint " $config\n";
2334 delete $config_list{$config};
2337 my $ret;
2338 do {
2339 $ret = run_config_bisect;
2340 } while (!$ret);
2342 return $ret if ($ret < 0);
2344 success $i;
2347 sub patchcheck_reboot {
2348 doprint "Reboot and sleep $patchcheck_sleep_time seconds\n";
2349 reboot $patchcheck_sleep_time;
2352 sub patchcheck {
2353 my ($i) = @_;
2355 die "PATCHCHECK_START[$i] not defined\n"
2356 if (!defined($opt{"PATCHCHECK_START[$i]"}));
2357 die "PATCHCHECK_TYPE[$i] not defined\n"
2358 if (!defined($opt{"PATCHCHECK_TYPE[$i]"}));
2360 my $start = $opt{"PATCHCHECK_START[$i]"};
2362 my $end = "HEAD";
2363 if (defined($opt{"PATCHCHECK_END[$i]"})) {
2364 $end = $opt{"PATCHCHECK_END[$i]"};
2367 # Get the true sha1's since we can use things like HEAD~3
2368 $start = get_sha1($start);
2369 $end = get_sha1($end);
2371 my $type = $opt{"PATCHCHECK_TYPE[$i]"};
2373 # Can't have a test without having a test to run
2374 if ($type eq "test" && !defined($run_test)) {
2375 $type = "boot";
2378 open (IN, "git log --pretty=oneline $end|") or
2379 dodie "could not get git list";
2381 my @list;
2383 while (<IN>) {
2384 chomp;
2385 $list[$#list+1] = $_;
2386 last if (/^$start/);
2388 close(IN);
2390 if ($list[$#list] !~ /^$start/) {
2391 fail "SHA1 $start not found";
2394 # go backwards in the list
2395 @list = reverse @list;
2397 my $save_clean = $noclean;
2398 my %ignored_warnings;
2400 if (defined($ignore_warnings)) {
2401 foreach my $sha1 (split /\s+/, $ignore_warnings) {
2402 $ignored_warnings{$sha1} = 1;
2406 $in_patchcheck = 1;
2407 foreach my $item (@list) {
2408 my $sha1 = $item;
2409 $sha1 =~ s/^([[:xdigit:]]+).*/$1/;
2411 doprint "\nProcessing commit $item\n\n";
2413 run_command "git checkout $sha1" or
2414 die "Failed to checkout $sha1";
2416 # only clean on the first and last patch
2417 if ($item eq $list[0] ||
2418 $item eq $list[$#list]) {
2419 $noclean = $save_clean;
2420 } else {
2421 $noclean = 1;
2424 if (defined($minconfig)) {
2425 build "useconfig:$minconfig" or return 0;
2426 } else {
2427 # ?? no config to use?
2428 build "oldconfig" or return 0;
2432 if (!defined($ignored_warnings{$sha1})) {
2433 check_buildlog $sha1 or return 0;
2436 next if ($type eq "build");
2438 my $failed = 0;
2440 start_monitor_and_boot or $failed = 1;
2442 if (!$failed && $type ne "boot"){
2443 do_run_test or $failed = 1;
2445 end_monitor;
2446 return 0 if ($failed);
2448 patchcheck_reboot;
2451 $in_patchcheck = 0;
2452 success $i;
2454 return 1;
2457 my %depends;
2458 my %depcount;
2459 my $iflevel = 0;
2460 my @ifdeps;
2462 # prevent recursion
2463 my %read_kconfigs;
2465 sub add_dep {
2466 # $config depends on $dep
2467 my ($config, $dep) = @_;
2469 if (defined($depends{$config})) {
2470 $depends{$config} .= " " . $dep;
2471 } else {
2472 $depends{$config} = $dep;
2475 # record the number of configs depending on $dep
2476 if (defined $depcount{$dep}) {
2477 $depcount{$dep}++;
2478 } else {
2479 $depcount{$dep} = 1;
2483 # taken from streamline_config.pl
2484 sub read_kconfig {
2485 my ($kconfig) = @_;
2487 my $state = "NONE";
2488 my $config;
2489 my @kconfigs;
2491 my $cont = 0;
2492 my $line;
2495 if (! -f $kconfig) {
2496 doprint "file $kconfig does not exist, skipping\n";
2497 return;
2500 open(KIN, "$kconfig")
2501 or die "Can't open $kconfig";
2502 while (<KIN>) {
2503 chomp;
2505 # Make sure that lines ending with \ continue
2506 if ($cont) {
2507 $_ = $line . " " . $_;
2510 if (s/\\$//) {
2511 $cont = 1;
2512 $line = $_;
2513 next;
2516 $cont = 0;
2518 # collect any Kconfig sources
2519 if (/^source\s*"(.*)"/) {
2520 $kconfigs[$#kconfigs+1] = $1;
2523 # configs found
2524 if (/^\s*(menu)?config\s+(\S+)\s*$/) {
2525 $state = "NEW";
2526 $config = $2;
2528 for (my $i = 0; $i < $iflevel; $i++) {
2529 add_dep $config, $ifdeps[$i];
2532 # collect the depends for the config
2533 } elsif ($state eq "NEW" && /^\s*depends\s+on\s+(.*)$/) {
2535 add_dep $config, $1;
2537 # Get the configs that select this config
2538 } elsif ($state eq "NEW" && /^\s*select\s+(\S+)/) {
2540 # selected by depends on config
2541 add_dep $1, $config;
2543 # Check for if statements
2544 } elsif (/^if\s+(.*\S)\s*$/) {
2545 my $deps = $1;
2546 # remove beginning and ending non text
2547 $deps =~ s/^[^a-zA-Z0-9_]*//;
2548 $deps =~ s/[^a-zA-Z0-9_]*$//;
2550 my @deps = split /[^a-zA-Z0-9_]+/, $deps;
2552 $ifdeps[$iflevel++] = join ':', @deps;
2554 } elsif (/^endif/) {
2556 $iflevel-- if ($iflevel);
2558 # stop on "help"
2559 } elsif (/^\s*help\s*$/) {
2560 $state = "NONE";
2563 close(KIN);
2565 # read in any configs that were found.
2566 foreach $kconfig (@kconfigs) {
2567 if (!defined($read_kconfigs{$kconfig})) {
2568 $read_kconfigs{$kconfig} = 1;
2569 read_kconfig("$builddir/$kconfig");
2574 sub read_depends {
2575 # find out which arch this is by the kconfig file
2576 open (IN, $output_config)
2577 or dodie "Failed to read $output_config";
2578 my $arch;
2579 while (<IN>) {
2580 if (m,Linux/(\S+)\s+\S+\s+Kernel Configuration,) {
2581 $arch = $1;
2582 last;
2585 close IN;
2587 if (!defined($arch)) {
2588 doprint "Could not find arch from config file\n";
2589 doprint "no dependencies used\n";
2590 return;
2593 # arch is really the subarch, we need to know
2594 # what directory to look at.
2595 if ($arch eq "i386" || $arch eq "x86_64") {
2596 $arch = "x86";
2597 } elsif ($arch =~ /^tile/) {
2598 $arch = "tile";
2601 my $kconfig = "$builddir/arch/$arch/Kconfig";
2603 if (! -f $kconfig && $arch =~ /\d$/) {
2604 my $orig = $arch;
2605 # some subarchs have numbers, truncate them
2606 $arch =~ s/\d*$//;
2607 $kconfig = "$builddir/arch/$arch/Kconfig";
2608 if (! -f $kconfig) {
2609 doprint "No idea what arch dir $orig is for\n";
2610 doprint "no dependencies used\n";
2611 return;
2615 read_kconfig($kconfig);
2618 sub read_config_list {
2619 my ($config) = @_;
2621 open (IN, $config)
2622 or dodie "Failed to read $config";
2624 while (<IN>) {
2625 if (/^((CONFIG\S*)=.*)/) {
2626 if (!defined($config_ignore{$2})) {
2627 $config_list{$2} = $1;
2632 close(IN);
2635 sub read_output_config {
2636 my ($config) = @_;
2638 assign_configs \%config_ignore, $config;
2641 sub make_new_config {
2642 my @configs = @_;
2644 open (OUT, ">$output_config")
2645 or dodie "Failed to write $output_config";
2647 foreach my $config (@configs) {
2648 print OUT "$config\n";
2650 close OUT;
2653 sub chomp_config {
2654 my ($config) = @_;
2656 $config =~ s/CONFIG_//;
2658 return $config;
2661 sub get_depends {
2662 my ($dep) = @_;
2664 my $kconfig = chomp_config $dep;
2666 $dep = $depends{"$kconfig"};
2668 # the dep string we have saves the dependencies as they
2669 # were found, including expressions like ! && ||. We
2670 # want to split this out into just an array of configs.
2672 my $valid = "A-Za-z_0-9";
2674 my @configs;
2676 while ($dep =~ /[$valid]/) {
2678 if ($dep =~ /^[^$valid]*([$valid]+)/) {
2679 my $conf = "CONFIG_" . $1;
2681 $configs[$#configs + 1] = $conf;
2683 $dep =~ s/^[^$valid]*[$valid]+//;
2684 } else {
2685 die "this should never happen";
2689 return @configs;
2692 my %min_configs;
2693 my %keep_configs;
2694 my %save_configs;
2695 my %processed_configs;
2696 my %nochange_config;
2698 sub test_this_config {
2699 my ($config) = @_;
2701 my $found;
2703 # if we already processed this config, skip it
2704 if (defined($processed_configs{$config})) {
2705 return undef;
2707 $processed_configs{$config} = 1;
2709 # if this config failed during this round, skip it
2710 if (defined($nochange_config{$config})) {
2711 return undef;
2714 my $kconfig = chomp_config $config;
2716 # Test dependencies first
2717 if (defined($depends{"$kconfig"})) {
2718 my @parents = get_depends $config;
2719 foreach my $parent (@parents) {
2720 # if the parent is in the min config, check it first
2721 next if (!defined($min_configs{$parent}));
2722 $found = test_this_config($parent);
2723 if (defined($found)) {
2724 return $found;
2729 # Remove this config from the list of configs
2730 # do a make oldnoconfig and then read the resulting
2731 # .config to make sure it is missing the config that
2732 # we had before
2733 my %configs = %min_configs;
2734 delete $configs{$config};
2735 make_new_config ((values %configs), (values %keep_configs));
2736 make_oldconfig;
2737 undef %configs;
2738 assign_configs \%configs, $output_config;
2740 return $config if (!defined($configs{$config}));
2742 doprint "disabling config $config did not change .config\n";
2744 $nochange_config{$config} = 1;
2746 return undef;
2749 sub make_min_config {
2750 my ($i) = @_;
2752 if (!defined($output_minconfig)) {
2753 fail "OUTPUT_MIN_CONFIG not defined" and return;
2756 # If output_minconfig exists, and the start_minconfig
2757 # came from min_config, than ask if we should use
2758 # that instead.
2759 if (-f $output_minconfig && !$start_minconfig_defined) {
2760 print "$output_minconfig exists\n";
2761 if (read_yn " Use it as minconfig?") {
2762 $start_minconfig = $output_minconfig;
2766 if (!defined($start_minconfig)) {
2767 fail "START_MIN_CONFIG or MIN_CONFIG not defined" and return;
2770 my $temp_config = "$tmpdir/temp_config";
2772 # First things first. We build an allnoconfig to find
2773 # out what the defaults are that we can't touch.
2774 # Some are selections, but we really can't handle selections.
2776 my $save_minconfig = $minconfig;
2777 undef $minconfig;
2779 run_command "$make allnoconfig" or return 0;
2781 read_depends;
2783 process_config_ignore $output_config;
2785 undef %save_configs;
2786 undef %min_configs;
2788 if (defined($ignore_config)) {
2789 # make sure the file exists
2790 `touch $ignore_config`;
2791 assign_configs \%save_configs, $ignore_config;
2794 %keep_configs = %save_configs;
2796 doprint "Load initial configs from $start_minconfig\n";
2798 # Look at the current min configs, and save off all the
2799 # ones that were set via the allnoconfig
2800 assign_configs \%min_configs, $start_minconfig;
2802 my @config_keys = keys %min_configs;
2804 # All configs need a depcount
2805 foreach my $config (@config_keys) {
2806 my $kconfig = chomp_config $config;
2807 if (!defined $depcount{$kconfig}) {
2808 $depcount{$kconfig} = 0;
2812 # Remove anything that was set by the make allnoconfig
2813 # we shouldn't need them as they get set for us anyway.
2814 foreach my $config (@config_keys) {
2815 # Remove anything in the ignore_config
2816 if (defined($keep_configs{$config})) {
2817 my $file = $ignore_config;
2818 $file =~ s,.*/(.*?)$,$1,;
2819 doprint "$config set by $file ... ignored\n";
2820 delete $min_configs{$config};
2821 next;
2823 # But make sure the settings are the same. If a min config
2824 # sets a selection, we do not want to get rid of it if
2825 # it is not the same as what we have. Just move it into
2826 # the keep configs.
2827 if (defined($config_ignore{$config})) {
2828 if ($config_ignore{$config} ne $min_configs{$config}) {
2829 doprint "$config is in allnoconfig as '$config_ignore{$config}'";
2830 doprint " but it is '$min_configs{$config}' in minconfig .. keeping\n";
2831 $keep_configs{$config} = $min_configs{$config};
2832 } else {
2833 doprint "$config set by allnoconfig ... ignored\n";
2835 delete $min_configs{$config};
2839 my $done = 0;
2840 my $take_two = 0;
2842 while (!$done) {
2844 my $config;
2845 my $found;
2847 # Now disable each config one by one and do a make oldconfig
2848 # till we find a config that changes our list.
2850 my @test_configs = keys %min_configs;
2852 # Sort keys by who is most dependent on
2853 @test_configs = sort { $depcount{chomp_config($b)} <=> $depcount{chomp_config($a)} }
2854 @test_configs ;
2856 # Put configs that did not modify the config at the end.
2857 my $reset = 1;
2858 for (my $i = 0; $i < $#test_configs; $i++) {
2859 if (!defined($nochange_config{$test_configs[0]})) {
2860 $reset = 0;
2861 last;
2863 # This config didn't change the .config last time.
2864 # Place it at the end
2865 my $config = shift @test_configs;
2866 push @test_configs, $config;
2869 # if every test config has failed to modify the .config file
2870 # in the past, then reset and start over.
2871 if ($reset) {
2872 undef %nochange_config;
2875 undef %processed_configs;
2877 foreach my $config (@test_configs) {
2879 $found = test_this_config $config;
2881 last if (defined($found));
2883 # oh well, try another config
2886 if (!defined($found)) {
2887 # we could have failed due to the nochange_config hash
2888 # reset and try again
2889 if (!$take_two) {
2890 undef %nochange_config;
2891 $take_two = 1;
2892 next;
2894 doprint "No more configs found that we can disable\n";
2895 $done = 1;
2896 last;
2898 $take_two = 0;
2900 $config = $found;
2902 doprint "Test with $config disabled\n";
2904 # set in_bisect to keep build and monitor from dieing
2905 $in_bisect = 1;
2907 my $failed = 0;
2908 build "oldconfig";
2909 start_monitor_and_boot or $failed = 1;
2910 end_monitor;
2912 $in_bisect = 0;
2914 if ($failed) {
2915 doprint "$min_configs{$config} is needed to boot the box... keeping\n";
2916 # this config is needed, add it to the ignore list.
2917 $keep_configs{$config} = $min_configs{$config};
2918 $save_configs{$config} = $min_configs{$config};
2919 delete $min_configs{$config};
2921 # update new ignore configs
2922 if (defined($ignore_config)) {
2923 open (OUT, ">$temp_config")
2924 or die "Can't write to $temp_config";
2925 foreach my $config (keys %save_configs) {
2926 print OUT "$save_configs{$config}\n";
2928 close OUT;
2929 run_command "mv $temp_config $ignore_config" or
2930 dodie "failed to copy update to $ignore_config";
2933 } else {
2934 # We booted without this config, remove it from the minconfigs.
2935 doprint "$config is not needed, disabling\n";
2937 delete $min_configs{$config};
2939 # Also disable anything that is not enabled in this config
2940 my %configs;
2941 assign_configs \%configs, $output_config;
2942 my @config_keys = keys %min_configs;
2943 foreach my $config (@config_keys) {
2944 if (!defined($configs{$config})) {
2945 doprint "$config is not set, disabling\n";
2946 delete $min_configs{$config};
2950 # Save off all the current mandidory configs
2951 open (OUT, ">$temp_config")
2952 or die "Can't write to $temp_config";
2953 foreach my $config (keys %keep_configs) {
2954 print OUT "$keep_configs{$config}\n";
2956 foreach my $config (keys %min_configs) {
2957 print OUT "$min_configs{$config}\n";
2959 close OUT;
2961 run_command "mv $temp_config $output_minconfig" or
2962 dodie "failed to copy update to $output_minconfig";
2965 doprint "Reboot and wait $sleep_time seconds\n";
2966 reboot $sleep_time;
2969 success $i;
2970 return 1;
2973 $#ARGV < 1 or die "ktest.pl version: $VERSION\n usage: ktest.pl config-file\n";
2975 if ($#ARGV == 0) {
2976 $ktest_config = $ARGV[0];
2977 if (! -f $ktest_config) {
2978 print "$ktest_config does not exist.\n";
2979 if (!read_yn "Create it?") {
2980 exit 0;
2983 } else {
2984 $ktest_config = "ktest.conf";
2987 if (! -f $ktest_config) {
2988 open(OUT, ">$ktest_config") or die "Can not create $ktest_config";
2989 print OUT << "EOF"
2990 # Generated by ktest.pl
2992 # Define each test with TEST_START
2993 # The config options below it will override the defaults
2994 TEST_START
2996 DEFAULTS
2999 close(OUT);
3001 read_config $ktest_config;
3003 if (defined($opt{"LOG_FILE"})) {
3004 $opt{"LOG_FILE"} = eval_option($opt{"LOG_FILE"}, -1);
3007 # Append any configs entered in manually to the config file.
3008 my @new_configs = keys %entered_configs;
3009 if ($#new_configs >= 0) {
3010 print "\nAppending entered in configs to $ktest_config\n";
3011 open(OUT, ">>$ktest_config") or die "Can not append to $ktest_config";
3012 foreach my $config (@new_configs) {
3013 print OUT "$config = $entered_configs{$config}\n";
3014 $opt{$config} = $entered_configs{$config};
3018 if ($opt{"CLEAR_LOG"} && defined($opt{"LOG_FILE"})) {
3019 unlink $opt{"LOG_FILE"};
3022 doprint "\n\nSTARTING AUTOMATED TESTS\n\n";
3024 for (my $i = 0, my $repeat = 1; $i <= $opt{"NUM_TESTS"}; $i += $repeat) {
3026 if (!$i) {
3027 doprint "DEFAULT OPTIONS:\n";
3028 } else {
3029 doprint "\nTEST $i OPTIONS";
3030 if (defined($repeat_tests{$i})) {
3031 $repeat = $repeat_tests{$i};
3032 doprint " ITERATE $repeat";
3034 doprint "\n";
3037 foreach my $option (sort keys %opt) {
3039 if ($option =~ /\[(\d+)\]$/) {
3040 next if ($i != $1);
3041 } else {
3042 next if ($i);
3045 doprint "$option = $opt{$option}\n";
3049 sub __set_test_option {
3050 my ($name, $i) = @_;
3052 my $option = "$name\[$i\]";
3054 if (defined($opt{$option})) {
3055 return $opt{$option};
3058 foreach my $test (keys %repeat_tests) {
3059 if ($i >= $test &&
3060 $i < $test + $repeat_tests{$test}) {
3061 $option = "$name\[$test\]";
3062 if (defined($opt{$option})) {
3063 return $opt{$option};
3068 if (defined($opt{$name})) {
3069 return $opt{$name};
3072 return undef;
3075 sub set_test_option {
3076 my ($name, $i) = @_;
3078 my $option = __set_test_option($name, $i);
3079 return $option if (!defined($option));
3081 return eval_option($option, $i);
3084 # First we need to do is the builds
3085 for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
3087 # Do not reboot on failing test options
3088 $no_reboot = 1;
3090 $iteration = $i;
3092 my $makecmd = set_test_option("MAKE_CMD", $i);
3094 $machine = set_test_option("MACHINE", $i);
3095 $ssh_user = set_test_option("SSH_USER", $i);
3096 $tmpdir = set_test_option("TMP_DIR", $i);
3097 $outputdir = set_test_option("OUTPUT_DIR", $i);
3098 $builddir = set_test_option("BUILD_DIR", $i);
3099 $test_type = set_test_option("TEST_TYPE", $i);
3100 $build_type = set_test_option("BUILD_TYPE", $i);
3101 $build_options = set_test_option("BUILD_OPTIONS", $i);
3102 $pre_build = set_test_option("PRE_BUILD", $i);
3103 $post_build = set_test_option("POST_BUILD", $i);
3104 $pre_build_die = set_test_option("PRE_BUILD_DIE", $i);
3105 $post_build_die = set_test_option("POST_BUILD_DIE", $i);
3106 $power_cycle = set_test_option("POWER_CYCLE", $i);
3107 $reboot = set_test_option("REBOOT", $i);
3108 $noclean = set_test_option("BUILD_NOCLEAN", $i);
3109 $minconfig = set_test_option("MIN_CONFIG", $i);
3110 $output_minconfig = set_test_option("OUTPUT_MIN_CONFIG", $i);
3111 $start_minconfig = set_test_option("START_MIN_CONFIG", $i);
3112 $ignore_config = set_test_option("IGNORE_CONFIG", $i);
3113 $run_test = set_test_option("TEST", $i);
3114 $addconfig = set_test_option("ADD_CONFIG", $i);
3115 $reboot_type = set_test_option("REBOOT_TYPE", $i);
3116 $grub_menu = set_test_option("GRUB_MENU", $i);
3117 $post_install = set_test_option("POST_INSTALL", $i);
3118 $no_install = set_test_option("NO_INSTALL", $i);
3119 $reboot_script = set_test_option("REBOOT_SCRIPT", $i);
3120 $reboot_on_error = set_test_option("REBOOT_ON_ERROR", $i);
3121 $poweroff_on_error = set_test_option("POWEROFF_ON_ERROR", $i);
3122 $die_on_failure = set_test_option("DIE_ON_FAILURE", $i);
3123 $power_off = set_test_option("POWER_OFF", $i);
3124 $powercycle_after_reboot = set_test_option("POWERCYCLE_AFTER_REBOOT", $i);
3125 $poweroff_after_halt = set_test_option("POWEROFF_AFTER_HALT", $i);
3126 $sleep_time = set_test_option("SLEEP_TIME", $i);
3127 $bisect_sleep_time = set_test_option("BISECT_SLEEP_TIME", $i);
3128 $patchcheck_sleep_time = set_test_option("PATCHCHECK_SLEEP_TIME", $i);
3129 $ignore_warnings = set_test_option("IGNORE_WARNINGS", $i);
3130 $bisect_manual = set_test_option("BISECT_MANUAL", $i);
3131 $bisect_skip = set_test_option("BISECT_SKIP", $i);
3132 $config_bisect_good = set_test_option("CONFIG_BISECT_GOOD", $i);
3133 $store_failures = set_test_option("STORE_FAILURES", $i);
3134 $test_name = set_test_option("TEST_NAME", $i);
3135 $timeout = set_test_option("TIMEOUT", $i);
3136 $booted_timeout = set_test_option("BOOTED_TIMEOUT", $i);
3137 $console = set_test_option("CONSOLE", $i);
3138 $detect_triplefault = set_test_option("DETECT_TRIPLE_FAULT", $i);
3139 $success_line = set_test_option("SUCCESS_LINE", $i);
3140 $reboot_success_line = set_test_option("REBOOT_SUCCESS_LINE", $i);
3141 $stop_after_success = set_test_option("STOP_AFTER_SUCCESS", $i);
3142 $stop_after_failure = set_test_option("STOP_AFTER_FAILURE", $i);
3143 $stop_test_after = set_test_option("STOP_TEST_AFTER", $i);
3144 $build_target = set_test_option("BUILD_TARGET", $i);
3145 $ssh_exec = set_test_option("SSH_EXEC", $i);
3146 $scp_to_target = set_test_option("SCP_TO_TARGET", $i);
3147 $target_image = set_test_option("TARGET_IMAGE", $i);
3148 $localversion = set_test_option("LOCALVERSION", $i);
3150 $start_minconfig_defined = 1;
3152 if (!defined($start_minconfig)) {
3153 $start_minconfig_defined = 0;
3154 $start_minconfig = $minconfig;
3157 chdir $builddir || die "can't change directory to $builddir";
3159 foreach my $dir ($tmpdir, $outputdir) {
3160 if (!-d $dir) {
3161 mkpath($dir) or
3162 die "can't create $dir";
3166 $ENV{"SSH_USER"} = $ssh_user;
3167 $ENV{"MACHINE"} = $machine;
3169 $target = "$ssh_user\@$machine";
3171 $buildlog = "$tmpdir/buildlog-$machine";
3172 $dmesg = "$tmpdir/dmesg-$machine";
3173 $make = "$makecmd O=$outputdir";
3174 $output_config = "$outputdir/.config";
3176 if ($reboot_type eq "grub") {
3177 dodie "GRUB_MENU not defined" if (!defined($grub_menu));
3178 } elsif (!defined($reboot_script)) {
3179 dodie "REBOOT_SCRIPT not defined"
3182 my $run_type = $build_type;
3183 if ($test_type eq "patchcheck") {
3184 $run_type = $opt{"PATCHCHECK_TYPE[$i]"};
3185 } elsif ($test_type eq "bisect") {
3186 $run_type = $opt{"BISECT_TYPE[$i]"};
3187 } elsif ($test_type eq "config_bisect") {
3188 $run_type = $opt{"CONFIG_BISECT_TYPE[$i]"};
3191 if ($test_type eq "make_min_config") {
3192 $run_type = "";
3195 # mistake in config file?
3196 if (!defined($run_type)) {
3197 $run_type = "ERROR";
3200 my $installme = "";
3201 $installme = " no_install" if ($no_install);
3203 doprint "\n\n";
3204 doprint "RUNNING TEST $i of $opt{NUM_TESTS} with option $test_type $run_type$installme\n\n";
3206 unlink $dmesg;
3207 unlink $buildlog;
3209 if (defined($addconfig)) {
3210 my $min = $minconfig;
3211 if (!defined($minconfig)) {
3212 $min = "";
3214 run_command "cat $addconfig $min > $tmpdir/add_config" or
3215 dodie "Failed to create temp config";
3216 $minconfig = "$tmpdir/add_config";
3219 my $checkout = $opt{"CHECKOUT[$i]"};
3220 if (defined($checkout)) {
3221 run_command "git checkout $checkout" or
3222 die "failed to checkout $checkout";
3225 $no_reboot = 0;
3228 if ($test_type eq "bisect") {
3229 bisect $i;
3230 next;
3231 } elsif ($test_type eq "config_bisect") {
3232 config_bisect $i;
3233 next;
3234 } elsif ($test_type eq "patchcheck") {
3235 patchcheck $i;
3236 next;
3237 } elsif ($test_type eq "make_min_config") {
3238 make_min_config $i;
3239 next;
3242 if ($build_type ne "nobuild") {
3243 build $build_type or next;
3246 if ($test_type eq "install") {
3247 get_version;
3248 install;
3249 success $i;
3250 next;
3253 if ($test_type ne "build") {
3254 my $failed = 0;
3255 start_monitor_and_boot or $failed = 1;
3257 if (!$failed && $test_type ne "boot" && defined($run_test)) {
3258 do_run_test or $failed = 1;
3260 end_monitor;
3261 next if ($failed);
3264 success $i;
3267 if ($opt{"POWEROFF_ON_SUCCESS"}) {
3268 halt;
3269 } elsif ($opt{"REBOOT_ON_SUCCESS"} && !do_not_reboot) {
3270 reboot;
3273 doprint "\n $successes of $opt{NUM_TESTS} tests were successful\n\n";
3275 exit 0;