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);
26 "TEST_TYPE" => "build",
27 "BUILD_TYPE" => "randconfig",
29 "CLOSE_CONSOLE_SIGNAL" => "INT",
31 "TMP_DIR" => "/tmp/ktest/\${MACHINE}",
32 "SLEEP_TIME" => 60, # sleep time between tests
34 "REBOOT_ON_ERROR" => 0,
35 "POWEROFF_ON_ERROR" => 0,
36 "REBOOT_ON_SUCCESS" => 1,
37 "POWEROFF_ON_SUCCESS" => 0,
38 "BUILD_OPTIONS" => "",
39 "BISECT_SLEEP_TIME" => 60, # sleep time between bisects
40 "PATCHCHECK_SLEEP_TIME" => 60, # sleep time between patch checks
45 "MIN_CONFIG_TYPE" => "boot",
46 "SUCCESS_LINE" => "login:",
47 "DETECT_TRIPLE_FAULT" => 1,
49 "BOOTED_TIMEOUT" => 1,
50 "DIE_ON_FAILURE" => 1,
51 "SSH_EXEC" => "ssh \$SSH_USER\@\$MACHINE \$SSH_COMMAND",
52 "SCP_TO_TARGET" => "scp \$SRC_FILE \$SSH_USER\@\$MACHINE:\$DST_FILE",
53 "SCP_TO_TARGET_INSTALL" => "\${SCP_TO_TARGET}",
54 "REBOOT" => "ssh \$SSH_USER\@\$MACHINE reboot",
55 "STOP_AFTER_SUCCESS" => 10,
56 "STOP_AFTER_FAILURE" => 60,
57 "STOP_TEST_AFTER" => 600,
58 "MAX_MONITOR_WAIT" => 1800,
59 "GRUB_REBOOT" => "grub2-reboot",
60 "SYSLINUX" => "extlinux",
61 "SYSLINUX_PATH" => "/boot/extlinux",
63 # required, and we will ask users if they don't have them but we keep the default
64 # value something that is common.
65 "REBOOT_TYPE" => "grub",
66 "LOCALVERSION" => "-test",
68 "BUILD_TARGET" => "arch/x86/boot/bzImage",
69 "TARGET_IMAGE" => "/boot/vmlinuz-test",
75 my $ktest_config = "ktest.conf";
104 my $poweroff_on_error;
105 my $reboot_on_success;
107 my $powercycle_after_reboot;
108 my $poweroff_after_halt;
109 my $max_monitor_wait;
112 my $scp_to_target_install;
130 my $start_minconfig_defined;
131 my $output_minconfig;
133 my $use_output_minconfig;
139 my $bisect_bad_commit = "";
144 my $config_bisect_good;
148 my $bisect_ret_abort;
149 my $bisect_ret_default;
150 my $in_patchcheck = 0;
159 my $bisect_sleep_time;
160 my $patchcheck_sleep_time;
167 my $detect_triplefault;
169 my $close_console_signal;
170 my $reboot_success_line;
172 my $stop_after_success;
173 my $stop_after_failure;
182 my $run_command_status = 0;
194 my $config_bisect_type;
195 my $config_bisect_check;
198 my $patchcheck_start;
199 my $patchcheck_cherry;
207 # set when a test is something other that just building or install
208 # which would require more options.
211 # tell build not to worry about warnings, even when WARNINGS_FILE is set
214 # set when creating a new config
221 # force_config is the list of configs that we force enabled (or disabled)
222 # in a .config file. The MIN_CONFIG and ADD_CONFIG configs.
225 # do not force reboots on config problems
229 my $reboot_success = 0;
232 "MACHINE" => \$machine,
233 "SSH_USER" => \$ssh_user,
234 "TMP_DIR" => \$tmpdir,
235 "OUTPUT_DIR" => \$outputdir,
236 "BUILD_DIR" => \$builddir,
237 "TEST_TYPE" => \$test_type,
238 "PRE_KTEST" => \$pre_ktest,
239 "POST_KTEST" => \$post_ktest,
240 "PRE_TEST" => \$pre_test,
241 "POST_TEST" => \$post_test,
242 "BUILD_TYPE" => \$build_type,
243 "BUILD_OPTIONS" => \$build_options,
244 "PRE_BUILD" => \$pre_build,
245 "POST_BUILD" => \$post_build,
246 "PRE_BUILD_DIE" => \$pre_build_die,
247 "POST_BUILD_DIE" => \$post_build_die,
248 "POWER_CYCLE" => \$power_cycle,
249 "REBOOT" => \$reboot,
250 "BUILD_NOCLEAN" => \$noclean,
251 "MIN_CONFIG" => \$minconfig,
252 "OUTPUT_MIN_CONFIG" => \$output_minconfig,
253 "START_MIN_CONFIG" => \$start_minconfig,
254 "MIN_CONFIG_TYPE" => \$minconfig_type,
255 "USE_OUTPUT_MIN_CONFIG" => \$use_output_minconfig,
256 "WARNINGS_FILE" => \$warnings_file,
257 "IGNORE_CONFIG" => \$ignore_config,
258 "TEST" => \$run_test,
259 "ADD_CONFIG" => \$addconfig,
260 "REBOOT_TYPE" => \$reboot_type,
261 "GRUB_MENU" => \$grub_menu,
262 "GRUB_FILE" => \$grub_file,
263 "GRUB_REBOOT" => \$grub_reboot,
264 "SYSLINUX" => \$syslinux,
265 "SYSLINUX_PATH" => \$syslinux_path,
266 "SYSLINUX_LABEL" => \$syslinux_label,
267 "PRE_INSTALL" => \$pre_install,
268 "POST_INSTALL" => \$post_install,
269 "NO_INSTALL" => \$no_install,
270 "REBOOT_SCRIPT" => \$reboot_script,
271 "REBOOT_ON_ERROR" => \$reboot_on_error,
272 "SWITCH_TO_GOOD" => \$switch_to_good,
273 "SWITCH_TO_TEST" => \$switch_to_test,
274 "POWEROFF_ON_ERROR" => \$poweroff_on_error,
275 "REBOOT_ON_SUCCESS" => \$reboot_on_success,
276 "DIE_ON_FAILURE" => \$die_on_failure,
277 "POWER_OFF" => \$power_off,
278 "POWERCYCLE_AFTER_REBOOT" => \$powercycle_after_reboot,
279 "POWEROFF_AFTER_HALT" => \$poweroff_after_halt,
280 "MAX_MONITOR_WAIT" => \$max_monitor_wait,
281 "SLEEP_TIME" => \$sleep_time,
282 "BISECT_SLEEP_TIME" => \$bisect_sleep_time,
283 "PATCHCHECK_SLEEP_TIME" => \$patchcheck_sleep_time,
284 "IGNORE_WARNINGS" => \$ignore_warnings,
285 "IGNORE_ERRORS" => \$ignore_errors,
286 "BISECT_MANUAL" => \$bisect_manual,
287 "BISECT_SKIP" => \$bisect_skip,
288 "BISECT_TRIES" => \$bisect_tries,
289 "CONFIG_BISECT_GOOD" => \$config_bisect_good,
290 "BISECT_RET_GOOD" => \$bisect_ret_good,
291 "BISECT_RET_BAD" => \$bisect_ret_bad,
292 "BISECT_RET_SKIP" => \$bisect_ret_skip,
293 "BISECT_RET_ABORT" => \$bisect_ret_abort,
294 "BISECT_RET_DEFAULT" => \$bisect_ret_default,
295 "STORE_FAILURES" => \$store_failures,
296 "STORE_SUCCESSES" => \$store_successes,
297 "TEST_NAME" => \$test_name,
298 "TIMEOUT" => \$timeout,
299 "BOOTED_TIMEOUT" => \$booted_timeout,
300 "CONSOLE" => \$console,
301 "CLOSE_CONSOLE_SIGNAL" => \$close_console_signal,
302 "DETECT_TRIPLE_FAULT" => \$detect_triplefault,
303 "SUCCESS_LINE" => \$success_line,
304 "REBOOT_SUCCESS_LINE" => \$reboot_success_line,
305 "STOP_AFTER_SUCCESS" => \$stop_after_success,
306 "STOP_AFTER_FAILURE" => \$stop_after_failure,
307 "STOP_TEST_AFTER" => \$stop_test_after,
308 "BUILD_TARGET" => \$build_target,
309 "SSH_EXEC" => \$ssh_exec,
310 "SCP_TO_TARGET" => \$scp_to_target,
311 "SCP_TO_TARGET_INSTALL" => \$scp_to_target_install,
312 "CHECKOUT" => \$checkout,
313 "TARGET_IMAGE" => \$target_image,
314 "LOCALVERSION" => \$localversion,
316 "BISECT_GOOD" => \$bisect_good,
317 "BISECT_BAD" => \$bisect_bad,
318 "BISECT_TYPE" => \$bisect_type,
319 "BISECT_START" => \$bisect_start,
320 "BISECT_REPLAY" => \$bisect_replay,
321 "BISECT_FILES" => \$bisect_files,
322 "BISECT_REVERSE" => \$bisect_reverse,
323 "BISECT_CHECK" => \$bisect_check,
325 "CONFIG_BISECT" => \$config_bisect,
326 "CONFIG_BISECT_TYPE" => \$config_bisect_type,
327 "CONFIG_BISECT_CHECK" => \$config_bisect_check,
329 "PATCHCHECK_TYPE" => \$patchcheck_type,
330 "PATCHCHECK_START" => \$patchcheck_start,
331 "PATCHCHECK_CHERRY" => \$patchcheck_cherry,
332 "PATCHCHECK_END" => \$patchcheck_end,
335 # Options may be used by other options, record them.
338 # default variables that can be used
339 chomp ($variable{"PWD"} = `pwd`);
341 $config_help{"MACHINE"} = << "EOF"
342 The machine hostname that you will test.
343 For build only tests, it is still needed to differentiate log files.
346 $config_help{"SSH_USER"} = << "EOF"
347 The box is expected to have ssh on normal bootup, provide the user
348 (most likely root, since you need privileged operations)
351 $config_help{"BUILD_DIR"} = << "EOF"
352 The directory that contains the Linux source code (full path).
353 You can use \${PWD} that will be the path where ktest.pl is run, or use
354 \${THIS_DIR} which is assigned \${PWD} but may be changed later.
357 $config_help{"OUTPUT_DIR"} = << "EOF"
358 The directory that the objects will be built (full path).
359 (can not be same as BUILD_DIR)
360 You can use \${PWD} that will be the path where ktest.pl is run, or use
361 \${THIS_DIR} which is assigned \${PWD} but may be changed later.
364 $config_help{"BUILD_TARGET"} = << "EOF"
365 The location of the compiled file to copy to the target.
366 (relative to OUTPUT_DIR)
369 $config_help{"BUILD_OPTIONS"} = << "EOF"
370 Options to add to \"make\" when building.
374 $config_help{"TARGET_IMAGE"} = << "EOF"
375 The place to put your image on the test machine.
378 $config_help{"POWER_CYCLE"} = << "EOF"
379 A script or command to reboot the box.
381 Here is a digital loggers power switch example
382 POWER_CYCLE = wget --no-proxy -O /dev/null -q --auth-no-challenge 'http://admin:admin\@power/outlet?5=CCL'
384 Here is an example to reboot a virtual box on the current host
385 with the name "Guest".
386 POWER_CYCLE = virsh destroy Guest; sleep 5; virsh start Guest
389 $config_help{"CONSOLE"} = << "EOF"
390 The script or command that reads the console
392 If you use ttywatch server, something like the following would work.
393 CONSOLE = nc -d localhost 3001
395 For a virtual machine with guest name "Guest".
396 CONSOLE = virsh console Guest
399 $config_help{"LOCALVERSION"} = << "EOF"
400 Required version ending to differentiate the test
401 from other linux builds on the system.
404 $config_help{"REBOOT_TYPE"} = << "EOF"
405 Way to reboot the box to the test kernel.
406 Only valid options so far are "grub", "grub2", "syslinux", and "script".
408 If you specify grub, it will assume grub version 1
409 and will search in /boot/grub/menu.lst for the title \$GRUB_MENU
410 and select that target to reboot to the kernel. If this is not
411 your setup, then specify "script" and have a command or script
412 specified in REBOOT_SCRIPT to boot to the target.
414 The entry in /boot/grub/menu.lst must be entered in manually.
415 The test will not modify that file.
417 If you specify grub2, then you also need to specify both \$GRUB_MENU
420 If you specify syslinux, then you may use SYSLINUX to define the syslinux
421 command (defaults to extlinux), and SYSLINUX_PATH to specify the path to
422 the syslinux install (defaults to /boot/extlinux). But you have to specify
423 SYSLINUX_LABEL to define the label to boot to for the test kernel.
426 $config_help{"GRUB_MENU"} = << "EOF"
427 The grub title name for the test kernel to boot
428 (Only mandatory if REBOOT_TYPE = grub or grub2)
430 Note, ktest.pl will not update the grub menu.lst, you need to
431 manually add an option for the test. ktest.pl will search
432 the grub menu.lst for this option to find what kernel to
435 For example, if in the /boot/grub/menu.lst the test kernel title has:
438 GRUB_MENU = Test Kernel
440 For grub2, a search of \$GRUB_FILE is performed for the lines
441 that begin with "menuentry". It will not detect submenus. The
442 menu must be a non-nested menu. Add the quotes used in the menu
443 to guarantee your selection, as the first menuentry with the content
444 of \$GRUB_MENU that is found will be used.
447 $config_help{"GRUB_FILE"} = << "EOF"
448 If grub2 is used, the full path for the grub.cfg file is placed
449 here. Use something like /boot/grub2/grub.cfg to search.
452 $config_help{"SYSLINUX_LABEL"} = << "EOF"
453 If syslinux is used, the label that boots the target kernel must
454 be specified with SYSLINUX_LABEL.
457 $config_help{"REBOOT_SCRIPT"} = << "EOF"
458 A script to reboot the target into the test kernel
459 (Only mandatory if REBOOT_TYPE = script)
464 if (defined($opt{"LOG_FILE"})) {
465 open(OUT, ">> $opt{LOG_FILE}") or die "Can't write to $opt{LOG_FILE}";
472 if (defined($opt{"LOG_FILE"})) {
485 my ($cancel, $prompt) = @_;
491 print "$prompt [y/n/C] ";
493 print "$prompt [Y/n] ";
497 if ($ans =~ /^\s*$/) {
504 last if ($ans =~ /^y$/i || $ans =~ /^n$/i);
506 last if ($ans =~ /^c$/i);
507 print "Please answer either 'y', 'n' or 'c'.\n";
509 print "Please answer either 'y' or 'n'.\n";
515 if ($ans !~ /^y$/i) {
524 return read_prompt 0, $prompt;
530 return read_prompt 1, $prompt;
533 sub get_mandatory_config {
537 return if (defined($opt{$config}));
539 if (defined($config_help{$config})) {
541 print $config_help{$config};
546 if (defined($default{$config}) && length($default{$config})) {
547 print "\[$default{$config}\] ";
550 $ans =~ s/^\s*(.*\S)\s*$/$1/;
551 if ($ans =~ /^\s*$/) {
552 if ($default{$config}) {
553 $ans = $default{$config};
555 print "Your answer can not be blank\n";
559 $entered_configs{$config} = ${ans};
571 $hours = int($time / 3600);
572 $time -= $hours * 3600;
575 $minutes = int($time / 60);
576 $time -= $minutes * 60;
580 doprint "$hours hour";
581 doprint "s" if ($hours > 1);
586 doprint "$minutes minute";
587 doprint "s" if ($minutes > 1);
591 doprint "$time second";
592 doprint "s" if ($time != 1);
598 doprint "Build time: ";
599 show_time($build_time);
603 doprint "Install time: ";
604 show_time($install_time);
608 doprint "Reboot time: ";
609 show_time($reboot_time);
613 doprint "Test time: ";
614 show_time($test_time);
617 # reset for iterations like bisect
624 sub get_mandatory_configs {
625 get_mandatory_config("MACHINE");
626 get_mandatory_config("BUILD_DIR");
627 get_mandatory_config("OUTPUT_DIR");
630 get_mandatory_config("BUILD_OPTIONS");
633 # options required for other than just building a kernel
635 get_mandatory_config("POWER_CYCLE");
636 get_mandatory_config("CONSOLE");
639 # options required for install and more
640 if ($buildonly != 1) {
641 get_mandatory_config("SSH_USER");
642 get_mandatory_config("BUILD_TARGET");
643 get_mandatory_config("TARGET_IMAGE");
646 get_mandatory_config("LOCALVERSION");
648 return if ($buildonly);
650 my $rtype = $opt{"REBOOT_TYPE"};
652 if (!defined($rtype)) {
653 if (!defined($opt{"GRUB_MENU"})) {
654 get_mandatory_config("REBOOT_TYPE");
655 $rtype = $entered_configs{"REBOOT_TYPE"};
661 if ($rtype eq "grub") {
662 get_mandatory_config("GRUB_MENU");
665 if ($rtype eq "grub2") {
666 get_mandatory_config("GRUB_MENU");
667 get_mandatory_config("GRUB_FILE");
670 if ($rtype eq "syslinux") {
671 get_mandatory_config("SYSLINUX_LABEL");
675 sub process_variables {
676 my ($value, $remove_undef) = @_;
679 # We want to check for '\', and it is just easier
680 # to check the previous characet of '$' and not need
681 # to worry if '$' is the first character. By adding
682 # a space to $value, we can just check [^\\]\$ and
683 # it will still work.
686 while ($value =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) {
690 # append beginning of value to retval
691 $retval = "$retval$begin";
692 if (defined($variable{$var})) {
693 $retval = "$retval$variable{$var}";
694 } elsif (defined($remove_undef) && $remove_undef) {
695 # for if statements, any variable that is not defined,
696 # we simple convert to 0
697 $retval = "${retval}0";
699 # put back the origin piece.
700 $retval = "$retval\$\{$var\}";
701 # This could be an option that is used later, save
702 # it so we don't warn if this option is not one of
704 $used_options{$var} = 1;
708 $retval = "$retval$value";
710 # remove the space added in the beginning
717 my ($lvalue, $rvalue, $override, $overrides, $name) = @_;
719 my $prvalue = process_variables($rvalue);
721 if ($buildonly && $lvalue =~ /^TEST_TYPE(\[.*\])?$/ && $prvalue ne "build") {
722 # Note if a test is something other than build, then we
723 # will need other mandatory options.
724 if ($prvalue ne "install") {
725 # for bisect, we need to check BISECT_TYPE
726 if ($prvalue ne "bisect") {
730 # install still limits some mandatory options.
735 if ($buildonly && $lvalue =~ /^BISECT_TYPE(\[.*\])?$/ && $prvalue ne "build") {
736 if ($prvalue ne "install") {
739 # install still limits some mandatory options.
744 if (defined($opt{$lvalue})) {
745 if (!$override || defined(${$overrides}{$lvalue})) {
748 $extra = "In the same override section!\n";
750 die "$name: $.: Option $lvalue defined more than once!\n$extra";
752 ${$overrides}{$lvalue} = $prvalue;
755 $opt{$lvalue} = $prvalue;
759 my ($lvalue, $rvalue, $name) = @_;
761 my $prvalue = process_variables($rvalue);
764 if (defined($evals{$lvalue})) {
765 $arr = $evals{$lvalue};
768 $evals{$lvalue} = $arr;
771 push @{$arr}, $rvalue;
775 my ($lvalue, $rvalue) = @_;
777 if ($rvalue =~ /^\s*$/) {
778 delete $variable{$lvalue};
780 $rvalue = process_variables($rvalue);
781 $variable{$lvalue} = $rvalue;
785 sub process_compare {
786 my ($lval, $cmp, $rval) = @_;
797 return $lval eq $rval;
798 } elsif ($cmp eq "!=") {
799 return $lval ne $rval;
800 } elsif ($cmp eq "=~") {
801 return $lval =~ m/$rval/;
802 } elsif ($cmp eq "!~") {
803 return $lval !~ m/$rval/;
806 my $statement = "$lval $cmp $rval";
807 my $ret = eval $statement;
809 # $@ stores error of eval
820 return defined($variable{$2}) ||
825 sub process_expression {
826 my ($name, $val) = @_;
830 while ($val =~ s/\(([^\(]*?)\)/\&\&\&\&VAL\&\&\&\&/) {
833 if (process_expression($name, $express)) {
834 $val =~ s/\&\&\&\&VAL\&\&\&\&/ 1 /;
836 $val =~ s/\&\&\&\&VAL\&\&\&\&/ 0 /;
844 while ($val =~ s/^(.*?)($OR|$AND)//) {
848 if (process_expression($name, $express)) {
859 if ($val =~ /(.*)(==|\!=|>=|<=|>|<|=~|\!~)(.*)/) {
860 my $ret = process_compare($1, $2, $3);
862 die "$name: $.: Unable to process comparison\n";
867 if ($val =~ /^\s*(NOT\s*)?DEFINED\s+(\S+)\s*$/) {
869 return !value_defined($2);
871 return value_defined($2);
875 if ($val =~ /^\s*0\s*$/) {
877 } elsif ($val =~ /^\s*\d+\s*$/) {
881 die ("$name: $.: Undefined content $val in if statement\n");
885 my ($name, $value) = @_;
887 # Convert variables and replace undefined ones with 0
888 my $val = process_variables($value, 1);
889 my $ret = process_expression $name, $val;
895 my ($config, $current_test_num) = @_;
898 open($in, $config) || die "can't read file $config";
901 $name =~ s,.*/(.*),$1,;
903 my $test_num = $$current_test_num;
906 my $num_tests_set = 0;
919 # ignore blank lines and comments
920 next if (/^\s*$/ || /\s*\#/);
922 if (/^\s*(TEST_START|DEFAULTS)\b(.*)/) {
932 if ($type eq "TEST_START") {
934 if ($num_tests_set) {
935 die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
938 $old_test_num = $test_num;
939 $old_repeat = $repeat;
941 $test_num += $repeat;
948 # If SKIP is anywhere in the line, the command will be skipped
949 if ($rest =~ s/\s+SKIP\b//) {
956 if ($rest =~ s/\sELSE\b//) {
958 die "$name: $.: ELSE found with out matching IF section\n$_";
969 if ($rest =~ s/\sIF\s+(.*)//) {
970 if (process_if($name, $1)) {
982 if ($type eq "TEST_START") {
983 if ($rest =~ s/\s+ITERATE\s+(\d+)//) {
985 $repeat_tests{"$test_num"} = $repeat;
987 } elsif ($rest =~ s/\sOVERRIDE\b//) {
990 # Clear previous overrides
995 if (!$skip && $rest !~ /^\s*$/) {
996 die "$name: $.: Gargbage found after $type\n$_";
999 if ($skip && $type eq "TEST_START") {
1000 $test_num = $old_test_num;
1001 $repeat = $old_repeat;
1004 } elsif (/^\s*ELSE\b(.*)$/) {
1006 die "$name: $.: ELSE found with out matching IF section\n$_";
1015 if ($rest =~ /\sIF\s+(.*)/) {
1016 # May be a ELSE IF section.
1017 if (process_if($name, $1)) {
1028 if ($rest !~ /^\s*$/) {
1029 die "$name: $.: Gargbage found after DEFAULTS\n$_";
1032 } elsif (/^\s*INCLUDE\s+(\S+)/) {
1037 die "$name: $.: INCLUDE can only be done in default sections\n$_";
1040 my $file = process_variables($1);
1042 if ($file !~ m,^/,) {
1043 # check the path of the config file first
1044 if ($config =~ m,(.*)/,) {
1045 if (-f "$1/$file") {
1052 die "$name: $.: Can't read file $file\n$_";
1055 if (__read_config($file, \$test_num)) {
1059 } elsif (/^\s*([A-Z_\[\]\d]+)\s*=~\s*(.*?)\s*$/) {
1066 if ($default || $lvalue =~ /\[\d+\]$/) {
1067 set_eval($lvalue, $rvalue, $name);
1069 my $val = "$lvalue\[$test_num\]";
1070 set_eval($val, $rvalue, $name);
1073 } elsif (/^\s*([A-Z_\[\]\d]+)\s*=\s*(.*?)\s*$/) {
1081 ($lvalue eq "NUM_TESTS" ||
1082 $lvalue eq "LOG_FILE" ||
1083 $lvalue eq "CLEAR_LOG")) {
1084 die "$name: $.: $lvalue must be set in DEFAULTS section\n";
1087 if ($lvalue eq "NUM_TESTS") {
1089 die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
1092 die "$name: $.: NUM_TESTS must be set in default section\n";
1097 if ($default || $lvalue =~ /\[\d+\]$/) {
1098 set_value($lvalue, $rvalue, $override, \%overrides, $name);
1100 my $val = "$lvalue\[$test_num\]";
1101 set_value($val, $rvalue, $override, \%overrides, $name);
1104 $repeats{$val} = $repeat;
1107 } elsif (/^\s*([A-Z_\[\]\d]+)\s*:=\s*(.*?)\s*$/) {
1113 # process config variables.
1114 # Config variables are only active while reading the
1115 # config and can be defined anywhere. They also ignore
1116 # TEST_START and DEFAULTS, but are skipped if they are in
1117 # on of these sections that have SKIP defined.
1118 # The save variable can be
1119 # defined multiple times and the new one simply overrides
1121 set_variable($lvalue, $rvalue);
1124 die "$name: $.: Garbage found in config\n$_";
1129 $test_num += $repeat - 1;
1130 $opt{"NUM_TESTS"} = $test_num;
1135 $$current_test_num = $test_num;
1141 print "What test case would you like to run?\n";
1142 print " (build, install or boot)\n";
1143 print " Other tests are available but require editing the config file\n";
1146 $default{"TEST_TYPE"} = $ans;
1155 $test_case = __read_config $config, \$test_num;
1157 # make sure we have all mandatory configs
1158 get_mandatory_configs;
1160 # was a test specified?
1162 print "No test case specified.\n";
1168 foreach my $default (keys %default) {
1169 if (!defined($opt{$default})) {
1170 $opt{$default} = $default{$default};
1174 if ($opt{"IGNORE_UNUSED"} == 1) {
1180 # check if there are any stragglers (typos?)
1181 foreach my $option (keys %opt) {
1183 # remove per test labels.
1185 if (!exists($option_map{$op}) &&
1186 !exists($default{$op}) &&
1187 !exists($used_options{$op})) {
1194 $s = " is" if (keys %not_used == 1);
1195 print "The following option$s not used; could be a typo:\n";
1196 foreach my $option (keys %not_used) {
1199 print "Set IGRNORE_UNUSED = 1 to have ktest ignore unused variables\n";
1200 if (!read_yn "Do you want to continue?") {
1207 my ($name, $option, $i) = @_;
1209 # Add space to evaluate the character before $
1210 $option = " $option";
1215 foreach my $test (keys %repeat_tests) {
1217 $i < $test + $repeat_tests{$test}) {
1225 while ($option =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) {
1230 # Append beginning of line
1231 $retval = "$retval$start";
1233 # If the iteration option OPT[$i] exists, then use that.
1234 # otherwise see if the default OPT (without [$i]) exists.
1236 my $o = "$var\[$i\]";
1237 my $parento = "$var\[$parent\]";
1239 # If a variable contains itself, use the default var
1240 if (($var eq $name) && defined($opt{$var})) {
1242 $retval = "$retval$o";
1243 } elsif (defined($opt{$o})) {
1245 $retval = "$retval$o";
1246 } elsif ($repeated && defined($opt{$parento})) {
1247 $o = $opt{$parento};
1248 $retval = "$retval$o";
1249 } elsif (defined($opt{$var})) {
1251 $retval = "$retval$o";
1252 } elsif ($var eq "KERNEL_VERSION" && defined($make)) {
1253 # special option KERNEL_VERSION uses kernel version
1255 $retval = "$retval$version";
1257 $retval = "$retval\$\{$var\}";
1263 $retval = "$retval$option";
1271 my ($name, $option, $i) = @_;
1273 my $option_name = "$name\[$i\]";
1276 my $old_option = $option;
1278 if (defined($evals{$option_name})) {
1279 $ev = $evals{$option_name};
1280 } elsif (defined($evals{$name})) {
1281 $ev = $evals{$name};
1286 for my $e (@{$ev}) {
1287 eval "\$option =~ $e";
1290 if ($option ne $old_option) {
1291 doprint("$name changed from '$old_option' to '$option'\n");
1298 my ($name, $option, $i) = @_;
1302 # Since an option can evaluate to another option,
1303 # keep iterating until we do not evaluate any more
1306 while ($prev ne $option) {
1307 # Check for recursive evaluations.
1308 # 100 deep should be more than enough.
1310 die "Over 100 evaluations accurred with $option\n" .
1311 "Check for recursive variables\n";
1314 $option = __eval_option($name, $option, $i);
1317 $option = process_evals($name, $option, $i);
1325 sub wait_for_monitor;
1331 # test if the machine can be connected to within 5 seconds
1332 my $stat = run_ssh("echo check machine status", 5);
1334 doprint("power cycle\n");
1339 run_command "$power_cycle";
1342 # flush out current monitor
1343 # May contain the reboot success line
1347 # Make sure everything has been written to disk
1350 if (defined($time)) {
1352 # flush out current monitor
1353 # May contain the reboot success line
1357 # try to reboot normally
1358 if (run_command $reboot) {
1359 if (defined($powercycle_after_reboot)) {
1360 sleep $powercycle_after_reboot;
1361 run_command "$power_cycle";
1364 # nope? power cycle it.
1365 run_command "$power_cycle";
1369 if (defined($time)) {
1371 # We only want to get to the new kernel, don't fail
1372 # if we stumble over a call trace.
1373 my $save_ignore_errors = $ignore_errors;
1376 # Look for the good kernel to boot
1377 if (wait_for_monitor($time, "Linux version")) {
1379 doprint "Reboot did not finish. Forcing power cycle\n";
1380 run_command "$power_cycle";
1383 $ignore_errors = $save_ignore_errors;
1385 # Still need to wait for the reboot to finish
1386 wait_for_monitor($time, $reboot_success_line);
1392 sub reboot_to_good {
1395 if (defined($switch_to_good)) {
1396 run_command $switch_to_good;
1405 return $test_type eq "build" || $no_reboot ||
1406 ($test_type eq "patchcheck" && $opt{"PATCHCHECK_TYPE[$i]"} eq "build") ||
1407 ($test_type eq "bisect" && $opt{"BISECT_TYPE[$i]"} eq "build");
1411 doprint "CRITICAL FAILURE... ", @_, "\n";
1415 if ($reboot_on_error && !do_not_reboot) {
1417 doprint "REBOOTING\n";
1420 } elsif ($poweroff_on_error && defined($power_off)) {
1421 doprint "POWERING OFF\n";
1425 if (defined($opt{"LOG_FILE"})) {
1426 print " See $opt{LOG_FILE} for more info.\n";
1430 # restore terminal settings
1431 system("stty $stty_orig");
1434 if (defined($post_test)) {
1435 run_command $post_test;
1442 my ($ptm, $pts) = @_;
1444 my $TIOCSPTLCK = 0x40045431;
1445 my $TIOCGPTN = 0x80045430;
1447 sysopen($ptm, "/dev/ptmx", O_RDWR | O_NONBLOCK) or
1448 dodie "Cant open /dev/ptmx";
1451 $tmp = pack("i", 0);
1452 ioctl($ptm, $TIOCSPTLCK, $tmp) or
1453 dodie "ioctl TIOCSPTLCK for /dev/ptmx failed";
1456 ioctl($ptm, $TIOCGPTN, $tmp) or
1457 dodie "ioctl TIOCGPTN for /dev/ptmx failed";
1458 $tmp = unpack("i", $tmp);
1460 sysopen($pts, "/dev/pts/$tmp", O_RDWR | O_NONBLOCK) or
1461 dodie "Can't open /dev/pts/$tmp";
1465 my ($ptm, $pts) = @_;
1473 open(\*STDIN, '<&', $pts);
1474 open(\*STDOUT, '>&', $pts);
1475 open(\*STDERR, '>&', $pts);
1480 die "Can't open console $console";
1488 # save terminal settings
1489 $stty_orig = `stty -g`;
1491 # place terminal in cbreak mode so that stdin can be read one character at
1492 # a time without having to wait for a newline
1493 system("stty -icanon -echo -icrnl");
1495 create_pty($ptm, $pts);
1501 exec_console($ptm, $pts)
1509 open(PTSFD, "Stop perl from warning about single use of PTSFD");
1513 my ($fp, $pid) = @_;
1515 doprint "kill child process $pid\n";
1516 kill $close_console_signal, $pid;
1521 # restore terminal settings
1522 system("stty $stty_orig");
1526 if ($monitor_cnt++) {
1529 $monitor_fp = \*MONFD;
1530 $monitor_pid = open_console $monitor_fp;
1534 open(MONFD, "Stop perl from warning about single use of MONFD");
1538 return if (!defined $console);
1539 if (--$monitor_cnt) {
1542 close_console($monitor_fp, $monitor_pid);
1545 sub wait_for_monitor {
1546 my ($time, $stop) = @_;
1550 my $start_time = time;
1551 my $skip_call_trace = 0;
1553 my $bug_ignored = 0;
1556 doprint "** Wait for monitor to settle down **\n";
1558 # read the monitor and wait for the system to calm down
1560 $line = wait_for_input($monitor_fp, $time);
1561 last if (!defined($line));
1563 $full_line .= $line;
1565 if (defined($stop) && $full_line =~ /$stop/) {
1566 doprint "wait for monitor detected $stop\n";
1570 if ($full_line =~ /\[ backtrace testing \]/) {
1571 $skip_call_trace = 1;
1574 if ($full_line =~ /call trace:/i) {
1575 if (!$bug && !$skip_call_trace) {
1576 if ($ignore_errors) {
1584 if ($full_line =~ /\[ end of backtrace testing \]/) {
1585 $skip_call_trace = 0;
1588 if ($full_line =~ /Kernel panic -/) {
1592 if ($line =~ /\n/) {
1596 if ($now - $start_time >= $max_monitor_wait) {
1597 doprint "Exiting monitor flush due to hitting MAX_MONITOR_WAIT\n";
1601 print "** Monitor flushed **\n";
1603 # if stop is defined but wasn't hit, return error
1604 # used by reboot (which wants to see a reboot)
1605 if (defined($stop) && !$booted) {
1612 my ($result, $basedir) = @_;
1614 my $date = sprintf "%04d%02d%02d%02d%02d%02d",
1615 1900+$t[5],$t[4],$t[3],$t[2],$t[1],$t[0];
1617 my $type = $build_type;
1618 if ($type =~ /useconfig/) {
1619 $type = "useconfig";
1622 my $dir = "$machine-$test_type-$type-$result-$date";
1624 $dir = "$basedir/$dir";
1628 die "can't create $dir";
1632 "config" => $output_config,
1633 "buildlog" => $buildlog,
1635 "testlog" => $testlog,
1638 while (my ($name, $source) = each(%files)) {
1640 cp "$source", "$dir/$name" or
1641 die "failed to copy $source";
1645 doprint "*** Saved info to $dir ***\n";
1650 if ($die_on_failure) {
1658 # no need to reboot for just building.
1659 if (!do_not_reboot) {
1660 doprint "REBOOTING\n";
1661 reboot_to_good $sleep_time;
1666 if (defined($test_name)) {
1667 $name = " ($test_name)";
1672 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
1673 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
1674 doprint "KTEST RESULT: TEST $i$name Failed: ", @_, "\n";
1675 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
1676 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
1678 if (defined($store_failures)) {
1679 save_logs "fail", $store_failures;
1682 if (defined($post_test)) {
1683 run_command $post_test;
1690 my ($command, $redirect, $timeout) = @_;
1697 $command =~ s/\$SSH_USER/$ssh_user/g;
1698 $command =~ s/\$MACHINE/$machine/g;
1700 doprint("$command ... ");
1703 $pid = open(CMD, "$command 2>&1 |") or
1704 (fail "unable to exec $command" and return 0);
1706 if (defined($opt{"LOG_FILE"})) {
1707 open(LOG, ">>$opt{LOG_FILE}") or
1708 dodie "failed to write to log";
1712 if (defined($redirect)) {
1713 open (RD, ">$redirect") or
1714 dodie "failed to write to redirect $redirect";
1718 my $hit_timeout = 0;
1722 if (defined($timeout)) {
1723 doprint "timeout = $timeout\n";
1725 my $line = wait_for_input($fp, $timeout);
1726 if (!defined($line)) {
1728 if (defined($timeout) && (($now - $start_time) >= $timeout)) {
1729 doprint "Hit timeout of $timeout, killing process\n";
1735 print LOG $line if ($dolog);
1736 print RD $line if ($dord);
1740 # shift 8 for real exit status
1741 $run_command_status = $? >> 8;
1744 close(LOG) if ($dolog);
1745 close(RD) if ($dord);
1748 my $delta = $end_time - $start_time;
1751 doprint "[1 second] ";
1753 doprint "[$delta seconds] ";
1757 $run_command_status = 1;
1760 if ($run_command_status) {
1761 doprint "FAILED!\n";
1763 doprint "SUCCESS\n";
1766 return !$run_command_status;
1770 my ($cmd, $timeout) = @_;
1771 my $cp_exec = $ssh_exec;
1773 $cp_exec =~ s/\$SSH_COMMAND/$cmd/g;
1774 return run_command "$cp_exec", undef , $timeout;
1778 my ($src, $dst, $cp_scp) = @_;
1780 $cp_scp =~ s/\$SRC_FILE/$src/g;
1781 $cp_scp =~ s/\$DST_FILE/$dst/g;
1783 return run_command "$cp_scp";
1786 sub run_scp_install {
1787 my ($src, $dst) = @_;
1789 my $cp_scp = $scp_to_target_install;
1791 return run_scp($src, $dst, $cp_scp);
1795 my ($src, $dst) = @_;
1797 my $cp_scp = $scp_to_target;
1799 return run_scp($src, $dst, $cp_scp);
1802 sub get_grub2_index {
1804 return if (defined($grub_number) && defined($last_grub_menu) &&
1805 $last_grub_menu eq $grub_menu && defined($last_machine) &&
1806 $last_machine eq $machine);
1808 doprint "Find grub2 menu ... ";
1811 my $ssh_grub = $ssh_exec;
1812 $ssh_grub =~ s,\$SSH_COMMAND,cat $grub_file,g;
1814 open(IN, "$ssh_grub |")
1815 or die "unable to get $grub_file";
1820 if (/^menuentry.*$grub_menu/) {
1824 } elsif (/^menuentry\s/) {
1830 die "Could not find '$grub_menu' in $grub_file on $machine"
1832 doprint "$grub_number\n";
1833 $last_grub_menu = $grub_menu;
1834 $last_machine = $machine;
1837 sub get_grub_index {
1839 if ($reboot_type eq "grub2") {
1844 if ($reboot_type ne "grub") {
1847 return if (defined($grub_number) && defined($last_grub_menu) &&
1848 $last_grub_menu eq $grub_menu && defined($last_machine) &&
1849 $last_machine eq $machine);
1851 doprint "Find grub menu ... ";
1854 my $ssh_grub = $ssh_exec;
1855 $ssh_grub =~ s,\$SSH_COMMAND,cat /boot/grub/menu.lst,g;
1857 open(IN, "$ssh_grub |")
1858 or die "unable to get menu.lst";
1863 if (/^\s*title\s+$grub_menu\s*$/) {
1867 } elsif (/^\s*title\s/) {
1873 die "Could not find '$grub_menu' in /boot/grub/menu on $machine"
1875 doprint "$grub_number\n";
1876 $last_grub_menu = $grub_menu;
1877 $last_machine = $machine;
1882 my ($fp, $time) = @_;
1890 if (!defined($time)) {
1895 vec($rin, fileno($fp), 1) = 1;
1896 vec($rin, fileno(\*STDIN), 1) = 1;
1899 $nr = select($rout=$rin, undef, undef, $time);
1905 # copy data from stdin to the console
1906 if (vec($rout, fileno(\*STDIN), 1) == 1) {
1907 sysread(\*STDIN, $buf, 1000);
1908 syswrite($fp, $buf, 1000);
1914 # try to read one char at a time
1915 while (sysread $fp, $ch, 1) {
1917 last if ($ch eq "\n");
1920 if (!length($line)) {
1929 if (defined($switch_to_test)) {
1930 run_command $switch_to_test;
1933 if ($reboot_type eq "grub") {
1934 run_ssh "'(echo \"savedefault --default=$grub_number --once\" | grub --batch)'";
1935 } elsif ($reboot_type eq "grub2") {
1936 run_ssh "$grub_reboot $grub_number";
1937 } elsif ($reboot_type eq "syslinux") {
1938 run_ssh "$syslinux --once \\\"$syslinux_label\\\" $syslinux_path";
1939 } elsif (defined $reboot_script) {
1940 run_command "$reboot_script";
1948 doprint "git rev-list --max-count=1 $commit ... ";
1949 my $sha1 = `git rev-list --max-count=1 $commit`;
1956 dodie "Failed to get git $commit";
1969 my $bug_ignored = 0;
1970 my $skip_call_trace = 0;
1973 my $start_time = time;
1980 open(DMESG, "> $dmesg") or
1981 die "unable to write to $dmesg";
1987 my $monitor_start = time;
1989 my $version_found = 0;
1993 if ($bug && defined($stop_after_failure) &&
1994 $stop_after_failure >= 0) {
1995 my $time = $stop_after_failure - (time - $failure_start);
1996 $line = wait_for_input($monitor_fp, $time);
1997 if (!defined($line)) {
1998 doprint "bug timed out after $booted_timeout seconds\n";
1999 doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
2003 $line = wait_for_input($monitor_fp, $booted_timeout);
2004 if (!defined($line)) {
2005 my $s = $booted_timeout == 1 ? "" : "s";
2006 doprint "Successful boot found: break after $booted_timeout second$s\n";
2010 $line = wait_for_input($monitor_fp);
2011 if (!defined($line)) {
2012 my $s = $timeout == 1 ? "" : "s";
2013 doprint "Timed out after $timeout second$s\n";
2021 # we are not guaranteed to get a full line
2022 $full_line .= $line;
2024 if ($full_line =~ /$success_line/) {
2026 $success_start = time;
2029 if ($booted && defined($stop_after_success) &&
2030 $stop_after_success >= 0) {
2032 if ($now - $success_start >= $stop_after_success) {
2033 doprint "Test forced to stop after $stop_after_success seconds after success\n";
2038 if ($full_line =~ /\[ backtrace testing \]/) {
2039 $skip_call_trace = 1;
2042 if ($full_line =~ /call trace:/i) {
2043 if (!$bug && !$skip_call_trace) {
2044 if ($ignore_errors) {
2048 $failure_start = time;
2053 if ($bug && defined($stop_after_failure) &&
2054 $stop_after_failure >= 0) {
2056 if ($now - $failure_start >= $stop_after_failure) {
2057 doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
2062 if ($full_line =~ /\[ end of backtrace testing \]/) {
2063 $skip_call_trace = 0;
2066 if ($full_line =~ /Kernel panic -/) {
2067 $failure_start = time;
2071 # Detect triple faults by testing the banner
2072 if ($full_line =~ /\bLinux version (\S+).*\n/) {
2073 if ($1 eq $version) {
2075 } elsif ($version_found && $detect_triplefault) {
2076 # We already booted into the kernel we are testing,
2077 # but now we booted into another kernel?
2078 # Consider this a triple fault.
2079 doprint "Already booted in Linux kernel $version, but now\n";
2080 doprint "we booted into Linux kernel $1.\n";
2081 doprint "Assuming that this is a triple fault.\n";
2082 doprint "To disable this: set DETECT_TRIPLE_FAULT to 0\n";
2087 if ($line =~ /\n/) {
2091 if ($stop_test_after > 0 && !$booted && !$bug) {
2092 if (time - $monitor_start > $stop_test_after) {
2093 doprint "STOP_TEST_AFTER ($stop_test_after seconds) timed out\n";
2099 my $end_time = time;
2100 $reboot_time = $end_time - $start_time;
2105 return 0 if ($in_bisect);
2106 fail "failed - got a bug report" and return 0;
2110 return 0 if ($in_bisect);
2111 fail "failed - never got a boot prompt." and return 0;
2115 doprint "WARNING: Call Trace detected but ignored due to IGNORE_ERRORS=1\n";
2121 sub eval_kernel_version {
2124 $option =~ s/\$KERNEL_VERSION/$version/g;
2129 sub do_post_install {
2131 return if (!defined($post_install));
2133 my $cp_post_install = eval_kernel_version $post_install;
2134 run_command "$cp_post_install" or
2135 dodie "Failed to run post install";
2138 # Sometimes the reboot fails, and will hang. We try to ssh to the box
2139 # and if we fail, we force another reboot, that should powercycle it.
2141 if (!run_ssh "echo testing connection") {
2148 return if ($no_install);
2150 my $start_time = time;
2152 if (defined($pre_install)) {
2153 my $cp_pre_install = eval_kernel_version $pre_install;
2154 run_command "$cp_pre_install" or
2155 dodie "Failed to run pre install";
2158 my $cp_target = eval_kernel_version $target_image;
2162 run_scp_install "$outputdir/$build_target", "$cp_target" or
2163 dodie "failed to copy image";
2165 my $install_mods = 0;
2167 # should we process modules?
2169 open(IN, "$output_config") or dodie("Can't read config file");
2171 if (/CONFIG_MODULES(=y)?/) {
2180 if (!$install_mods) {
2182 doprint "No modules needed\n";
2183 my $end_time = time;
2184 $install_time = $end_time - $start_time;
2188 run_command "$make INSTALL_MOD_STRIP=1 INSTALL_MOD_PATH=$tmpdir modules_install" or
2189 dodie "Failed to install modules";
2191 my $modlib = "/lib/modules/$version";
2192 my $modtar = "ktest-mods.tar.bz2";
2194 run_ssh "rm -rf $modlib" or
2195 dodie "failed to remove old mods: $modlib";
2197 # would be nice if scp -r did not follow symbolic links
2198 run_command "cd $tmpdir && tar -cjf $modtar lib/modules/$version" or
2199 dodie "making tarball";
2201 run_scp_mod "$tmpdir/$modtar", "/tmp" or
2202 dodie "failed to copy modules";
2204 unlink "$tmpdir/$modtar";
2206 run_ssh "'(cd / && tar xjf /tmp/$modtar)'" or
2207 dodie "failed to tar modules";
2209 run_ssh "rm -f /tmp/$modtar";
2213 my $end_time = time;
2214 $install_time = $end_time - $start_time;
2218 # get the release name
2219 return if ($have_version);
2220 doprint "$make kernelrelease ... ";
2221 $version = `$make -s kernelrelease | tail -1`;
2223 doprint "$version\n";
2227 sub start_monitor_and_install {
2228 # Make sure the stable kernel has finished booting
2230 # Install bisects, don't need console
2231 if (defined $console) {
2241 start_monitor if (defined $console);
2245 my $check_build_re = ".*:.*(warning|error|Error):.*";
2246 my $utf8_quote = "\\x{e2}\\x{80}(\\x{98}|\\x{99})";
2248 sub process_warning_line {
2253 # for distcc heterogeneous systems, some compilers
2254 # do things differently causing warning lines
2255 # to be slightly different. This makes an attempt
2256 # to fixe those issues.
2258 # chop off the index into the line
2259 # using distcc, some compilers give different indexes
2260 # depending on white space
2261 $line =~ s/^(\s*\S+:\d+:)\d+/$1/;
2263 # Some compilers use UTF-8 extended for quotes and some don't.
2264 $line =~ s/$utf8_quote/'/g;
2269 # Read buildlog and check against warnings file for any
2274 sub check_buildlog {
2275 return 1 if (!defined $warnings_file);
2279 # Failed builds should not reboot the target
2280 my $save_no_reboot = $no_reboot;
2283 if (-f $warnings_file) {
2284 open(IN, $warnings_file) or
2285 dodie "Error opening $warnings_file";
2288 if (/$check_build_re/) {
2289 my $warning = process_warning_line $_;
2291 $warnings_list{$warning} = 1;
2297 # If warnings file didn't exist, and WARNINGS_FILE exist,
2298 # then we fail on any warning!
2300 open(IN, $buildlog) or dodie "Can't open $buildlog";
2302 if (/$check_build_re/) {
2303 my $warning = process_warning_line $_;
2305 if (!defined $warnings_list{$warning}) {
2306 fail "New warning found (not in $warnings_file)\n$_\n";
2307 $no_reboot = $save_no_reboot;
2312 $no_reboot = $save_no_reboot;
2316 sub check_patch_buildlog {
2319 my @files = `git show $patch | diffstat -l`;
2321 foreach my $file (@files) {
2325 open(IN, "git show $patch |") or
2326 dodie "failed to show $patch";
2328 if (m,^--- a/(.*),) {
2330 $files[$#files] = $1;
2335 open(IN, $buildlog) or dodie "Can't open $buildlog";
2337 if (/^\s*(.*?):.*(warning|error)/) {
2339 foreach my $file (@files) {
2340 my $fullpath = "$builddir/$file";
2341 if ($file eq $err || $fullpath eq $err) {
2342 fail "$file built with warnings" and return 0;
2352 sub apply_min_config {
2353 my $outconfig = "$output_config.new";
2355 # Read the config file and remove anything that
2356 # is in the force_config hash (from minconfig and others)
2357 # then add the force config back.
2359 doprint "Applying minimum configurations into $output_config.new\n";
2361 open (OUT, ">$outconfig") or
2362 dodie "Can't create $outconfig";
2364 if (-f $output_config) {
2365 open (IN, $output_config) or
2366 dodie "Failed to open $output_config";
2368 if (/^(# )?(CONFIG_[^\s=]*)/) {
2369 next if (defined($force_config{$2}));
2375 foreach my $config (keys %force_config) {
2376 print OUT "$force_config{$config}\n";
2380 run_command "mv $outconfig $output_config";
2383 sub make_oldconfig {
2385 my @force_list = keys %force_config;
2387 if ($#force_list >= 0) {
2391 if (!run_command "$make olddefconfig") {
2392 # Perhaps olddefconfig doesn't exist in this version of the kernel
2394 doprint "olddefconfig failed, trying make oldnoconfig\n";
2395 if (!run_command "$make oldnoconfig") {
2396 doprint "oldnoconfig failed, trying yes '' | make oldconfig\n";
2397 # try a yes '' | oldconfig
2398 run_command "yes '' | $make oldconfig" or
2399 dodie "failed make config oldconfig";
2404 # read a config file and use this to force new configs.
2405 sub load_force_config {
2408 doprint "Loading force configs from $config\n";
2409 open(IN, $config) or
2410 dodie "failed to read $config";
2413 if (/^(CONFIG[^\s=]*)(\s*=.*)/) {
2414 $force_config{$1} = $_;
2415 } elsif (/^# (CONFIG_\S*) is not set/) {
2416 $force_config{$1} = $_;
2427 my $start_time = time;
2429 # Failed builds should not reboot the target
2430 my $save_no_reboot = $no_reboot;
2433 # Calculate a new version from here.
2436 if (defined($pre_build)) {
2437 my $ret = run_command $pre_build;
2438 if (!$ret && defined($pre_build_die) &&
2440 dodie "failed to pre_build\n";
2444 if ($type =~ /^useconfig:(.*)/) {
2445 run_command "cp $1 $output_config" or
2446 dodie "could not copy $1 to .config";
2448 $type = "oldconfig";
2451 # old config can ask questions
2452 if ($type eq "oldconfig") {
2453 $type = "olddefconfig";
2455 # allow for empty configs
2456 run_command "touch $output_config";
2459 run_command "mv $output_config $outputdir/config_temp" or
2460 dodie "moving .config";
2462 run_command "$make mrproper" or dodie "make mrproper";
2464 run_command "mv $outputdir/config_temp $output_config" or
2465 dodie "moving config_temp";
2468 } elsif (!$noclean) {
2469 unlink "$output_config";
2470 run_command "$make mrproper" or
2471 dodie "make mrproper";
2474 # add something to distinguish this build
2475 open(OUT, "> $outputdir/localversion") or dodie("Can't make localversion file");
2476 print OUT "$localversion\n";
2479 if (defined($minconfig)) {
2480 load_force_config($minconfig);
2483 if ($type ne "olddefconfig") {
2484 run_command "$make $type" or
2485 dodie "failed make config";
2487 # Run old config regardless, to enforce min configurations
2490 my $build_ret = run_command "$make $build_options", $buildlog;
2492 if (defined($post_build)) {
2493 # Because a post build may change the kernel version
2496 my $ret = run_command $post_build;
2497 if (!$ret && defined($post_build_die) &&
2499 dodie "failed to post_build\n";
2504 # bisect may need this to pass
2506 $no_reboot = $save_no_reboot;
2509 fail "failed build" and return 0;
2512 $no_reboot = $save_no_reboot;
2514 my $end_time = time;
2515 $build_time = $end_time - $start_time;
2521 if (!run_ssh "halt" or defined($power_off)) {
2522 if (defined($poweroff_after_halt)) {
2523 sleep $poweroff_after_halt;
2524 run_command "$power_off";
2528 run_command "$power_off";
2539 if (defined($test_name)) {
2540 $name = " ($test_name)";
2545 doprint "\n\n*******************************************\n";
2546 doprint "*******************************************\n";
2547 doprint "KTEST RESULT: TEST $i$name SUCCESS!!!! **\n";
2548 doprint "*******************************************\n";
2549 doprint "*******************************************\n";
2551 if (defined($store_successes)) {
2552 save_logs "success", $store_successes;
2555 if ($i != $opt{"NUM_TESTS"} && !do_not_reboot) {
2556 doprint "Reboot and wait $sleep_time seconds\n";
2557 reboot_to_good $sleep_time;
2560 if (defined($post_test)) {
2561 run_command $post_test;
2567 doprint "Pass, fail, or skip? [p/f/s]";
2570 if ($ans eq "p" || $ans eq "P") {
2572 } elsif ($ans eq "f" || $ans eq "F") {
2574 } elsif ($ans eq "s" || $ans eq "S") {
2577 print "Please answer 'p', 'f', or 's'\n";
2582 sub child_run_test {
2584 # child should have no power
2585 $reboot_on_error = 0;
2586 $poweroff_on_error = 0;
2587 $die_on_failure = 1;
2589 run_command $run_test, $testlog;
2591 exit $run_command_status;
2596 sub child_finished {
2606 my $bug_ignored = 0;
2608 my $start_time = time;
2612 doprint "run test $run_test\n";
2616 $SIG{CHLD} = qw(child_finished);
2620 child_run_test if (!$child_pid);
2625 $line = wait_for_input($monitor_fp, 1);
2626 if (defined($line)) {
2628 # we are not guaranteed to get a full line
2629 $full_line .= $line;
2632 if ($full_line =~ /call trace:/i) {
2633 if ($ignore_errors) {
2640 if ($full_line =~ /Kernel panic -/) {
2644 if ($line =~ /\n/) {
2648 } while (!$child_done && !$bug);
2650 if (!$bug && $bug_ignored) {
2651 doprint "WARNING: Call Trace detected but ignored due to IGNORE_ERRORS=1\n";
2655 my $failure_start = time;
2658 $line = wait_for_input($monitor_fp, 1);
2659 if (defined($line)) {
2663 if ($now - $failure_start >= $stop_after_failure) {
2666 } while (defined($line));
2668 doprint "Detected kernel crash!\n";
2669 # kill the child with extreme prejudice
2673 waitpid $child_pid, 0;
2674 $child_exit = $? >> 8;
2676 my $end_time = time;
2677 $test_time = $end_time - $start_time;
2679 if (!$bug && $in_bisect) {
2680 if (defined($bisect_ret_good)) {
2681 if ($child_exit == $bisect_ret_good) {
2685 if (defined($bisect_ret_skip)) {
2686 if ($child_exit == $bisect_ret_skip) {
2690 if (defined($bisect_ret_abort)) {
2691 if ($child_exit == $bisect_ret_abort) {
2692 fail "test abort" and return -2;
2695 if (defined($bisect_ret_bad)) {
2696 if ($child_exit == $bisect_ret_skip) {
2700 if (defined($bisect_ret_default)) {
2701 if ($bisect_ret_default eq "good") {
2703 } elsif ($bisect_ret_default eq "bad") {
2705 } elsif ($bisect_ret_default eq "skip") {
2707 } elsif ($bisect_ret_default eq "abort") {
2710 fail "unknown default action: $bisect_ret_default"
2716 if ($bug || $child_exit) {
2717 return 0 if $in_bisect;
2718 fail "test failed" and return 0;
2723 sub run_git_bisect {
2726 doprint "$command ... ";
2728 my $output = `$command 2>&1`;
2735 dodie "Failed to git bisect";
2738 doprint "SUCCESS\n";
2739 if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\))\s+\[([[:xdigit:]]+)\]/) {
2740 doprint "$1 [$2]\n";
2741 } elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) {
2742 $bisect_bad_commit = $1;
2743 doprint "Found bad commit... $1\n";
2746 # we already logged it, just print it now.
2754 doprint "Reboot and sleep $bisect_sleep_time seconds\n";
2755 reboot_to_good $bisect_sleep_time;
2758 # returns 1 on success, 0 on failure, -1 on skip
2759 sub run_bisect_test {
2760 my ($type, $buildtype) = @_;
2769 build $buildtype or $failed = 1;
2771 if ($type ne "build") {
2772 if ($failed && $bisect_skip) {
2776 dodie "Failed on build" if $failed;
2779 start_monitor_and_install or $failed = 1;
2781 if ($type ne "boot") {
2782 if ($failed && $bisect_skip) {
2788 dodie "Failed on boot" if $failed;
2790 do_run_test or $failed = 1;
2801 # reboot the box to a kernel we can ssh to
2802 if ($type ne "build") {
2812 my $buildtype = "oldconfig";
2814 # We should have a minconfig to use?
2815 if (defined($minconfig)) {
2816 $buildtype = "useconfig:$minconfig";
2819 # If the user sets bisect_tries to less than 1, then no tries
2823 # Still let the user manually decide that though.
2824 if ($bisect_tries < 1 && $bisect_manual) {
2825 $ret = answer_bisect;
2828 for (my $i = 0; $i < $bisect_tries; $i++) {
2829 if ($bisect_tries > 1) {
2831 doprint("Running bisect trial $t of $bisect_tries:\n");
2833 $ret = run_bisect_test $type, $buildtype;
2835 if ($bisect_manual) {
2836 $ret = answer_bisect;
2842 # Are we looking for where it worked, not failed?
2843 if ($reverse_bisect && $ret >= 0) {
2849 } elsif ($ret == 0) {
2851 } elsif ($bisect_skip) {
2852 doprint "HIT A BAD COMMIT ... SKIPPING\n";
2857 sub update_bisect_replay {
2858 my $tmp_log = "$tmpdir/ktest_bisect_log";
2859 run_command "git bisect log > $tmp_log" or
2860 die "can't create bisect log";
2869 die "BISECT_GOOD[$i] not defined\n" if (!defined($bisect_good));
2870 die "BISECT_BAD[$i] not defined\n" if (!defined($bisect_bad));
2871 die "BISECT_TYPE[$i] not defined\n" if (!defined($bisect_type));
2873 my $good = $bisect_good;
2874 my $bad = $bisect_bad;
2875 my $type = $bisect_type;
2876 my $start = $bisect_start;
2877 my $replay = $bisect_replay;
2878 my $start_files = $bisect_files;
2880 if (defined($start_files)) {
2881 $start_files = " -- " . $start_files;
2886 # convert to true sha1's
2887 $good = get_sha1($good);
2888 $bad = get_sha1($bad);
2890 if (defined($bisect_reverse) && $bisect_reverse == 1) {
2891 doprint "Performing a reverse bisect (bad is good, good is bad!)\n";
2892 $reverse_bisect = 1;
2894 $reverse_bisect = 0;
2897 # Can't have a test without having a test to run
2898 if ($type eq "test" && !defined($run_test)) {
2902 # Check if a bisect was running
2903 my $bisect_start_file = "$builddir/.git/BISECT_START";
2905 my $check = $bisect_check;
2906 my $do_check = defined($check) && $check ne "0";
2908 if ( -f $bisect_start_file ) {
2909 print "Bisect in progress found\n";
2911 print " If you say yes, then no checks of good or bad will be done\n";
2913 if (defined($replay)) {
2914 print "** BISECT_REPLAY is defined in config file **";
2915 print " Ignore config option and perform new git bisect log?\n";
2916 if (read_ync " (yes, no, or cancel) ") {
2917 $replay = update_bisect_replay;
2920 } elsif (read_yn "read git log and continue?") {
2921 $replay = update_bisect_replay;
2929 my $head = get_sha1("HEAD");
2931 if ($check ne "good") {
2932 doprint "TESTING BISECT BAD [$bad]\n";
2933 run_command "git checkout $bad" or
2934 die "Failed to checkout $bad";
2936 $result = run_bisect $type;
2938 if ($result ne "bad") {
2939 fail "Tested BISECT_BAD [$bad] and it succeeded" and return 0;
2943 if ($check ne "bad") {
2944 doprint "TESTING BISECT GOOD [$good]\n";
2945 run_command "git checkout $good" or
2946 die "Failed to checkout $good";
2948 $result = run_bisect $type;
2950 if ($result ne "good") {
2951 fail "Tested BISECT_GOOD [$good] and it failed" and return 0;
2955 # checkout where we started
2956 run_command "git checkout $head" or
2957 die "Failed to checkout $head";
2960 run_command "git bisect start$start_files" or
2961 dodie "could not start bisect";
2963 if (defined($replay)) {
2964 run_command "git bisect replay $replay" or
2965 dodie "failed to run replay";
2968 run_command "git bisect good $good" or
2969 dodie "could not set bisect good to $good";
2971 run_git_bisect "git bisect bad $bad" or
2972 dodie "could not set bisect bad to $bad";
2976 if (defined($start)) {
2977 run_command "git checkout $start" or
2978 dodie "failed to checkout $start";
2983 $result = run_bisect $type;
2984 $test = run_git_bisect "git bisect $result";
2988 run_command "git bisect log" or
2989 dodie "could not capture git bisect log";
2991 run_command "git bisect reset" or
2992 dodie "could not reset git bisect";
2994 doprint "Bad commit was [$bisect_bad_commit]\n";
2999 # config_ignore holds the configs that were set (or unset) for
3000 # a good config and we will ignore these configs for the rest
3001 # of a config bisect. These configs stay as they were.
3004 # config_set holds what all configs were set as.
3007 # config_off holds the set of configs that the bad config had disabled.
3008 # We need to record them and set them in the .config when running
3009 # olddefconfig, because olddefconfig keeps the defaults.
3012 # config_off_tmp holds a set of configs to turn off for now
3015 # config_list is the set of configs that are being tested
3021 sub assign_configs {
3022 my ($hash, $config) = @_;
3024 doprint "Reading configs from $config\n";
3027 or dodie "Failed to read $config";
3031 if (/^((CONFIG\S*)=.*)/) {
3033 } elsif (/^(# (CONFIG\S*) is not set)/) {
3041 sub process_config_ignore {
3044 assign_configs \%config_ignore, $config;
3047 sub get_dependencies {
3050 my $arr = $dependency{$config};
3051 if (!defined($arr)) {
3057 foreach my $dep (@{$arr}) {
3058 print "ADD DEP $dep\n";
3059 @deps = (@deps, get_dependencies $dep);
3066 my ($pc, $file) = @_;
3068 my %configs = %{$pc};
3070 doprint "Saving configs into $file\n";
3072 open(OUT, ">$file") or dodie "Can not write to $file";
3074 foreach my $config (keys %configs) {
3075 print OUT "$configs{$config}\n";
3081 my ($name, $pc) = @_;
3083 doprint "Creating old config from $name configs\n";
3085 save_config $pc, $output_config;
3090 # compare two config hashes, and return configs with different vals.
3091 # It returns B's config values, but you can use A to see what A was.
3092 sub diff_config_vals {
3095 # crappy Perl way to pass in hashes.
3101 foreach my $item (keys %a) {
3102 if (defined($b{$item}) && $b{$item} ne $a{$item}) {
3103 $ret{$item} = $b{$item};
3110 # compare two config hashes and return the configs in B but not A
3116 # crappy Perl way to pass in hashes.
3120 foreach my $item (keys %b) {
3121 if (!defined($a{$item})) {
3122 $ret{$item} = $b{$item};
3129 # return if two configs are equal or not
3130 # 0 is equal +1 b has something a does not
3131 # +1 if a and b have a different item.
3132 # -1 if a has something b does not
3133 sub compare_configs {
3138 # crappy Perl way to pass in hashes.
3142 foreach my $item (keys %b) {
3143 if (!defined($a{$item})) {
3146 if ($a{$item} ne $b{$item}) {
3151 foreach my $item (keys %a) {
3152 if (!defined($b{$item})) {
3160 sub run_config_bisect_test {
3163 my $ret = run_bisect_test $type, "oldconfig";
3165 if ($bisect_manual) {
3166 $ret = answer_bisect;
3172 sub process_failed {
3175 doprint "\n\n***************************************\n";
3176 doprint "Found bad config: $config\n";
3177 doprint "***************************************\n\n";
3180 # used for config bisecting
3184 sub process_new_config {
3185 my ($tc, $nc, $gc, $bc) = @_;
3187 my %tmp_config = %{$tc};
3188 my %good_configs = %{$gc};
3189 my %bad_configs = %{$bc};
3196 create_config "tmp_configs", \%tmp_config;
3197 assign_configs \%new_configs, $output_config;
3199 $ret = compare_configs \%new_configs, \%bad_configs;
3201 doprint "New config equals bad config, try next test\n";
3206 $ret = compare_configs \%new_configs, \%good_configs;
3208 doprint "New config equals good config, try next test\n";
3213 %{$nc} = %new_configs;
3218 sub run_config_bisect {
3219 my ($pgood, $pbad) = @_;
3221 my $type = $config_bisect_type;
3223 my %good_configs = %{$pgood};
3224 my %bad_configs = %{$pbad};
3226 my %diff_configs = diff_config_vals \%good_configs, \%bad_configs;
3227 my %b_configs = diff_configs \%good_configs, \%bad_configs;
3228 my %g_configs = diff_configs \%bad_configs, \%good_configs;
3230 my @diff_arr = keys %diff_configs;
3231 my $len_diff = $#diff_arr + 1;
3233 my @b_arr = keys %b_configs;
3234 my $len_b = $#b_arr + 1;
3236 my @g_arr = keys %g_configs;
3237 my $len_g = $#g_arr + 1;
3243 # First, lets get it down to a single subset.
3244 # Is the problem with a difference in values?
3245 # Is the problem with a missing config?
3246 # Is the problem with a config that breaks things?
3248 # Enable all of one set and see if we get a new bad
3251 # first set the good config to the bad values.
3253 doprint "d=$len_diff g=$len_g b=$len_b\n";
3255 # first lets enable things in bad config that are enabled in good config
3257 if ($len_diff > 0) {
3258 if ($len_b > 0 || $len_g > 0) {
3259 my %tmp_config = %bad_configs;
3261 doprint "Set tmp config to be bad config with good config values\n";
3262 foreach my $item (@diff_arr) {
3263 $tmp_config{$item} = $good_configs{$item};
3266 $runtest = process_new_config \%tmp_config, \%new_configs,
3267 \%good_configs, \%bad_configs;
3271 if (!$runtest && $len_diff > 0) {
3273 if ($len_diff == 1) {
3274 process_failed $diff_arr[0];
3277 my %tmp_config = %bad_configs;
3279 my $half = int($#diff_arr / 2);
3280 my @tophalf = @diff_arr[0 .. $half];
3282 doprint "Settings bisect with top half:\n";
3283 doprint "Set tmp config to be bad config with some good config values\n";
3284 foreach my $item (@tophalf) {
3285 $tmp_config{$item} = $good_configs{$item};
3288 $runtest = process_new_config \%tmp_config, \%new_configs,
3289 \%good_configs, \%bad_configs;
3292 my %tmp_config = %bad_configs;
3294 doprint "Try bottom half\n";
3296 my @bottomhalf = @diff_arr[$half+1 .. $#diff_arr];
3298 foreach my $item (@bottomhalf) {
3299 $tmp_config{$item} = $good_configs{$item};
3302 $runtest = process_new_config \%tmp_config, \%new_configs,
3303 \%good_configs, \%bad_configs;
3308 $ret = run_config_bisect_test $type;
3310 doprint "NEW GOOD CONFIG\n";
3311 %good_configs = %new_configs;
3312 run_command "mv $good_config ${good_config}.last";
3313 save_config \%good_configs, $good_config;
3314 %{$pgood} = %good_configs;
3316 doprint "NEW BAD CONFIG\n";
3317 %bad_configs = %new_configs;
3318 run_command "mv $bad_config ${bad_config}.last";
3319 save_config \%bad_configs, $bad_config;
3320 %{$pbad} = %bad_configs;
3325 fail "Hmm, need to do a mix match?\n";
3332 my $type = $config_bisect_type;
3335 $bad_config = $config_bisect;
3337 if (defined($config_bisect_good)) {
3338 $good_config = $config_bisect_good;
3339 } elsif (defined($minconfig)) {
3340 $good_config = $minconfig;
3342 doprint "No config specified, checking if defconfig works";
3343 $ret = run_bisect_test $type, "defconfig";
3345 fail "Have no good config to compare with, please set CONFIG_BISECT_GOOD";
3348 $good_config = $output_config;
3351 # we don't want min configs to cause issues here.
3352 doprint "Disabling 'MIN_CONFIG' for this test\n";
3359 doprint "Run good configs through make oldconfig\n";
3360 assign_configs \%tmp_configs, $good_config;
3361 create_config "$good_config", \%tmp_configs;
3362 assign_configs \%good_configs, $output_config;
3364 doprint "Run bad configs through make oldconfig\n";
3365 assign_configs \%tmp_configs, $bad_config;
3366 create_config "$bad_config", \%tmp_configs;
3367 assign_configs \%bad_configs, $output_config;
3369 $good_config = "$tmpdir/good_config";
3370 $bad_config = "$tmpdir/bad_config";
3372 save_config \%good_configs, $good_config;
3373 save_config \%bad_configs, $bad_config;
3375 if (defined($config_bisect_check) && $config_bisect_check ne "0") {
3376 if ($config_bisect_check ne "good") {
3377 doprint "Testing bad config\n";
3379 $ret = run_bisect_test $type, "useconfig:$bad_config";
3381 fail "Bad config succeeded when expected to fail!";
3385 if ($config_bisect_check ne "bad") {
3386 doprint "Testing good config\n";
3388 $ret = run_bisect_test $type, "useconfig:$good_config";
3390 fail "Good config failed when expected to succeed!";
3397 $ret = run_config_bisect \%good_configs, \%bad_configs;
3401 return $ret if ($ret < 0);
3406 sub patchcheck_reboot {
3407 doprint "Reboot and sleep $patchcheck_sleep_time seconds\n";
3408 reboot_to_good $patchcheck_sleep_time;
3414 die "PATCHCHECK_START[$i] not defined\n"
3415 if (!defined($patchcheck_start));
3416 die "PATCHCHECK_TYPE[$i] not defined\n"
3417 if (!defined($patchcheck_type));
3419 my $start = $patchcheck_start;
3421 my $cherry = $patchcheck_cherry;
3422 if (!defined($cherry)) {
3427 if (defined($patchcheck_end)) {
3428 $end = $patchcheck_end;
3430 die "PATCHCHECK_END must be defined with PATCHCHECK_CHERRY\n";
3433 # Get the true sha1's since we can use things like HEAD~3
3434 $start = get_sha1($start);
3435 $end = get_sha1($end);
3437 my $type = $patchcheck_type;
3439 # Can't have a test without having a test to run
3440 if ($type eq "test" && !defined($run_test)) {
3445 open (IN, "git cherry -v $start $end|") or
3446 dodie "could not get git list";
3448 open (IN, "git log --pretty=oneline $end|") or
3449 dodie "could not get git list";
3456 # git cherry adds a '+' we want to remove
3458 $list[$#list+1] = $_;
3459 last if (/^$start/);
3464 if ($list[$#list] !~ /^$start/) {
3465 fail "SHA1 $start not found";
3468 # go backwards in the list
3469 @list = reverse @list;
3472 doprint("Going to test the following commits:\n");
3473 foreach my $l (@list) {
3477 my $save_clean = $noclean;
3478 my %ignored_warnings;
3480 if (defined($ignore_warnings)) {
3481 foreach my $sha1 (split /\s+/, $ignore_warnings) {
3482 $ignored_warnings{$sha1} = 1;
3487 foreach my $item (@list) {
3489 $sha1 =~ s/^([[:xdigit:]]+).*/$1/;
3491 doprint "\nProcessing commit \"$item\"\n\n";
3493 run_command "git checkout $sha1" or
3494 die "Failed to checkout $sha1";
3496 # only clean on the first and last patch
3497 if ($item eq $list[0] ||
3498 $item eq $list[$#list]) {
3499 $noclean = $save_clean;
3504 if (defined($minconfig)) {
3505 build "useconfig:$minconfig" or return 0;
3507 # ?? no config to use?
3508 build "oldconfig" or return 0;
3511 # No need to do per patch checking if warnings file exists
3512 if (!defined($warnings_file) && !defined($ignored_warnings{$sha1})) {
3513 check_patch_buildlog $sha1 or return 0;
3516 check_buildlog or return 0;
3518 next if ($type eq "build");
3522 start_monitor_and_install or $failed = 1;
3524 if (!$failed && $type ne "boot"){
3525 do_run_test or $failed = 1;
3550 # $config depends on $dep
3551 my ($config, $dep) = @_;
3553 if (defined($depends{$config})) {
3554 $depends{$config} .= " " . $dep;
3556 $depends{$config} = $dep;
3559 # record the number of configs depending on $dep
3560 if (defined $depcount{$dep}) {
3563 $depcount{$dep} = 1;
3567 # taken from streamline_config.pl
3579 if (! -f $kconfig) {
3580 doprint "file $kconfig does not exist, skipping\n";
3584 open(KIN, "$kconfig")
3585 or die "Can't open $kconfig";
3589 # Make sure that lines ending with \ continue
3591 $_ = $line . " " . $_;
3602 # collect any Kconfig sources
3603 if (/^source\s*"(.*)"/) {
3604 $kconfigs[$#kconfigs+1] = $1;
3608 if (/^\s*(menu)?config\s+(\S+)\s*$/) {
3612 for (my $i = 0; $i < $iflevel; $i++) {
3613 add_dep $config, $ifdeps[$i];
3616 # collect the depends for the config
3617 } elsif ($state eq "NEW" && /^\s*depends\s+on\s+(.*)$/) {
3619 add_dep $config, $1;
3621 # Get the configs that select this config
3622 } elsif ($state eq "NEW" && /^\s*select\s+(\S+)/) {
3624 # selected by depends on config
3625 add_dep $1, $config;
3627 # Check for if statements
3628 } elsif (/^if\s+(.*\S)\s*$/) {
3630 # remove beginning and ending non text
3631 $deps =~ s/^[^a-zA-Z0-9_]*//;
3632 $deps =~ s/[^a-zA-Z0-9_]*$//;
3634 my @deps = split /[^a-zA-Z0-9_]+/, $deps;
3636 $ifdeps[$iflevel++] = join ':', @deps;
3638 } elsif (/^endif/) {
3640 $iflevel-- if ($iflevel);
3643 } elsif (/^\s*help\s*$/) {
3649 # read in any configs that were found.
3650 foreach $kconfig (@kconfigs) {
3651 if (!defined($read_kconfigs{$kconfig})) {
3652 $read_kconfigs{$kconfig} = 1;
3653 read_kconfig("$builddir/$kconfig");
3659 # find out which arch this is by the kconfig file
3660 open (IN, $output_config)
3661 or dodie "Failed to read $output_config";
3664 if (m,Linux/(\S+)\s+\S+\s+Kernel Configuration,) {
3671 if (!defined($arch)) {
3672 doprint "Could not find arch from config file\n";
3673 doprint "no dependencies used\n";
3677 # arch is really the subarch, we need to know
3678 # what directory to look at.
3679 if ($arch eq "i386" || $arch eq "x86_64") {
3681 } elsif ($arch =~ /^tile/) {
3685 my $kconfig = "$builddir/arch/$arch/Kconfig";
3687 if (! -f $kconfig && $arch =~ /\d$/) {
3689 # some subarchs have numbers, truncate them
3691 $kconfig = "$builddir/arch/$arch/Kconfig";
3692 if (! -f $kconfig) {
3693 doprint "No idea what arch dir $orig is for\n";
3694 doprint "no dependencies used\n";
3699 read_kconfig($kconfig);
3702 sub make_new_config {
3705 open (OUT, ">$output_config")
3706 or dodie "Failed to write $output_config";
3708 foreach my $config (@configs) {
3709 print OUT "$config\n";
3717 $config =~ s/CONFIG_//;
3725 my $kconfig = chomp_config $dep;
3727 $dep = $depends{"$kconfig"};
3729 # the dep string we have saves the dependencies as they
3730 # were found, including expressions like ! && ||. We
3731 # want to split this out into just an array of configs.
3733 my $valid = "A-Za-z_0-9";
3737 while ($dep =~ /[$valid]/) {
3739 if ($dep =~ /^[^$valid]*([$valid]+)/) {
3740 my $conf = "CONFIG_" . $1;
3742 $configs[$#configs + 1] = $conf;
3744 $dep =~ s/^[^$valid]*[$valid]+//;
3746 die "this should never happen";
3756 my %processed_configs;
3757 my %nochange_config;
3759 sub test_this_config {
3764 # if we already processed this config, skip it
3765 if (defined($processed_configs{$config})) {
3768 $processed_configs{$config} = 1;
3770 # if this config failed during this round, skip it
3771 if (defined($nochange_config{$config})) {
3775 my $kconfig = chomp_config $config;
3777 # Test dependencies first
3778 if (defined($depends{"$kconfig"})) {
3779 my @parents = get_depends $config;
3780 foreach my $parent (@parents) {
3781 # if the parent is in the min config, check it first
3782 next if (!defined($min_configs{$parent}));
3783 $found = test_this_config($parent);
3784 if (defined($found)) {
3790 # Remove this config from the list of configs
3791 # do a make olddefconfig and then read the resulting
3792 # .config to make sure it is missing the config that
3794 my %configs = %min_configs;
3795 delete $configs{$config};
3796 make_new_config ((values %configs), (values %keep_configs));
3799 assign_configs \%configs, $output_config;
3801 if (!defined($configs{$config}) || $configs{$config} =~ /^#/) {
3805 doprint "disabling config $config did not change .config\n";
3807 $nochange_config{$config} = 1;
3812 sub make_min_config {
3815 my $type = $minconfig_type;
3816 if ($type ne "boot" && $type ne "test") {
3817 fail "Invalid MIN_CONFIG_TYPE '$minconfig_type'\n" .
3818 " make_min_config works only with 'boot' and 'test'\n" and return;
3821 if (!defined($output_minconfig)) {
3822 fail "OUTPUT_MIN_CONFIG not defined" and return;
3825 # If output_minconfig exists, and the start_minconfig
3826 # came from min_config, than ask if we should use
3828 if (-f $output_minconfig && !$start_minconfig_defined) {
3829 print "$output_minconfig exists\n";
3830 if (!defined($use_output_minconfig)) {
3831 if (read_yn " Use it as minconfig?") {
3832 $start_minconfig = $output_minconfig;
3834 } elsif ($use_output_minconfig > 0) {
3835 doprint "Using $output_minconfig as MIN_CONFIG\n";
3836 $start_minconfig = $output_minconfig;
3838 doprint "Set to still use MIN_CONFIG as starting point\n";
3842 if (!defined($start_minconfig)) {
3843 fail "START_MIN_CONFIG or MIN_CONFIG not defined" and return;
3846 my $temp_config = "$tmpdir/temp_config";
3848 # First things first. We build an allnoconfig to find
3849 # out what the defaults are that we can't touch.
3850 # Some are selections, but we really can't handle selections.
3852 my $save_minconfig = $minconfig;
3855 run_command "$make allnoconfig" or return 0;
3859 process_config_ignore $output_config;
3861 undef %save_configs;
3864 if (defined($ignore_config)) {
3865 # make sure the file exists
3866 `touch $ignore_config`;
3867 assign_configs \%save_configs, $ignore_config;
3870 %keep_configs = %save_configs;
3872 doprint "Load initial configs from $start_minconfig\n";
3874 # Look at the current min configs, and save off all the
3875 # ones that were set via the allnoconfig
3876 assign_configs \%min_configs, $start_minconfig;
3878 my @config_keys = keys %min_configs;
3880 # All configs need a depcount
3881 foreach my $config (@config_keys) {
3882 my $kconfig = chomp_config $config;
3883 if (!defined $depcount{$kconfig}) {
3884 $depcount{$kconfig} = 0;
3888 # Remove anything that was set by the make allnoconfig
3889 # we shouldn't need them as they get set for us anyway.
3890 foreach my $config (@config_keys) {
3891 # Remove anything in the ignore_config
3892 if (defined($keep_configs{$config})) {
3893 my $file = $ignore_config;
3894 $file =~ s,.*/(.*?)$,$1,;
3895 doprint "$config set by $file ... ignored\n";
3896 delete $min_configs{$config};
3899 # But make sure the settings are the same. If a min config
3900 # sets a selection, we do not want to get rid of it if
3901 # it is not the same as what we have. Just move it into
3903 if (defined($config_ignore{$config})) {
3904 if ($config_ignore{$config} ne $min_configs{$config}) {
3905 doprint "$config is in allnoconfig as '$config_ignore{$config}'";
3906 doprint " but it is '$min_configs{$config}' in minconfig .. keeping\n";
3907 $keep_configs{$config} = $min_configs{$config};
3909 doprint "$config set by allnoconfig ... ignored\n";
3911 delete $min_configs{$config};
3923 # Now disable each config one by one and do a make oldconfig
3924 # till we find a config that changes our list.
3926 my @test_configs = keys %min_configs;
3928 # Sort keys by who is most dependent on
3929 @test_configs = sort { $depcount{chomp_config($b)} <=> $depcount{chomp_config($a)} }
3932 # Put configs that did not modify the config at the end.
3934 for (my $i = 0; $i < $#test_configs; $i++) {
3935 if (!defined($nochange_config{$test_configs[0]})) {
3939 # This config didn't change the .config last time.
3940 # Place it at the end
3941 my $config = shift @test_configs;
3942 push @test_configs, $config;
3945 # if every test config has failed to modify the .config file
3946 # in the past, then reset and start over.
3948 undef %nochange_config;
3951 undef %processed_configs;
3953 foreach my $config (@test_configs) {
3955 $found = test_this_config $config;
3957 last if (defined($found));
3959 # oh well, try another config
3962 if (!defined($found)) {
3963 # we could have failed due to the nochange_config hash
3964 # reset and try again
3966 undef %nochange_config;
3970 doprint "No more configs found that we can disable\n";
3978 doprint "Test with $config disabled\n";
3980 # set in_bisect to keep build and monitor from dieing
3984 build "oldconfig" or $failed = 1;
3986 start_monitor_and_install or $failed = 1;
3988 if ($type eq "test" && !$failed) {
3989 do_run_test or $failed = 1;
3998 doprint "$min_configs{$config} is needed to boot the box... keeping\n";
3999 # this config is needed, add it to the ignore list.
4000 $keep_configs{$config} = $min_configs{$config};
4001 $save_configs{$config} = $min_configs{$config};
4002 delete $min_configs{$config};
4004 # update new ignore configs
4005 if (defined($ignore_config)) {
4006 open (OUT, ">$temp_config")
4007 or die "Can't write to $temp_config";
4008 foreach my $config (keys %save_configs) {
4009 print OUT "$save_configs{$config}\n";
4012 run_command "mv $temp_config $ignore_config" or
4013 dodie "failed to copy update to $ignore_config";
4017 # We booted without this config, remove it from the minconfigs.
4018 doprint "$config is not needed, disabling\n";
4020 delete $min_configs{$config};
4022 # Also disable anything that is not enabled in this config
4024 assign_configs \%configs, $output_config;
4025 my @config_keys = keys %min_configs;
4026 foreach my $config (@config_keys) {
4027 if (!defined($configs{$config})) {
4028 doprint "$config is not set, disabling\n";
4029 delete $min_configs{$config};
4033 # Save off all the current mandatory configs
4034 open (OUT, ">$temp_config")
4035 or die "Can't write to $temp_config";
4036 foreach my $config (keys %keep_configs) {
4037 print OUT "$keep_configs{$config}\n";
4039 foreach my $config (keys %min_configs) {
4040 print OUT "$min_configs{$config}\n";
4044 run_command "mv $temp_config $output_minconfig" or
4045 dodie "failed to copy update to $output_minconfig";
4048 doprint "Reboot and wait $sleep_time seconds\n";
4049 reboot_to_good $sleep_time;
4056 sub make_warnings_file {
4059 if (!defined($warnings_file)) {
4060 dodie "Must define WARNINGS_FILE for make_warnings_file test";
4063 if ($build_type eq "nobuild") {
4064 dodie "BUILD_TYPE can not be 'nobuild' for make_warnings_file test";
4067 build $build_type or dodie "Failed to build";
4069 open(OUT, ">$warnings_file") or dodie "Can't create $warnings_file";
4071 open(IN, $buildlog) or dodie "Can't open $buildlog";
4074 # Some compilers use UTF-8 extended for quotes
4075 # for distcc heterogeneous systems, this causes issues
4078 if (/$check_build_re/) {
4089 $#ARGV < 1 or die "ktest.pl version: $VERSION\n usage: ktest.pl [config-file]\n";
4092 $ktest_config = $ARGV[0];
4093 if (! -f $ktest_config) {
4094 print "$ktest_config does not exist.\n";
4095 if (!read_yn "Create it?") {
4101 if (! -f $ktest_config) {
4104 open(OUT, ">$ktest_config") or die "Can not create $ktest_config";
4106 # Generated by ktest.pl
4109 # PWD is a ktest.pl variable that will result in the process working
4110 # directory that ktest.pl is executed in.
4112 # THIS_DIR is automatically assigned the PWD of the path that generated
4113 # the config file. It is best to use this variable when assigning other
4114 # directory paths within this directory. This allows you to easily
4115 # move the test cases to other locations or to other machines.
4117 THIS_DIR := $variable{"PWD"}
4119 # Define each test with TEST_START
4120 # The config options below it will override the defaults
4122 TEST_TYPE = $default{"TEST_TYPE"}
4129 read_config $ktest_config;
4131 if (defined($opt{"LOG_FILE"})) {
4132 $opt{"LOG_FILE"} = eval_option("LOG_FILE", $opt{"LOG_FILE"}, -1);
4135 # Append any configs entered in manually to the config file.
4136 my @new_configs = keys %entered_configs;
4137 if ($#new_configs >= 0) {
4138 print "\nAppending entered in configs to $ktest_config\n";
4139 open(OUT, ">>$ktest_config") or die "Can not append to $ktest_config";
4140 foreach my $config (@new_configs) {
4141 print OUT "$config = $entered_configs{$config}\n";
4142 $opt{$config} = process_variables($entered_configs{$config});
4146 if ($opt{"CLEAR_LOG"} && defined($opt{"LOG_FILE"})) {
4147 unlink $opt{"LOG_FILE"};
4150 doprint "\n\nSTARTING AUTOMATED TESTS\n\n";
4152 for (my $i = 0, my $repeat = 1; $i <= $opt{"NUM_TESTS"}; $i += $repeat) {
4155 doprint "DEFAULT OPTIONS:\n";
4157 doprint "\nTEST $i OPTIONS";
4158 if (defined($repeat_tests{$i})) {
4159 $repeat = $repeat_tests{$i};
4160 doprint " ITERATE $repeat";
4165 foreach my $option (sort keys %opt) {
4167 if ($option =~ /\[(\d+)\]$/) {
4173 doprint "$option = $opt{$option}\n";
4177 sub option_defined {
4180 if (defined($opt{$option}) && $opt{$option} !~ /^\s*$/) {
4187 sub __set_test_option {
4188 my ($name, $i) = @_;
4190 my $option = "$name\[$i\]";
4192 if (option_defined($option)) {
4193 return $opt{$option};
4196 foreach my $test (keys %repeat_tests) {
4198 $i < $test + $repeat_tests{$test}) {
4199 $option = "$name\[$test\]";
4200 if (option_defined($option)) {
4201 return $opt{$option};
4206 if (option_defined($name)) {
4213 sub set_test_option {
4214 my ($name, $i) = @_;
4216 my $option = __set_test_option($name, $i);
4217 return $option if (!defined($option));
4219 return eval_option($name, $option, $i);
4222 # First we need to do is the builds
4223 for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
4225 # Do not reboot on failing test options
4227 $reboot_success = 0;
4238 undef %force_config;
4240 my $makecmd = set_test_option("MAKE_CMD", $i);
4242 $outputdir = set_test_option("OUTPUT_DIR", $i);
4243 $builddir = set_test_option("BUILD_DIR", $i);
4245 chdir $builddir || die "can't change directory to $builddir";
4247 if (!-d $outputdir) {
4248 mkpath($outputdir) or
4249 die "can't create $outputdir";
4252 $make = "$makecmd O=$outputdir";
4254 # Load all the options into their mapped variable names
4255 foreach my $opt (keys %option_map) {
4256 ${$option_map{$opt}} = set_test_option($opt, $i);
4259 $start_minconfig_defined = 1;
4261 # The first test may override the PRE_KTEST option
4262 if (defined($pre_ktest) && $i == 1) {
4264 run_command $pre_ktest;
4267 # Any test can override the POST_KTEST option
4268 # The last test takes precedence.
4269 if (defined($post_ktest)) {
4270 $final_post_ktest = $post_ktest;
4273 if (!defined($start_minconfig)) {
4274 $start_minconfig_defined = 0;
4275 $start_minconfig = $minconfig;
4280 die "can't create $tmpdir";
4283 $ENV{"SSH_USER"} = $ssh_user;
4284 $ENV{"MACHINE"} = $machine;
4286 $buildlog = "$tmpdir/buildlog-$machine";
4287 $testlog = "$tmpdir/testlog-$machine";
4288 $dmesg = "$tmpdir/dmesg-$machine";
4289 $output_config = "$outputdir/.config";
4292 $target = "$ssh_user\@$machine";
4293 if ($reboot_type eq "grub") {
4294 dodie "GRUB_MENU not defined" if (!defined($grub_menu));
4295 } elsif ($reboot_type eq "grub2") {
4296 dodie "GRUB_MENU not defined" if (!defined($grub_menu));
4297 dodie "GRUB_FILE not defined" if (!defined($grub_file));
4298 } elsif ($reboot_type eq "syslinux") {
4299 dodie "SYSLINUX_LABEL not defined" if (!defined($syslinux_label));
4303 my $run_type = $build_type;
4304 if ($test_type eq "patchcheck") {
4305 $run_type = $patchcheck_type;
4306 } elsif ($test_type eq "bisect") {
4307 $run_type = $bisect_type;
4308 } elsif ($test_type eq "config_bisect") {
4309 $run_type = $config_bisect_type;
4310 } elsif ($test_type eq "make_min_config") {
4312 } elsif ($test_type eq "make_warnings_file") {
4316 # mistake in config file?
4317 if (!defined($run_type)) {
4318 $run_type = "ERROR";
4322 $installme = " no_install" if ($no_install);
4326 if (defined($test_name)) {
4327 $name = " ($test_name)";
4331 doprint "RUNNING TEST $i of $opt{NUM_TESTS}$name with option $test_type $run_type$installme\n\n";
4333 if (defined($pre_test)) {
4334 run_command $pre_test;
4341 if (defined($addconfig)) {
4342 my $min = $minconfig;
4343 if (!defined($minconfig)) {
4346 run_command "cat $addconfig $min > $tmpdir/add_config" or
4347 dodie "Failed to create temp config";
4348 $minconfig = "$tmpdir/add_config";
4351 if (defined($checkout)) {
4352 run_command "git checkout $checkout" or
4353 die "failed to checkout $checkout";
4358 # A test may opt to not reboot the box
4359 if ($reboot_on_success) {
4360 $reboot_success = 1;
4363 if ($test_type eq "bisect") {
4366 } elsif ($test_type eq "config_bisect") {
4369 } elsif ($test_type eq "patchcheck") {
4372 } elsif ($test_type eq "make_min_config") {
4375 } elsif ($test_type eq "make_warnings_file") {
4377 make_warnings_file $i;
4381 if ($build_type ne "nobuild") {
4382 build $build_type or next;
4383 check_buildlog or next;
4386 if ($test_type eq "install") {
4393 if ($test_type ne "build") {
4395 start_monitor_and_install or $failed = 1;
4397 if (!$failed && $test_type ne "boot" && defined($run_test)) {
4398 do_run_test or $failed = 1;
4412 if (defined($final_post_ktest)) {
4413 run_command $final_post_ktest;
4416 if ($opt{"POWEROFF_ON_SUCCESS"}) {
4418 } elsif ($opt{"REBOOT_ON_SUCCESS"} && !do_not_reboot && $reboot_success) {
4420 } elsif (defined($switch_to_good)) {
4421 # still need to get to the good kernel
4422 run_command $switch_to_good;
4426 doprint "\n $successes of $opt{NUM_TESTS} tests were successful\n\n";