3 # Copyright 2010 - Steven Rostedt <srostedt@redhat.com>, Red Hat Inc.
4 # Licensed under the terms of the GNU GPL License version 2
9 use Fcntl qw(F_GETFL F_SETFL O_NONBLOCK);
10 use File::Path qw(mkpath);
11 use File::Copy qw(cp);
25 "TEST_TYPE" => "build",
26 "BUILD_TYPE" => "randconfig",
29 "TMP_DIR" => "/tmp/ktest/\${MACHINE}",
30 "SLEEP_TIME" => 60, # sleep time between tests
32 "REBOOT_ON_ERROR" => 0,
33 "POWEROFF_ON_ERROR" => 0,
34 "REBOOT_ON_SUCCESS" => 1,
35 "POWEROFF_ON_SUCCESS" => 0,
36 "BUILD_OPTIONS" => "",
37 "BISECT_SLEEP_TIME" => 60, # sleep time between bisects
38 "PATCHCHECK_SLEEP_TIME" => 60, # sleep time between patch checks
42 "SUCCESS_LINE" => "login:",
43 "DETECT_TRIPLE_FAULT" => 1,
45 "BOOTED_TIMEOUT" => 1,
46 "DIE_ON_FAILURE" => 1,
47 "SSH_EXEC" => "ssh \$SSH_USER\@\$MACHINE \$SSH_COMMAND",
48 "SCP_TO_TARGET" => "scp \$SRC_FILE \$SSH_USER\@\$MACHINE:\$DST_FILE",
49 "REBOOT" => "ssh \$SSH_USER\@\$MACHINE reboot",
50 "STOP_AFTER_SUCCESS" => 10,
51 "STOP_AFTER_FAILURE" => 60,
52 "STOP_TEST_AFTER" => 600,
54 # required, and we will ask users if they don't have them but we keep the default
55 # value something that is common.
56 "REBOOT_TYPE" => "grub",
57 "LOCALVERSION" => "-test",
59 "BUILD_TARGET" => "arch/x86/boot/bzImage",
60 "TARGET_IMAGE" => "/boot/vmlinuz-test",
88 my $poweroff_on_error;
90 my $powercycle_after_reboot;
91 my $poweroff_after_halt;
104 my $start_minconfig_defined;
105 my $output_minconfig;
110 my $bisect_bad_commit = "";
114 my $config_bisect_good;
118 my $bisect_ret_abort;
119 my $bisect_ret_default;
120 my $in_patchcheck = 0;
130 my $bisect_sleep_time;
131 my $patchcheck_sleep_time;
138 my $detect_triplefault;
140 my $reboot_success_line;
142 my $stop_after_success;
143 my $stop_after_failure;
162 my $config_bisect_type;
165 my $patchcheck_start;
168 # set when a test is something other that just building or install
169 # which would require more options.
172 # set when creating a new config
180 # do not force reboots on config problems
184 "MACHINE" => \$machine,
185 "SSH_USER" => \$ssh_user,
186 "TMP_DIR" => \$tmpdir,
187 "OUTPUT_DIR" => \$outputdir,
188 "BUILD_DIR" => \$builddir,
189 "TEST_TYPE" => \$test_type,
190 "BUILD_TYPE" => \$build_type,
191 "BUILD_OPTIONS" => \$build_options,
192 "PRE_BUILD" => \$pre_build,
193 "POST_BUILD" => \$post_build,
194 "PRE_BUILD_DIE" => \$pre_build_die,
195 "POST_BUILD_DIE" => \$post_build_die,
196 "POWER_CYCLE" => \$power_cycle,
197 "REBOOT" => \$reboot,
198 "BUILD_NOCLEAN" => \$noclean,
199 "MIN_CONFIG" => \$minconfig,
200 "OUTPUT_MIN_CONFIG" => \$output_minconfig,
201 "START_MIN_CONFIG" => \$start_minconfig,
202 "IGNORE_CONFIG" => \$ignore_config,
203 "TEST" => \$run_test,
204 "ADD_CONFIG" => \$addconfig,
205 "REBOOT_TYPE" => \$reboot_type,
206 "GRUB_MENU" => \$grub_menu,
207 "POST_INSTALL" => \$post_install,
208 "NO_INSTALL" => \$no_install,
209 "REBOOT_SCRIPT" => \$reboot_script,
210 "REBOOT_ON_ERROR" => \$reboot_on_error,
211 "SWITCH_TO_GOOD" => \$switch_to_good,
212 "SWITCH_TO_TEST" => \$switch_to_test,
213 "POWEROFF_ON_ERROR" => \$poweroff_on_error,
214 "DIE_ON_FAILURE" => \$die_on_failure,
215 "POWER_OFF" => \$power_off,
216 "POWERCYCLE_AFTER_REBOOT" => \$powercycle_after_reboot,
217 "POWEROFF_AFTER_HALT" => \$poweroff_after_halt,
218 "SLEEP_TIME" => \$sleep_time,
219 "BISECT_SLEEP_TIME" => \$bisect_sleep_time,
220 "PATCHCHECK_SLEEP_TIME" => \$patchcheck_sleep_time,
221 "IGNORE_WARNINGS" => \$ignore_warnings,
222 "IGNORE_ERRORS" => \$ignore_errors,
223 "BISECT_MANUAL" => \$bisect_manual,
224 "BISECT_SKIP" => \$bisect_skip,
225 "CONFIG_BISECT_GOOD" => \$config_bisect_good,
226 "BISECT_RET_GOOD" => \$bisect_ret_good,
227 "BISECT_RET_BAD" => \$bisect_ret_bad,
228 "BISECT_RET_SKIP" => \$bisect_ret_skip,
229 "BISECT_RET_ABORT" => \$bisect_ret_abort,
230 "BISECT_RET_DEFAULT" => \$bisect_ret_default,
231 "STORE_FAILURES" => \$store_failures,
232 "STORE_SUCCESSES" => \$store_successes,
233 "TEST_NAME" => \$test_name,
234 "TIMEOUT" => \$timeout,
235 "BOOTED_TIMEOUT" => \$booted_timeout,
236 "CONSOLE" => \$console,
237 "DETECT_TRIPLE_FAULT" => \$detect_triplefault,
238 "SUCCESS_LINE" => \$success_line,
239 "REBOOT_SUCCESS_LINE" => \$reboot_success_line,
240 "STOP_AFTER_SUCCESS" => \$stop_after_success,
241 "STOP_AFTER_FAILURE" => \$stop_after_failure,
242 "STOP_TEST_AFTER" => \$stop_test_after,
243 "BUILD_TARGET" => \$build_target,
244 "SSH_EXEC" => \$ssh_exec,
245 "SCP_TO_TARGET" => \$scp_to_target,
246 "CHECKOUT" => \$checkout,
247 "TARGET_IMAGE" => \$target_image,
248 "LOCALVERSION" => \$localversion,
250 "BISECT_GOOD" => \$bisect_good,
251 "BISECT_BAD" => \$bisect_bad,
252 "BISECT_TYPE" => \$bisect_type,
253 "BISECT_START" => \$bisect_start,
254 "BISECT_REPLAY" => \$bisect_replay,
255 "BISECT_FILES" => \$bisect_files,
256 "BISECT_REVERSE" => \$bisect_reverse,
257 "BISECT_CHECK" => \$bisect_check,
259 "CONFIG_BISECT" => \$config_bisect,
260 "CONFIG_BISECT_TYPE" => \$config_bisect_type,
262 "PATCHCHECK_TYPE" => \$patchcheck_type,
263 "PATCHCHECK_START" => \$patchcheck_start,
264 "PATCHCHECK_END" => \$patchcheck_end,
267 # Options may be used by other options, record them.
270 # default variables that can be used
271 chomp ($variable{"PWD"} = `pwd`);
273 $config_help{"MACHINE"} = << "EOF"
274 The machine hostname that you will test.
275 For build only tests, it is still needed to differentiate log files.
278 $config_help{"SSH_USER"} = << "EOF"
279 The box is expected to have ssh on normal bootup, provide the user
280 (most likely root, since you need privileged operations)
283 $config_help{"BUILD_DIR"} = << "EOF"
284 The directory that contains the Linux source code (full path).
285 You can use \${PWD} that will be the path where ktest.pl is run, or use
286 \${THIS_DIR} which is assigned \${PWD} but may be changed later.
289 $config_help{"OUTPUT_DIR"} = << "EOF"
290 The directory that the objects will be built (full path).
291 (can not be same as BUILD_DIR)
292 You can use \${PWD} that will be the path where ktest.pl is run, or use
293 \${THIS_DIR} which is assigned \${PWD} but may be changed later.
296 $config_help{"BUILD_TARGET"} = << "EOF"
297 The location of the compiled file to copy to the target.
298 (relative to OUTPUT_DIR)
301 $config_help{"BUILD_OPTIONS"} = << "EOF"
302 Options to add to \"make\" when building.
306 $config_help{"TARGET_IMAGE"} = << "EOF"
307 The place to put your image on the test machine.
310 $config_help{"POWER_CYCLE"} = << "EOF"
311 A script or command to reboot the box.
313 Here is a digital loggers power switch example
314 POWER_CYCLE = wget --no-proxy -O /dev/null -q --auth-no-challenge 'http://admin:admin\@power/outlet?5=CCL'
316 Here is an example to reboot a virtual box on the current host
317 with the name "Guest".
318 POWER_CYCLE = virsh destroy Guest; sleep 5; virsh start Guest
321 $config_help{"CONSOLE"} = << "EOF"
322 The script or command that reads the console
324 If you use ttywatch server, something like the following would work.
325 CONSOLE = nc -d localhost 3001
327 For a virtual machine with guest name "Guest".
328 CONSOLE = virsh console Guest
331 $config_help{"LOCALVERSION"} = << "EOF"
332 Required version ending to differentiate the test
333 from other linux builds on the system.
336 $config_help{"REBOOT_TYPE"} = << "EOF"
337 Way to reboot the box to the test kernel.
338 Only valid options so far are "grub" and "script".
340 If you specify grub, it will assume grub version 1
341 and will search in /boot/grub/menu.lst for the title \$GRUB_MENU
342 and select that target to reboot to the kernel. If this is not
343 your setup, then specify "script" and have a command or script
344 specified in REBOOT_SCRIPT to boot to the target.
346 The entry in /boot/grub/menu.lst must be entered in manually.
347 The test will not modify that file.
350 $config_help{"GRUB_MENU"} = << "EOF"
351 The grub title name for the test kernel to boot
352 (Only mandatory if REBOOT_TYPE = grub)
354 Note, ktest.pl will not update the grub menu.lst, you need to
355 manually add an option for the test. ktest.pl will search
356 the grub menu.lst for this option to find what kernel to
359 For example, if in the /boot/grub/menu.lst the test kernel title has:
362 GRUB_MENU = Test Kernel
365 $config_help{"REBOOT_SCRIPT"} = << "EOF"
366 A script to reboot the target into the test kernel
367 (Only mandatory if REBOOT_TYPE = script)
372 my ($cancel, $prompt) = @_;
378 print "$prompt [y/n/C] ";
380 print "$prompt [Y/n] ";
384 if ($ans =~ /^\s*$/) {
391 last if ($ans =~ /^y$/i || $ans =~ /^n$/i);
393 last if ($ans =~ /^c$/i);
394 print "Please answer either 'y', 'n' or 'c'.\n";
396 print "Please answer either 'y' or 'n'.\n";
402 if ($ans !~ /^y$/i) {
411 return read_prompt 0, $prompt;
417 return read_prompt 1, $prompt;
420 sub get_ktest_config {
424 return if (defined($opt{$config}));
426 if (defined($config_help{$config})) {
428 print $config_help{$config};
433 if (defined($default{$config}) && length($default{$config})) {
434 print "\[$default{$config}\] ";
437 $ans =~ s/^\s*(.*\S)\s*$/$1/;
438 if ($ans =~ /^\s*$/) {
439 if ($default{$config}) {
440 $ans = $default{$config};
442 print "Your answer can not be blank\n";
446 $entered_configs{$config} = ${ans};
451 sub get_ktest_configs {
452 get_ktest_config("MACHINE");
453 get_ktest_config("BUILD_DIR");
454 get_ktest_config("OUTPUT_DIR");
457 get_ktest_config("BUILD_OPTIONS");
460 # options required for other than just building a kernel
462 get_ktest_config("POWER_CYCLE");
463 get_ktest_config("CONSOLE");
466 # options required for install and more
467 if ($buildonly != 1) {
468 get_ktest_config("SSH_USER");
469 get_ktest_config("BUILD_TARGET");
470 get_ktest_config("TARGET_IMAGE");
473 get_ktest_config("LOCALVERSION");
475 return if ($buildonly);
477 my $rtype = $opt{"REBOOT_TYPE"};
479 if (!defined($rtype)) {
480 if (!defined($opt{"GRUB_MENU"})) {
481 get_ktest_config("REBOOT_TYPE");
482 $rtype = $entered_configs{"REBOOT_TYPE"};
488 if ($rtype eq "grub") {
489 get_ktest_config("GRUB_MENU");
493 sub process_variables {
494 my ($value, $remove_undef) = @_;
497 # We want to check for '\', and it is just easier
498 # to check the previous characet of '$' and not need
499 # to worry if '$' is the first character. By adding
500 # a space to $value, we can just check [^\\]\$ and
501 # it will still work.
504 while ($value =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) {
508 # append beginning of value to retval
509 $retval = "$retval$begin";
510 if (defined($variable{$var})) {
511 $retval = "$retval$variable{$var}";
512 } elsif (defined($remove_undef) && $remove_undef) {
513 # for if statements, any variable that is not defined,
514 # we simple convert to 0
515 $retval = "${retval}0";
517 # put back the origin piece.
518 $retval = "$retval\$\{$var\}";
519 # This could be an option that is used later, save
520 # it so we don't warn if this option is not one of
522 $used_options{$var} = 1;
526 $retval = "$retval$value";
528 # remove the space added in the beginning
535 my ($lvalue, $rvalue, $override, $overrides, $name) = @_;
537 my $prvalue = process_variables($rvalue);
539 if ($buildonly && $lvalue =~ /^TEST_TYPE(\[.*\])?$/ && $prvalue ne "build") {
540 # Note if a test is something other than build, then we
541 # will need other manditory options.
542 if ($prvalue ne "install") {
545 # install still limits some manditory options.
550 if (defined($opt{$lvalue})) {
551 if (!$override || defined(${$overrides}{$lvalue})) {
554 $extra = "In the same override section!\n";
556 die "$name: $.: Option $lvalue defined more than once!\n$extra";
558 ${$overrides}{$lvalue} = $prvalue;
560 if ($rvalue =~ /^\s*$/) {
561 delete $opt{$lvalue};
563 $opt{$lvalue} = $prvalue;
568 my ($lvalue, $rvalue) = @_;
570 if ($rvalue =~ /^\s*$/) {
571 delete $variable{$lvalue};
573 $rvalue = process_variables($rvalue);
574 $variable{$lvalue} = $rvalue;
578 sub process_compare {
579 my ($lval, $cmp, $rval) = @_;
590 return $lval eq $rval;
591 } elsif ($cmp eq "!=") {
592 return $lval ne $rval;
595 my $statement = "$lval $cmp $rval";
596 my $ret = eval $statement;
598 # $@ stores error of eval
609 return defined($variable{$2}) ||
614 sub process_expression {
615 my ($name, $val) = @_;
619 while ($val =~ s/\(([^\(]*?)\)/\&\&\&\&VAL\&\&\&\&/) {
622 if (process_expression($name, $express)) {
623 $val =~ s/\&\&\&\&VAL\&\&\&\&/ 1 /;
625 $val =~ s/\&\&\&\&VAL\&\&\&\&/ 0 /;
633 while ($val =~ s/^(.*?)($OR|$AND)//) {
637 if (process_expression($name, $express)) {
648 if ($val =~ /(.*)(==|\!=|>=|<=|>|<)(.*)/) {
649 my $ret = process_compare($1, $2, $3);
651 die "$name: $.: Unable to process comparison\n";
656 if ($val =~ /^\s*(NOT\s*)?DEFINED\s+(\S+)\s*$/) {
658 return !value_defined($2);
660 return value_defined($2);
664 if ($val =~ /^\s*0\s*$/) {
666 } elsif ($val =~ /^\s*\d+\s*$/) {
670 die ("$name: $.: Undefined content $val in if statement\n");
674 my ($name, $value) = @_;
676 # Convert variables and replace undefined ones with 0
677 my $val = process_variables($value, 1);
678 my $ret = process_expression $name, $val;
684 my ($config, $current_test_num) = @_;
687 open($in, $config) || die "can't read file $config";
690 $name =~ s,.*/(.*),$1,;
692 my $test_num = $$current_test_num;
695 my $num_tests_set = 0;
708 # ignore blank lines and comments
709 next if (/^\s*$/ || /\s*\#/);
711 if (/^\s*(TEST_START|DEFAULTS)\b(.*)/) {
721 if ($type eq "TEST_START") {
723 if ($num_tests_set) {
724 die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
727 $old_test_num = $test_num;
728 $old_repeat = $repeat;
730 $test_num += $repeat;
737 # If SKIP is anywhere in the line, the command will be skipped
738 if ($rest =~ s/\s+SKIP\b//) {
745 if ($rest =~ s/\sELSE\b//) {
747 die "$name: $.: ELSE found with out matching IF section\n$_";
758 if ($rest =~ s/\sIF\s+(.*)//) {
759 if (process_if($name, $1)) {
771 if ($type eq "TEST_START") {
772 if ($rest =~ s/\s+ITERATE\s+(\d+)//) {
774 $repeat_tests{"$test_num"} = $repeat;
776 } elsif ($rest =~ s/\sOVERRIDE\b//) {
779 # Clear previous overrides
784 if (!$skip && $rest !~ /^\s*$/) {
785 die "$name: $.: Gargbage found after $type\n$_";
788 if ($skip && $type eq "TEST_START") {
789 $test_num = $old_test_num;
790 $repeat = $old_repeat;
793 } elsif (/^\s*ELSE\b(.*)$/) {
795 die "$name: $.: ELSE found with out matching IF section\n$_";
804 if ($rest =~ /\sIF\s+(.*)/) {
805 # May be a ELSE IF section.
806 if (!process_if($name, $1)) {
815 if ($rest !~ /^\s*$/) {
816 die "$name: $.: Gargbage found after DEFAULTS\n$_";
819 } elsif (/^\s*INCLUDE\s+(\S+)/) {
824 die "$name: $.: INCLUDE can only be done in default sections\n$_";
827 my $file = process_variables($1);
829 if ($file !~ m,^/,) {
830 # check the path of the config file first
831 if ($config =~ m,(.*)/,) {
839 die "$name: $.: Can't read file $file\n$_";
842 if (__read_config($file, \$test_num)) {
846 } elsif (/^\s*([A-Z_\[\]\d]+)\s*=\s*(.*?)\s*$/) {
854 ($lvalue eq "NUM_TESTS" ||
855 $lvalue eq "LOG_FILE" ||
856 $lvalue eq "CLEAR_LOG")) {
857 die "$name: $.: $lvalue must be set in DEFAULTS section\n";
860 if ($lvalue eq "NUM_TESTS") {
862 die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
865 die "$name: $.: NUM_TESTS must be set in default section\n";
870 if ($default || $lvalue =~ /\[\d+\]$/) {
871 set_value($lvalue, $rvalue, $override, \%overrides, $name);
873 my $val = "$lvalue\[$test_num\]";
874 set_value($val, $rvalue, $override, \%overrides, $name);
877 $repeats{$val} = $repeat;
880 } elsif (/^\s*([A-Z_\[\]\d]+)\s*:=\s*(.*?)\s*$/) {
886 # process config variables.
887 # Config variables are only active while reading the
888 # config and can be defined anywhere. They also ignore
889 # TEST_START and DEFAULTS, but are skipped if they are in
890 # on of these sections that have SKIP defined.
891 # The save variable can be
892 # defined multiple times and the new one simply overrides
894 set_variable($lvalue, $rvalue);
897 die "$name: $.: Garbage found in config\n$_";
902 $test_num += $repeat - 1;
903 $opt{"NUM_TESTS"} = $test_num;
908 $$current_test_num = $test_num;
914 print "What test case would you like to run?\n";
915 print " (build, install or boot)\n";
916 print " Other tests are available but require editing the config file\n";
919 $default{"TEST_TYPE"} = $ans;
928 $test_case = __read_config $config, \$test_num;
930 # make sure we have all mandatory configs
933 # was a test specified?
935 print "No test case specified.\n";
941 foreach my $default (keys %default) {
942 if (!defined($opt{$default})) {
943 $opt{$default} = $default{$default};
947 if ($opt{"IGNORE_UNUSED"} == 1) {
953 # check if there are any stragglers (typos?)
954 foreach my $option (keys %opt) {
956 # remove per test labels.
958 if (!exists($option_map{$op}) &&
959 !exists($default{$op}) &&
960 !exists($used_options{$op})) {
967 $s = " is" if (keys %not_used == 1);
968 print "The following option$s not used; could be a typo:\n";
969 foreach my $option (keys %not_used) {
972 print "Set IGRNORE_UNUSED = 1 to have ktest ignore unused variables\n";
973 if (!read_yn "Do you want to continue?") {
980 my ($option, $i) = @_;
982 # Add space to evaluate the character before $
983 $option = " $option";
988 foreach my $test (keys %repeat_tests) {
990 $i < $test + $repeat_tests{$test}) {
998 while ($option =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) {
1003 # Append beginning of line
1004 $retval = "$retval$start";
1006 # If the iteration option OPT[$i] exists, then use that.
1007 # otherwise see if the default OPT (without [$i]) exists.
1009 my $o = "$var\[$i\]";
1010 my $parento = "$var\[$parent\]";
1012 if (defined($opt{$o})) {
1014 $retval = "$retval$o";
1015 } elsif ($repeated && defined($opt{$parento})) {
1016 $o = $opt{$parento};
1017 $retval = "$retval$o";
1018 } elsif (defined($opt{$var})) {
1020 $retval = "$retval$o";
1022 $retval = "$retval\$\{$var\}";
1028 $retval = "$retval$option";
1036 my ($option, $i) = @_;
1040 # Since an option can evaluate to another option,
1041 # keep iterating until we do not evaluate any more
1044 while ($prev ne $option) {
1045 # Check for recursive evaluations.
1046 # 100 deep should be more than enough.
1048 die "Over 100 evaluations accurred with $option\n" .
1049 "Check for recursive variables\n";
1052 $option = __eval_option($option, $i);
1059 if (defined($opt{"LOG_FILE"})) {
1060 open(OUT, ">> $opt{LOG_FILE}") or die "Can't write to $opt{LOG_FILE}";
1067 if (defined($opt{"LOG_FILE"})) {
1082 sub wait_for_monitor;
1087 if (defined($time)) {
1089 # flush out current monitor
1090 # May contain the reboot success line
1094 # try to reboot normally
1095 if (run_command $reboot) {
1096 if (defined($powercycle_after_reboot)) {
1097 sleep $powercycle_after_reboot;
1098 run_command "$power_cycle";
1101 # nope? power cycle it.
1102 run_command "$power_cycle";
1105 if (defined($time)) {
1106 wait_for_monitor($time, $reboot_success_line);
1111 sub reboot_to_good {
1114 if (defined($switch_to_good)) {
1115 run_command $switch_to_good;
1125 return $test_type eq "build" || $no_reboot ||
1126 ($test_type eq "patchcheck" && $opt{"PATCHCHECK_TYPE[$i]"} eq "build") ||
1127 ($test_type eq "bisect" && $opt{"BISECT_TYPE[$i]"} eq "build");
1131 doprint "CRITICAL FAILURE... ", @_, "\n";
1135 if ($reboot_on_error && !do_not_reboot) {
1137 doprint "REBOOTING\n";
1140 } elsif ($poweroff_on_error && defined($power_off)) {
1141 doprint "POWERING OFF\n";
1145 if (defined($opt{"LOG_FILE"})) {
1146 print " See $opt{LOG_FILE} for more info.\n";
1157 my $pid = open($fp, "$console|") or
1158 dodie "Can't open console $console";
1160 $flags = fcntl($fp, F_GETFL, 0) or
1161 dodie "Can't get flags for the socket: $!";
1162 $flags = fcntl($fp, F_SETFL, $flags | O_NONBLOCK) or
1163 dodie "Can't set flags for the socket: $!";
1169 my ($fp, $pid) = @_;
1171 doprint "kill child process $pid\n";
1179 if ($monitor_cnt++) {
1182 $monitor_fp = \*MONFD;
1183 $monitor_pid = open_console $monitor_fp;
1187 open(MONFD, "Stop perl from warning about single use of MONFD");
1191 if (--$monitor_cnt) {
1194 close_console($monitor_fp, $monitor_pid);
1197 sub wait_for_monitor {
1198 my ($time, $stop) = @_;
1203 doprint "** Wait for monitor to settle down **\n";
1205 # read the monitor and wait for the system to calm down
1207 $line = wait_for_input($monitor_fp, $time);
1208 last if (!defined($line));
1210 $full_line .= $line;
1212 if (defined($stop) && $full_line =~ /$stop/) {
1213 doprint "wait for monitor detected $stop\n";
1217 if ($line =~ /\n/) {
1221 print "** Monitor flushed **\n";
1225 my ($result, $basedir) = @_;
1227 my $date = sprintf "%04d%02d%02d%02d%02d%02d",
1228 1900+$t[5],$t[4],$t[3],$t[2],$t[1],$t[0];
1230 my $type = $build_type;
1231 if ($type =~ /useconfig/) {
1232 $type = "useconfig";
1235 my $dir = "$machine-$test_type-$type-$result-$date";
1237 $dir = "$basedir/$dir";
1241 die "can't create $dir";
1245 "config" => $output_config,
1246 "buildlog" => $buildlog,
1248 "testlog" => $testlog,
1251 while (my ($name, $source) = each(%files)) {
1253 cp "$source", "$dir/$name" or
1254 die "failed to copy $source";
1258 doprint "*** Saved info to $dir ***\n";
1263 if ($die_on_failure) {
1271 # no need to reboot for just building.
1272 if (!do_not_reboot) {
1273 doprint "REBOOTING\n";
1274 reboot_to_good $sleep_time;
1279 if (defined($test_name)) {
1280 $name = " ($test_name)";
1283 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
1284 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
1285 doprint "KTEST RESULT: TEST $i$name Failed: ", @_, "\n";
1286 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
1287 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
1289 if (defined($store_failures)) {
1290 save_logs "fail", $store_failures;
1302 $command =~ s/\$SSH_USER/$ssh_user/g;
1303 $command =~ s/\$MACHINE/$machine/g;
1305 doprint("$command ... ");
1307 $pid = open(CMD, "$command 2>&1 |") or
1308 (fail "unable to exec $command" and return 0);
1310 if (defined($opt{"LOG_FILE"})) {
1311 open(LOG, ">>$opt{LOG_FILE}") or
1312 dodie "failed to write to log";
1316 if (defined($redirect)) {
1317 open (RD, ">$redirect") or
1318 dodie "failed to write to redirect $redirect";
1323 print LOG if ($dolog);
1324 print RD if ($dord);
1331 close(LOG) if ($dolog);
1332 close(RD) if ($dord);
1335 doprint "FAILED!\n";
1337 doprint "SUCCESS\n";
1345 my $cp_exec = $ssh_exec;
1347 $cp_exec =~ s/\$SSH_COMMAND/$cmd/g;
1348 return run_command "$cp_exec";
1352 my ($src, $dst) = @_;
1353 my $cp_scp = $scp_to_target;
1355 $cp_scp =~ s/\$SRC_FILE/$src/g;
1356 $cp_scp =~ s/\$DST_FILE/$dst/g;
1358 return run_command "$cp_scp";
1361 sub get_grub_index {
1363 if ($reboot_type ne "grub") {
1366 return if (defined($grub_number));
1368 doprint "Find grub menu ... ";
1371 my $ssh_grub = $ssh_exec;
1372 $ssh_grub =~ s,\$SSH_COMMAND,cat /boot/grub/menu.lst,g;
1374 open(IN, "$ssh_grub |")
1375 or die "unable to get menu.lst";
1380 if (/^\s*title\s+$grub_menu\s*$/) {
1384 } elsif (/^\s*title\s/) {
1390 die "Could not find '$grub_menu' in /boot/grub/menu on $machine"
1392 doprint "$grub_number\n";
1397 my ($fp, $time) = @_;
1403 if (!defined($time)) {
1408 vec($rin, fileno($fp), 1) = 1;
1409 $ready = select($rin, undef, undef, $time);
1413 # try to read one char at a time
1414 while (sysread $fp, $ch, 1) {
1416 last if ($ch eq "\n");
1419 if (!length($line)) {
1427 if (defined($switch_to_test)) {
1428 run_command $switch_to_test;
1431 if ($reboot_type eq "grub") {
1432 run_ssh "'(echo \"savedefault --default=$grub_number --once\" | grub --batch)'";
1433 } elsif (defined $reboot_script) {
1434 run_command "$reboot_script";
1442 doprint "git rev-list --max-count=1 $commit ... ";
1443 my $sha1 = `git rev-list --max-count=1 $commit`;
1450 dodie "Failed to get git $commit";
1463 my $bug_ignored = 0;
1464 my $skip_call_trace = 0;
1472 open(DMESG, "> $dmesg") or
1473 die "unable to write to $dmesg";
1479 my $monitor_start = time;
1481 my $version_found = 0;
1485 if ($bug && defined($stop_after_failure) &&
1486 $stop_after_failure >= 0) {
1487 my $time = $stop_after_failure - (time - $failure_start);
1488 $line = wait_for_input($monitor_fp, $time);
1489 if (!defined($line)) {
1490 doprint "bug timed out after $booted_timeout seconds\n";
1491 doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
1495 $line = wait_for_input($monitor_fp, $booted_timeout);
1496 if (!defined($line)) {
1497 my $s = $booted_timeout == 1 ? "" : "s";
1498 doprint "Successful boot found: break after $booted_timeout second$s\n";
1502 $line = wait_for_input($monitor_fp);
1503 if (!defined($line)) {
1504 my $s = $timeout == 1 ? "" : "s";
1505 doprint "Timed out after $timeout second$s\n";
1513 # we are not guaranteed to get a full line
1514 $full_line .= $line;
1516 if ($full_line =~ /$success_line/) {
1518 $success_start = time;
1521 if ($booted && defined($stop_after_success) &&
1522 $stop_after_success >= 0) {
1524 if ($now - $success_start >= $stop_after_success) {
1525 doprint "Test forced to stop after $stop_after_success seconds after success\n";
1530 if ($full_line =~ /\[ backtrace testing \]/) {
1531 $skip_call_trace = 1;
1534 if ($full_line =~ /call trace:/i) {
1535 if (!$bug && !$skip_call_trace) {
1536 if ($ignore_errors) {
1540 $failure_start = time;
1545 if ($bug && defined($stop_after_failure) &&
1546 $stop_after_failure >= 0) {
1548 if ($now - $failure_start >= $stop_after_failure) {
1549 doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
1554 if ($full_line =~ /\[ end of backtrace testing \]/) {
1555 $skip_call_trace = 0;
1558 if ($full_line =~ /Kernel panic -/) {
1559 $failure_start = time;
1563 # Detect triple faults by testing the banner
1564 if ($full_line =~ /\bLinux version (\S+).*\n/) {
1565 if ($1 eq $version) {
1567 } elsif ($version_found && $detect_triplefault) {
1568 # We already booted into the kernel we are testing,
1569 # but now we booted into another kernel?
1570 # Consider this a triple fault.
1571 doprint "Aleady booted in Linux kernel $version, but now\n";
1572 doprint "we booted into Linux kernel $1.\n";
1573 doprint "Assuming that this is a triple fault.\n";
1574 doprint "To disable this: set DETECT_TRIPLE_FAULT to 0\n";
1579 if ($line =~ /\n/) {
1583 if ($stop_test_after > 0 && !$booted && !$bug) {
1584 if (time - $monitor_start > $stop_test_after) {
1585 doprint "STOP_TEST_AFTER ($stop_test_after seconds) timed out\n";
1594 return 0 if ($in_bisect);
1595 fail "failed - got a bug report" and return 0;
1599 return 0 if ($in_bisect);
1600 fail "failed - never got a boot prompt." and return 0;
1604 doprint "WARNING: Call Trace detected but ignored due to IGNORE_ERRORS=1\n";
1610 sub eval_kernel_version {
1613 $option =~ s/\$KERNEL_VERSION/$version/g;
1618 sub do_post_install {
1620 return if (!defined($post_install));
1622 my $cp_post_install = eval_kernel_version $post_install;
1623 run_command "$cp_post_install" or
1624 dodie "Failed to run post install";
1629 return if ($no_install);
1631 my $cp_target = eval_kernel_version $target_image;
1633 run_scp "$outputdir/$build_target", "$cp_target" or
1634 dodie "failed to copy image";
1636 my $install_mods = 0;
1638 # should we process modules?
1640 open(IN, "$output_config") or dodie("Can't read config file");
1642 if (/CONFIG_MODULES(=y)?/) {
1643 $install_mods = 1 if (defined($1));
1649 if (!$install_mods) {
1651 doprint "No modules needed\n";
1655 run_command "$make INSTALL_MOD_STRIP=1 INSTALL_MOD_PATH=$tmpdir modules_install" or
1656 dodie "Failed to install modules";
1658 my $modlib = "/lib/modules/$version";
1659 my $modtar = "ktest-mods.tar.bz2";
1661 run_ssh "rm -rf $modlib" or
1662 dodie "failed to remove old mods: $modlib";
1664 # would be nice if scp -r did not follow symbolic links
1665 run_command "cd $tmpdir && tar -cjf $modtar lib/modules/$version" or
1666 dodie "making tarball";
1668 run_scp "$tmpdir/$modtar", "/tmp" or
1669 dodie "failed to copy modules";
1671 unlink "$tmpdir/$modtar";
1673 run_ssh "'(cd / && tar xjf /tmp/$modtar)'" or
1674 dodie "failed to tar modules";
1676 run_ssh "rm -f /tmp/$modtar";
1682 # get the release name
1683 doprint "$make kernelrelease ... ";
1684 $version = `$make kernelrelease | tail -1`;
1686 doprint "$version\n";
1689 sub start_monitor_and_boot {
1690 # Make sure the stable kernel has finished booting
1703 sub check_buildlog {
1706 my @files = `git show $patch | diffstat -l`;
1708 open(IN, "git show $patch |") or
1709 dodie "failed to show $patch";
1711 if (m,^--- a/(.*),) {
1713 $files[$#files] = $1;
1718 open(IN, $buildlog) or dodie "Can't open $buildlog";
1720 if (/^\s*(.*?):.*(warning|error)/) {
1722 foreach my $file (@files) {
1723 my $fullpath = "$builddir/$file";
1724 if ($file eq $err || $fullpath eq $err) {
1725 fail "$file built with warnings" and return 0;
1735 sub apply_min_config {
1736 my $outconfig = "$output_config.new";
1738 # Read the config file and remove anything that
1739 # is in the force_config hash (from minconfig and others)
1740 # then add the force config back.
1742 doprint "Applying minimum configurations into $output_config.new\n";
1744 open (OUT, ">$outconfig") or
1745 dodie "Can't create $outconfig";
1747 if (-f $output_config) {
1748 open (IN, $output_config) or
1749 dodie "Failed to open $output_config";
1751 if (/^(# )?(CONFIG_[^\s=]*)/) {
1752 next if (defined($force_config{$2}));
1758 foreach my $config (keys %force_config) {
1759 print OUT "$force_config{$config}\n";
1763 run_command "mv $outconfig $output_config";
1766 sub make_oldconfig {
1768 my @force_list = keys %force_config;
1770 if ($#force_list >= 0) {
1774 if (!run_command "$make oldnoconfig") {
1775 # Perhaps oldnoconfig doesn't exist in this version of the kernel
1776 # try a yes '' | oldconfig
1777 doprint "oldnoconfig failed, trying yes '' | make oldconfig\n";
1778 run_command "yes '' | $make oldconfig" or
1779 dodie "failed make config oldconfig";
1783 # read a config file and use this to force new configs.
1784 sub load_force_config {
1787 open(IN, $config) or
1788 dodie "failed to read $config";
1791 if (/^(CONFIG[^\s=]*)(\s*=.*)/) {
1792 $force_config{$1} = $_;
1793 } elsif (/^# (CONFIG_\S*) is not set/) {
1794 $force_config{$1} = $_;
1805 # Failed builds should not reboot the target
1806 my $save_no_reboot = $no_reboot;
1809 if (defined($pre_build)) {
1810 my $ret = run_command $pre_build;
1811 if (!$ret && defined($pre_build_die) &&
1813 dodie "failed to pre_build\n";
1817 if ($type =~ /^useconfig:(.*)/) {
1818 run_command "cp $1 $output_config" or
1819 dodie "could not copy $1 to .config";
1821 $type = "oldconfig";
1824 # old config can ask questions
1825 if ($type eq "oldconfig") {
1826 $type = "oldnoconfig";
1828 # allow for empty configs
1829 run_command "touch $output_config";
1832 run_command "mv $output_config $outputdir/config_temp" or
1833 dodie "moving .config";
1835 run_command "$make mrproper" or dodie "make mrproper";
1837 run_command "mv $outputdir/config_temp $output_config" or
1838 dodie "moving config_temp";
1841 } elsif (!$noclean) {
1842 unlink "$output_config";
1843 run_command "$make mrproper" or
1844 dodie "make mrproper";
1847 # add something to distinguish this build
1848 open(OUT, "> $outputdir/localversion") or dodie("Can't make localversion file");
1849 print OUT "$localversion\n";
1852 if (defined($minconfig)) {
1853 load_force_config($minconfig);
1856 if ($type ne "oldnoconfig") {
1857 run_command "$make $type" or
1858 dodie "failed make config";
1860 # Run old config regardless, to enforce min configurations
1863 $redirect = "$buildlog";
1864 my $build_ret = run_command "$make $build_options";
1867 if (defined($post_build)) {
1868 my $ret = run_command $post_build;
1869 if (!$ret && defined($post_build_die) &&
1871 dodie "failed to post_build\n";
1876 # bisect may need this to pass
1878 $no_reboot = $save_no_reboot;
1881 fail "failed build" and return 0;
1884 $no_reboot = $save_no_reboot;
1890 if (!run_ssh "halt" or defined($power_off)) {
1891 if (defined($poweroff_after_halt)) {
1892 sleep $poweroff_after_halt;
1893 run_command "$power_off";
1897 run_command "$power_off";
1908 if (defined($test_name)) {
1909 $name = " ($test_name)";
1912 doprint "\n\n*******************************************\n";
1913 doprint "*******************************************\n";
1914 doprint "KTEST RESULT: TEST $i$name SUCCESS!!!! **\n";
1915 doprint "*******************************************\n";
1916 doprint "*******************************************\n";
1918 if (defined($store_successes)) {
1919 save_logs "success", $store_successes;
1922 if ($i != $opt{"NUM_TESTS"} && !do_not_reboot) {
1923 doprint "Reboot and wait $sleep_time seconds\n";
1924 reboot_to_good $sleep_time;
1930 doprint "Pass or fail? [p/f]";
1933 if ($ans eq "p" || $ans eq "P") {
1935 } elsif ($ans eq "f" || $ans eq "F") {
1938 print "Please answer 'P' or 'F'\n";
1943 sub child_run_test {
1946 # child should have no power
1947 $reboot_on_error = 0;
1948 $poweroff_on_error = 0;
1949 $die_on_failure = 1;
1951 $redirect = "$testlog";
1952 run_command $run_test or $failed = 1;
1960 sub child_finished {
1973 doprint "run test $run_test\n";
1977 $SIG{CHLD} = qw(child_finished);
1981 child_run_test if (!$child_pid);
1986 $line = wait_for_input($monitor_fp, 1);
1987 if (defined($line)) {
1989 # we are not guaranteed to get a full line
1990 $full_line .= $line;
1993 if ($full_line =~ /call trace:/i) {
1997 if ($full_line =~ /Kernel panic -/) {
2001 if ($line =~ /\n/) {
2005 } while (!$child_done && !$bug);
2008 my $failure_start = time;
2011 $line = wait_for_input($monitor_fp, 1);
2012 if (defined($line)) {
2016 if ($now - $failure_start >= $stop_after_failure) {
2019 } while (defined($line));
2021 doprint "Detected kernel crash!\n";
2022 # kill the child with extreme prejudice
2026 waitpid $child_pid, 0;
2029 if (!$bug && $in_bisect) {
2030 if (defined($bisect_ret_good)) {
2031 if ($child_exit == $bisect_ret_good) {
2035 if (defined($bisect_ret_skip)) {
2036 if ($child_exit == $bisect_ret_skip) {
2040 if (defined($bisect_ret_abort)) {
2041 if ($child_exit == $bisect_ret_abort) {
2042 fail "test abort" and return -2;
2045 if (defined($bisect_ret_bad)) {
2046 if ($child_exit == $bisect_ret_skip) {
2050 if (defined($bisect_ret_default)) {
2051 if ($bisect_ret_default eq "good") {
2053 } elsif ($bisect_ret_default eq "bad") {
2055 } elsif ($bisect_ret_default eq "skip") {
2057 } elsif ($bisect_ret_default eq "abort") {
2060 fail "unknown default action: $bisect_ret_default"
2066 if ($bug || $child_exit) {
2067 return 0 if $in_bisect;
2068 fail "test failed" and return 0;
2073 sub run_git_bisect {
2076 doprint "$command ... ";
2078 my $output = `$command 2>&1`;
2085 dodie "Failed to git bisect";
2088 doprint "SUCCESS\n";
2089 if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\))\s+\[([[:xdigit:]]+)\]/) {
2090 doprint "$1 [$2]\n";
2091 } elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) {
2092 $bisect_bad_commit = $1;
2093 doprint "Found bad commit... $1\n";
2096 # we already logged it, just print it now.
2104 doprint "Reboot and sleep $bisect_sleep_time seconds\n";
2105 reboot_to_good $bisect_sleep_time;
2108 # returns 1 on success, 0 on failure, -1 on skip
2109 sub run_bisect_test {
2110 my ($type, $buildtype) = @_;
2119 build $buildtype or $failed = 1;
2121 if ($type ne "build") {
2122 if ($failed && $bisect_skip) {
2126 dodie "Failed on build" if $failed;
2129 start_monitor_and_boot or $failed = 1;
2131 if ($type ne "boot") {
2132 if ($failed && $bisect_skip) {
2138 dodie "Failed on boot" if $failed;
2140 do_run_test or $failed = 1;
2151 # reboot the box to a kernel we can ssh to
2152 if ($type ne "build") {
2162 my $buildtype = "oldconfig";
2164 # We should have a minconfig to use?
2165 if (defined($minconfig)) {
2166 $buildtype = "useconfig:$minconfig";
2169 my $ret = run_bisect_test $type, $buildtype;
2171 if ($bisect_manual) {
2172 $ret = answer_bisect;
2175 # Are we looking for where it worked, not failed?
2176 if ($reverse_bisect) {
2182 } elsif ($ret == 0) {
2184 } elsif ($bisect_skip) {
2185 doprint "HIT A BAD COMMIT ... SKIPPING\n";
2190 sub update_bisect_replay {
2191 my $tmp_log = "$tmpdir/ktest_bisect_log";
2192 run_command "git bisect log > $tmp_log" or
2193 die "can't create bisect log";
2202 die "BISECT_GOOD[$i] not defined\n" if (!defined($bisect_good));
2203 die "BISECT_BAD[$i] not defined\n" if (!defined($bisect_bad));
2204 die "BISECT_TYPE[$i] not defined\n" if (!defined($bisect_type));
2206 my $good = $bisect_good;
2207 my $bad = $bisect_bad;
2208 my $type = $bisect_type;
2209 my $start = $bisect_start;
2210 my $replay = $bisect_replay;
2211 my $start_files = $bisect_files;
2213 if (defined($start_files)) {
2214 $start_files = " -- " . $start_files;
2219 # convert to true sha1's
2220 $good = get_sha1($good);
2221 $bad = get_sha1($bad);
2223 if (defined($bisect_reverse) && $bisect_reverse == 1) {
2224 doprint "Performing a reverse bisect (bad is good, good is bad!)\n";
2225 $reverse_bisect = 1;
2227 $reverse_bisect = 0;
2230 # Can't have a test without having a test to run
2231 if ($type eq "test" && !defined($run_test)) {
2235 # Check if a bisect was running
2236 my $bisect_start_file = "$builddir/.git/BISECT_START";
2238 my $check = $bisect_check;
2239 my $do_check = defined($check) && $check ne "0";
2241 if ( -f $bisect_start_file ) {
2242 print "Bisect in progress found\n";
2244 print " If you say yes, then no checks of good or bad will be done\n";
2246 if (defined($replay)) {
2247 print "** BISECT_REPLAY is defined in config file **";
2248 print " Ignore config option and perform new git bisect log?\n";
2249 if (read_ync " (yes, no, or cancel) ") {
2250 $replay = update_bisect_replay;
2253 } elsif (read_yn "read git log and continue?") {
2254 $replay = update_bisect_replay;
2262 my $head = get_sha1("HEAD");
2264 if ($check ne "good") {
2265 doprint "TESTING BISECT BAD [$bad]\n";
2266 run_command "git checkout $bad" or
2267 die "Failed to checkout $bad";
2269 $result = run_bisect $type;
2271 if ($result ne "bad") {
2272 fail "Tested BISECT_BAD [$bad] and it succeeded" and return 0;
2276 if ($check ne "bad") {
2277 doprint "TESTING BISECT GOOD [$good]\n";
2278 run_command "git checkout $good" or
2279 die "Failed to checkout $good";
2281 $result = run_bisect $type;
2283 if ($result ne "good") {
2284 fail "Tested BISECT_GOOD [$good] and it failed" and return 0;
2288 # checkout where we started
2289 run_command "git checkout $head" or
2290 die "Failed to checkout $head";
2293 run_command "git bisect start$start_files" or
2294 dodie "could not start bisect";
2296 run_command "git bisect good $good" or
2297 dodie "could not set bisect good to $good";
2299 run_git_bisect "git bisect bad $bad" or
2300 dodie "could not set bisect bad to $bad";
2302 if (defined($replay)) {
2303 run_command "git bisect replay $replay" or
2304 dodie "failed to run replay";
2307 if (defined($start)) {
2308 run_command "git checkout $start" or
2309 dodie "failed to checkout $start";
2314 $result = run_bisect $type;
2315 $test = run_git_bisect "git bisect $result";
2318 run_command "git bisect log" or
2319 dodie "could not capture git bisect log";
2321 run_command "git bisect reset" or
2322 dodie "could not reset git bisect";
2324 doprint "Bad commit was [$bisect_bad_commit]\n";
2337 sub assign_configs {
2338 my ($hash, $config) = @_;
2341 or dodie "Failed to read $config";
2344 if (/^((CONFIG\S*)=.*)/) {
2352 sub process_config_ignore {
2355 assign_configs \%config_ignore, $config;
2358 sub read_current_config {
2359 my ($config_ref) = @_;
2361 %{$config_ref} = ();
2362 undef %{$config_ref};
2364 my @key = keys %{$config_ref};
2366 print "did not delete!\n";
2369 open (IN, "$output_config");
2372 if (/^(CONFIG\S+)=(.*)/) {
2373 ${$config_ref}{$1} = $2;
2379 sub get_dependencies {
2382 my $arr = $dependency{$config};
2383 if (!defined($arr)) {
2389 foreach my $dep (@{$arr}) {
2390 print "ADD DEP $dep\n";
2391 @deps = (@deps, get_dependencies $dep);
2400 open(OUT, ">$output_config") or dodie "Can not write to $output_config";
2402 foreach my $config (@configs) {
2403 print OUT "$config_set{$config}\n";
2404 my @deps = get_dependencies $config;
2405 foreach my $dep (@deps) {
2406 print OUT "$config_set{$dep}\n";
2410 foreach my $config (keys %config_ignore) {
2411 print OUT "$config_ignore{$config}\n";
2419 sub compare_configs {
2422 foreach my $item (keys %a) {
2423 if (!defined($b{$item})) {
2424 print "diff $item\n";
2432 print "diff2 $keys[0]\n";
2434 return -1 if ($#keys >= 0);
2439 sub run_config_bisect_test {
2442 return run_bisect_test $type, "oldconfig";
2445 sub process_passed {
2448 doprint "These configs had no failure: (Enabling them for further compiles)\n";
2449 # Passed! All these configs are part of a good compile.
2450 # Add them to the min options.
2451 foreach my $config (keys %configs) {
2452 if (defined($config_list{$config})) {
2453 doprint " removing $config\n";
2454 $config_ignore{$config} = $config_list{$config};
2455 delete $config_list{$config};
2458 doprint "config copied to $outputdir/config_good\n";
2459 run_command "cp -f $output_config $outputdir/config_good";
2462 sub process_failed {
2465 doprint "\n\n***************************************\n";
2466 doprint "Found bad config: $config\n";
2467 doprint "***************************************\n\n";
2470 sub run_config_bisect {
2472 my @start_list = keys %config_list;
2474 if ($#start_list < 0) {
2475 doprint "No more configs to test!!!\n";
2479 doprint "***** RUN TEST ***\n";
2480 my $type = $config_bisect_type;
2484 my $count = $#start_list + 1;
2485 doprint " $count configs to test\n";
2487 my $half = int($#start_list / 2);
2490 my @tophalf = @start_list[0 .. $half];
2492 create_config @tophalf;
2493 read_current_config \%current_config;
2495 $count = $#tophalf + 1;
2496 doprint "Testing $count configs\n";
2498 # make sure we test something
2499 foreach my $config (@tophalf) {
2500 if (defined($current_config{$config})) {
2506 # try the other half
2507 doprint "Top half produced no set configs, trying bottom half\n";
2508 @tophalf = @start_list[$half + 1 .. $#start_list];
2509 create_config @tophalf;
2510 read_current_config \%current_config;
2511 foreach my $config (@tophalf) {
2512 if (defined($current_config{$config})) {
2518 doprint "Failed: Can't make new config with current configs\n";
2519 foreach my $config (@start_list) {
2520 doprint " CONFIG: $config\n";
2524 $count = $#tophalf + 1;
2525 doprint "Testing $count configs\n";
2528 $ret = run_config_bisect_test $type;
2529 if ($bisect_manual) {
2530 $ret = answer_bisect;
2533 process_passed %current_config;
2537 doprint "This config had a failure.\n";
2538 doprint "Removing these configs that were not set in this config:\n";
2539 doprint "config copied to $outputdir/config_bad\n";
2540 run_command "cp -f $output_config $outputdir/config_bad";
2542 # A config exists in this group that was bad.
2543 foreach my $config (keys %config_list) {
2544 if (!defined($current_config{$config})) {
2545 doprint " removing $config\n";
2546 delete $config_list{$config};
2550 @start_list = @tophalf;
2552 if ($#start_list == 0) {
2553 process_failed $start_list[0];
2557 # remove half the configs we are looking at and see if
2559 $half = int($#start_list / 2);
2560 } while ($#start_list > 0);
2562 # we found a single config, try it again unless we are running manually
2564 if ($bisect_manual) {
2565 process_failed $start_list[0];
2569 my @tophalf = @start_list[0 .. 0];
2571 $ret = run_config_bisect_test $type;
2573 process_passed %current_config;
2577 process_failed $start_list[0];
2584 my $start_config = $config_bisect;
2586 my $tmpconfig = "$tmpdir/use_config";
2588 if (defined($config_bisect_good)) {
2589 process_config_ignore $config_bisect_good;
2592 # Make the file with the bad config and the min config
2593 if (defined($minconfig)) {
2594 # read the min config for things to ignore
2595 run_command "cp $minconfig $tmpconfig" or
2596 dodie "failed to copy $minconfig to $tmpconfig";
2601 if (-f $tmpconfig) {
2602 load_force_config($tmpconfig);
2603 process_config_ignore $tmpconfig;
2606 # now process the start config
2607 run_command "cp $start_config $output_config" or
2608 dodie "failed to copy $start_config to $output_config";
2610 # read directly what we want to check
2612 open (IN, $output_config)
2613 or dodie "faied to open $output_config";
2616 if (/^((CONFIG\S*)=.*)/) {
2617 $config_check{$2} = $1;
2622 # Now run oldconfig with the minconfig
2625 # check to see what we lost (or gained)
2626 open (IN, $output_config)
2627 or dodie "Failed to read $start_config";
2629 my %removed_configs;
2633 if (/^((CONFIG\S*)=.*)/) {
2634 # save off all options
2635 $config_set{$2} = $1;
2636 if (defined($config_check{$2})) {
2637 if (defined($config_ignore{$2})) {
2638 $removed_configs{$2} = $1;
2640 $config_list{$2} = $1;
2642 } elsif (!defined($config_ignore{$2})) {
2643 $added_configs{$2} = $1;
2644 $config_list{$2} = $1;
2650 my @confs = keys %removed_configs;
2652 doprint "Configs overridden by default configs and removed from check:\n";
2653 foreach my $config (@confs) {
2654 doprint " $config\n";
2657 @confs = keys %added_configs;
2659 doprint "Configs appearing in make oldconfig and added:\n";
2660 foreach my $config (@confs) {
2661 doprint " $config\n";
2668 # Sometimes kconfig does weird things. We must make sure
2669 # that the config we autocreate has everything we need
2670 # to test, otherwise we may miss testing configs, or
2671 # may not be able to create a new config.
2672 # Here we create a config with everything set.
2673 create_config (keys %config_list);
2674 read_current_config \%config_test;
2675 foreach my $config (keys %config_list) {
2676 if (!defined($config_test{$config})) {
2679 doprint "Configs not produced by kconfig (will not be checked):\n";
2681 doprint " $config\n";
2682 delete $config_list{$config};
2687 $ret = run_config_bisect;
2690 return $ret if ($ret < 0);
2695 sub patchcheck_reboot {
2696 doprint "Reboot and sleep $patchcheck_sleep_time seconds\n";
2697 reboot_to_good $patchcheck_sleep_time;
2703 die "PATCHCHECK_START[$i] not defined\n"
2704 if (!defined($patchcheck_start));
2705 die "PATCHCHECK_TYPE[$i] not defined\n"
2706 if (!defined($patchcheck_type));
2708 my $start = $patchcheck_start;
2711 if (defined($patchcheck_end)) {
2712 $end = $patchcheck_end;
2715 # Get the true sha1's since we can use things like HEAD~3
2716 $start = get_sha1($start);
2717 $end = get_sha1($end);
2719 my $type = $patchcheck_type;
2721 # Can't have a test without having a test to run
2722 if ($type eq "test" && !defined($run_test)) {
2726 open (IN, "git log --pretty=oneline $end|") or
2727 dodie "could not get git list";
2733 $list[$#list+1] = $_;
2734 last if (/^$start/);
2738 if ($list[$#list] !~ /^$start/) {
2739 fail "SHA1 $start not found";
2742 # go backwards in the list
2743 @list = reverse @list;
2745 my $save_clean = $noclean;
2746 my %ignored_warnings;
2748 if (defined($ignore_warnings)) {
2749 foreach my $sha1 (split /\s+/, $ignore_warnings) {
2750 $ignored_warnings{$sha1} = 1;
2755 foreach my $item (@list) {
2757 $sha1 =~ s/^([[:xdigit:]]+).*/$1/;
2759 doprint "\nProcessing commit $item\n\n";
2761 run_command "git checkout $sha1" or
2762 die "Failed to checkout $sha1";
2764 # only clean on the first and last patch
2765 if ($item eq $list[0] ||
2766 $item eq $list[$#list]) {
2767 $noclean = $save_clean;
2772 if (defined($minconfig)) {
2773 build "useconfig:$minconfig" or return 0;
2775 # ?? no config to use?
2776 build "oldconfig" or return 0;
2780 if (!defined($ignored_warnings{$sha1})) {
2781 check_buildlog $sha1 or return 0;
2784 next if ($type eq "build");
2788 start_monitor_and_boot or $failed = 1;
2790 if (!$failed && $type ne "boot"){
2791 do_run_test or $failed = 1;
2794 return 0 if ($failed);
2814 # $config depends on $dep
2815 my ($config, $dep) = @_;
2817 if (defined($depends{$config})) {
2818 $depends{$config} .= " " . $dep;
2820 $depends{$config} = $dep;
2823 # record the number of configs depending on $dep
2824 if (defined $depcount{$dep}) {
2827 $depcount{$dep} = 1;
2831 # taken from streamline_config.pl
2843 if (! -f $kconfig) {
2844 doprint "file $kconfig does not exist, skipping\n";
2848 open(KIN, "$kconfig")
2849 or die "Can't open $kconfig";
2853 # Make sure that lines ending with \ continue
2855 $_ = $line . " " . $_;
2866 # collect any Kconfig sources
2867 if (/^source\s*"(.*)"/) {
2868 $kconfigs[$#kconfigs+1] = $1;
2872 if (/^\s*(menu)?config\s+(\S+)\s*$/) {
2876 for (my $i = 0; $i < $iflevel; $i++) {
2877 add_dep $config, $ifdeps[$i];
2880 # collect the depends for the config
2881 } elsif ($state eq "NEW" && /^\s*depends\s+on\s+(.*)$/) {
2883 add_dep $config, $1;
2885 # Get the configs that select this config
2886 } elsif ($state eq "NEW" && /^\s*select\s+(\S+)/) {
2888 # selected by depends on config
2889 add_dep $1, $config;
2891 # Check for if statements
2892 } elsif (/^if\s+(.*\S)\s*$/) {
2894 # remove beginning and ending non text
2895 $deps =~ s/^[^a-zA-Z0-9_]*//;
2896 $deps =~ s/[^a-zA-Z0-9_]*$//;
2898 my @deps = split /[^a-zA-Z0-9_]+/, $deps;
2900 $ifdeps[$iflevel++] = join ':', @deps;
2902 } elsif (/^endif/) {
2904 $iflevel-- if ($iflevel);
2907 } elsif (/^\s*help\s*$/) {
2913 # read in any configs that were found.
2914 foreach $kconfig (@kconfigs) {
2915 if (!defined($read_kconfigs{$kconfig})) {
2916 $read_kconfigs{$kconfig} = 1;
2917 read_kconfig("$builddir/$kconfig");
2923 # find out which arch this is by the kconfig file
2924 open (IN, $output_config)
2925 or dodie "Failed to read $output_config";
2928 if (m,Linux/(\S+)\s+\S+\s+Kernel Configuration,) {
2935 if (!defined($arch)) {
2936 doprint "Could not find arch from config file\n";
2937 doprint "no dependencies used\n";
2941 # arch is really the subarch, we need to know
2942 # what directory to look at.
2943 if ($arch eq "i386" || $arch eq "x86_64") {
2945 } elsif ($arch =~ /^tile/) {
2949 my $kconfig = "$builddir/arch/$arch/Kconfig";
2951 if (! -f $kconfig && $arch =~ /\d$/) {
2953 # some subarchs have numbers, truncate them
2955 $kconfig = "$builddir/arch/$arch/Kconfig";
2956 if (! -f $kconfig) {
2957 doprint "No idea what arch dir $orig is for\n";
2958 doprint "no dependencies used\n";
2963 read_kconfig($kconfig);
2966 sub read_config_list {
2970 or dodie "Failed to read $config";
2973 if (/^((CONFIG\S*)=.*)/) {
2974 if (!defined($config_ignore{$2})) {
2975 $config_list{$2} = $1;
2983 sub read_output_config {
2986 assign_configs \%config_ignore, $config;
2989 sub make_new_config {
2992 open (OUT, ">$output_config")
2993 or dodie "Failed to write $output_config";
2995 foreach my $config (@configs) {
2996 print OUT "$config\n";
3004 $config =~ s/CONFIG_//;
3012 my $kconfig = chomp_config $dep;
3014 $dep = $depends{"$kconfig"};
3016 # the dep string we have saves the dependencies as they
3017 # were found, including expressions like ! && ||. We
3018 # want to split this out into just an array of configs.
3020 my $valid = "A-Za-z_0-9";
3024 while ($dep =~ /[$valid]/) {
3026 if ($dep =~ /^[^$valid]*([$valid]+)/) {
3027 my $conf = "CONFIG_" . $1;
3029 $configs[$#configs + 1] = $conf;
3031 $dep =~ s/^[^$valid]*[$valid]+//;
3033 die "this should never happen";
3043 my %processed_configs;
3044 my %nochange_config;
3046 sub test_this_config {
3051 # if we already processed this config, skip it
3052 if (defined($processed_configs{$config})) {
3055 $processed_configs{$config} = 1;
3057 # if this config failed during this round, skip it
3058 if (defined($nochange_config{$config})) {
3062 my $kconfig = chomp_config $config;
3064 # Test dependencies first
3065 if (defined($depends{"$kconfig"})) {
3066 my @parents = get_depends $config;
3067 foreach my $parent (@parents) {
3068 # if the parent is in the min config, check it first
3069 next if (!defined($min_configs{$parent}));
3070 $found = test_this_config($parent);
3071 if (defined($found)) {
3077 # Remove this config from the list of configs
3078 # do a make oldnoconfig and then read the resulting
3079 # .config to make sure it is missing the config that
3081 my %configs = %min_configs;
3082 delete $configs{$config};
3083 make_new_config ((values %configs), (values %keep_configs));
3086 assign_configs \%configs, $output_config;
3088 return $config if (!defined($configs{$config}));
3090 doprint "disabling config $config did not change .config\n";
3092 $nochange_config{$config} = 1;
3097 sub make_min_config {
3100 if (!defined($output_minconfig)) {
3101 fail "OUTPUT_MIN_CONFIG not defined" and return;
3104 # If output_minconfig exists, and the start_minconfig
3105 # came from min_config, than ask if we should use
3107 if (-f $output_minconfig && !$start_minconfig_defined) {
3108 print "$output_minconfig exists\n";
3109 if (read_yn " Use it as minconfig?") {
3110 $start_minconfig = $output_minconfig;
3114 if (!defined($start_minconfig)) {
3115 fail "START_MIN_CONFIG or MIN_CONFIG not defined" and return;
3118 my $temp_config = "$tmpdir/temp_config";
3120 # First things first. We build an allnoconfig to find
3121 # out what the defaults are that we can't touch.
3122 # Some are selections, but we really can't handle selections.
3124 my $save_minconfig = $minconfig;
3127 run_command "$make allnoconfig" or return 0;
3131 process_config_ignore $output_config;
3133 undef %save_configs;
3136 if (defined($ignore_config)) {
3137 # make sure the file exists
3138 `touch $ignore_config`;
3139 assign_configs \%save_configs, $ignore_config;
3142 %keep_configs = %save_configs;
3144 doprint "Load initial configs from $start_minconfig\n";
3146 # Look at the current min configs, and save off all the
3147 # ones that were set via the allnoconfig
3148 assign_configs \%min_configs, $start_minconfig;
3150 my @config_keys = keys %min_configs;
3152 # All configs need a depcount
3153 foreach my $config (@config_keys) {
3154 my $kconfig = chomp_config $config;
3155 if (!defined $depcount{$kconfig}) {
3156 $depcount{$kconfig} = 0;
3160 # Remove anything that was set by the make allnoconfig
3161 # we shouldn't need them as they get set for us anyway.
3162 foreach my $config (@config_keys) {
3163 # Remove anything in the ignore_config
3164 if (defined($keep_configs{$config})) {
3165 my $file = $ignore_config;
3166 $file =~ s,.*/(.*?)$,$1,;
3167 doprint "$config set by $file ... ignored\n";
3168 delete $min_configs{$config};
3171 # But make sure the settings are the same. If a min config
3172 # sets a selection, we do not want to get rid of it if
3173 # it is not the same as what we have. Just move it into
3175 if (defined($config_ignore{$config})) {
3176 if ($config_ignore{$config} ne $min_configs{$config}) {
3177 doprint "$config is in allnoconfig as '$config_ignore{$config}'";
3178 doprint " but it is '$min_configs{$config}' in minconfig .. keeping\n";
3179 $keep_configs{$config} = $min_configs{$config};
3181 doprint "$config set by allnoconfig ... ignored\n";
3183 delete $min_configs{$config};
3195 # Now disable each config one by one and do a make oldconfig
3196 # till we find a config that changes our list.
3198 my @test_configs = keys %min_configs;
3200 # Sort keys by who is most dependent on
3201 @test_configs = sort { $depcount{chomp_config($b)} <=> $depcount{chomp_config($a)} }
3204 # Put configs that did not modify the config at the end.
3206 for (my $i = 0; $i < $#test_configs; $i++) {
3207 if (!defined($nochange_config{$test_configs[0]})) {
3211 # This config didn't change the .config last time.
3212 # Place it at the end
3213 my $config = shift @test_configs;
3214 push @test_configs, $config;
3217 # if every test config has failed to modify the .config file
3218 # in the past, then reset and start over.
3220 undef %nochange_config;
3223 undef %processed_configs;
3225 foreach my $config (@test_configs) {
3227 $found = test_this_config $config;
3229 last if (defined($found));
3231 # oh well, try another config
3234 if (!defined($found)) {
3235 # we could have failed due to the nochange_config hash
3236 # reset and try again
3238 undef %nochange_config;
3242 doprint "No more configs found that we can disable\n";
3250 doprint "Test with $config disabled\n";
3252 # set in_bisect to keep build and monitor from dieing
3256 build "oldconfig" or $failed = 1;
3258 start_monitor_and_boot or $failed = 1;
3265 doprint "$min_configs{$config} is needed to boot the box... keeping\n";
3266 # this config is needed, add it to the ignore list.
3267 $keep_configs{$config} = $min_configs{$config};
3268 $save_configs{$config} = $min_configs{$config};
3269 delete $min_configs{$config};
3271 # update new ignore configs
3272 if (defined($ignore_config)) {
3273 open (OUT, ">$temp_config")
3274 or die "Can't write to $temp_config";
3275 foreach my $config (keys %save_configs) {
3276 print OUT "$save_configs{$config}\n";
3279 run_command "mv $temp_config $ignore_config" or
3280 dodie "failed to copy update to $ignore_config";
3284 # We booted without this config, remove it from the minconfigs.
3285 doprint "$config is not needed, disabling\n";
3287 delete $min_configs{$config};
3289 # Also disable anything that is not enabled in this config
3291 assign_configs \%configs, $output_config;
3292 my @config_keys = keys %min_configs;
3293 foreach my $config (@config_keys) {
3294 if (!defined($configs{$config})) {
3295 doprint "$config is not set, disabling\n";
3296 delete $min_configs{$config};
3300 # Save off all the current mandidory configs
3301 open (OUT, ">$temp_config")
3302 or die "Can't write to $temp_config";
3303 foreach my $config (keys %keep_configs) {
3304 print OUT "$keep_configs{$config}\n";
3306 foreach my $config (keys %min_configs) {
3307 print OUT "$min_configs{$config}\n";
3311 run_command "mv $temp_config $output_minconfig" or
3312 dodie "failed to copy update to $output_minconfig";
3315 doprint "Reboot and wait $sleep_time seconds\n";
3316 reboot_to_good $sleep_time;
3323 $#ARGV < 1 or die "ktest.pl version: $VERSION\n usage: ktest.pl config-file\n";
3326 $ktest_config = $ARGV[0];
3327 if (! -f $ktest_config) {
3328 print "$ktest_config does not exist.\n";
3329 if (!read_yn "Create it?") {
3334 $ktest_config = "ktest.conf";
3337 if (! -f $ktest_config) {
3340 open(OUT, ">$ktest_config") or die "Can not create $ktest_config";
3342 # Generated by ktest.pl
3345 # PWD is a ktest.pl variable that will result in the process working
3346 # directory that ktest.pl is executed in.
3348 # THIS_DIR is automatically assigned the PWD of the path that generated
3349 # the config file. It is best to use this variable when assigning other
3350 # directory paths within this directory. This allows you to easily
3351 # move the test cases to other locations or to other machines.
3353 THIS_DIR := $variable{"PWD"}
3355 # Define each test with TEST_START
3356 # The config options below it will override the defaults
3358 TEST_TYPE = $default{"TEST_TYPE"}
3365 read_config $ktest_config;
3367 if (defined($opt{"LOG_FILE"})) {
3368 $opt{"LOG_FILE"} = eval_option($opt{"LOG_FILE"}, -1);
3371 # Append any configs entered in manually to the config file.
3372 my @new_configs = keys %entered_configs;
3373 if ($#new_configs >= 0) {
3374 print "\nAppending entered in configs to $ktest_config\n";
3375 open(OUT, ">>$ktest_config") or die "Can not append to $ktest_config";
3376 foreach my $config (@new_configs) {
3377 print OUT "$config = $entered_configs{$config}\n";
3378 $opt{$config} = process_variables($entered_configs{$config});
3382 if ($opt{"CLEAR_LOG"} && defined($opt{"LOG_FILE"})) {
3383 unlink $opt{"LOG_FILE"};
3386 doprint "\n\nSTARTING AUTOMATED TESTS\n\n";
3388 for (my $i = 0, my $repeat = 1; $i <= $opt{"NUM_TESTS"}; $i += $repeat) {
3391 doprint "DEFAULT OPTIONS:\n";
3393 doprint "\nTEST $i OPTIONS";
3394 if (defined($repeat_tests{$i})) {
3395 $repeat = $repeat_tests{$i};
3396 doprint " ITERATE $repeat";
3401 foreach my $option (sort keys %opt) {
3403 if ($option =~ /\[(\d+)\]$/) {
3409 doprint "$option = $opt{$option}\n";
3413 sub __set_test_option {
3414 my ($name, $i) = @_;
3416 my $option = "$name\[$i\]";
3418 if (defined($opt{$option})) {
3419 return $opt{$option};
3422 foreach my $test (keys %repeat_tests) {
3424 $i < $test + $repeat_tests{$test}) {
3425 $option = "$name\[$test\]";
3426 if (defined($opt{$option})) {
3427 return $opt{$option};
3432 if (defined($opt{$name})) {
3439 sub set_test_option {
3440 my ($name, $i) = @_;
3442 my $option = __set_test_option($name, $i);
3443 return $option if (!defined($option));
3445 return eval_option($option, $i);
3448 # First we need to do is the builds
3449 for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
3451 # Do not reboot on failing test options
3456 my $makecmd = set_test_option("MAKE_CMD", $i);
3458 # Load all the options into their mapped variable names
3459 foreach my $opt (keys %option_map) {
3460 ${$option_map{$opt}} = set_test_option($opt, $i);
3463 $start_minconfig_defined = 1;
3465 if (!defined($start_minconfig)) {
3466 $start_minconfig_defined = 0;
3467 $start_minconfig = $minconfig;
3470 chdir $builddir || die "can't change directory to $builddir";
3472 foreach my $dir ($tmpdir, $outputdir) {
3475 die "can't create $dir";
3479 $ENV{"SSH_USER"} = $ssh_user;
3480 $ENV{"MACHINE"} = $machine;
3482 $buildlog = "$tmpdir/buildlog-$machine";
3483 $testlog = "$tmpdir/testlog-$machine";
3484 $dmesg = "$tmpdir/dmesg-$machine";
3485 $make = "$makecmd O=$outputdir";
3486 $output_config = "$outputdir/.config";
3489 $target = "$ssh_user\@$machine";
3490 if ($reboot_type eq "grub") {
3491 dodie "GRUB_MENU not defined" if (!defined($grub_menu));
3495 my $run_type = $build_type;
3496 if ($test_type eq "patchcheck") {
3497 $run_type = $patchcheck_type;
3498 } elsif ($test_type eq "bisect") {
3499 $run_type = $bisect_type;
3500 } elsif ($test_type eq "config_bisect") {
3501 $run_type = $config_bisect_type;
3504 if ($test_type eq "make_min_config") {
3508 # mistake in config file?
3509 if (!defined($run_type)) {
3510 $run_type = "ERROR";
3514 $installme = " no_install" if ($no_install);
3517 doprint "RUNNING TEST $i of $opt{NUM_TESTS} with option $test_type $run_type$installme\n\n";
3523 if (defined($addconfig)) {
3524 my $min = $minconfig;
3525 if (!defined($minconfig)) {
3528 run_command "cat $addconfig $min > $tmpdir/add_config" or
3529 dodie "Failed to create temp config";
3530 $minconfig = "$tmpdir/add_config";
3533 if (defined($checkout)) {
3534 run_command "git checkout $checkout" or
3535 die "failed to checkout $checkout";
3541 if ($test_type eq "bisect") {
3544 } elsif ($test_type eq "config_bisect") {
3547 } elsif ($test_type eq "patchcheck") {
3550 } elsif ($test_type eq "make_min_config") {
3555 if ($build_type ne "nobuild") {
3556 build $build_type or next;
3559 if ($test_type eq "install") {
3566 if ($test_type ne "build") {
3568 start_monitor_and_boot or $failed = 1;
3570 if (!$failed && $test_type ne "boot" && defined($run_test)) {
3571 do_run_test or $failed = 1;
3580 if ($opt{"POWEROFF_ON_SUCCESS"}) {
3582 } elsif ($opt{"REBOOT_ON_SUCCESS"} && !do_not_reboot) {
3586 doprint "\n $successes of $opt{NUM_TESTS} tests were successful\n\n";