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;
109 my $bisect_bad_commit = "";
113 my $config_bisect_good;
117 my $bisect_ret_abort;
118 my $bisect_ret_default;
119 my $in_patchcheck = 0;
129 my $bisect_sleep_time;
130 my $patchcheck_sleep_time;
137 my $detect_triplefault;
139 my $reboot_success_line;
141 my $stop_after_success;
142 my $stop_after_failure;
161 my $config_bisect_type;
164 my $patchcheck_start;
167 # set when a test is something other that just building or install
168 # which would require more options.
171 # set when creating a new config
179 # do not force reboots on config problems
183 "MACHINE" => \$machine,
184 "SSH_USER" => \$ssh_user,
185 "TMP_DIR" => \$tmpdir,
186 "OUTPUT_DIR" => \$outputdir,
187 "BUILD_DIR" => \$builddir,
188 "TEST_TYPE" => \$test_type,
189 "BUILD_TYPE" => \$build_type,
190 "BUILD_OPTIONS" => \$build_options,
191 "PRE_BUILD" => \$pre_build,
192 "POST_BUILD" => \$post_build,
193 "PRE_BUILD_DIE" => \$pre_build_die,
194 "POST_BUILD_DIE" => \$post_build_die,
195 "POWER_CYCLE" => \$power_cycle,
196 "REBOOT" => \$reboot,
197 "BUILD_NOCLEAN" => \$noclean,
198 "MIN_CONFIG" => \$minconfig,
199 "OUTPUT_MIN_CONFIG" => \$output_minconfig,
200 "START_MIN_CONFIG" => \$start_minconfig,
201 "IGNORE_CONFIG" => \$ignore_config,
202 "TEST" => \$run_test,
203 "ADD_CONFIG" => \$addconfig,
204 "REBOOT_TYPE" => \$reboot_type,
205 "GRUB_MENU" => \$grub_menu,
206 "POST_INSTALL" => \$post_install,
207 "NO_INSTALL" => \$no_install,
208 "REBOOT_SCRIPT" => \$reboot_script,
209 "REBOOT_ON_ERROR" => \$reboot_on_error,
210 "SWITCH_TO_GOOD" => \$switch_to_good,
211 "SWITCH_TO_TEST" => \$switch_to_test,
212 "POWEROFF_ON_ERROR" => \$poweroff_on_error,
213 "DIE_ON_FAILURE" => \$die_on_failure,
214 "POWER_OFF" => \$power_off,
215 "POWERCYCLE_AFTER_REBOOT" => \$powercycle_after_reboot,
216 "POWEROFF_AFTER_HALT" => \$poweroff_after_halt,
217 "SLEEP_TIME" => \$sleep_time,
218 "BISECT_SLEEP_TIME" => \$bisect_sleep_time,
219 "PATCHCHECK_SLEEP_TIME" => \$patchcheck_sleep_time,
220 "IGNORE_WARNINGS" => \$ignore_warnings,
221 "BISECT_MANUAL" => \$bisect_manual,
222 "BISECT_SKIP" => \$bisect_skip,
223 "CONFIG_BISECT_GOOD" => \$config_bisect_good,
224 "BISECT_RET_GOOD" => \$bisect_ret_good,
225 "BISECT_RET_BAD" => \$bisect_ret_bad,
226 "BISECT_RET_SKIP" => \$bisect_ret_skip,
227 "BISECT_RET_ABORT" => \$bisect_ret_abort,
228 "BISECT_RET_DEFAULT" => \$bisect_ret_default,
229 "STORE_FAILURES" => \$store_failures,
230 "STORE_SUCCESSES" => \$store_successes,
231 "TEST_NAME" => \$test_name,
232 "TIMEOUT" => \$timeout,
233 "BOOTED_TIMEOUT" => \$booted_timeout,
234 "CONSOLE" => \$console,
235 "DETECT_TRIPLE_FAULT" => \$detect_triplefault,
236 "SUCCESS_LINE" => \$success_line,
237 "REBOOT_SUCCESS_LINE" => \$reboot_success_line,
238 "STOP_AFTER_SUCCESS" => \$stop_after_success,
239 "STOP_AFTER_FAILURE" => \$stop_after_failure,
240 "STOP_TEST_AFTER" => \$stop_test_after,
241 "BUILD_TARGET" => \$build_target,
242 "SSH_EXEC" => \$ssh_exec,
243 "SCP_TO_TARGET" => \$scp_to_target,
244 "CHECKOUT" => \$checkout,
245 "TARGET_IMAGE" => \$target_image,
246 "LOCALVERSION" => \$localversion,
248 "BISECT_GOOD" => \$bisect_good,
249 "BISECT_BAD" => \$bisect_bad,
250 "BISECT_TYPE" => \$bisect_type,
251 "BISECT_START" => \$bisect_start,
252 "BISECT_REPLAY" => \$bisect_replay,
253 "BISECT_FILES" => \$bisect_files,
254 "BISECT_REVERSE" => \$bisect_reverse,
255 "BISECT_CHECK" => \$bisect_check,
257 "CONFIG_BISECT" => \$config_bisect,
258 "CONFIG_BISECT_TYPE" => \$config_bisect_type,
260 "PATCHCHECK_TYPE" => \$patchcheck_type,
261 "PATCHCHECK_START" => \$patchcheck_start,
262 "PATCHCHECK_END" => \$patchcheck_end,
265 # Options may be used by other options, record them.
268 # default variables that can be used
269 chomp ($variable{"PWD"} = `pwd`);
271 $config_help{"MACHINE"} = << "EOF"
272 The machine hostname that you will test.
273 For build only tests, it is still needed to differentiate log files.
276 $config_help{"SSH_USER"} = << "EOF"
277 The box is expected to have ssh on normal bootup, provide the user
278 (most likely root, since you need privileged operations)
281 $config_help{"BUILD_DIR"} = << "EOF"
282 The directory that contains the Linux source code (full path).
283 You can use \${PWD} that will be the path where ktest.pl is run, or use
284 \${THIS_DIR} which is assigned \${PWD} but may be changed later.
287 $config_help{"OUTPUT_DIR"} = << "EOF"
288 The directory that the objects will be built (full path).
289 (can not be same as BUILD_DIR)
290 You can use \${PWD} that will be the path where ktest.pl is run, or use
291 \${THIS_DIR} which is assigned \${PWD} but may be changed later.
294 $config_help{"BUILD_TARGET"} = << "EOF"
295 The location of the compiled file to copy to the target.
296 (relative to OUTPUT_DIR)
299 $config_help{"BUILD_OPTIONS"} = << "EOF"
300 Options to add to \"make\" when building.
304 $config_help{"TARGET_IMAGE"} = << "EOF"
305 The place to put your image on the test machine.
308 $config_help{"POWER_CYCLE"} = << "EOF"
309 A script or command to reboot the box.
311 Here is a digital loggers power switch example
312 POWER_CYCLE = wget --no-proxy -O /dev/null -q --auth-no-challenge 'http://admin:admin\@power/outlet?5=CCL'
314 Here is an example to reboot a virtual box on the current host
315 with the name "Guest".
316 POWER_CYCLE = virsh destroy Guest; sleep 5; virsh start Guest
319 $config_help{"CONSOLE"} = << "EOF"
320 The script or command that reads the console
322 If you use ttywatch server, something like the following would work.
323 CONSOLE = nc -d localhost 3001
325 For a virtual machine with guest name "Guest".
326 CONSOLE = virsh console Guest
329 $config_help{"LOCALVERSION"} = << "EOF"
330 Required version ending to differentiate the test
331 from other linux builds on the system.
334 $config_help{"REBOOT_TYPE"} = << "EOF"
335 Way to reboot the box to the test kernel.
336 Only valid options so far are "grub" and "script".
338 If you specify grub, it will assume grub version 1
339 and will search in /boot/grub/menu.lst for the title \$GRUB_MENU
340 and select that target to reboot to the kernel. If this is not
341 your setup, then specify "script" and have a command or script
342 specified in REBOOT_SCRIPT to boot to the target.
344 The entry in /boot/grub/menu.lst must be entered in manually.
345 The test will not modify that file.
348 $config_help{"GRUB_MENU"} = << "EOF"
349 The grub title name for the test kernel to boot
350 (Only mandatory if REBOOT_TYPE = grub)
352 Note, ktest.pl will not update the grub menu.lst, you need to
353 manually add an option for the test. ktest.pl will search
354 the grub menu.lst for this option to find what kernel to
357 For example, if in the /boot/grub/menu.lst the test kernel title has:
360 GRUB_MENU = Test Kernel
363 $config_help{"REBOOT_SCRIPT"} = << "EOF"
364 A script to reboot the target into the test kernel
365 (Only mandatory if REBOOT_TYPE = script)
370 my ($cancel, $prompt) = @_;
376 print "$prompt [y/n/C] ";
378 print "$prompt [Y/n] ";
382 if ($ans =~ /^\s*$/) {
389 last if ($ans =~ /^y$/i || $ans =~ /^n$/i);
391 last if ($ans =~ /^c$/i);
392 print "Please answer either 'y', 'n' or 'c'.\n";
394 print "Please answer either 'y' or 'n'.\n";
400 if ($ans !~ /^y$/i) {
409 return read_prompt 0, $prompt;
415 return read_prompt 1, $prompt;
418 sub get_ktest_config {
422 return if (defined($opt{$config}));
424 if (defined($config_help{$config})) {
426 print $config_help{$config};
431 if (defined($default{$config}) && length($default{$config})) {
432 print "\[$default{$config}\] ";
435 $ans =~ s/^\s*(.*\S)\s*$/$1/;
436 if ($ans =~ /^\s*$/) {
437 if ($default{$config}) {
438 $ans = $default{$config};
440 print "Your answer can not be blank\n";
444 $entered_configs{$config} = ${ans};
449 sub get_ktest_configs {
450 get_ktest_config("MACHINE");
451 get_ktest_config("BUILD_DIR");
452 get_ktest_config("OUTPUT_DIR");
455 get_ktest_config("BUILD_OPTIONS");
458 # options required for other than just building a kernel
460 get_ktest_config("POWER_CYCLE");
461 get_ktest_config("CONSOLE");
464 # options required for install and more
465 if ($buildonly != 1) {
466 get_ktest_config("SSH_USER");
467 get_ktest_config("BUILD_TARGET");
468 get_ktest_config("TARGET_IMAGE");
471 get_ktest_config("LOCALVERSION");
473 return if ($buildonly);
475 my $rtype = $opt{"REBOOT_TYPE"};
477 if (!defined($rtype)) {
478 if (!defined($opt{"GRUB_MENU"})) {
479 get_ktest_config("REBOOT_TYPE");
480 $rtype = $entered_configs{"REBOOT_TYPE"};
486 if ($rtype eq "grub") {
487 get_ktest_config("GRUB_MENU");
491 sub process_variables {
492 my ($value, $remove_undef) = @_;
495 # We want to check for '\', and it is just easier
496 # to check the previous characet of '$' and not need
497 # to worry if '$' is the first character. By adding
498 # a space to $value, we can just check [^\\]\$ and
499 # it will still work.
502 while ($value =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) {
506 # append beginning of value to retval
507 $retval = "$retval$begin";
508 if (defined($variable{$var})) {
509 $retval = "$retval$variable{$var}";
510 } elsif (defined($remove_undef) && $remove_undef) {
511 # for if statements, any variable that is not defined,
512 # we simple convert to 0
513 $retval = "${retval}0";
515 # put back the origin piece.
516 $retval = "$retval\$\{$var\}";
517 # This could be an option that is used later, save
518 # it so we don't warn if this option is not one of
520 $used_options{$var} = 1;
524 $retval = "$retval$value";
526 # remove the space added in the beginning
533 my ($lvalue, $rvalue, $override, $overrides, $name) = @_;
535 my $prvalue = process_variables($rvalue);
537 if ($buildonly && $lvalue =~ /^TEST_TYPE(\[.*\])?$/ && $prvalue ne "build") {
538 # Note if a test is something other than build, then we
539 # will need other manditory options.
540 if ($prvalue ne "install") {
543 # install still limits some manditory options.
548 if (defined($opt{$lvalue})) {
549 if (!$override || defined(${$overrides}{$lvalue})) {
552 $extra = "In the same override section!\n";
554 die "$name: $.: Option $lvalue defined more than once!\n$extra";
556 ${$overrides}{$lvalue} = $prvalue;
558 if ($rvalue =~ /^\s*$/) {
559 delete $opt{$lvalue};
561 $opt{$lvalue} = $prvalue;
566 my ($lvalue, $rvalue) = @_;
568 if ($rvalue =~ /^\s*$/) {
569 delete $variable{$lvalue};
571 $rvalue = process_variables($rvalue);
572 $variable{$lvalue} = $rvalue;
576 sub process_compare {
577 my ($lval, $cmp, $rval) = @_;
588 return $lval eq $rval;
589 } elsif ($cmp eq "!=") {
590 return $lval ne $rval;
593 my $statement = "$lval $cmp $rval";
594 my $ret = eval $statement;
596 # $@ stores error of eval
607 return defined($variable{$2}) ||
612 sub process_expression {
613 my ($name, $val) = @_;
617 while ($val =~ s/\(([^\(]*?)\)/\&\&\&\&VAL\&\&\&\&/) {
620 if (process_expression($name, $express)) {
621 $val =~ s/\&\&\&\&VAL\&\&\&\&/ 1 /;
623 $val =~ s/\&\&\&\&VAL\&\&\&\&/ 0 /;
631 while ($val =~ s/^(.*?)($OR|$AND)//) {
635 if (process_expression($name, $express)) {
646 if ($val =~ /(.*)(==|\!=|>=|<=|>|<)(.*)/) {
647 my $ret = process_compare($1, $2, $3);
649 die "$name: $.: Unable to process comparison\n";
654 if ($val =~ /^\s*(NOT\s*)?DEFINED\s+(\S+)\s*$/) {
656 return !value_defined($2);
658 return value_defined($2);
662 if ($val =~ /^\s*0\s*$/) {
664 } elsif ($val =~ /^\s*\d+\s*$/) {
668 die ("$name: $.: Undefined content $val in if statement\n");
672 my ($name, $value) = @_;
674 # Convert variables and replace undefined ones with 0
675 my $val = process_variables($value, 1);
676 my $ret = process_expression $name, $val;
682 my ($config, $current_test_num) = @_;
685 open($in, $config) || die "can't read file $config";
688 $name =~ s,.*/(.*),$1,;
690 my $test_num = $$current_test_num;
693 my $num_tests_set = 0;
706 # ignore blank lines and comments
707 next if (/^\s*$/ || /\s*\#/);
709 if (/^\s*(TEST_START|DEFAULTS)\b(.*)/) {
719 if ($type eq "TEST_START") {
721 if ($num_tests_set) {
722 die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
725 $old_test_num = $test_num;
726 $old_repeat = $repeat;
728 $test_num += $repeat;
735 # If SKIP is anywhere in the line, the command will be skipped
736 if ($rest =~ s/\s+SKIP\b//) {
743 if ($rest =~ s/\sELSE\b//) {
745 die "$name: $.: ELSE found with out matching IF section\n$_";
756 if ($rest =~ s/\sIF\s+(.*)//) {
757 if (process_if($name, $1)) {
769 if ($type eq "TEST_START") {
770 if ($rest =~ s/\s+ITERATE\s+(\d+)//) {
772 $repeat_tests{"$test_num"} = $repeat;
774 } elsif ($rest =~ s/\sOVERRIDE\b//) {
777 # Clear previous overrides
782 if (!$skip && $rest !~ /^\s*$/) {
783 die "$name: $.: Gargbage found after $type\n$_";
786 if ($skip && $type eq "TEST_START") {
787 $test_num = $old_test_num;
788 $repeat = $old_repeat;
791 } elsif (/^\s*ELSE\b(.*)$/) {
793 die "$name: $.: ELSE found with out matching IF section\n$_";
802 if ($rest =~ /\sIF\s+(.*)/) {
803 # May be a ELSE IF section.
804 if (!process_if($name, $1)) {
813 if ($rest !~ /^\s*$/) {
814 die "$name: $.: Gargbage found after DEFAULTS\n$_";
817 } elsif (/^\s*INCLUDE\s+(\S+)/) {
822 die "$name: $.: INCLUDE can only be done in default sections\n$_";
825 my $file = process_variables($1);
827 if ($file !~ m,^/,) {
828 # check the path of the config file first
829 if ($config =~ m,(.*)/,) {
837 die "$name: $.: Can't read file $file\n$_";
840 if (__read_config($file, \$test_num)) {
844 } elsif (/^\s*([A-Z_\[\]\d]+)\s*=\s*(.*?)\s*$/) {
852 ($lvalue eq "NUM_TESTS" ||
853 $lvalue eq "LOG_FILE" ||
854 $lvalue eq "CLEAR_LOG")) {
855 die "$name: $.: $lvalue must be set in DEFAULTS section\n";
858 if ($lvalue eq "NUM_TESTS") {
860 die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
863 die "$name: $.: NUM_TESTS must be set in default section\n";
868 if ($default || $lvalue =~ /\[\d+\]$/) {
869 set_value($lvalue, $rvalue, $override, \%overrides, $name);
871 my $val = "$lvalue\[$test_num\]";
872 set_value($val, $rvalue, $override, \%overrides, $name);
875 $repeats{$val} = $repeat;
878 } elsif (/^\s*([A-Z_\[\]\d]+)\s*:=\s*(.*?)\s*$/) {
884 # process config variables.
885 # Config variables are only active while reading the
886 # config and can be defined anywhere. They also ignore
887 # TEST_START and DEFAULTS, but are skipped if they are in
888 # on of these sections that have SKIP defined.
889 # The save variable can be
890 # defined multiple times and the new one simply overrides
892 set_variable($lvalue, $rvalue);
895 die "$name: $.: Garbage found in config\n$_";
900 $test_num += $repeat - 1;
901 $opt{"NUM_TESTS"} = $test_num;
906 $$current_test_num = $test_num;
912 print "What test case would you like to run?\n";
913 print " (build, install or boot)\n";
914 print " Other tests are available but require editing the config file\n";
917 $default{"TEST_TYPE"} = $ans;
926 $test_case = __read_config $config, \$test_num;
928 # make sure we have all mandatory configs
931 # was a test specified?
933 print "No test case specified.\n";
939 foreach my $default (keys %default) {
940 if (!defined($opt{$default})) {
941 $opt{$default} = $default{$default};
945 if ($opt{"IGNORE_UNUSED"} == 1) {
951 # check if there are any stragglers (typos?)
952 foreach my $option (keys %opt) {
954 # remove per test labels.
956 if (!exists($option_map{$op}) &&
957 !exists($default{$op}) &&
958 !exists($used_options{$op})) {
965 $s = " is" if (keys %not_used == 1);
966 print "The following option$s not used; could be a typo:\n";
967 foreach my $option (keys %not_used) {
970 print "Set IGRNORE_UNUSED = 1 to have ktest ignore unused variables\n";
971 if (!read_yn "Do you want to continue?") {
978 my ($option, $i) = @_;
980 # Add space to evaluate the character before $
981 $option = " $option";
986 foreach my $test (keys %repeat_tests) {
988 $i < $test + $repeat_tests{$test}) {
996 while ($option =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) {
1001 # Append beginning of line
1002 $retval = "$retval$start";
1004 # If the iteration option OPT[$i] exists, then use that.
1005 # otherwise see if the default OPT (without [$i]) exists.
1007 my $o = "$var\[$i\]";
1008 my $parento = "$var\[$parent\]";
1010 if (defined($opt{$o})) {
1012 $retval = "$retval$o";
1013 } elsif ($repeated && defined($opt{$parento})) {
1014 $o = $opt{$parento};
1015 $retval = "$retval$o";
1016 } elsif (defined($opt{$var})) {
1018 $retval = "$retval$o";
1020 $retval = "$retval\$\{$var\}";
1026 $retval = "$retval$option";
1034 my ($option, $i) = @_;
1038 # Since an option can evaluate to another option,
1039 # keep iterating until we do not evaluate any more
1042 while ($prev ne $option) {
1043 # Check for recursive evaluations.
1044 # 100 deep should be more than enough.
1046 die "Over 100 evaluations accurred with $option\n" .
1047 "Check for recursive variables\n";
1050 $option = __eval_option($option, $i);
1057 if (defined($opt{"LOG_FILE"})) {
1058 open(OUT, ">> $opt{LOG_FILE}") or die "Can't write to $opt{LOG_FILE}";
1065 if (defined($opt{"LOG_FILE"})) {
1080 sub wait_for_monitor;
1085 if (defined($time)) {
1087 # flush out current monitor
1088 # May contain the reboot success line
1092 # try to reboot normally
1093 if (run_command $reboot) {
1094 if (defined($powercycle_after_reboot)) {
1095 sleep $powercycle_after_reboot;
1096 run_command "$power_cycle";
1099 # nope? power cycle it.
1100 run_command "$power_cycle";
1103 if (defined($time)) {
1104 wait_for_monitor($time, $reboot_success_line);
1109 sub reboot_to_good {
1112 if (defined($switch_to_good)) {
1113 run_command $switch_to_good;
1123 return $test_type eq "build" || $no_reboot ||
1124 ($test_type eq "patchcheck" && $opt{"PATCHCHECK_TYPE[$i]"} eq "build") ||
1125 ($test_type eq "bisect" && $opt{"BISECT_TYPE[$i]"} eq "build");
1129 doprint "CRITICAL FAILURE... ", @_, "\n";
1133 if ($reboot_on_error && !do_not_reboot) {
1135 doprint "REBOOTING\n";
1138 } elsif ($poweroff_on_error && defined($power_off)) {
1139 doprint "POWERING OFF\n";
1143 if (defined($opt{"LOG_FILE"})) {
1144 print " See $opt{LOG_FILE} for more info.\n";
1155 my $pid = open($fp, "$console|") or
1156 dodie "Can't open console $console";
1158 $flags = fcntl($fp, F_GETFL, 0) or
1159 dodie "Can't get flags for the socket: $!";
1160 $flags = fcntl($fp, F_SETFL, $flags | O_NONBLOCK) or
1161 dodie "Can't set flags for the socket: $!";
1167 my ($fp, $pid) = @_;
1169 doprint "kill child process $pid\n";
1177 if ($monitor_cnt++) {
1180 $monitor_fp = \*MONFD;
1181 $monitor_pid = open_console $monitor_fp;
1185 open(MONFD, "Stop perl from warning about single use of MONFD");
1189 if (--$monitor_cnt) {
1192 close_console($monitor_fp, $monitor_pid);
1195 sub wait_for_monitor {
1196 my ($time, $stop) = @_;
1201 doprint "** Wait for monitor to settle down **\n";
1203 # read the monitor and wait for the system to calm down
1205 $line = wait_for_input($monitor_fp, $time);
1206 last if (!defined($line));
1208 $full_line .= $line;
1210 if (defined($stop) && $full_line =~ /$stop/) {
1211 doprint "wait for monitor detected $stop\n";
1215 if ($line =~ /\n/) {
1219 print "** Monitor flushed **\n";
1223 my ($result, $basedir) = @_;
1225 my $date = sprintf "%04d%02d%02d%02d%02d%02d",
1226 1900+$t[5],$t[4],$t[3],$t[2],$t[1],$t[0];
1228 my $type = $build_type;
1229 if ($type =~ /useconfig/) {
1230 $type = "useconfig";
1233 my $dir = "$machine-$test_type-$type-$result-$date";
1235 $dir = "$basedir/$dir";
1239 die "can't create $dir";
1243 "config" => $output_config,
1244 "buildlog" => $buildlog,
1246 "testlog" => $testlog,
1249 while (my ($name, $source) = each(%files)) {
1251 cp "$source", "$dir/$name" or
1252 die "failed to copy $source";
1256 doprint "*** Saved info to $dir ***\n";
1261 if ($die_on_failure) {
1269 # no need to reboot for just building.
1270 if (!do_not_reboot) {
1271 doprint "REBOOTING\n";
1272 reboot_to_good $sleep_time;
1277 if (defined($test_name)) {
1278 $name = " ($test_name)";
1281 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
1282 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
1283 doprint "KTEST RESULT: TEST $i$name Failed: ", @_, "\n";
1284 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
1285 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
1287 if (defined($store_failures)) {
1288 save_logs "fail", $store_failures;
1300 $command =~ s/\$SSH_USER/$ssh_user/g;
1301 $command =~ s/\$MACHINE/$machine/g;
1303 doprint("$command ... ");
1305 $pid = open(CMD, "$command 2>&1 |") or
1306 (fail "unable to exec $command" and return 0);
1308 if (defined($opt{"LOG_FILE"})) {
1309 open(LOG, ">>$opt{LOG_FILE}") or
1310 dodie "failed to write to log";
1314 if (defined($redirect)) {
1315 open (RD, ">$redirect") or
1316 dodie "failed to write to redirect $redirect";
1321 print LOG if ($dolog);
1322 print RD if ($dord);
1329 close(LOG) if ($dolog);
1330 close(RD) if ($dord);
1333 doprint "FAILED!\n";
1335 doprint "SUCCESS\n";
1343 my $cp_exec = $ssh_exec;
1345 $cp_exec =~ s/\$SSH_COMMAND/$cmd/g;
1346 return run_command "$cp_exec";
1350 my ($src, $dst) = @_;
1351 my $cp_scp = $scp_to_target;
1353 $cp_scp =~ s/\$SRC_FILE/$src/g;
1354 $cp_scp =~ s/\$DST_FILE/$dst/g;
1356 return run_command "$cp_scp";
1359 sub get_grub_index {
1361 if ($reboot_type ne "grub") {
1364 return if (defined($grub_number));
1366 doprint "Find grub menu ... ";
1369 my $ssh_grub = $ssh_exec;
1370 $ssh_grub =~ s,\$SSH_COMMAND,cat /boot/grub/menu.lst,g;
1372 open(IN, "$ssh_grub |")
1373 or die "unable to get menu.lst";
1378 if (/^\s*title\s+$grub_menu\s*$/) {
1382 } elsif (/^\s*title\s/) {
1388 die "Could not find '$grub_menu' in /boot/grub/menu on $machine"
1390 doprint "$grub_number\n";
1395 my ($fp, $time) = @_;
1401 if (!defined($time)) {
1406 vec($rin, fileno($fp), 1) = 1;
1407 $ready = select($rin, undef, undef, $time);
1411 # try to read one char at a time
1412 while (sysread $fp, $ch, 1) {
1414 last if ($ch eq "\n");
1417 if (!length($line)) {
1425 if (defined($switch_to_test)) {
1426 run_command $switch_to_test;
1429 if ($reboot_type eq "grub") {
1430 run_ssh "'(echo \"savedefault --default=$grub_number --once\" | grub --batch)'";
1431 } elsif (defined $reboot_script) {
1432 run_command "$reboot_script";
1440 doprint "git rev-list --max-count=1 $commit ... ";
1441 my $sha1 = `git rev-list --max-count=1 $commit`;
1448 dodie "Failed to get git $commit";
1461 my $skip_call_trace = 0;
1469 open(DMESG, "> $dmesg") or
1470 die "unable to write to $dmesg";
1476 my $monitor_start = time;
1478 my $version_found = 0;
1482 if ($bug && defined($stop_after_failure) &&
1483 $stop_after_failure >= 0) {
1484 my $time = $stop_after_failure - (time - $failure_start);
1485 $line = wait_for_input($monitor_fp, $time);
1486 if (!defined($line)) {
1487 doprint "bug timed out after $booted_timeout seconds\n";
1488 doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
1492 $line = wait_for_input($monitor_fp, $booted_timeout);
1493 if (!defined($line)) {
1494 my $s = $booted_timeout == 1 ? "" : "s";
1495 doprint "Successful boot found: break after $booted_timeout second$s\n";
1499 $line = wait_for_input($monitor_fp);
1500 if (!defined($line)) {
1501 my $s = $timeout == 1 ? "" : "s";
1502 doprint "Timed out after $timeout second$s\n";
1510 # we are not guaranteed to get a full line
1511 $full_line .= $line;
1513 if ($full_line =~ /$success_line/) {
1515 $success_start = time;
1518 if ($booted && defined($stop_after_success) &&
1519 $stop_after_success >= 0) {
1521 if ($now - $success_start >= $stop_after_success) {
1522 doprint "Test forced to stop after $stop_after_success seconds after success\n";
1527 if ($full_line =~ /\[ backtrace testing \]/) {
1528 $skip_call_trace = 1;
1531 if ($full_line =~ /call trace:/i) {
1532 if (!$bug && !$skip_call_trace) {
1534 $failure_start = time;
1538 if ($bug && defined($stop_after_failure) &&
1539 $stop_after_failure >= 0) {
1541 if ($now - $failure_start >= $stop_after_failure) {
1542 doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
1547 if ($full_line =~ /\[ end of backtrace testing \]/) {
1548 $skip_call_trace = 0;
1551 if ($full_line =~ /Kernel panic -/) {
1552 $failure_start = time;
1556 # Detect triple faults by testing the banner
1557 if ($full_line =~ /\bLinux version (\S+).*\n/) {
1558 if ($1 eq $version) {
1560 } elsif ($version_found && $detect_triplefault) {
1561 # We already booted into the kernel we are testing,
1562 # but now we booted into another kernel?
1563 # Consider this a triple fault.
1564 doprint "Aleady booted in Linux kernel $version, but now\n";
1565 doprint "we booted into Linux kernel $1.\n";
1566 doprint "Assuming that this is a triple fault.\n";
1567 doprint "To disable this: set DETECT_TRIPLE_FAULT to 0\n";
1572 if ($line =~ /\n/) {
1576 if ($stop_test_after > 0 && !$booted && !$bug) {
1577 if (time - $monitor_start > $stop_test_after) {
1578 doprint "STOP_TEST_AFTER ($stop_test_after seconds) timed out\n";
1587 return 0 if ($in_bisect);
1588 fail "failed - got a bug report" and return 0;
1592 return 0 if ($in_bisect);
1593 fail "failed - never got a boot prompt." and return 0;
1599 sub eval_kernel_version {
1602 $option =~ s/\$KERNEL_VERSION/$version/g;
1607 sub do_post_install {
1609 return if (!defined($post_install));
1611 my $cp_post_install = eval_kernel_version $post_install;
1612 run_command "$cp_post_install" or
1613 dodie "Failed to run post install";
1618 return if ($no_install);
1620 my $cp_target = eval_kernel_version $target_image;
1622 run_scp "$outputdir/$build_target", "$cp_target" or
1623 dodie "failed to copy image";
1625 my $install_mods = 0;
1627 # should we process modules?
1629 open(IN, "$output_config") or dodie("Can't read config file");
1631 if (/CONFIG_MODULES(=y)?/) {
1632 $install_mods = 1 if (defined($1));
1638 if (!$install_mods) {
1640 doprint "No modules needed\n";
1644 run_command "$make INSTALL_MOD_PATH=$tmpdir modules_install" or
1645 dodie "Failed to install modules";
1647 my $modlib = "/lib/modules/$version";
1648 my $modtar = "ktest-mods.tar.bz2";
1650 run_ssh "rm -rf $modlib" or
1651 dodie "failed to remove old mods: $modlib";
1653 # would be nice if scp -r did not follow symbolic links
1654 run_command "cd $tmpdir && tar -cjf $modtar lib/modules/$version" or
1655 dodie "making tarball";
1657 run_scp "$tmpdir/$modtar", "/tmp" or
1658 dodie "failed to copy modules";
1660 unlink "$tmpdir/$modtar";
1662 run_ssh "'(cd / && tar xjf /tmp/$modtar)'" or
1663 dodie "failed to tar modules";
1665 run_ssh "rm -f /tmp/$modtar";
1671 # get the release name
1672 doprint "$make kernelrelease ... ";
1673 $version = `$make kernelrelease | tail -1`;
1675 doprint "$version\n";
1678 sub start_monitor_and_boot {
1679 # Make sure the stable kernel has finished booting
1692 sub check_buildlog {
1695 my @files = `git show $patch | diffstat -l`;
1697 open(IN, "git show $patch |") or
1698 dodie "failed to show $patch";
1700 if (m,^--- a/(.*),) {
1702 $files[$#files] = $1;
1707 open(IN, $buildlog) or dodie "Can't open $buildlog";
1709 if (/^\s*(.*?):.*(warning|error)/) {
1711 foreach my $file (@files) {
1712 my $fullpath = "$builddir/$file";
1713 if ($file eq $err || $fullpath eq $err) {
1714 fail "$file built with warnings" and return 0;
1724 sub apply_min_config {
1725 my $outconfig = "$output_config.new";
1727 # Read the config file and remove anything that
1728 # is in the force_config hash (from minconfig and others)
1729 # then add the force config back.
1731 doprint "Applying minimum configurations into $output_config.new\n";
1733 open (OUT, ">$outconfig") or
1734 dodie "Can't create $outconfig";
1736 if (-f $output_config) {
1737 open (IN, $output_config) or
1738 dodie "Failed to open $output_config";
1740 if (/^(# )?(CONFIG_[^\s=]*)/) {
1741 next if (defined($force_config{$2}));
1747 foreach my $config (keys %force_config) {
1748 print OUT "$force_config{$config}\n";
1752 run_command "mv $outconfig $output_config";
1755 sub make_oldconfig {
1757 my @force_list = keys %force_config;
1759 if ($#force_list >= 0) {
1763 if (!run_command "$make oldnoconfig") {
1764 # Perhaps oldnoconfig doesn't exist in this version of the kernel
1765 # try a yes '' | oldconfig
1766 doprint "oldnoconfig failed, trying yes '' | make oldconfig\n";
1767 run_command "yes '' | $make oldconfig" or
1768 dodie "failed make config oldconfig";
1772 # read a config file and use this to force new configs.
1773 sub load_force_config {
1776 open(IN, $config) or
1777 dodie "failed to read $config";
1780 if (/^(CONFIG[^\s=]*)(\s*=.*)/) {
1781 $force_config{$1} = $_;
1782 } elsif (/^# (CONFIG_\S*) is not set/) {
1783 $force_config{$1} = $_;
1794 # Failed builds should not reboot the target
1795 my $save_no_reboot = $no_reboot;
1798 if (defined($pre_build)) {
1799 my $ret = run_command $pre_build;
1800 if (!$ret && defined($pre_build_die) &&
1802 dodie "failed to pre_build\n";
1806 if ($type =~ /^useconfig:(.*)/) {
1807 run_command "cp $1 $output_config" or
1808 dodie "could not copy $1 to .config";
1810 $type = "oldconfig";
1813 # old config can ask questions
1814 if ($type eq "oldconfig") {
1815 $type = "oldnoconfig";
1817 # allow for empty configs
1818 run_command "touch $output_config";
1821 run_command "mv $output_config $outputdir/config_temp" or
1822 dodie "moving .config";
1824 run_command "$make mrproper" or dodie "make mrproper";
1826 run_command "mv $outputdir/config_temp $output_config" or
1827 dodie "moving config_temp";
1830 } elsif (!$noclean) {
1831 unlink "$output_config";
1832 run_command "$make mrproper" or
1833 dodie "make mrproper";
1836 # add something to distinguish this build
1837 open(OUT, "> $outputdir/localversion") or dodie("Can't make localversion file");
1838 print OUT "$localversion\n";
1841 if (defined($minconfig)) {
1842 load_force_config($minconfig);
1845 if ($type ne "oldnoconfig") {
1846 run_command "$make $type" or
1847 dodie "failed make config";
1849 # Run old config regardless, to enforce min configurations
1852 $redirect = "$buildlog";
1853 my $build_ret = run_command "$make $build_options";
1856 if (defined($post_build)) {
1857 my $ret = run_command $post_build;
1858 if (!$ret && defined($post_build_die) &&
1860 dodie "failed to post_build\n";
1865 # bisect may need this to pass
1867 $no_reboot = $save_no_reboot;
1870 fail "failed build" and return 0;
1873 $no_reboot = $save_no_reboot;
1879 if (!run_ssh "halt" or defined($power_off)) {
1880 if (defined($poweroff_after_halt)) {
1881 sleep $poweroff_after_halt;
1882 run_command "$power_off";
1886 run_command "$power_off";
1897 if (defined($test_name)) {
1898 $name = " ($test_name)";
1901 doprint "\n\n*******************************************\n";
1902 doprint "*******************************************\n";
1903 doprint "KTEST RESULT: TEST $i$name SUCCESS!!!! **\n";
1904 doprint "*******************************************\n";
1905 doprint "*******************************************\n";
1907 if (defined($store_successes)) {
1908 save_logs "success", $store_successes;
1911 if ($i != $opt{"NUM_TESTS"} && !do_not_reboot) {
1912 doprint "Reboot and wait $sleep_time seconds\n";
1913 reboot_to_good $sleep_time;
1919 doprint "Pass or fail? [p/f]";
1922 if ($ans eq "p" || $ans eq "P") {
1924 } elsif ($ans eq "f" || $ans eq "F") {
1927 print "Please answer 'P' or 'F'\n";
1932 sub child_run_test {
1935 # child should have no power
1936 $reboot_on_error = 0;
1937 $poweroff_on_error = 0;
1938 $die_on_failure = 1;
1940 $redirect = "$testlog";
1941 run_command $run_test or $failed = 1;
1949 sub child_finished {
1962 doprint "run test $run_test\n";
1966 $SIG{CHLD} = qw(child_finished);
1970 child_run_test if (!$child_pid);
1975 $line = wait_for_input($monitor_fp, 1);
1976 if (defined($line)) {
1978 # we are not guaranteed to get a full line
1979 $full_line .= $line;
1982 if ($full_line =~ /call trace:/i) {
1986 if ($full_line =~ /Kernel panic -/) {
1990 if ($line =~ /\n/) {
1994 } while (!$child_done && !$bug);
1997 my $failure_start = time;
2000 $line = wait_for_input($monitor_fp, 1);
2001 if (defined($line)) {
2005 if ($now - $failure_start >= $stop_after_failure) {
2008 } while (defined($line));
2010 doprint "Detected kernel crash!\n";
2011 # kill the child with extreme prejudice
2015 waitpid $child_pid, 0;
2018 if (!$bug && $in_bisect) {
2019 if (defined($bisect_ret_good)) {
2020 if ($child_exit == $bisect_ret_good) {
2024 if (defined($bisect_ret_skip)) {
2025 if ($child_exit == $bisect_ret_skip) {
2029 if (defined($bisect_ret_abort)) {
2030 if ($child_exit == $bisect_ret_abort) {
2031 fail "test abort" and return -2;
2034 if (defined($bisect_ret_bad)) {
2035 if ($child_exit == $bisect_ret_skip) {
2039 if (defined($bisect_ret_default)) {
2040 if ($bisect_ret_default eq "good") {
2042 } elsif ($bisect_ret_default eq "bad") {
2044 } elsif ($bisect_ret_default eq "skip") {
2046 } elsif ($bisect_ret_default eq "abort") {
2049 fail "unknown default action: $bisect_ret_default"
2055 if ($bug || $child_exit) {
2056 return 0 if $in_bisect;
2057 fail "test failed" and return 0;
2062 sub run_git_bisect {
2065 doprint "$command ... ";
2067 my $output = `$command 2>&1`;
2074 dodie "Failed to git bisect";
2077 doprint "SUCCESS\n";
2078 if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\))\s+\[([[:xdigit:]]+)\]/) {
2079 doprint "$1 [$2]\n";
2080 } elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) {
2081 $bisect_bad_commit = $1;
2082 doprint "Found bad commit... $1\n";
2085 # we already logged it, just print it now.
2093 doprint "Reboot and sleep $bisect_sleep_time seconds\n";
2094 reboot_to_good $bisect_sleep_time;
2097 # returns 1 on success, 0 on failure, -1 on skip
2098 sub run_bisect_test {
2099 my ($type, $buildtype) = @_;
2108 build $buildtype or $failed = 1;
2110 if ($type ne "build") {
2111 if ($failed && $bisect_skip) {
2115 dodie "Failed on build" if $failed;
2118 start_monitor_and_boot or $failed = 1;
2120 if ($type ne "boot") {
2121 if ($failed && $bisect_skip) {
2127 dodie "Failed on boot" if $failed;
2129 do_run_test or $failed = 1;
2140 # reboot the box to a kernel we can ssh to
2141 if ($type ne "build") {
2151 my $buildtype = "oldconfig";
2153 # We should have a minconfig to use?
2154 if (defined($minconfig)) {
2155 $buildtype = "useconfig:$minconfig";
2158 my $ret = run_bisect_test $type, $buildtype;
2160 if ($bisect_manual) {
2161 $ret = answer_bisect;
2164 # Are we looking for where it worked, not failed?
2165 if ($reverse_bisect) {
2171 } elsif ($ret == 0) {
2173 } elsif ($bisect_skip) {
2174 doprint "HIT A BAD COMMIT ... SKIPPING\n";
2179 sub update_bisect_replay {
2180 my $tmp_log = "$tmpdir/ktest_bisect_log";
2181 run_command "git bisect log > $tmp_log" or
2182 die "can't create bisect log";
2191 die "BISECT_GOOD[$i] not defined\n" if (!defined($bisect_good));
2192 die "BISECT_BAD[$i] not defined\n" if (!defined($bisect_bad));
2193 die "BISECT_TYPE[$i] not defined\n" if (!defined($bisect_type));
2195 my $good = $bisect_good;
2196 my $bad = $bisect_bad;
2197 my $type = $bisect_type;
2198 my $start = $bisect_start;
2199 my $replay = $bisect_replay;
2200 my $start_files = $bisect_files;
2202 if (defined($start_files)) {
2203 $start_files = " -- " . $start_files;
2208 # convert to true sha1's
2209 $good = get_sha1($good);
2210 $bad = get_sha1($bad);
2212 if (defined($bisect_reverse) && $bisect_reverse == 1) {
2213 doprint "Performing a reverse bisect (bad is good, good is bad!)\n";
2214 $reverse_bisect = 1;
2216 $reverse_bisect = 0;
2219 # Can't have a test without having a test to run
2220 if ($type eq "test" && !defined($run_test)) {
2224 # Check if a bisect was running
2225 my $bisect_start_file = "$builddir/.git/BISECT_START";
2227 my $check = $bisect_check;
2228 my $do_check = defined($check) && $check ne "0";
2230 if ( -f $bisect_start_file ) {
2231 print "Bisect in progress found\n";
2233 print " If you say yes, then no checks of good or bad will be done\n";
2235 if (defined($replay)) {
2236 print "** BISECT_REPLAY is defined in config file **";
2237 print " Ignore config option and perform new git bisect log?\n";
2238 if (read_ync " (yes, no, or cancel) ") {
2239 $replay = update_bisect_replay;
2242 } elsif (read_yn "read git log and continue?") {
2243 $replay = update_bisect_replay;
2251 my $head = get_sha1("HEAD");
2253 if ($check ne "good") {
2254 doprint "TESTING BISECT BAD [$bad]\n";
2255 run_command "git checkout $bad" or
2256 die "Failed to checkout $bad";
2258 $result = run_bisect $type;
2260 if ($result ne "bad") {
2261 fail "Tested BISECT_BAD [$bad] and it succeeded" and return 0;
2265 if ($check ne "bad") {
2266 doprint "TESTING BISECT GOOD [$good]\n";
2267 run_command "git checkout $good" or
2268 die "Failed to checkout $good";
2270 $result = run_bisect $type;
2272 if ($result ne "good") {
2273 fail "Tested BISECT_GOOD [$good] and it failed" and return 0;
2277 # checkout where we started
2278 run_command "git checkout $head" or
2279 die "Failed to checkout $head";
2282 run_command "git bisect start$start_files" or
2283 dodie "could not start bisect";
2285 run_command "git bisect good $good" or
2286 dodie "could not set bisect good to $good";
2288 run_git_bisect "git bisect bad $bad" or
2289 dodie "could not set bisect bad to $bad";
2291 if (defined($replay)) {
2292 run_command "git bisect replay $replay" or
2293 dodie "failed to run replay";
2296 if (defined($start)) {
2297 run_command "git checkout $start" or
2298 dodie "failed to checkout $start";
2303 $result = run_bisect $type;
2304 $test = run_git_bisect "git bisect $result";
2307 run_command "git bisect log" or
2308 dodie "could not capture git bisect log";
2310 run_command "git bisect reset" or
2311 dodie "could not reset git bisect";
2313 doprint "Bad commit was [$bisect_bad_commit]\n";
2326 sub assign_configs {
2327 my ($hash, $config) = @_;
2330 or dodie "Failed to read $config";
2333 if (/^((CONFIG\S*)=.*)/) {
2341 sub process_config_ignore {
2344 assign_configs \%config_ignore, $config;
2347 sub read_current_config {
2348 my ($config_ref) = @_;
2350 %{$config_ref} = ();
2351 undef %{$config_ref};
2353 my @key = keys %{$config_ref};
2355 print "did not delete!\n";
2358 open (IN, "$output_config");
2361 if (/^(CONFIG\S+)=(.*)/) {
2362 ${$config_ref}{$1} = $2;
2368 sub get_dependencies {
2371 my $arr = $dependency{$config};
2372 if (!defined($arr)) {
2378 foreach my $dep (@{$arr}) {
2379 print "ADD DEP $dep\n";
2380 @deps = (@deps, get_dependencies $dep);
2389 open(OUT, ">$output_config") or dodie "Can not write to $output_config";
2391 foreach my $config (@configs) {
2392 print OUT "$config_set{$config}\n";
2393 my @deps = get_dependencies $config;
2394 foreach my $dep (@deps) {
2395 print OUT "$config_set{$dep}\n";
2399 foreach my $config (keys %config_ignore) {
2400 print OUT "$config_ignore{$config}\n";
2408 sub compare_configs {
2411 foreach my $item (keys %a) {
2412 if (!defined($b{$item})) {
2413 print "diff $item\n";
2421 print "diff2 $keys[0]\n";
2423 return -1 if ($#keys >= 0);
2428 sub run_config_bisect_test {
2431 return run_bisect_test $type, "oldconfig";
2434 sub process_passed {
2437 doprint "These configs had no failure: (Enabling them for further compiles)\n";
2438 # Passed! All these configs are part of a good compile.
2439 # Add them to the min options.
2440 foreach my $config (keys %configs) {
2441 if (defined($config_list{$config})) {
2442 doprint " removing $config\n";
2443 $config_ignore{$config} = $config_list{$config};
2444 delete $config_list{$config};
2447 doprint "config copied to $outputdir/config_good\n";
2448 run_command "cp -f $output_config $outputdir/config_good";
2451 sub process_failed {
2454 doprint "\n\n***************************************\n";
2455 doprint "Found bad config: $config\n";
2456 doprint "***************************************\n\n";
2459 sub run_config_bisect {
2461 my @start_list = keys %config_list;
2463 if ($#start_list < 0) {
2464 doprint "No more configs to test!!!\n";
2468 doprint "***** RUN TEST ***\n";
2469 my $type = $config_bisect_type;
2473 my $count = $#start_list + 1;
2474 doprint " $count configs to test\n";
2476 my $half = int($#start_list / 2);
2479 my @tophalf = @start_list[0 .. $half];
2481 create_config @tophalf;
2482 read_current_config \%current_config;
2484 $count = $#tophalf + 1;
2485 doprint "Testing $count configs\n";
2487 # make sure we test something
2488 foreach my $config (@tophalf) {
2489 if (defined($current_config{$config})) {
2495 # try the other half
2496 doprint "Top half produced no set configs, trying bottom half\n";
2497 @tophalf = @start_list[$half + 1 .. $#start_list];
2498 create_config @tophalf;
2499 read_current_config \%current_config;
2500 foreach my $config (@tophalf) {
2501 if (defined($current_config{$config})) {
2507 doprint "Failed: Can't make new config with current configs\n";
2508 foreach my $config (@start_list) {
2509 doprint " CONFIG: $config\n";
2513 $count = $#tophalf + 1;
2514 doprint "Testing $count configs\n";
2517 $ret = run_config_bisect_test $type;
2518 if ($bisect_manual) {
2519 $ret = answer_bisect;
2522 process_passed %current_config;
2526 doprint "This config had a failure.\n";
2527 doprint "Removing these configs that were not set in this config:\n";
2528 doprint "config copied to $outputdir/config_bad\n";
2529 run_command "cp -f $output_config $outputdir/config_bad";
2531 # A config exists in this group that was bad.
2532 foreach my $config (keys %config_list) {
2533 if (!defined($current_config{$config})) {
2534 doprint " removing $config\n";
2535 delete $config_list{$config};
2539 @start_list = @tophalf;
2541 if ($#start_list == 0) {
2542 process_failed $start_list[0];
2546 # remove half the configs we are looking at and see if
2548 $half = int($#start_list / 2);
2549 } while ($#start_list > 0);
2551 # we found a single config, try it again unless we are running manually
2553 if ($bisect_manual) {
2554 process_failed $start_list[0];
2558 my @tophalf = @start_list[0 .. 0];
2560 $ret = run_config_bisect_test $type;
2562 process_passed %current_config;
2566 process_failed $start_list[0];
2573 my $start_config = $config_bisect;
2575 my $tmpconfig = "$tmpdir/use_config";
2577 if (defined($config_bisect_good)) {
2578 process_config_ignore $config_bisect_good;
2581 # Make the file with the bad config and the min config
2582 if (defined($minconfig)) {
2583 # read the min config for things to ignore
2584 run_command "cp $minconfig $tmpconfig" or
2585 dodie "failed to copy $minconfig to $tmpconfig";
2590 if (-f $tmpconfig) {
2591 load_force_config($tmpconfig);
2592 process_config_ignore $tmpconfig;
2595 # now process the start config
2596 run_command "cp $start_config $output_config" or
2597 dodie "failed to copy $start_config to $output_config";
2599 # read directly what we want to check
2601 open (IN, $output_config)
2602 or dodie "faied to open $output_config";
2605 if (/^((CONFIG\S*)=.*)/) {
2606 $config_check{$2} = $1;
2611 # Now run oldconfig with the minconfig
2614 # check to see what we lost (or gained)
2615 open (IN, $output_config)
2616 or dodie "Failed to read $start_config";
2618 my %removed_configs;
2622 if (/^((CONFIG\S*)=.*)/) {
2623 # save off all options
2624 $config_set{$2} = $1;
2625 if (defined($config_check{$2})) {
2626 if (defined($config_ignore{$2})) {
2627 $removed_configs{$2} = $1;
2629 $config_list{$2} = $1;
2631 } elsif (!defined($config_ignore{$2})) {
2632 $added_configs{$2} = $1;
2633 $config_list{$2} = $1;
2639 my @confs = keys %removed_configs;
2641 doprint "Configs overridden by default configs and removed from check:\n";
2642 foreach my $config (@confs) {
2643 doprint " $config\n";
2646 @confs = keys %added_configs;
2648 doprint "Configs appearing in make oldconfig and added:\n";
2649 foreach my $config (@confs) {
2650 doprint " $config\n";
2657 # Sometimes kconfig does weird things. We must make sure
2658 # that the config we autocreate has everything we need
2659 # to test, otherwise we may miss testing configs, or
2660 # may not be able to create a new config.
2661 # Here we create a config with everything set.
2662 create_config (keys %config_list);
2663 read_current_config \%config_test;
2664 foreach my $config (keys %config_list) {
2665 if (!defined($config_test{$config})) {
2668 doprint "Configs not produced by kconfig (will not be checked):\n";
2670 doprint " $config\n";
2671 delete $config_list{$config};
2676 $ret = run_config_bisect;
2679 return $ret if ($ret < 0);
2684 sub patchcheck_reboot {
2685 doprint "Reboot and sleep $patchcheck_sleep_time seconds\n";
2686 reboot_to_good $patchcheck_sleep_time;
2692 die "PATCHCHECK_START[$i] not defined\n"
2693 if (!defined($patchcheck_start));
2694 die "PATCHCHECK_TYPE[$i] not defined\n"
2695 if (!defined($patchcheck_type));
2697 my $start = $patchcheck_start;
2700 if (defined($patchcheck_end)) {
2701 $end = $patchcheck_end;
2704 # Get the true sha1's since we can use things like HEAD~3
2705 $start = get_sha1($start);
2706 $end = get_sha1($end);
2708 my $type = $patchcheck_type;
2710 # Can't have a test without having a test to run
2711 if ($type eq "test" && !defined($run_test)) {
2715 open (IN, "git log --pretty=oneline $end|") or
2716 dodie "could not get git list";
2722 $list[$#list+1] = $_;
2723 last if (/^$start/);
2727 if ($list[$#list] !~ /^$start/) {
2728 fail "SHA1 $start not found";
2731 # go backwards in the list
2732 @list = reverse @list;
2734 my $save_clean = $noclean;
2735 my %ignored_warnings;
2737 if (defined($ignore_warnings)) {
2738 foreach my $sha1 (split /\s+/, $ignore_warnings) {
2739 $ignored_warnings{$sha1} = 1;
2744 foreach my $item (@list) {
2746 $sha1 =~ s/^([[:xdigit:]]+).*/$1/;
2748 doprint "\nProcessing commit $item\n\n";
2750 run_command "git checkout $sha1" or
2751 die "Failed to checkout $sha1";
2753 # only clean on the first and last patch
2754 if ($item eq $list[0] ||
2755 $item eq $list[$#list]) {
2756 $noclean = $save_clean;
2761 if (defined($minconfig)) {
2762 build "useconfig:$minconfig" or return 0;
2764 # ?? no config to use?
2765 build "oldconfig" or return 0;
2769 if (!defined($ignored_warnings{$sha1})) {
2770 check_buildlog $sha1 or return 0;
2773 next if ($type eq "build");
2777 start_monitor_and_boot or $failed = 1;
2779 if (!$failed && $type ne "boot"){
2780 do_run_test or $failed = 1;
2783 return 0 if ($failed);
2803 # $config depends on $dep
2804 my ($config, $dep) = @_;
2806 if (defined($depends{$config})) {
2807 $depends{$config} .= " " . $dep;
2809 $depends{$config} = $dep;
2812 # record the number of configs depending on $dep
2813 if (defined $depcount{$dep}) {
2816 $depcount{$dep} = 1;
2820 # taken from streamline_config.pl
2832 if (! -f $kconfig) {
2833 doprint "file $kconfig does not exist, skipping\n";
2837 open(KIN, "$kconfig")
2838 or die "Can't open $kconfig";
2842 # Make sure that lines ending with \ continue
2844 $_ = $line . " " . $_;
2855 # collect any Kconfig sources
2856 if (/^source\s*"(.*)"/) {
2857 $kconfigs[$#kconfigs+1] = $1;
2861 if (/^\s*(menu)?config\s+(\S+)\s*$/) {
2865 for (my $i = 0; $i < $iflevel; $i++) {
2866 add_dep $config, $ifdeps[$i];
2869 # collect the depends for the config
2870 } elsif ($state eq "NEW" && /^\s*depends\s+on\s+(.*)$/) {
2872 add_dep $config, $1;
2874 # Get the configs that select this config
2875 } elsif ($state eq "NEW" && /^\s*select\s+(\S+)/) {
2877 # selected by depends on config
2878 add_dep $1, $config;
2880 # Check for if statements
2881 } elsif (/^if\s+(.*\S)\s*$/) {
2883 # remove beginning and ending non text
2884 $deps =~ s/^[^a-zA-Z0-9_]*//;
2885 $deps =~ s/[^a-zA-Z0-9_]*$//;
2887 my @deps = split /[^a-zA-Z0-9_]+/, $deps;
2889 $ifdeps[$iflevel++] = join ':', @deps;
2891 } elsif (/^endif/) {
2893 $iflevel-- if ($iflevel);
2896 } elsif (/^\s*help\s*$/) {
2902 # read in any configs that were found.
2903 foreach $kconfig (@kconfigs) {
2904 if (!defined($read_kconfigs{$kconfig})) {
2905 $read_kconfigs{$kconfig} = 1;
2906 read_kconfig("$builddir/$kconfig");
2912 # find out which arch this is by the kconfig file
2913 open (IN, $output_config)
2914 or dodie "Failed to read $output_config";
2917 if (m,Linux/(\S+)\s+\S+\s+Kernel Configuration,) {
2924 if (!defined($arch)) {
2925 doprint "Could not find arch from config file\n";
2926 doprint "no dependencies used\n";
2930 # arch is really the subarch, we need to know
2931 # what directory to look at.
2932 if ($arch eq "i386" || $arch eq "x86_64") {
2934 } elsif ($arch =~ /^tile/) {
2938 my $kconfig = "$builddir/arch/$arch/Kconfig";
2940 if (! -f $kconfig && $arch =~ /\d$/) {
2942 # some subarchs have numbers, truncate them
2944 $kconfig = "$builddir/arch/$arch/Kconfig";
2945 if (! -f $kconfig) {
2946 doprint "No idea what arch dir $orig is for\n";
2947 doprint "no dependencies used\n";
2952 read_kconfig($kconfig);
2955 sub read_config_list {
2959 or dodie "Failed to read $config";
2962 if (/^((CONFIG\S*)=.*)/) {
2963 if (!defined($config_ignore{$2})) {
2964 $config_list{$2} = $1;
2972 sub read_output_config {
2975 assign_configs \%config_ignore, $config;
2978 sub make_new_config {
2981 open (OUT, ">$output_config")
2982 or dodie "Failed to write $output_config";
2984 foreach my $config (@configs) {
2985 print OUT "$config\n";
2993 $config =~ s/CONFIG_//;
3001 my $kconfig = chomp_config $dep;
3003 $dep = $depends{"$kconfig"};
3005 # the dep string we have saves the dependencies as they
3006 # were found, including expressions like ! && ||. We
3007 # want to split this out into just an array of configs.
3009 my $valid = "A-Za-z_0-9";
3013 while ($dep =~ /[$valid]/) {
3015 if ($dep =~ /^[^$valid]*([$valid]+)/) {
3016 my $conf = "CONFIG_" . $1;
3018 $configs[$#configs + 1] = $conf;
3020 $dep =~ s/^[^$valid]*[$valid]+//;
3022 die "this should never happen";
3032 my %processed_configs;
3033 my %nochange_config;
3035 sub test_this_config {
3040 # if we already processed this config, skip it
3041 if (defined($processed_configs{$config})) {
3044 $processed_configs{$config} = 1;
3046 # if this config failed during this round, skip it
3047 if (defined($nochange_config{$config})) {
3051 my $kconfig = chomp_config $config;
3053 # Test dependencies first
3054 if (defined($depends{"$kconfig"})) {
3055 my @parents = get_depends $config;
3056 foreach my $parent (@parents) {
3057 # if the parent is in the min config, check it first
3058 next if (!defined($min_configs{$parent}));
3059 $found = test_this_config($parent);
3060 if (defined($found)) {
3066 # Remove this config from the list of configs
3067 # do a make oldnoconfig and then read the resulting
3068 # .config to make sure it is missing the config that
3070 my %configs = %min_configs;
3071 delete $configs{$config};
3072 make_new_config ((values %configs), (values %keep_configs));
3075 assign_configs \%configs, $output_config;
3077 return $config if (!defined($configs{$config}));
3079 doprint "disabling config $config did not change .config\n";
3081 $nochange_config{$config} = 1;
3086 sub make_min_config {
3089 if (!defined($output_minconfig)) {
3090 fail "OUTPUT_MIN_CONFIG not defined" and return;
3093 # If output_minconfig exists, and the start_minconfig
3094 # came from min_config, than ask if we should use
3096 if (-f $output_minconfig && !$start_minconfig_defined) {
3097 print "$output_minconfig exists\n";
3098 if (read_yn " Use it as minconfig?") {
3099 $start_minconfig = $output_minconfig;
3103 if (!defined($start_minconfig)) {
3104 fail "START_MIN_CONFIG or MIN_CONFIG not defined" and return;
3107 my $temp_config = "$tmpdir/temp_config";
3109 # First things first. We build an allnoconfig to find
3110 # out what the defaults are that we can't touch.
3111 # Some are selections, but we really can't handle selections.
3113 my $save_minconfig = $minconfig;
3116 run_command "$make allnoconfig" or return 0;
3120 process_config_ignore $output_config;
3122 undef %save_configs;
3125 if (defined($ignore_config)) {
3126 # make sure the file exists
3127 `touch $ignore_config`;
3128 assign_configs \%save_configs, $ignore_config;
3131 %keep_configs = %save_configs;
3133 doprint "Load initial configs from $start_minconfig\n";
3135 # Look at the current min configs, and save off all the
3136 # ones that were set via the allnoconfig
3137 assign_configs \%min_configs, $start_minconfig;
3139 my @config_keys = keys %min_configs;
3141 # All configs need a depcount
3142 foreach my $config (@config_keys) {
3143 my $kconfig = chomp_config $config;
3144 if (!defined $depcount{$kconfig}) {
3145 $depcount{$kconfig} = 0;
3149 # Remove anything that was set by the make allnoconfig
3150 # we shouldn't need them as they get set for us anyway.
3151 foreach my $config (@config_keys) {
3152 # Remove anything in the ignore_config
3153 if (defined($keep_configs{$config})) {
3154 my $file = $ignore_config;
3155 $file =~ s,.*/(.*?)$,$1,;
3156 doprint "$config set by $file ... ignored\n";
3157 delete $min_configs{$config};
3160 # But make sure the settings are the same. If a min config
3161 # sets a selection, we do not want to get rid of it if
3162 # it is not the same as what we have. Just move it into
3164 if (defined($config_ignore{$config})) {
3165 if ($config_ignore{$config} ne $min_configs{$config}) {
3166 doprint "$config is in allnoconfig as '$config_ignore{$config}'";
3167 doprint " but it is '$min_configs{$config}' in minconfig .. keeping\n";
3168 $keep_configs{$config} = $min_configs{$config};
3170 doprint "$config set by allnoconfig ... ignored\n";
3172 delete $min_configs{$config};
3184 # Now disable each config one by one and do a make oldconfig
3185 # till we find a config that changes our list.
3187 my @test_configs = keys %min_configs;
3189 # Sort keys by who is most dependent on
3190 @test_configs = sort { $depcount{chomp_config($b)} <=> $depcount{chomp_config($a)} }
3193 # Put configs that did not modify the config at the end.
3195 for (my $i = 0; $i < $#test_configs; $i++) {
3196 if (!defined($nochange_config{$test_configs[0]})) {
3200 # This config didn't change the .config last time.
3201 # Place it at the end
3202 my $config = shift @test_configs;
3203 push @test_configs, $config;
3206 # if every test config has failed to modify the .config file
3207 # in the past, then reset and start over.
3209 undef %nochange_config;
3212 undef %processed_configs;
3214 foreach my $config (@test_configs) {
3216 $found = test_this_config $config;
3218 last if (defined($found));
3220 # oh well, try another config
3223 if (!defined($found)) {
3224 # we could have failed due to the nochange_config hash
3225 # reset and try again
3227 undef %nochange_config;
3231 doprint "No more configs found that we can disable\n";
3239 doprint "Test with $config disabled\n";
3241 # set in_bisect to keep build and monitor from dieing
3246 start_monitor_and_boot or $failed = 1;
3252 doprint "$min_configs{$config} is needed to boot the box... keeping\n";
3253 # this config is needed, add it to the ignore list.
3254 $keep_configs{$config} = $min_configs{$config};
3255 $save_configs{$config} = $min_configs{$config};
3256 delete $min_configs{$config};
3258 # update new ignore configs
3259 if (defined($ignore_config)) {
3260 open (OUT, ">$temp_config")
3261 or die "Can't write to $temp_config";
3262 foreach my $config (keys %save_configs) {
3263 print OUT "$save_configs{$config}\n";
3266 run_command "mv $temp_config $ignore_config" or
3267 dodie "failed to copy update to $ignore_config";
3271 # We booted without this config, remove it from the minconfigs.
3272 doprint "$config is not needed, disabling\n";
3274 delete $min_configs{$config};
3276 # Also disable anything that is not enabled in this config
3278 assign_configs \%configs, $output_config;
3279 my @config_keys = keys %min_configs;
3280 foreach my $config (@config_keys) {
3281 if (!defined($configs{$config})) {
3282 doprint "$config is not set, disabling\n";
3283 delete $min_configs{$config};
3287 # Save off all the current mandidory configs
3288 open (OUT, ">$temp_config")
3289 or die "Can't write to $temp_config";
3290 foreach my $config (keys %keep_configs) {
3291 print OUT "$keep_configs{$config}\n";
3293 foreach my $config (keys %min_configs) {
3294 print OUT "$min_configs{$config}\n";
3298 run_command "mv $temp_config $output_minconfig" or
3299 dodie "failed to copy update to $output_minconfig";
3302 doprint "Reboot and wait $sleep_time seconds\n";
3303 reboot_to_good $sleep_time;
3310 $#ARGV < 1 or die "ktest.pl version: $VERSION\n usage: ktest.pl config-file\n";
3313 $ktest_config = $ARGV[0];
3314 if (! -f $ktest_config) {
3315 print "$ktest_config does not exist.\n";
3316 if (!read_yn "Create it?") {
3321 $ktest_config = "ktest.conf";
3324 if (! -f $ktest_config) {
3327 open(OUT, ">$ktest_config") or die "Can not create $ktest_config";
3329 # Generated by ktest.pl
3332 # PWD is a ktest.pl variable that will result in the process working
3333 # directory that ktest.pl is executed in.
3335 # THIS_DIR is automatically assigned the PWD of the path that generated
3336 # the config file. It is best to use this variable when assigning other
3337 # directory paths within this directory. This allows you to easily
3338 # move the test cases to other locations or to other machines.
3340 THIS_DIR := $variable{"PWD"}
3342 # Define each test with TEST_START
3343 # The config options below it will override the defaults
3345 TEST_TYPE = $default{"TEST_TYPE"}
3352 read_config $ktest_config;
3354 if (defined($opt{"LOG_FILE"})) {
3355 $opt{"LOG_FILE"} = eval_option($opt{"LOG_FILE"}, -1);
3358 # Append any configs entered in manually to the config file.
3359 my @new_configs = keys %entered_configs;
3360 if ($#new_configs >= 0) {
3361 print "\nAppending entered in configs to $ktest_config\n";
3362 open(OUT, ">>$ktest_config") or die "Can not append to $ktest_config";
3363 foreach my $config (@new_configs) {
3364 print OUT "$config = $entered_configs{$config}\n";
3365 $opt{$config} = process_variables($entered_configs{$config});
3369 if ($opt{"CLEAR_LOG"} && defined($opt{"LOG_FILE"})) {
3370 unlink $opt{"LOG_FILE"};
3373 doprint "\n\nSTARTING AUTOMATED TESTS\n\n";
3375 for (my $i = 0, my $repeat = 1; $i <= $opt{"NUM_TESTS"}; $i += $repeat) {
3378 doprint "DEFAULT OPTIONS:\n";
3380 doprint "\nTEST $i OPTIONS";
3381 if (defined($repeat_tests{$i})) {
3382 $repeat = $repeat_tests{$i};
3383 doprint " ITERATE $repeat";
3388 foreach my $option (sort keys %opt) {
3390 if ($option =~ /\[(\d+)\]$/) {
3396 doprint "$option = $opt{$option}\n";
3400 sub __set_test_option {
3401 my ($name, $i) = @_;
3403 my $option = "$name\[$i\]";
3405 if (defined($opt{$option})) {
3406 return $opt{$option};
3409 foreach my $test (keys %repeat_tests) {
3411 $i < $test + $repeat_tests{$test}) {
3412 $option = "$name\[$test\]";
3413 if (defined($opt{$option})) {
3414 return $opt{$option};
3419 if (defined($opt{$name})) {
3426 sub set_test_option {
3427 my ($name, $i) = @_;
3429 my $option = __set_test_option($name, $i);
3430 return $option if (!defined($option));
3432 return eval_option($option, $i);
3435 # First we need to do is the builds
3436 for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
3438 # Do not reboot on failing test options
3443 my $makecmd = set_test_option("MAKE_CMD", $i);
3445 # Load all the options into their mapped variable names
3446 foreach my $opt (keys %option_map) {
3447 ${$option_map{$opt}} = set_test_option($opt, $i);
3450 $start_minconfig_defined = 1;
3452 if (!defined($start_minconfig)) {
3453 $start_minconfig_defined = 0;
3454 $start_minconfig = $minconfig;
3457 chdir $builddir || die "can't change directory to $builddir";
3459 foreach my $dir ($tmpdir, $outputdir) {
3462 die "can't create $dir";
3466 $ENV{"SSH_USER"} = $ssh_user;
3467 $ENV{"MACHINE"} = $machine;
3469 $buildlog = "$tmpdir/buildlog-$machine";
3470 $testlog = "$tmpdir/testlog-$machine";
3471 $dmesg = "$tmpdir/dmesg-$machine";
3472 $make = "$makecmd O=$outputdir";
3473 $output_config = "$outputdir/.config";
3476 $target = "$ssh_user\@$machine";
3477 if ($reboot_type eq "grub") {
3478 dodie "GRUB_MENU not defined" if (!defined($grub_menu));
3482 my $run_type = $build_type;
3483 if ($test_type eq "patchcheck") {
3484 $run_type = $patchcheck_type;
3485 } elsif ($test_type eq "bisect") {
3486 $run_type = $bisect_type;
3487 } elsif ($test_type eq "config_bisect") {
3488 $run_type = $config_bisect_type;
3491 if ($test_type eq "make_min_config") {
3495 # mistake in config file?
3496 if (!defined($run_type)) {
3497 $run_type = "ERROR";
3501 $installme = " no_install" if ($no_install);
3504 doprint "RUNNING TEST $i of $opt{NUM_TESTS} with option $test_type $run_type$installme\n\n";
3510 if (defined($addconfig)) {
3511 my $min = $minconfig;
3512 if (!defined($minconfig)) {
3515 run_command "cat $addconfig $min > $tmpdir/add_config" or
3516 dodie "Failed to create temp config";
3517 $minconfig = "$tmpdir/add_config";
3520 if (defined($checkout)) {
3521 run_command "git checkout $checkout" or
3522 die "failed to checkout $checkout";
3528 if ($test_type eq "bisect") {
3531 } elsif ($test_type eq "config_bisect") {
3534 } elsif ($test_type eq "patchcheck") {
3537 } elsif ($test_type eq "make_min_config") {
3542 if ($build_type ne "nobuild") {
3543 build $build_type or next;
3546 if ($test_type eq "install") {
3553 if ($test_type ne "build") {
3555 start_monitor_and_boot or $failed = 1;
3557 if (!$failed && $test_type ne "boot" && defined($run_test)) {
3558 do_run_test or $failed = 1;
3567 if ($opt{"POWEROFF_ON_SUCCESS"}) {
3569 } elsif ($opt{"REBOOT_ON_SUCCESS"} && !do_not_reboot) {
3573 doprint "\n $successes of $opt{NUM_TESTS} tests were successful\n\n";