2 # SPDX-License-Identifier: GPL-2.0-only
4 # Copyright 2010 - Steven Rostedt <srostedt@redhat.com>, Red Hat Inc.
9 use Fcntl qw(F_GETFL F_SETFL O_NONBLOCK);
10 use File::Path qw(mkpath);
11 use File::Copy qw(cp);
27 "MAILER" => "sendmail", # default mailer
28 "EMAIL_ON_ERROR" => 1,
29 "EMAIL_WHEN_FINISHED" => 1,
30 "EMAIL_WHEN_CANCELED" => 0,
31 "EMAIL_WHEN_STARTED" => 0,
33 "TEST_TYPE" => "build",
34 "BUILD_TYPE" => "oldconfig",
36 "CLOSE_CONSOLE_SIGNAL" => "INT",
38 "TMP_DIR" => "/tmp/ktest/\${MACHINE}",
39 "SLEEP_TIME" => 60, # sleep time between tests
41 "REBOOT_ON_ERROR" => 0,
42 "POWEROFF_ON_ERROR" => 0,
43 "REBOOT_ON_SUCCESS" => 1,
44 "POWEROFF_ON_SUCCESS" => 0,
45 "BUILD_OPTIONS" => "",
46 "BISECT_SLEEP_TIME" => 60, # sleep time between bisects
47 "PATCHCHECK_SLEEP_TIME" => 60, # sleep time between patch checks
52 "MIN_CONFIG_TYPE" => "boot",
53 "SUCCESS_LINE" => "login:",
54 "DETECT_TRIPLE_FAULT" => 1,
56 "BOOTED_TIMEOUT" => 1,
57 "DIE_ON_FAILURE" => 1,
58 "SSH_EXEC" => "ssh \$SSH_USER\@\$MACHINE \$SSH_COMMAND",
59 "SCP_TO_TARGET" => "scp \$SRC_FILE \$SSH_USER\@\$MACHINE:\$DST_FILE",
60 "SCP_TO_TARGET_INSTALL" => "\${SCP_TO_TARGET}",
61 "REBOOT" => "ssh \$SSH_USER\@\$MACHINE reboot",
62 "REBOOT_RETURN_CODE" => 255,
63 "STOP_AFTER_SUCCESS" => 10,
64 "STOP_AFTER_FAILURE" => 60,
65 "STOP_TEST_AFTER" => 600,
66 "MAX_MONITOR_WAIT" => 1800,
67 "GRUB_REBOOT" => "grub2-reboot",
68 "GRUB_BLS_GET" => "grubby --info=ALL",
69 "SYSLINUX" => "extlinux",
70 "SYSLINUX_PATH" => "/boot/extlinux",
71 "CONNECT_TIMEOUT" => 25,
73 # required, and we will ask users if they don't have them but we keep the default
74 # value something that is common.
75 "REBOOT_TYPE" => "grub",
76 "LOCALVERSION" => "-test",
78 "BUILD_TARGET" => "arch/x86/boot/bzImage",
79 "TARGET_IMAGE" => "/boot/vmlinuz-test",
85 my $test_log_start = 0;
87 my $ktest_config = "ktest.conf";
100 my $final_post_ktest;
114 my $reboot_return_code;
118 my $poweroff_on_error;
119 my $reboot_on_success;
121 my $powercycle_after_reboot;
122 my $poweroff_after_halt;
123 my $max_monitor_wait;
126 my $scp_to_target_install;
145 my $start_minconfig_defined;
146 my $output_minconfig;
148 my $use_output_minconfig;
154 my $bisect_bad_commit = "";
159 my $config_bisect_good;
163 my $bisect_ret_abort;
164 my $bisect_ret_default;
165 my $in_patchcheck = 0;
174 my $bisect_sleep_time;
175 my $patchcheck_sleep_time;
183 my $config_bisect_exec;
185 my $detect_triplefault;
187 my $close_console_signal;
188 my $reboot_success_line;
190 my $stop_after_success;
191 my $stop_after_failure;
200 my $run_command_status = 0;
212 my $config_bisect_type;
213 my $config_bisect_check;
216 my $patchcheck_start;
217 my $patchcheck_cherry;
226 my $dirname = $FindBin::Bin;
234 my $email_when_finished;
235 my $email_when_started;
236 my $email_when_canceled;
238 my $script_start_time = localtime();
240 # set when a test is something other that just building or install
241 # which would require more options.
244 # tell build not to worry about warnings, even when WARNINGS_FILE is set
247 # set when creating a new config
254 # force_config is the list of configs that we force enabled (or disabled)
255 # in a .config file. The MIN_CONFIG and ADD_CONFIG configs.
258 # do not force reboots on config problems
262 my $reboot_success = 0;
265 "MAILTO" => \$mailto,
266 "MAILER" => \$mailer,
267 "MAIL_PATH" => \$mail_path,
268 "MAIL_MAX_SIZE" => \$mail_max_size,
269 "MAIL_COMMAND" => \$mail_command,
270 "EMAIL_ON_ERROR" => \$email_on_error,
271 "EMAIL_WHEN_FINISHED" => \$email_when_finished,
272 "EMAIL_WHEN_STARTED" => \$email_when_started,
273 "EMAIL_WHEN_CANCELED" => \$email_when_canceled,
274 "MACHINE" => \$machine,
275 "SSH_USER" => \$ssh_user,
276 "TMP_DIR" => \$tmpdir,
277 "OUTPUT_DIR" => \$outputdir,
278 "BUILD_DIR" => \$builddir,
279 "TEST_TYPE" => \$test_type,
280 "PRE_KTEST" => \$pre_ktest,
281 "POST_KTEST" => \$post_ktest,
282 "PRE_TEST" => \$pre_test,
283 "PRE_TEST_DIE" => \$pre_test_die,
284 "POST_TEST" => \$post_test,
285 "BUILD_TYPE" => \$build_type,
286 "BUILD_OPTIONS" => \$build_options,
287 "PRE_BUILD" => \$pre_build,
288 "POST_BUILD" => \$post_build,
289 "PRE_BUILD_DIE" => \$pre_build_die,
290 "POST_BUILD_DIE" => \$post_build_die,
291 "POWER_CYCLE" => \$power_cycle,
292 "REBOOT" => \$reboot,
293 "REBOOT_RETURN_CODE" => \$reboot_return_code,
294 "BUILD_NOCLEAN" => \$noclean,
295 "MIN_CONFIG" => \$minconfig,
296 "OUTPUT_MIN_CONFIG" => \$output_minconfig,
297 "START_MIN_CONFIG" => \$start_minconfig,
298 "MIN_CONFIG_TYPE" => \$minconfig_type,
299 "USE_OUTPUT_MIN_CONFIG" => \$use_output_minconfig,
300 "WARNINGS_FILE" => \$warnings_file,
301 "IGNORE_CONFIG" => \$ignore_config,
302 "TEST" => \$run_test,
303 "ADD_CONFIG" => \$addconfig,
304 "REBOOT_TYPE" => \$reboot_type,
305 "GRUB_MENU" => \$grub_menu,
306 "GRUB_FILE" => \$grub_file,
307 "GRUB_REBOOT" => \$grub_reboot,
308 "GRUB_BLS_GET" => \$grub_bls_get,
309 "SYSLINUX" => \$syslinux,
310 "SYSLINUX_PATH" => \$syslinux_path,
311 "SYSLINUX_LABEL" => \$syslinux_label,
312 "PRE_INSTALL" => \$pre_install,
313 "POST_INSTALL" => \$post_install,
314 "NO_INSTALL" => \$no_install,
315 "REBOOT_SCRIPT" => \$reboot_script,
316 "REBOOT_ON_ERROR" => \$reboot_on_error,
317 "SWITCH_TO_GOOD" => \$switch_to_good,
318 "SWITCH_TO_TEST" => \$switch_to_test,
319 "POWEROFF_ON_ERROR" => \$poweroff_on_error,
320 "REBOOT_ON_SUCCESS" => \$reboot_on_success,
321 "DIE_ON_FAILURE" => \$die_on_failure,
322 "POWER_OFF" => \$power_off,
323 "POWERCYCLE_AFTER_REBOOT" => \$powercycle_after_reboot,
324 "POWEROFF_AFTER_HALT" => \$poweroff_after_halt,
325 "MAX_MONITOR_WAIT" => \$max_monitor_wait,
326 "SLEEP_TIME" => \$sleep_time,
327 "BISECT_SLEEP_TIME" => \$bisect_sleep_time,
328 "PATCHCHECK_SLEEP_TIME" => \$patchcheck_sleep_time,
329 "IGNORE_WARNINGS" => \$ignore_warnings,
330 "IGNORE_ERRORS" => \$ignore_errors,
331 "BISECT_MANUAL" => \$bisect_manual,
332 "BISECT_SKIP" => \$bisect_skip,
333 "BISECT_TRIES" => \$bisect_tries,
334 "CONFIG_BISECT_GOOD" => \$config_bisect_good,
335 "BISECT_RET_GOOD" => \$bisect_ret_good,
336 "BISECT_RET_BAD" => \$bisect_ret_bad,
337 "BISECT_RET_SKIP" => \$bisect_ret_skip,
338 "BISECT_RET_ABORT" => \$bisect_ret_abort,
339 "BISECT_RET_DEFAULT" => \$bisect_ret_default,
340 "STORE_FAILURES" => \$store_failures,
341 "STORE_SUCCESSES" => \$store_successes,
342 "TEST_NAME" => \$test_name,
343 "TIMEOUT" => \$timeout,
344 "RUN_TIMEOUT" => \$run_timeout,
345 "CONNECT_TIMEOUT" => \$connect_timeout,
346 "CONFIG_BISECT_EXEC" => \$config_bisect_exec,
347 "BOOTED_TIMEOUT" => \$booted_timeout,
348 "CONSOLE" => \$console,
349 "CLOSE_CONSOLE_SIGNAL" => \$close_console_signal,
350 "DETECT_TRIPLE_FAULT" => \$detect_triplefault,
351 "SUCCESS_LINE" => \$success_line,
352 "REBOOT_SUCCESS_LINE" => \$reboot_success_line,
353 "STOP_AFTER_SUCCESS" => \$stop_after_success,
354 "STOP_AFTER_FAILURE" => \$stop_after_failure,
355 "STOP_TEST_AFTER" => \$stop_test_after,
356 "BUILD_TARGET" => \$build_target,
357 "SSH_EXEC" => \$ssh_exec,
358 "SCP_TO_TARGET" => \$scp_to_target,
359 "SCP_TO_TARGET_INSTALL" => \$scp_to_target_install,
360 "CHECKOUT" => \$checkout,
361 "TARGET_IMAGE" => \$target_image,
362 "LOCALVERSION" => \$localversion,
364 "BISECT_GOOD" => \$bisect_good,
365 "BISECT_BAD" => \$bisect_bad,
366 "BISECT_TYPE" => \$bisect_type,
367 "BISECT_START" => \$bisect_start,
368 "BISECT_REPLAY" => \$bisect_replay,
369 "BISECT_FILES" => \$bisect_files,
370 "BISECT_REVERSE" => \$bisect_reverse,
371 "BISECT_CHECK" => \$bisect_check,
373 "CONFIG_BISECT" => \$config_bisect,
374 "CONFIG_BISECT_TYPE" => \$config_bisect_type,
375 "CONFIG_BISECT_CHECK" => \$config_bisect_check,
377 "PATCHCHECK_TYPE" => \$patchcheck_type,
378 "PATCHCHECK_START" => \$patchcheck_start,
379 "PATCHCHECK_CHERRY" => \$patchcheck_cherry,
380 "PATCHCHECK_END" => \$patchcheck_end,
383 # Options may be used by other options, record them.
386 # default variables that can be used
387 chomp ($variable{"PWD"} = `pwd`);
388 $pwd = $variable{"PWD"};
390 $config_help{"MACHINE"} = << "EOF"
391 The machine hostname that you will test.
392 For build only tests, it is still needed to differentiate log files.
395 $config_help{"SSH_USER"} = << "EOF"
396 The box is expected to have ssh on normal bootup, provide the user
397 (most likely root, since you need privileged operations)
400 $config_help{"BUILD_DIR"} = << "EOF"
401 The directory that contains the Linux source code (full path).
402 You can use \${PWD} that will be the path where ktest.pl is run, or use
403 \${THIS_DIR} which is assigned \${PWD} but may be changed later.
406 $config_help{"OUTPUT_DIR"} = << "EOF"
407 The directory that the objects will be built (full path).
408 (can not be same as BUILD_DIR)
409 You can use \${PWD} that will be the path where ktest.pl is run, or use
410 \${THIS_DIR} which is assigned \${PWD} but may be changed later.
413 $config_help{"BUILD_TARGET"} = << "EOF"
414 The location of the compiled file to copy to the target.
415 (relative to OUTPUT_DIR)
418 $config_help{"BUILD_OPTIONS"} = << "EOF"
419 Options to add to \"make\" when building.
423 $config_help{"TARGET_IMAGE"} = << "EOF"
424 The place to put your image on the test machine.
427 $config_help{"POWER_CYCLE"} = << "EOF"
428 A script or command to reboot the box.
430 Here is a digital loggers power switch example
431 POWER_CYCLE = wget --no-proxy -O /dev/null -q --auth-no-challenge 'http://admin:admin\@power/outlet?5=CCL'
433 Here is an example to reboot a virtual box on the current host
434 with the name "Guest".
435 POWER_CYCLE = virsh destroy Guest; sleep 5; virsh start Guest
438 $config_help{"CONSOLE"} = << "EOF"
439 The script or command that reads the console
441 If you use ttywatch server, something like the following would work.
442 CONSOLE = nc -d localhost 3001
444 For a virtual machine with guest name "Guest".
445 CONSOLE = virsh console Guest
448 $config_help{"LOCALVERSION"} = << "EOF"
449 Required version ending to differentiate the test
450 from other linux builds on the system.
453 $config_help{"REBOOT_TYPE"} = << "EOF"
454 Way to reboot the box to the test kernel.
455 Only valid options so far are "grub", "grub2", "grub2bls", "syslinux", and "script".
457 If you specify grub, it will assume grub version 1
458 and will search in /boot/grub/menu.lst for the title \$GRUB_MENU
459 and select that target to reboot to the kernel. If this is not
460 your setup, then specify "script" and have a command or script
461 specified in REBOOT_SCRIPT to boot to the target.
463 The entry in /boot/grub/menu.lst must be entered in manually.
464 The test will not modify that file.
466 If you specify grub2, then you also need to specify both \$GRUB_MENU
469 If you specify grub2bls, then you also need to specify \$GRUB_MENU.
471 If you specify syslinux, then you may use SYSLINUX to define the syslinux
472 command (defaults to extlinux), and SYSLINUX_PATH to specify the path to
473 the syslinux install (defaults to /boot/extlinux). But you have to specify
474 SYSLINUX_LABEL to define the label to boot to for the test kernel.
477 $config_help{"GRUB_MENU"} = << "EOF"
478 The grub title name for the test kernel to boot
479 (Only mandatory if REBOOT_TYPE = grub or grub2)
481 Note, ktest.pl will not update the grub menu.lst, you need to
482 manually add an option for the test. ktest.pl will search
483 the grub menu.lst for this option to find what kernel to
486 For example, if in the /boot/grub/menu.lst the test kernel title has:
489 GRUB_MENU = Test Kernel
491 For grub2, a search of \$GRUB_FILE is performed for the lines
492 that begin with "menuentry". It will not detect submenus. The
493 menu must be a non-nested menu. Add the quotes used in the menu
494 to guarantee your selection, as the first menuentry with the content
495 of \$GRUB_MENU that is found will be used.
497 For grub2bls, \$GRUB_MENU is searched on the result of \$GRUB_BLS_GET
498 command for the lines that begin with "title".
501 $config_help{"GRUB_FILE"} = << "EOF"
502 If grub2 is used, the full path for the grub.cfg file is placed
503 here. Use something like /boot/grub2/grub.cfg to search.
506 $config_help{"SYSLINUX_LABEL"} = << "EOF"
507 If syslinux is used, the label that boots the target kernel must
508 be specified with SYSLINUX_LABEL.
511 $config_help{"REBOOT_SCRIPT"} = << "EOF"
512 A script to reboot the target into the test kernel
513 (Only mandatory if REBOOT_TYPE = script)
517 # used with process_expression()
520 # defined before get_test_name()
523 # defined before process_warning_line()
524 my $check_build_re = ".*:.*(warning|error|Error):.*";
525 my $utf8_quote = "\\x{e2}\\x{80}(\\x{98}|\\x{99})";
527 # defined before child_finished()
530 # config_ignore holds the configs that were set (or unset) for
531 # a good config and we will ignore these configs for the rest
532 # of a config bisect. These configs stay as they were.
535 # config_set holds what all configs were set as.
538 # config_off holds the set of configs that the bad config had disabled.
539 # We need to record them and set them in the .config when running
540 # olddefconfig, because olddefconfig keeps the defaults.
543 # config_off_tmp holds a set of configs to turn off for now
546 # config_list is the set of configs that are being tested
552 # found above run_config_bisect()
555 # found above add_dep()
565 # found above test_this_config()
569 my %processed_configs;
573 # These are first defined here, main function later on
578 sub wait_for_monitor;
581 if (defined($opt{"LOG_FILE"})) {
587 if (defined($opt{"LOG_FILE"})) {
600 my ($cancel, $prompt) = @_;
606 print "$prompt [y/n/C] ";
608 print "$prompt [Y/n] ";
612 if ($ans =~ /^\s*$/) {
619 last if ($ans =~ /^y$/i || $ans =~ /^n$/i);
621 last if ($ans =~ /^c$/i);
622 print "Please answer either 'y', 'n' or 'c'.\n";
624 print "Please answer either 'y' or 'n'.\n";
630 if ($ans !~ /^y$/i) {
639 return read_prompt 0, $prompt;
645 return read_prompt 1, $prompt;
648 sub get_mandatory_config {
652 return if (defined($opt{$config}));
654 if (defined($config_help{$config})) {
656 print $config_help{$config};
661 if (defined($default{$config}) && length($default{$config})) {
662 print "\[$default{$config}\] ";
665 $ans =~ s/^\s*(.*\S)\s*$/$1/;
666 if ($ans =~ /^\s*$/) {
667 if ($default{$config}) {
668 $ans = $default{$config};
670 print "Your answer can not be blank\n";
674 $entered_configs{$config} = ${ans};
686 $hours = int($time / 3600);
687 $time -= $hours * 3600;
690 $minutes = int($time / 60);
691 $time -= $minutes * 60;
695 doprint "$hours hour";
696 doprint "s" if ($hours > 1);
701 doprint "$minutes minute";
702 doprint "s" if ($minutes > 1);
706 doprint "$time second";
707 doprint "s" if ($time != 1);
713 doprint "Build time: ";
714 show_time($build_time);
718 doprint "Install time: ";
719 show_time($install_time);
723 doprint "Reboot time: ";
724 show_time($reboot_time);
728 doprint "Test time: ";
729 show_time($test_time);
732 # reset for iterations like bisect
739 sub get_mandatory_configs {
740 get_mandatory_config("MACHINE");
741 get_mandatory_config("BUILD_DIR");
742 get_mandatory_config("OUTPUT_DIR");
745 get_mandatory_config("BUILD_OPTIONS");
748 # options required for other than just building a kernel
750 get_mandatory_config("POWER_CYCLE");
751 get_mandatory_config("CONSOLE");
754 # options required for install and more
755 if ($buildonly != 1) {
756 get_mandatory_config("SSH_USER");
757 get_mandatory_config("BUILD_TARGET");
758 get_mandatory_config("TARGET_IMAGE");
761 get_mandatory_config("LOCALVERSION");
763 return if ($buildonly);
765 my $rtype = $opt{"REBOOT_TYPE"};
767 if (!defined($rtype)) {
768 if (!defined($opt{"GRUB_MENU"})) {
769 get_mandatory_config("REBOOT_TYPE");
770 $rtype = $entered_configs{"REBOOT_TYPE"};
776 if (($rtype eq "grub") or ($rtype eq "grub2bls")) {
777 get_mandatory_config("GRUB_MENU");
780 if ($rtype eq "grub2") {
781 get_mandatory_config("GRUB_MENU");
782 get_mandatory_config("GRUB_FILE");
785 if ($rtype eq "syslinux") {
786 get_mandatory_config("SYSLINUX_LABEL");
790 sub process_variables {
791 my ($value, $remove_undef) = @_;
794 # We want to check for '\', and it is just easier
795 # to check the previous characet of '$' and not need
796 # to worry if '$' is the first character. By adding
797 # a space to $value, we can just check [^\\]\$ and
798 # it will still work.
801 while ($value =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) {
805 # append beginning of value to retval
806 $retval = "$retval$begin";
807 if (defined($variable{$var})) {
808 $retval = "$retval$variable{$var}";
809 } elsif (defined($remove_undef) && $remove_undef) {
810 # for if statements, any variable that is not defined,
811 # we simple convert to 0
812 $retval = "${retval}0";
814 # put back the origin piece.
815 $retval = "$retval\$\{$var\}";
816 # This could be an option that is used later, save
817 # it so we don't warn if this option is not one of
819 $used_options{$var} = 1;
823 $retval = "$retval$value";
825 # remove the space added in the beginning
832 my ($lvalue, $rvalue, $override, $overrides, $name) = @_;
834 my $prvalue = process_variables($rvalue);
836 if ($lvalue =~ /^(TEST|BISECT|CONFIG_BISECT)_TYPE(\[.*\])?$/ &&
837 $prvalue !~ /^(config_|)bisect$/ &&
838 $prvalue !~ /^build$/ &&
841 # Note if a test is something other than build, then we
842 # will need other mandatory options.
843 if ($prvalue ne "install") {
846 # install still limits some mandatory options.
851 if (defined($opt{$lvalue})) {
852 if (!$override || defined(${$overrides}{$lvalue})) {
855 $extra = "In the same override section!\n";
857 die "$name: $.: Option $lvalue defined more than once!\n$extra";
859 ${$overrides}{$lvalue} = $prvalue;
862 $opt{$lvalue} = $prvalue;
866 my ($lvalue, $rvalue, $name) = @_;
868 my $prvalue = process_variables($rvalue);
871 if (defined($evals{$lvalue})) {
872 $arr = $evals{$lvalue};
875 $evals{$lvalue} = $arr;
878 push @{$arr}, $rvalue;
882 my ($lvalue, $rvalue) = @_;
884 if ($rvalue =~ /^\s*$/) {
885 delete $variable{$lvalue};
887 $rvalue = process_variables($rvalue);
888 $variable{$lvalue} = $rvalue;
892 sub process_compare {
893 my ($lval, $cmp, $rval) = @_;
904 return $lval eq $rval;
905 } elsif ($cmp eq "!=") {
906 return $lval ne $rval;
907 } elsif ($cmp eq "=~") {
908 return $lval =~ m/$rval/;
909 } elsif ($cmp eq "!~") {
910 return $lval !~ m/$rval/;
913 my $statement = "$lval $cmp $rval";
914 my $ret = eval $statement;
916 # $@ stores error of eval
927 return defined($variable{$2}) ||
931 sub process_expression {
932 my ($name, $val) = @_;
936 while ($val =~ s/\(([^\(]*?)\)/\&\&\&\&VAL\&\&\&\&/) {
939 if (process_expression($name, $express)) {
940 $val =~ s/\&\&\&\&VAL\&\&\&\&/ 1 /;
942 $val =~ s/\&\&\&\&VAL\&\&\&\&/ 0 /;
950 while ($val =~ s/^(.*?)($OR|$AND)//) {
954 if (process_expression($name, $express)) {
965 if ($val =~ /(.*)(==|\!=|>=|<=|>|<|=~|\!~)(.*)/) {
966 my $ret = process_compare($1, $2, $3);
968 die "$name: $.: Unable to process comparison\n";
973 if ($val =~ /^\s*(NOT\s*)?DEFINED\s+(\S+)\s*$/) {
975 return !value_defined($2);
977 return value_defined($2);
981 if ($val =~ s/^\s*NOT\s+(.*)//) {
983 my $ret = process_expression($name, $express);
987 if ($val =~ /^\s*0\s*$/) {
989 } elsif ($val =~ /^\s*\d+\s*$/) {
993 die ("$name: $.: Undefined content $val in if statement\n");
997 my ($name, $value) = @_;
999 # Convert variables and replace undefined ones with 0
1000 my $val = process_variables($value, 1);
1001 my $ret = process_expression $name, $val;
1007 my ($config, $current_test_num) = @_;
1010 open($in, $config) || die "can't read file $config";
1013 $name =~ s,.*/(.*),$1,;
1015 my $test_num = $$current_test_num;
1018 my $num_tests_set = 0;
1031 # ignore blank lines and comments
1032 next if (/^\s*$/ || /\s*\#/);
1034 if (/^\s*(TEST_START|DEFAULTS)\b(.*)/) {
1044 if ($type eq "TEST_START") {
1045 if ($num_tests_set) {
1046 die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
1049 $old_test_num = $test_num;
1050 $old_repeat = $repeat;
1052 $test_num += $repeat;
1059 # If SKIP is anywhere in the line, the command will be skipped
1060 if ($rest =~ s/\s+SKIP\b//) {
1067 if ($rest =~ s/\sELSE\b//) {
1069 die "$name: $.: ELSE found with out matching IF section\n$_";
1080 if ($rest =~ s/\sIF\s+(.*)//) {
1081 if (process_if($name, $1)) {
1093 if ($type eq "TEST_START") {
1094 if ($rest =~ s/\s+ITERATE\s+(\d+)//) {
1096 $repeat_tests{"$test_num"} = $repeat;
1098 } elsif ($rest =~ s/\sOVERRIDE\b//) {
1101 # Clear previous overrides
1106 if (!$skip && $rest !~ /^\s*$/) {
1107 die "$name: $.: Garbage found after $type\n$_";
1110 if ($skip && $type eq "TEST_START") {
1111 $test_num = $old_test_num;
1112 $repeat = $old_repeat;
1114 } elsif (/^\s*ELSE\b(.*)$/) {
1116 die "$name: $.: ELSE found with out matching IF section\n$_";
1125 if ($rest =~ /\sIF\s+(.*)/) {
1126 # May be a ELSE IF section.
1127 if (process_if($name, $1)) {
1138 if ($rest !~ /^\s*$/) {
1139 die "$name: $.: Garbage found after DEFAULTS\n$_";
1142 } elsif (/^\s*INCLUDE\s+(\S+)/) {
1147 die "$name: $.: INCLUDE can only be done in default sections\n$_";
1150 my $file = process_variables($1);
1152 if ($file !~ m,^/,) {
1153 # check the path of the config file first
1154 if ($config =~ m,(.*)/,) {
1155 if (-f "$1/$file") {
1162 die "$name: $.: Can't read file $file\n$_";
1165 if (__read_config($file, \$test_num)) {
1169 } elsif (/^\s*([A-Z_\[\]\d]+)\s*=~\s*(.*?)\s*$/) {
1176 if ($default || $lvalue =~ /\[\d+\]$/) {
1177 set_eval($lvalue, $rvalue, $name);
1179 my $val = "$lvalue\[$test_num\]";
1180 set_eval($val, $rvalue, $name);
1183 } elsif (/^\s*([A-Z_\[\]\d]+)\s*=\s*(.*?)\s*$/) {
1191 ($lvalue eq "NUM_TESTS" ||
1192 $lvalue eq "LOG_FILE" ||
1193 $lvalue eq "CLEAR_LOG")) {
1194 die "$name: $.: $lvalue must be set in DEFAULTS section\n";
1197 if ($lvalue eq "NUM_TESTS") {
1199 die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
1202 die "$name: $.: NUM_TESTS must be set in default section\n";
1207 if ($default || $lvalue =~ /\[\d+\]$/) {
1208 set_value($lvalue, $rvalue, $override, \%overrides, $name);
1210 my $val = "$lvalue\[$test_num\]";
1211 set_value($val, $rvalue, $override, \%overrides, $name);
1214 $repeats{$val} = $repeat;
1217 } elsif (/^\s*([A-Z_\[\]\d]+)\s*:=\s*(.*?)\s*$/) {
1223 # process config variables.
1224 # Config variables are only active while reading the
1225 # config and can be defined anywhere. They also ignore
1226 # TEST_START and DEFAULTS, but are skipped if they are in
1227 # on of these sections that have SKIP defined.
1228 # The save variable can be
1229 # defined multiple times and the new one simply overrides
1231 set_variable($lvalue, $rvalue);
1234 die "$name: $.: Garbage found in config\n$_";
1239 $test_num += $repeat - 1;
1240 $opt{"NUM_TESTS"} = $test_num;
1245 $$current_test_num = $test_num;
1251 print "What test case would you like to run?\n";
1252 print " (build, install or boot)\n";
1253 print " Other tests are available but require editing ktest.conf\n";
1254 print " (see tools/testing/ktest/sample.conf)\n";
1257 $default{"TEST_TYPE"} = $ans;
1266 $test_case = __read_config $config, \$test_num;
1268 # make sure we have all mandatory configs
1269 get_mandatory_configs;
1271 # was a test specified?
1273 print "No test case specified.\n";
1279 foreach my $default (keys %default) {
1280 if (!defined($opt{$default})) {
1281 $opt{$default} = $default{$default};
1285 if ($opt{"IGNORE_UNUSED"} == 1) {
1291 # check if there are any stragglers (typos?)
1292 foreach my $option (keys %opt) {
1294 # remove per test labels.
1296 if (!exists($option_map{$op}) &&
1297 !exists($default{$op}) &&
1298 !exists($used_options{$op})) {
1305 $s = " is" if (keys %not_used == 1);
1306 print "The following option$s not used; could be a typo:\n";
1307 foreach my $option (keys %not_used) {
1310 print "Set IGNORE_UNUSED = 1 to have ktest ignore unused variables\n";
1311 if (!read_yn "Do you want to continue?") {
1318 my ($name, $option, $i) = @_;
1320 # Add space to evaluate the character before $
1321 $option = " $option";
1326 foreach my $test (keys %repeat_tests) {
1328 $i < $test + $repeat_tests{$test}) {
1336 while ($option =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) {
1341 # Append beginning of line
1342 $retval = "$retval$start";
1344 # If the iteration option OPT[$i] exists, then use that.
1345 # otherwise see if the default OPT (without [$i]) exists.
1347 my $o = "$var\[$i\]";
1348 my $parento = "$var\[$parent\]";
1350 # If a variable contains itself, use the default var
1351 if (($var eq $name) && defined($opt{$var})) {
1353 $retval = "$retval$o";
1354 } elsif (defined($opt{$o})) {
1356 $retval = "$retval$o";
1357 } elsif ($repeated && defined($opt{$parento})) {
1358 $o = $opt{$parento};
1359 $retval = "$retval$o";
1360 } elsif (defined($opt{$var})) {
1362 $retval = "$retval$o";
1363 } elsif ($var eq "KERNEL_VERSION" && defined($make)) {
1364 # special option KERNEL_VERSION uses kernel version
1366 $retval = "$retval$version";
1368 $retval = "$retval\$\{$var\}";
1374 $retval = "$retval$option";
1382 my ($name, $option, $i) = @_;
1384 my $option_name = "$name\[$i\]";
1387 my $old_option = $option;
1389 if (defined($evals{$option_name})) {
1390 $ev = $evals{$option_name};
1391 } elsif (defined($evals{$name})) {
1392 $ev = $evals{$name};
1397 for my $e (@{$ev}) {
1398 eval "\$option =~ $e";
1401 if ($option ne $old_option) {
1402 doprint("$name changed from '$old_option' to '$option'\n");
1409 my ($name, $option, $i) = @_;
1413 # Since an option can evaluate to another option,
1414 # keep iterating until we do not evaluate any more
1417 while ($prev ne $option) {
1418 # Check for recursive evaluations.
1419 # 100 deep should be more than enough.
1421 die "Over 100 evaluations occurred with $option\n" .
1422 "Check for recursive variables\n";
1425 $option = __eval_option($name, $option, $i);
1428 $option = process_evals($name, $option, $i);
1437 # test if the machine can be connected to within a few seconds
1438 my $stat = run_ssh("echo check machine status", $connect_timeout);
1440 doprint("power cycle\n");
1445 run_command "$power_cycle";
1448 # flush out current monitor
1449 # May contain the reboot success line
1453 # Make sure everything has been written to disk
1454 run_ssh("sync", 10);
1456 if (defined($time)) {
1458 # flush out current monitor
1459 # May contain the reboot success line
1463 # try to reboot normally
1464 if (run_command $reboot) {
1465 if (defined($powercycle_after_reboot)) {
1466 sleep $powercycle_after_reboot;
1467 run_command "$power_cycle";
1470 # nope? power cycle it.
1471 run_command "$power_cycle";
1475 if (defined($time)) {
1477 # We only want to get to the new kernel, don't fail
1478 # if we stumble over a call trace.
1479 my $save_ignore_errors = $ignore_errors;
1482 # Look for the good kernel to boot
1483 if (wait_for_monitor($time, "Linux version")) {
1485 doprint "Reboot did not finish. Forcing power cycle\n";
1486 run_command "$power_cycle";
1489 $ignore_errors = $save_ignore_errors;
1491 # Still need to wait for the reboot to finish
1492 wait_for_monitor($time, $reboot_success_line);
1494 if ($powercycle || $time) {
1499 sub reboot_to_good {
1502 if (defined($switch_to_good)) {
1503 run_command $switch_to_good;
1512 return $test_type eq "build" || $no_reboot ||
1513 ($test_type eq "patchcheck" && $opt{"PATCHCHECK_TYPE[$i]"} eq "build") ||
1514 ($test_type eq "bisect" && $opt{"BISECT_TYPE[$i]"} eq "build") ||
1515 ($test_type eq "config_bisect" && $opt{"CONFIG_BISECT_TYPE[$i]"} eq "build");
1518 sub get_test_name() {
1521 if (defined($test_name)) {
1522 $name = "$test_name:$test_type";
1531 return if ($in_die);
1536 doprint "CRITICAL FAILURE... [TEST $i] ", @_, "\n";
1538 if ($reboot_on_error && !do_not_reboot) {
1539 doprint "REBOOTING\n";
1541 } elsif ($poweroff_on_error && defined($power_off)) {
1542 doprint "POWERING OFF\n";
1546 if (defined($opt{"LOG_FILE"})) {
1547 print " See $opt{LOG_FILE} for more info.\n";
1550 if ($email_on_error) {
1551 my $name = get_test_name;
1554 if (defined($opt{"LOG_FILE"})) {
1555 my $whence = 2; # End of file
1556 my $log_size = tell LOG;
1557 my $size = $log_size - $test_log_start;
1559 if (defined($mail_max_size)) {
1560 if ($size > $mail_max_size) {
1561 $size = $mail_max_size;
1565 $log_file = "$tmpdir/log";
1566 open (L, "$opt{LOG_FILE}") or die "Can't open $opt{LOG_FILE} to read)";
1567 open (O, "> $tmpdir/log") or die "Can't open $tmpdir/log\n";
1568 seek(L, $pos, $whence);
1576 send_email("KTEST: critical failure for test $i [$name]",
1577 "Your test started at $script_start_time has failed with:\n@_\n", $log_file);
1581 # restore terminal settings
1582 system("stty $stty_orig");
1585 if (defined($post_test)) {
1586 run_command $post_test;
1593 my ($ptm, $pts) = @_;
1595 my $TIOCSPTLCK = 0x40045431;
1596 my $TIOCGPTN = 0x80045430;
1598 sysopen($ptm, "/dev/ptmx", O_RDWR | O_NONBLOCK) or
1599 dodie "Can't open /dev/ptmx";
1602 $tmp = pack("i", 0);
1603 ioctl($ptm, $TIOCSPTLCK, $tmp) or
1604 dodie "ioctl TIOCSPTLCK for /dev/ptmx failed";
1607 ioctl($ptm, $TIOCGPTN, $tmp) or
1608 dodie "ioctl TIOCGPTN for /dev/ptmx failed";
1609 $tmp = unpack("i", $tmp);
1611 sysopen($pts, "/dev/pts/$tmp", O_RDWR | O_NONBLOCK) or
1612 dodie "Can't open /dev/pts/$tmp";
1616 my ($ptm, $pts) = @_;
1624 open(\*STDIN, '<&', $pts);
1625 open(\*STDOUT, '>&', $pts);
1626 open(\*STDERR, '>&', $pts);
1631 dodie "Can't open console $console";
1639 # save terminal settings
1640 $stty_orig = `stty -g`;
1642 # place terminal in cbreak mode so that stdin can be read one character at
1643 # a time without having to wait for a newline
1644 system("stty -icanon -echo -icrnl");
1646 create_pty($ptm, $pts);
1652 exec_console($ptm, $pts)
1660 open(PTSFD, "Stop perl from warning about single use of PTSFD");
1664 my ($fp, $pid) = @_;
1666 doprint "kill child process $pid\n";
1667 kill $close_console_signal, $pid;
1669 doprint "wait for child process $pid to exit\n";
1675 # restore terminal settings
1676 system("stty $stty_orig");
1680 if ($monitor_cnt++) {
1683 $monitor_fp = \*MONFD;
1684 $monitor_pid = open_console $monitor_fp;
1688 open(MONFD, "Stop perl from warning about single use of MONFD");
1692 return if (!defined $console);
1693 if (--$monitor_cnt) {
1696 close_console($monitor_fp, $monitor_pid);
1699 sub wait_for_monitor {
1700 my ($time, $stop) = @_;
1704 my $start_time = time;
1705 my $skip_call_trace = 0;
1707 my $bug_ignored = 0;
1710 doprint "** Wait for monitor to settle down **\n";
1712 # read the monitor and wait for the system to calm down
1714 $line = wait_for_input($monitor_fp, $time);
1715 last if (!defined($line));
1717 $full_line .= $line;
1719 if (defined($stop) && $full_line =~ /$stop/) {
1720 doprint "wait for monitor detected $stop\n";
1724 if ($full_line =~ /\[ backtrace testing \]/) {
1725 $skip_call_trace = 1;
1728 if ($full_line =~ /call trace:/i) {
1729 if (!$bug && !$skip_call_trace) {
1730 if ($ignore_errors) {
1738 if ($full_line =~ /\[ end of backtrace testing \]/) {
1739 $skip_call_trace = 0;
1742 if ($full_line =~ /Kernel panic -/) {
1746 if ($line =~ /\n/) {
1750 if ($now - $start_time >= $max_monitor_wait) {
1751 doprint "Exiting monitor flush due to hitting MAX_MONITOR_WAIT\n";
1755 print "** Monitor flushed **\n";
1757 # if stop is defined but wasn't hit, return error
1758 # used by reboot (which wants to see a reboot)
1759 if (defined($stop) && !$booted) {
1766 my ($result, $basedir) = @_;
1768 my $date = sprintf "%04d%02d%02d%02d%02d%02d",
1769 1900+$t[5],$t[4],$t[3],$t[2],$t[1],$t[0];
1771 my $type = $build_type;
1772 if ($type =~ /useconfig/) {
1773 $type = "useconfig";
1776 my $dir = "$machine-$test_type-$type-$result-$date";
1778 $dir = "$basedir/$dir";
1782 dodie "can't create $dir";
1786 "config" => $output_config,
1787 "buildlog" => $buildlog,
1789 "testlog" => $testlog,
1792 while (my ($name, $source) = each(%files)) {
1794 cp "$source", "$dir/$name" or
1795 dodie "failed to copy $source";
1799 doprint "*** Saved info to $dir ***\n";
1804 if ($die_on_failure) {
1812 # no need to reboot for just building.
1813 if (!do_not_reboot) {
1814 doprint "REBOOTING\n";
1815 reboot_to_good $sleep_time;
1820 if (defined($test_name)) {
1821 $name = " ($test_name)";
1826 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
1827 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
1828 doprint "KTEST RESULT: TEST $i$name Failed: ", @_, "\n";
1829 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
1830 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
1832 if (defined($store_failures)) {
1833 save_logs "fail", $store_failures;
1836 if (defined($post_test)) {
1837 run_command $post_test;
1844 my ($command, $redirect, $timeout) = @_;
1851 my $command_orig = $command;
1853 $command =~ s/\$SSH_USER/$ssh_user/g;
1854 $command =~ s/\$MACHINE/$machine/g;
1856 if (!defined($timeout)) {
1857 $timeout = $run_timeout;
1860 if (!defined($timeout)) {
1861 $timeout = -1; # tell wait_for_input to wait indefinitely
1864 doprint("$command ... ");
1867 $pid = open(CMD, "$command 2>&1 |") or
1868 (fail "unable to exec $command" and return 0);
1870 if (defined($opt{"LOG_FILE"})) {
1874 if (defined($redirect)) {
1875 if ($redirect eq 1) {
1877 # Have the output of the command on its own line
1880 open (RD, ">$redirect") or
1881 dodie "failed to write to redirect $redirect";
1886 my $hit_timeout = 0;
1890 my $line = wait_for_input($fp, $timeout);
1891 if (!defined($line)) {
1893 if ($timeout >= 0 && (($now - $start_time) >= $timeout)) {
1894 doprint "Hit timeout of $timeout, killing process\n";
1900 print LOG $line if ($dolog);
1901 print RD $line if ($dord);
1902 print $line if ($dostdout);
1906 # shift 8 for real exit status
1907 $run_command_status = $? >> 8;
1909 if ($command_orig eq $default{REBOOT} &&
1910 $run_command_status == $reboot_return_code) {
1911 $run_command_status = 0;
1915 close(RD) if ($dord);
1918 my $delta = $end_time - $start_time;
1921 doprint "[1 second] ";
1923 doprint "[$delta seconds] ";
1927 $run_command_status = 1;
1930 if ($run_command_status) {
1931 doprint "FAILED!\n";
1933 doprint "SUCCESS\n";
1936 return !$run_command_status;
1940 my ($cmd, $timeout) = @_;
1941 my $cp_exec = $ssh_exec;
1943 $cp_exec =~ s/\$SSH_COMMAND/$cmd/g;
1944 return run_command "$cp_exec", undef , $timeout;
1948 my ($src, $dst, $cp_scp) = @_;
1950 $cp_scp =~ s/\$SRC_FILE/$src/g;
1951 $cp_scp =~ s/\$DST_FILE/$dst/g;
1953 return run_command "$cp_scp";
1956 sub run_scp_install {
1957 my ($src, $dst) = @_;
1959 my $cp_scp = $scp_to_target_install;
1961 return run_scp($src, $dst, $cp_scp);
1965 my ($src, $dst) = @_;
1967 my $cp_scp = $scp_to_target;
1969 return run_scp($src, $dst, $cp_scp);
1972 sub _get_grub_index {
1974 my ($command, $target, $skip, $submenu) = @_;
1976 return if (defined($grub_number) && defined($last_grub_menu) &&
1977 $last_grub_menu eq $grub_menu && defined($last_machine) &&
1978 $last_machine eq $machine);
1980 doprint "Find $reboot_type menu ... ";
1983 my $ssh_grub = $ssh_exec;
1984 $ssh_grub =~ s,\$SSH_COMMAND,$command,g;
1986 open(IN, "$ssh_grub |") or
1987 dodie "unable to execute $command";
1991 my $submenu_number = 0;
1998 } elsif (defined($submenu) && /$submenu/) {
2007 dodie "Could not find '$grub_menu' through $command on $machine"
2009 if ($submenu_number > 0) {
2010 $grub_number = "$submenu_number>$grub_number";
2012 doprint "$grub_number\n";
2013 $last_grub_menu = $grub_menu;
2014 $last_machine = $machine;
2017 sub get_grub_index {
2025 if ($reboot_type !~ /^grub/) {
2029 $grub_menu_qt = quotemeta($grub_menu);
2031 if ($reboot_type eq "grub") {
2032 $command = "cat /boot/grub/menu.lst";
2033 $target = '^\s*title\s+' . $grub_menu_qt . '\s*$';
2034 $skip = '^\s*title\s';
2035 } elsif ($reboot_type eq "grub2") {
2036 $command = "cat $grub_file";
2037 $target = '^\s*menuentry.*' . $grub_menu_qt;
2038 $skip = '^\s*menuentry';
2039 $submenu = '^\s*submenu\s';
2040 } elsif ($reboot_type eq "grub2bls") {
2041 $command = $grub_bls_get;
2042 $target = '^title=.*' . $grub_menu_qt;
2048 _get_grub_index($command, $target, $skip, $submenu);
2051 sub wait_for_input {
2052 my ($fp, $time) = @_;
2061 if (!defined($time)) {
2066 # Negative number means wait indefinitely
2071 vec($rin, fileno($fp), 1) = 1;
2072 vec($rin, fileno(\*STDIN), 1) = 1;
2077 $nr = select($rout=$rin, undef, undef, $time);
2081 # copy data from stdin to the console
2082 if (vec($rout, fileno(\*STDIN), 1) == 1) {
2083 $nr = sysread(\*STDIN, $buf, 1000);
2084 syswrite($fp, $buf, $nr) if ($nr > 0);
2087 # The timeout is based on time waiting for the fp data
2088 if (vec($rout, fileno($fp), 1) != 1) {
2089 last if (defined($time) && (time - $start_time > $time));
2095 # try to read one char at a time
2096 while (sysread $fp, $ch, 1) {
2098 last if ($ch eq "\n");
2101 last if (!length($line));
2109 if (defined($switch_to_test)) {
2110 run_command $switch_to_test;
2113 if ($reboot_type eq "grub") {
2114 run_ssh "'(echo \"savedefault --default=$grub_number --once\" | grub --batch)'";
2115 } elsif (($reboot_type eq "grub2") or ($reboot_type eq "grub2bls")) {
2116 run_ssh "$grub_reboot \"'$grub_number'\"";
2117 } elsif ($reboot_type eq "syslinux") {
2118 run_ssh "$syslinux --once \\\"$syslinux_label\\\" $syslinux_path";
2119 } elsif (defined $reboot_script) {
2120 run_command "$reboot_script";
2128 doprint "git rev-list --max-count=1 $commit ... ";
2129 my $sha1 = `git rev-list --max-count=1 $commit`;
2136 dodie "Failed to get git $commit";
2149 my $bug_ignored = 0;
2150 my $skip_call_trace = 0;
2153 my $start_time = time;
2160 open(DMESG, "> $dmesg") or
2161 dodie "unable to write to $dmesg";
2167 my $monitor_start = time;
2169 my $version_found = 0;
2172 if ($bug && defined($stop_after_failure) &&
2173 $stop_after_failure >= 0) {
2174 my $time = $stop_after_failure - (time - $failure_start);
2175 $line = wait_for_input($monitor_fp, $time);
2176 if (!defined($line)) {
2177 doprint "bug timed out after $booted_timeout seconds\n";
2178 doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
2182 $line = wait_for_input($monitor_fp, $booted_timeout);
2183 if (!defined($line)) {
2184 my $s = $booted_timeout == 1 ? "" : "s";
2185 doprint "Successful boot found: break after $booted_timeout second$s\n";
2189 $line = wait_for_input($monitor_fp);
2190 if (!defined($line)) {
2191 my $s = $timeout == 1 ? "" : "s";
2192 doprint "Timed out after $timeout second$s\n";
2200 # we are not guaranteed to get a full line
2201 $full_line .= $line;
2203 if ($full_line =~ /$success_line/) {
2205 $success_start = time;
2208 if ($booted && defined($stop_after_success) &&
2209 $stop_after_success >= 0) {
2211 if ($now - $success_start >= $stop_after_success) {
2212 doprint "Test forced to stop after $stop_after_success seconds after success\n";
2217 if ($full_line =~ /\[ backtrace testing \]/) {
2218 $skip_call_trace = 1;
2221 if ($full_line =~ /call trace:/i) {
2222 if (!$bug && !$skip_call_trace) {
2223 if ($ignore_errors) {
2227 $failure_start = time;
2232 if ($bug && defined($stop_after_failure) &&
2233 $stop_after_failure >= 0) {
2235 if ($now - $failure_start >= $stop_after_failure) {
2236 doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
2241 if ($full_line =~ /\[ end of backtrace testing \]/) {
2242 $skip_call_trace = 0;
2245 if ($full_line =~ /Kernel panic -/) {
2246 $failure_start = time;
2250 # Detect triple faults by testing the banner
2251 if ($full_line =~ /\bLinux version (\S+).*\n/) {
2252 if ($1 eq $version) {
2254 } elsif ($version_found && $detect_triplefault) {
2255 # We already booted into the kernel we are testing,
2256 # but now we booted into another kernel?
2257 # Consider this a triple fault.
2258 doprint "Already booted in Linux kernel $version, but now\n";
2259 doprint "we booted into Linux kernel $1.\n";
2260 doprint "Assuming that this is a triple fault.\n";
2261 doprint "To disable this: set DETECT_TRIPLE_FAULT to 0\n";
2266 if ($line =~ /\n/) {
2270 if ($stop_test_after > 0 && !$booted && !$bug) {
2271 if (time - $monitor_start > $stop_test_after) {
2272 doprint "STOP_TEST_AFTER ($stop_test_after seconds) timed out\n";
2278 my $end_time = time;
2279 $reboot_time = $end_time - $start_time;
2284 return 0 if ($in_bisect);
2285 fail "failed - got a bug report" and return 0;
2289 return 0 if ($in_bisect);
2290 fail "failed - never got a boot prompt." and return 0;
2294 doprint "WARNING: Call Trace detected but ignored due to IGNORE_ERRORS=1\n";
2300 sub eval_kernel_version {
2303 $option =~ s/\$KERNEL_VERSION/$version/g;
2308 sub do_post_install {
2310 return if (!defined($post_install));
2312 my $cp_post_install = eval_kernel_version $post_install;
2313 run_command "$cp_post_install" or
2314 dodie "Failed to run post install";
2317 # Sometimes the reboot fails, and will hang. We try to ssh to the box
2318 # and if we fail, we force another reboot, that should powercycle it.
2320 if (!run_ssh "echo testing connection") {
2327 return if ($no_install);
2329 my $start_time = time;
2331 if (defined($pre_install)) {
2332 my $cp_pre_install = eval_kernel_version $pre_install;
2333 run_command "$cp_pre_install" or
2334 dodie "Failed to run pre install";
2337 my $cp_target = eval_kernel_version $target_image;
2341 run_scp_install "$outputdir/$build_target", "$cp_target" or
2342 dodie "failed to copy image";
2344 my $install_mods = 0;
2346 # should we process modules?
2348 open(IN, "$output_config") or dodie("Can't read config file");
2350 if (/CONFIG_MODULES(=y)?/) {
2359 if (!$install_mods) {
2361 doprint "No modules needed\n";
2362 my $end_time = time;
2363 $install_time = $end_time - $start_time;
2367 run_command "$make INSTALL_MOD_STRIP=1 INSTALL_MOD_PATH=$tmpdir modules_install" or
2368 dodie "Failed to install modules";
2370 my $modlib = "/lib/modules/$version";
2371 my $modtar = "ktest-mods.tar.bz2";
2373 run_ssh "rm -rf $modlib" or
2374 dodie "failed to remove old mods: $modlib";
2376 # would be nice if scp -r did not follow symbolic links
2377 run_command "cd $tmpdir && tar -cjf $modtar lib/modules/$version" or
2378 dodie "making tarball";
2380 run_scp_mod "$tmpdir/$modtar", "/tmp" or
2381 dodie "failed to copy modules";
2383 unlink "$tmpdir/$modtar";
2385 run_ssh "'(cd / && tar xjf /tmp/$modtar)'" or
2386 dodie "failed to tar modules";
2388 run_ssh "rm -f /tmp/$modtar";
2392 my $end_time = time;
2393 $install_time = $end_time - $start_time;
2397 # get the release name
2398 return if ($have_version);
2399 doprint "$make kernelrelease ... ";
2400 $version = `$make -s kernelrelease | tail -1`;
2402 doprint "$version\n";
2406 sub start_monitor_and_install {
2407 # Make sure the stable kernel has finished booting
2409 # Install bisects, don't need console
2410 if (defined $console) {
2420 start_monitor if (defined $console);
2424 sub process_warning_line {
2429 # for distcc heterogeneous systems, some compilers
2430 # do things differently causing warning lines
2431 # to be slightly different. This makes an attempt
2432 # to fixe those issues.
2434 # chop off the index into the line
2435 # using distcc, some compilers give different indexes
2436 # depending on white space
2437 $line =~ s/^(\s*\S+:\d+:)\d+/$1/;
2439 # Some compilers use UTF-8 extended for quotes and some don't.
2440 $line =~ s/$utf8_quote/'/g;
2445 # Read buildlog and check against warnings file for any
2450 sub check_buildlog {
2451 return 1 if (!defined $warnings_file);
2455 # Failed builds should not reboot the target
2456 my $save_no_reboot = $no_reboot;
2459 if (-f $warnings_file) {
2460 open(IN, $warnings_file) or
2461 dodie "Error opening $warnings_file";
2464 if (/$check_build_re/) {
2465 my $warning = process_warning_line $_;
2467 $warnings_list{$warning} = 1;
2473 # If warnings file didn't exist, and WARNINGS_FILE exist,
2474 # then we fail on any warning!
2476 open(IN, $buildlog) or dodie "Can't open $buildlog";
2478 if (/$check_build_re/) {
2479 my $warning = process_warning_line $_;
2481 if (!defined $warnings_list{$warning}) {
2482 fail "New warning found (not in $warnings_file)\n$_\n";
2483 $no_reboot = $save_no_reboot;
2488 $no_reboot = $save_no_reboot;
2492 sub check_patch_buildlog {
2495 my @files = `git show $patch | diffstat -l`;
2497 foreach my $file (@files) {
2501 open(IN, "git show $patch |") or
2502 dodie "failed to show $patch";
2504 if (m,^--- a/(.*),) {
2506 $files[$#files] = $1;
2511 open(IN, $buildlog) or dodie "Can't open $buildlog";
2513 if (/^\s*(.*?):.*(warning|error)/) {
2515 foreach my $file (@files) {
2516 my $fullpath = "$builddir/$file";
2517 if ($file eq $err || $fullpath eq $err) {
2518 fail "$file built with warnings" and return 0;
2528 sub apply_min_config {
2529 my $outconfig = "$output_config.new";
2531 # Read the config file and remove anything that
2532 # is in the force_config hash (from minconfig and others)
2533 # then add the force config back.
2535 doprint "Applying minimum configurations into $output_config.new\n";
2537 open (OUT, ">$outconfig") or
2538 dodie "Can't create $outconfig";
2540 if (-f $output_config) {
2541 open (IN, $output_config) or
2542 dodie "Failed to open $output_config";
2544 if (/^(# )?(CONFIG_[^\s=]*)/) {
2545 next if (defined($force_config{$2}));
2551 foreach my $config (keys %force_config) {
2552 print OUT "$force_config{$config}\n";
2556 run_command "mv $outconfig $output_config";
2559 sub make_oldconfig {
2561 my @force_list = keys %force_config;
2563 if ($#force_list >= 0) {
2567 if (!run_command "$make olddefconfig") {
2568 # Perhaps olddefconfig doesn't exist in this version of the kernel
2570 doprint "olddefconfig failed, trying make oldnoconfig\n";
2571 if (!run_command "$make oldnoconfig") {
2572 doprint "oldnoconfig failed, trying yes '' | make oldconfig\n";
2573 # try a yes '' | oldconfig
2574 run_command "yes '' | $make oldconfig" or
2575 dodie "failed make config oldconfig";
2580 # read a config file and use this to force new configs.
2581 sub load_force_config {
2584 doprint "Loading force configs from $config\n";
2585 open(IN, $config) or
2586 dodie "failed to read $config";
2589 if (/^(CONFIG[^\s=]*)(\s*=.*)/) {
2590 $force_config{$1} = $_;
2591 } elsif (/^# (CONFIG_\S*) is not set/) {
2592 $force_config{$1} = $_;
2603 my $start_time = time;
2605 # Failed builds should not reboot the target
2606 my $save_no_reboot = $no_reboot;
2609 # Calculate a new version from here.
2612 if (defined($pre_build)) {
2613 my $ret = run_command $pre_build;
2614 if (!$ret && defined($pre_build_die) &&
2616 dodie "failed to pre_build\n";
2620 if ($type =~ /^useconfig:(.*)/) {
2621 run_command "cp $1 $output_config" or
2622 dodie "could not copy $1 to .config";
2624 $type = "oldconfig";
2627 # old config can ask questions
2628 if ($type eq "oldconfig") {
2629 $type = "olddefconfig";
2631 # allow for empty configs
2632 run_command "touch $output_config";
2635 run_command "mv $output_config $outputdir/config_temp" or
2636 dodie "moving .config";
2638 run_command "$make mrproper" or dodie "make mrproper";
2640 run_command "mv $outputdir/config_temp $output_config" or
2641 dodie "moving config_temp";
2643 } elsif (!$noclean) {
2644 unlink "$output_config";
2645 run_command "$make mrproper" or
2646 dodie "make mrproper";
2649 # add something to distinguish this build
2650 open(OUT, "> $outputdir/localversion") or dodie("Can't make localversion file");
2651 print OUT "$localversion\n";
2654 if (defined($minconfig)) {
2655 load_force_config($minconfig);
2658 if ($type ne "olddefconfig") {
2659 run_command "$make $type" or
2660 dodie "failed make config";
2662 # Run old config regardless, to enforce min configurations
2665 if (not defined($build_options)){
2666 $build_options = "";
2668 my $build_ret = run_command "$make $build_options", $buildlog;
2670 if (defined($post_build)) {
2671 # Because a post build may change the kernel version
2674 my $ret = run_command $post_build;
2675 if (!$ret && defined($post_build_die) &&
2677 dodie "failed to post_build\n";
2682 # bisect may need this to pass
2684 $no_reboot = $save_no_reboot;
2687 fail "failed build" and return 0;
2690 $no_reboot = $save_no_reboot;
2692 my $end_time = time;
2693 $build_time = $end_time - $start_time;
2699 if (!run_ssh "halt" or defined($power_off)) {
2700 if (defined($poweroff_after_halt)) {
2701 sleep $poweroff_after_halt;
2702 run_command "$power_off";
2706 run_command "$power_off";
2717 if (defined($test_name)) {
2718 $name = " ($test_name)";
2724 doprint "*******************************************\n";
2725 doprint "*******************************************\n";
2726 doprint "KTEST RESULT: TEST $i$name SUCCESS!!!! **\n";
2727 doprint "*******************************************\n";
2728 doprint "*******************************************\n";
2730 if (defined($store_successes)) {
2731 save_logs "success", $store_successes;
2734 if ($i != $opt{"NUM_TESTS"} && !do_not_reboot) {
2735 doprint "Reboot and wait $sleep_time seconds\n";
2736 reboot_to_good $sleep_time;
2739 if (defined($post_test)) {
2740 run_command $post_test;
2746 doprint "Pass, fail, or skip? [p/f/s]";
2749 if ($ans eq "p" || $ans eq "P") {
2751 } elsif ($ans eq "f" || $ans eq "F") {
2753 } elsif ($ans eq "s" || $ans eq "S") {
2756 print "Please answer 'p', 'f', or 's'\n";
2761 sub child_run_test {
2763 # child should have no power
2764 $reboot_on_error = 0;
2765 $poweroff_on_error = 0;
2766 $die_on_failure = 1;
2768 run_command $run_test, $testlog;
2770 exit $run_command_status;
2773 sub child_finished {
2783 my $bug_ignored = 0;
2785 my $start_time = time;
2789 doprint "run test $run_test\n";
2793 $SIG{CHLD} = qw(child_finished);
2797 child_run_test if (!$child_pid);
2802 $line = wait_for_input($monitor_fp, 1);
2803 if (defined($line)) {
2805 # we are not guaranteed to get a full line
2806 $full_line .= $line;
2809 if ($full_line =~ /call trace:/i) {
2810 if ($ignore_errors) {
2817 if ($full_line =~ /Kernel panic -/) {
2821 if ($line =~ /\n/) {
2825 } while (!$child_done && !$bug);
2827 if (!$bug && $bug_ignored) {
2828 doprint "WARNING: Call Trace detected but ignored due to IGNORE_ERRORS=1\n";
2832 my $failure_start = time;
2835 $line = wait_for_input($monitor_fp, 1);
2836 if (defined($line)) {
2840 if ($now - $failure_start >= $stop_after_failure) {
2843 } while (defined($line));
2845 doprint "Detected kernel crash!\n";
2846 # kill the child with extreme prejudice
2850 waitpid $child_pid, 0;
2851 $child_exit = $? >> 8;
2853 my $end_time = time;
2854 $test_time = $end_time - $start_time;
2856 if (!$bug && $in_bisect) {
2857 if (defined($bisect_ret_good)) {
2858 if ($child_exit == $bisect_ret_good) {
2862 if (defined($bisect_ret_skip)) {
2863 if ($child_exit == $bisect_ret_skip) {
2867 if (defined($bisect_ret_abort)) {
2868 if ($child_exit == $bisect_ret_abort) {
2869 fail "test abort" and return -2;
2872 if (defined($bisect_ret_bad)) {
2873 if ($child_exit == $bisect_ret_skip) {
2877 if (defined($bisect_ret_default)) {
2878 if ($bisect_ret_default eq "good") {
2880 } elsif ($bisect_ret_default eq "bad") {
2882 } elsif ($bisect_ret_default eq "skip") {
2884 } elsif ($bisect_ret_default eq "abort") {
2887 fail "unknown default action: $bisect_ret_default"
2893 if ($bug || $child_exit) {
2894 return 0 if $in_bisect;
2895 fail "test failed" and return 0;
2900 sub run_git_bisect {
2903 doprint "$command ... ";
2905 my $output = `$command 2>&1`;
2912 dodie "Failed to git bisect";
2915 doprint "SUCCESS\n";
2916 if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\))\s+\[([[:xdigit:]]+)\]/) {
2917 doprint "$1 [$2]\n";
2918 } elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) {
2919 $bisect_bad_commit = $1;
2920 doprint "Found bad commit... $1\n";
2923 # we already logged it, just print it now.
2931 doprint "Reboot and sleep $bisect_sleep_time seconds\n";
2932 reboot_to_good $bisect_sleep_time;
2935 # returns 1 on success, 0 on failure, -1 on skip
2936 sub run_bisect_test {
2937 my ($type, $buildtype) = @_;
2946 build $buildtype or $failed = 1;
2948 if ($type ne "build") {
2949 if ($failed && $bisect_skip) {
2953 dodie "Failed on build" if $failed;
2956 start_monitor_and_install or $failed = 1;
2958 if ($type ne "boot") {
2959 if ($failed && $bisect_skip) {
2965 dodie "Failed on boot" if $failed;
2967 do_run_test or $failed = 1;
2978 # reboot the box to a kernel we can ssh to
2979 if ($type ne "build") {
2989 my $buildtype = "oldconfig";
2991 # We should have a minconfig to use?
2992 if (defined($minconfig)) {
2993 $buildtype = "useconfig:$minconfig";
2996 # If the user sets bisect_tries to less than 1, then no tries
3000 # Still let the user manually decide that though.
3001 if ($bisect_tries < 1 && $bisect_manual) {
3002 $ret = answer_bisect;
3005 for (my $i = 0; $i < $bisect_tries; $i++) {
3006 if ($bisect_tries > 1) {
3008 doprint("Running bisect trial $t of $bisect_tries:\n");
3010 $ret = run_bisect_test $type, $buildtype;
3012 if ($bisect_manual) {
3013 $ret = answer_bisect;
3019 # Are we looking for where it worked, not failed?
3020 if ($reverse_bisect && $ret >= 0) {
3026 } elsif ($ret == 0) {
3028 } elsif ($bisect_skip) {
3029 doprint "HIT A BAD COMMIT ... SKIPPING\n";
3034 sub update_bisect_replay {
3035 my $tmp_log = "$tmpdir/ktest_bisect_log";
3036 run_command "git bisect log > $tmp_log" or
3037 dodie "can't create bisect log";
3046 dodie "BISECT_GOOD[$i] not defined\n" if (!defined($bisect_good));
3047 dodie "BISECT_BAD[$i] not defined\n" if (!defined($bisect_bad));
3048 dodie "BISECT_TYPE[$i] not defined\n" if (!defined($bisect_type));
3050 my $good = $bisect_good;
3051 my $bad = $bisect_bad;
3052 my $type = $bisect_type;
3053 my $start = $bisect_start;
3054 my $replay = $bisect_replay;
3055 my $start_files = $bisect_files;
3057 if (defined($start_files)) {
3058 $start_files = " -- " . $start_files;
3063 # convert to true sha1's
3064 $good = get_sha1($good);
3065 $bad = get_sha1($bad);
3067 if (defined($bisect_reverse) && $bisect_reverse == 1) {
3068 doprint "Performing a reverse bisect (bad is good, good is bad!)\n";
3069 $reverse_bisect = 1;
3071 $reverse_bisect = 0;
3074 # Can't have a test without having a test to run
3075 if ($type eq "test" && !defined($run_test)) {
3079 # Check if a bisect was running
3080 my $bisect_start_file = "$builddir/.git/BISECT_START";
3082 my $check = $bisect_check;
3083 my $do_check = defined($check) && $check ne "0";
3085 if ( -f $bisect_start_file ) {
3086 print "Bisect in progress found\n";
3088 print " If you say yes, then no checks of good or bad will be done\n";
3090 if (defined($replay)) {
3091 print "** BISECT_REPLAY is defined in config file **";
3092 print " Ignore config option and perform new git bisect log?\n";
3093 if (read_ync " (yes, no, or cancel) ") {
3094 $replay = update_bisect_replay;
3097 } elsif (read_yn "read git log and continue?") {
3098 $replay = update_bisect_replay;
3105 my $head = get_sha1("HEAD");
3107 if ($check ne "good") {
3108 doprint "TESTING BISECT BAD [$bad]\n";
3109 run_command "git checkout $bad" or
3110 dodie "Failed to checkout $bad";
3112 $result = run_bisect $type;
3114 if ($result ne "bad") {
3115 fail "Tested BISECT_BAD [$bad] and it succeeded" and return 0;
3119 if ($check ne "bad") {
3120 doprint "TESTING BISECT GOOD [$good]\n";
3121 run_command "git checkout $good" or
3122 dodie "Failed to checkout $good";
3124 $result = run_bisect $type;
3126 if ($result ne "good") {
3127 fail "Tested BISECT_GOOD [$good] and it failed" and return 0;
3131 # checkout where we started
3132 run_command "git checkout $head" or
3133 dodie "Failed to checkout $head";
3136 run_command "git bisect start$start_files" or
3137 dodie "could not start bisect";
3139 if (defined($replay)) {
3140 run_command "git bisect replay $replay" or
3141 dodie "failed to run replay";
3143 run_command "git bisect good $good" or
3144 dodie "could not set bisect good to $good";
3146 run_git_bisect "git bisect bad $bad" or
3147 dodie "could not set bisect bad to $bad";
3150 if (defined($start)) {
3151 run_command "git checkout $start" or
3152 dodie "failed to checkout $start";
3157 $result = run_bisect $type;
3158 $test = run_git_bisect "git bisect $result";
3162 run_command "git bisect log" or
3163 dodie "could not capture git bisect log";
3165 run_command "git bisect reset" or
3166 dodie "could not reset git bisect";
3168 doprint "Bad commit was [$bisect_bad_commit]\n";
3173 sub assign_configs {
3174 my ($hash, $config) = @_;
3176 doprint "Reading configs from $config\n";
3178 open (IN, $config) or
3179 dodie "Failed to read $config";
3183 if (/^((CONFIG\S*)=.*)/) {
3185 } elsif (/^(# (CONFIG\S*) is not set)/) {
3193 sub process_config_ignore {
3196 assign_configs \%config_ignore, $config;
3199 sub get_dependencies {
3202 my $arr = $dependency{$config};
3203 if (!defined($arr)) {
3209 foreach my $dep (@{$arr}) {
3210 print "ADD DEP $dep\n";
3211 @deps = (@deps, get_dependencies $dep);
3218 my ($pc, $file) = @_;
3220 my %configs = %{$pc};
3222 doprint "Saving configs into $file\n";
3224 open(OUT, ">$file") or dodie "Can not write to $file";
3226 foreach my $config (keys %configs) {
3227 print OUT "$configs{$config}\n";
3233 my ($name, $pc) = @_;
3235 doprint "Creating old config from $name configs\n";
3237 save_config $pc, $output_config;
3242 sub run_config_bisect_test {
3245 my $ret = run_bisect_test $type, "oldconfig";
3247 if ($bisect_manual) {
3248 $ret = answer_bisect;
3254 sub config_bisect_end {
3255 my ($good, $bad) = @_;
3256 my $diffexec = "diff -u";
3258 if (-f "$builddir/scripts/diffconfig") {
3259 $diffexec = "$builddir/scripts/diffconfig";
3261 doprint "\n\n***************************************\n";
3262 doprint "No more config bisecting possible.\n";
3263 run_command "$diffexec $good $bad", 1;
3264 doprint "***************************************\n\n";
3267 sub run_config_bisect {
3268 my ($good, $bad, $last_result) = @_;
3273 if (!length($last_result)) {
3276 run_command "$config_bisect_exec $reset -b $outputdir $good $bad $last_result", 1;
3278 # config-bisect returns:
3279 # 0 if there is more to bisect
3280 # 1 for finding a good config
3281 # 2 if it can not find any more configs
3283 if ($run_command_status) {
3284 return $run_command_status;
3287 $ret = run_config_bisect_test $config_bisect_type;
3289 doprint "NEW GOOD CONFIG ($pass)\n";
3290 system("cp $output_config $tmpdir/good_config.tmp.$pass");
3292 # Return 3 for good config
3295 doprint "NEW BAD CONFIG ($pass)\n";
3296 system("cp $output_config $tmpdir/bad_config.tmp.$pass");
3298 # Return 4 for bad config
3309 my $type = $config_bisect_type;
3312 $bad_config = $config_bisect;
3314 if (defined($config_bisect_good)) {
3315 $good_config = $config_bisect_good;
3316 } elsif (defined($minconfig)) {
3317 $good_config = $minconfig;
3319 doprint "No config specified, checking if defconfig works";
3320 $ret = run_bisect_test $type, "defconfig";
3322 fail "Have no good config to compare with, please set CONFIG_BISECT_GOOD";
3325 $good_config = $output_config;
3328 if (!defined($config_bisect_exec)) {
3329 # First check the location that ktest.pl ran
3331 "$pwd/config-bisect.pl",
3332 "$dirname/config-bisect.pl",
3333 "$builddir/tools/testing/ktest/config-bisect.pl",
3335 foreach my $loc (@locations) {
3336 doprint "loc = $loc\n";
3337 $config_bisect_exec = $loc;
3338 last if (defined($config_bisect_exec && -x $config_bisect_exec));
3340 if (!defined($config_bisect_exec)) {
3341 fail "Could not find an executable config-bisect.pl\n",
3342 " Set CONFIG_BISECT_EXEC to point to config-bisect.pl";
3347 # we don't want min configs to cause issues here.
3348 doprint "Disabling 'MIN_CONFIG' for this test\n";
3355 if (-f "$tmpdir/good_config.tmp" || -f "$tmpdir/bad_config.tmp") {
3356 if (read_yn "Interrupted config-bisect. Continue (n - will start new)?") {
3357 if (-f "$tmpdir/good_config.tmp") {
3358 $good_config = "$tmpdir/good_config.tmp";
3360 $good_config = "$tmpdir/good_config";
3362 if (-f "$tmpdir/bad_config.tmp") {
3363 $bad_config = "$tmpdir/bad_config.tmp";
3365 $bad_config = "$tmpdir/bad_config";
3369 doprint "Run good configs through make oldconfig\n";
3370 assign_configs \%tmp_configs, $good_config;
3371 create_config "$good_config", \%tmp_configs;
3372 $good_config = "$tmpdir/good_config";
3373 system("cp $output_config $good_config") == 0 or dodie "cp good config";
3375 doprint "Run bad configs through make oldconfig\n";
3376 assign_configs \%tmp_configs, $bad_config;
3377 create_config "$bad_config", \%tmp_configs;
3378 $bad_config = "$tmpdir/bad_config";
3379 system("cp $output_config $bad_config") == 0 or dodie "cp bad config";
3381 if (defined($config_bisect_check) && $config_bisect_check ne "0") {
3382 if ($config_bisect_check ne "good") {
3383 doprint "Testing bad config\n";
3385 $ret = run_bisect_test $type, "useconfig:$bad_config";
3387 fail "Bad config succeeded when expected to fail!";
3391 if ($config_bisect_check ne "bad") {
3392 doprint "Testing good config\n";
3394 $ret = run_bisect_test $type, "useconfig:$good_config";
3396 fail "Good config failed when expected to succeed!";
3405 $ret = run_config_bisect $good_config, $bad_config, $last_run;
3408 } elsif ($ret == 4) {
3412 } while ($ret == 3 || $ret == 4);
3415 config_bisect_end "$good_config.tmp", "$bad_config.tmp";
3418 return $ret if ($ret < 0);
3423 sub patchcheck_reboot {
3424 doprint "Reboot and sleep $patchcheck_sleep_time seconds\n";
3425 reboot_to_good $patchcheck_sleep_time;
3431 dodie "PATCHCHECK_START[$i] not defined\n"
3432 if (!defined($patchcheck_start));
3433 dodie "PATCHCHECK_TYPE[$i] not defined\n"
3434 if (!defined($patchcheck_type));
3436 my $start = $patchcheck_start;
3438 my $cherry = $patchcheck_cherry;
3439 if (!defined($cherry)) {
3444 if (defined($patchcheck_end)) {
3445 $end = $patchcheck_end;
3447 dodie "PATCHCHECK_END must be defined with PATCHCHECK_CHERRY\n";
3450 # Get the true sha1's since we can use things like HEAD~3
3451 $start = get_sha1($start);
3452 $end = get_sha1($end);
3454 my $type = $patchcheck_type;
3456 # Can't have a test without having a test to run
3457 if ($type eq "test" && !defined($run_test)) {
3462 open (IN, "git cherry -v $start $end|") or
3463 dodie "could not get git list";
3465 open (IN, "git log --pretty=oneline $end|") or
3466 dodie "could not get git list";
3473 # git cherry adds a '+' we want to remove
3475 $list[$#list+1] = $_;
3476 last if (/^$start/);
3481 if ($list[$#list] !~ /^$start/) {
3482 fail "SHA1 $start not found";
3485 # go backwards in the list
3486 @list = reverse @list;
3489 doprint("Going to test the following commits:\n");
3490 foreach my $l (@list) {
3494 my $save_clean = $noclean;
3495 my %ignored_warnings;
3497 if (defined($ignore_warnings)) {
3498 foreach my $sha1 (split /\s+/, $ignore_warnings) {
3499 $ignored_warnings{$sha1} = 1;
3504 foreach my $item (@list) {
3506 $sha1 =~ s/^([[:xdigit:]]+).*/$1/;
3508 doprint "\nProcessing commit \"$item\"\n\n";
3510 run_command "git checkout $sha1" or
3511 dodie "Failed to checkout $sha1";
3513 # only clean on the first and last patch
3514 if ($item eq $list[0] ||
3515 $item eq $list[$#list]) {
3516 $noclean = $save_clean;
3521 if (defined($minconfig)) {
3522 build "useconfig:$minconfig" or return 0;
3524 # ?? no config to use?
3525 build "oldconfig" or return 0;
3528 # No need to do per patch checking if warnings file exists
3529 if (!defined($warnings_file) && !defined($ignored_warnings{$sha1})) {
3530 check_patch_buildlog $sha1 or return 0;
3533 check_buildlog or return 0;
3535 next if ($type eq "build");
3539 start_monitor_and_install or $failed = 1;
3541 if (!$failed && $type ne "boot"){
3542 do_run_test or $failed = 1;
3559 # $config depends on $dep
3560 my ($config, $dep) = @_;
3562 if (defined($depends{$config})) {
3563 $depends{$config} .= " " . $dep;
3565 $depends{$config} = $dep;
3568 # record the number of configs depending on $dep
3569 if (defined $depcount{$dep}) {
3572 $depcount{$dep} = 1;
3576 # taken from streamline_config.pl
3587 if (! -f $kconfig) {
3588 doprint "file $kconfig does not exist, skipping\n";
3592 open(KIN, "$kconfig")
3593 or dodie "Can't open $kconfig";
3597 # Make sure that lines ending with \ continue
3599 $_ = $line . " " . $_;
3610 # collect any Kconfig sources
3611 if (/^source\s*"(.*)"/) {
3612 $kconfigs[$#kconfigs+1] = $1;
3616 if (/^\s*(menu)?config\s+(\S+)\s*$/) {
3620 for (my $i = 0; $i < $iflevel; $i++) {
3621 add_dep $config, $ifdeps[$i];
3624 # collect the depends for the config
3625 } elsif ($state eq "NEW" && /^\s*depends\s+on\s+(.*)$/) {
3627 add_dep $config, $1;
3629 # Get the configs that select this config
3630 } elsif ($state eq "NEW" && /^\s*select\s+(\S+)/) {
3632 # selected by depends on config
3633 add_dep $1, $config;
3635 # Check for if statements
3636 } elsif (/^if\s+(.*\S)\s*$/) {
3638 # remove beginning and ending non text
3639 $deps =~ s/^[^a-zA-Z0-9_]*//;
3640 $deps =~ s/[^a-zA-Z0-9_]*$//;
3642 my @deps = split /[^a-zA-Z0-9_]+/, $deps;
3644 $ifdeps[$iflevel++] = join ':', @deps;
3646 } elsif (/^endif/) {
3648 $iflevel-- if ($iflevel);
3651 } elsif (/^\s*help\s*$/) {
3657 # read in any configs that were found.
3658 foreach $kconfig (@kconfigs) {
3659 if (!defined($read_kconfigs{$kconfig})) {
3660 $read_kconfigs{$kconfig} = 1;
3661 read_kconfig("$builddir/$kconfig");
3667 # find out which arch this is by the kconfig file
3668 open (IN, $output_config) or
3669 dodie "Failed to read $output_config";
3672 if (m,Linux/(\S+)\s+\S+\s+Kernel Configuration,) {
3679 if (!defined($arch)) {
3680 doprint "Could not find arch from config file\n";
3681 doprint "no dependencies used\n";
3685 # arch is really the subarch, we need to know
3686 # what directory to look at.
3687 if ($arch eq "i386" || $arch eq "x86_64") {
3691 my $kconfig = "$builddir/arch/$arch/Kconfig";
3693 if (! -f $kconfig && $arch =~ /\d$/) {
3695 # some subarchs have numbers, truncate them
3697 $kconfig = "$builddir/arch/$arch/Kconfig";
3698 if (! -f $kconfig) {
3699 doprint "No idea what arch dir $orig is for\n";
3700 doprint "no dependencies used\n";
3705 read_kconfig($kconfig);
3708 sub make_new_config {
3711 open (OUT, ">$output_config")
3712 or dodie "Failed to write $output_config";
3714 foreach my $config (@configs) {
3715 print OUT "$config\n";
3723 $config =~ s/CONFIG_//;
3731 my $kconfig = chomp_config $dep;
3733 $dep = $depends{"$kconfig"};
3735 # the dep string we have saves the dependencies as they
3736 # were found, including expressions like ! && ||. We
3737 # want to split this out into just an array of configs.
3739 my $valid = "A-Za-z_0-9";
3743 while ($dep =~ /[$valid]/) {
3744 if ($dep =~ /^[^$valid]*([$valid]+)/) {
3745 my $conf = "CONFIG_" . $1;
3747 $configs[$#configs + 1] = $conf;
3749 $dep =~ s/^[^$valid]*[$valid]+//;
3751 dodie "this should never happen";
3758 sub test_this_config {
3763 # if we already processed this config, skip it
3764 if (defined($processed_configs{$config})) {
3767 $processed_configs{$config} = 1;
3769 # if this config failed during this round, skip it
3770 if (defined($nochange_config{$config})) {
3774 my $kconfig = chomp_config $config;
3776 # Test dependencies first
3777 if (defined($depends{"$kconfig"})) {
3778 my @parents = get_depends $config;
3779 foreach my $parent (@parents) {
3780 # if the parent is in the min config, check it first
3781 next if (!defined($min_configs{$parent}));
3782 $found = test_this_config($parent);
3783 if (defined($found)) {
3789 # Remove this config from the list of configs
3790 # do a make olddefconfig and then read the resulting
3791 # .config to make sure it is missing the config that
3793 my %configs = %min_configs;
3794 $configs{$config} = "# $config is not set";
3795 make_new_config ((values %configs), (values %keep_configs));
3797 delete $configs{$config};
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};
3922 # Now disable each config one by one and do a make oldconfig
3923 # till we find a config that changes our list.
3925 my @test_configs = keys %min_configs;
3927 # Sort keys by who is most dependent on
3928 @test_configs = sort { $depcount{chomp_config($b)} <=> $depcount{chomp_config($a)} }
3931 # Put configs that did not modify the config at the end.
3933 for (my $i = 0; $i < $#test_configs; $i++) {
3934 if (!defined($nochange_config{$test_configs[0]})) {
3938 # This config didn't change the .config last time.
3939 # Place it at the end
3940 my $config = shift @test_configs;
3941 push @test_configs, $config;
3944 # if every test config has failed to modify the .config file
3945 # in the past, then reset and start over.
3947 undef %nochange_config;
3950 undef %processed_configs;
3952 foreach my $config (@test_configs) {
3954 $found = test_this_config $config;
3956 last if (defined($found));
3958 # oh well, try another config
3961 if (!defined($found)) {
3962 # we could have failed due to the nochange_config hash
3963 # reset and try again
3965 undef %nochange_config;
3969 doprint "No more configs found that we can disable\n";
3977 doprint "Test with $config disabled\n";
3979 # set in_bisect to keep build and monitor from dieing
3983 build "oldconfig" or $failed = 1;
3985 start_monitor_and_install or $failed = 1;
3987 if ($type eq "test" && !$failed) {
3988 do_run_test or $failed = 1;
3997 doprint "$min_configs{$config} is needed to boot the box... keeping\n";
3998 # this config is needed, add it to the ignore list.
3999 $keep_configs{$config} = $min_configs{$config};
4000 $save_configs{$config} = $min_configs{$config};
4001 delete $min_configs{$config};
4003 # update new ignore configs
4004 if (defined($ignore_config)) {
4005 open (OUT, ">$temp_config") or
4006 dodie "Can't write to $temp_config";
4007 foreach my $config (keys %save_configs) {
4008 print OUT "$save_configs{$config}\n";
4011 run_command "mv $temp_config $ignore_config" or
4012 dodie "failed to copy update to $ignore_config";
4016 # We booted without this config, remove it from the minconfigs.
4017 doprint "$config is not needed, disabling\n";
4019 delete $min_configs{$config};
4021 # Also disable anything that is not enabled in this config
4023 assign_configs \%configs, $output_config;
4024 my @config_keys = keys %min_configs;
4025 foreach my $config (@config_keys) {
4026 if (!defined($configs{$config})) {
4027 doprint "$config is not set, disabling\n";
4028 delete $min_configs{$config};
4032 # Save off all the current mandatory configs
4033 open (OUT, ">$temp_config") or
4034 dodie "Can't write to $temp_config";
4035 foreach my $config (keys %keep_configs) {
4036 print OUT "$keep_configs{$config}\n";
4038 foreach my $config (keys %min_configs) {
4039 print OUT "$min_configs{$config}\n";
4043 run_command "mv $temp_config $output_minconfig" or
4044 dodie "failed to copy update to $output_minconfig";
4047 doprint "Reboot and wait $sleep_time seconds\n";
4048 reboot_to_good $sleep_time;
4055 sub make_warnings_file {
4058 if (!defined($warnings_file)) {
4059 dodie "Must define WARNINGS_FILE for make_warnings_file test";
4062 if ($build_type eq "nobuild") {
4063 dodie "BUILD_TYPE can not be 'nobuild' for make_warnings_file test";
4066 build $build_type or dodie "Failed to build";
4068 open(OUT, ">$warnings_file") or dodie "Can't create $warnings_file";
4070 open(IN, $buildlog) or dodie "Can't open $buildlog";
4072 # Some compilers use UTF-8 extended for quotes
4073 # for distcc heterogeneous systems, this causes issues
4076 if (/$check_build_re/) {
4087 sub option_defined {
4090 if (defined($opt{$option}) && $opt{$option} !~ /^\s*$/) {
4097 sub __set_test_option {
4098 my ($name, $i) = @_;
4100 my $option = "$name\[$i\]";
4102 if (option_defined($option)) {
4103 return $opt{$option};
4106 foreach my $test (keys %repeat_tests) {
4108 $i < $test + $repeat_tests{$test}) {
4109 $option = "$name\[$test\]";
4110 if (option_defined($option)) {
4111 return $opt{$option};
4116 if (option_defined($name)) {
4123 sub set_test_option {
4124 my ($name, $i) = @_;
4126 my $option = __set_test_option($name, $i);
4127 return $option if (!defined($option));
4129 return eval_option($name, $option, $i);
4135 my @paths = split /:/, $ENV{PATH};
4137 # sendmail is usually in /usr/sbin
4138 $paths[$#paths + 1] = "/usr/sbin";
4140 foreach my $path (@paths) {
4141 if (-x "$path/$mailer") {
4150 my ($subject, $message, $file) = @_;
4152 if (!defined($mail_path)) {
4154 $mail_path = find_mailer $mailer;
4155 if (!defined($mail_path)) {
4156 die "\nCan not find $mailer in PATH\n";
4160 my $header_file = "$tmpdir/header";
4161 open (HEAD, ">$header_file") or die "Can not create $header_file\n";
4162 print HEAD "To: $mailto\n";
4163 print HEAD "Subject: $subject\n\n";
4164 print HEAD "$message\n";
4167 if (!defined($mail_command)) {
4168 if ($mailer eq "mail" || $mailer eq "mailx") {
4169 $mail_command = "cat \$HEADER_FILE \$BODY_FILE | \$MAIL_PATH/\$MAILER -s \'\$SUBJECT\' \$MAILTO";
4170 } elsif ($mailer eq "sendmail" ) {
4171 $mail_command = "cat \$HEADER_FILE \$BODY_FILE | \$MAIL_PATH/\$MAILER -t \$MAILTO";
4173 die "\nYour mailer: $mailer is not supported.\n";
4177 if (defined($file)) {
4178 $mail_command =~ s/\$BODY_FILE/$file/g;
4180 $mail_command =~ s/\$BODY_FILE//g;
4183 $mail_command =~ s/\$HEADER_FILE/$header_file/g;
4184 $mail_command =~ s/\$MAILER/$mailer/g;
4185 $mail_command =~ s/\$MAIL_PATH/$mail_path/g;
4186 $mail_command =~ s/\$MAILTO/$mailto/g;
4187 $mail_command =~ s/\$SUBJECT/$subject/g;
4188 $mail_command =~ s/\$MESSAGE/$message/g;
4190 my $ret = run_command $mail_command;
4191 if (!$ret && defined($file)) {
4192 # try again without the file
4193 $message .= "\n\n*** FAILED TO SEND LOG ***\n\n";
4194 do_send_email($subject, $message);
4199 if (defined($mailto)) {
4200 if (!defined($mailer)) {
4201 doprint "No email sent: email or mailer not specified in config.\n";
4212 if ($email_when_canceled) {
4213 my $name = get_test_name;
4214 send_email("KTEST: Your [$name] test was cancelled",
4215 "Your test started at $script_start_time was cancelled: sig int");
4217 die "\nCaught Sig Int, test interrupted: $!\n"
4220 $#ARGV < 1 or die "ktest.pl version: $VERSION\n usage: ktest.pl [config-file]\n";
4223 $ktest_config = $ARGV[0];
4224 if (! -f $ktest_config) {
4225 print "$ktest_config does not exist.\n";
4226 if (!read_yn "Create it?") {
4232 if (! -f $ktest_config) {
4235 open(OUT, ">$ktest_config") or die "Can not create $ktest_config";
4237 # Generated by ktest.pl
4240 # PWD is a ktest.pl variable that will result in the process working
4241 # directory that ktest.pl is executed in.
4243 # THIS_DIR is automatically assigned the PWD of the path that generated
4244 # the config file. It is best to use this variable when assigning other
4245 # directory paths within this directory. This allows you to easily
4246 # move the test cases to other locations or to other machines.
4248 THIS_DIR := $variable{"PWD"}
4250 # Define each test with TEST_START
4251 # The config options below it will override the defaults
4253 TEST_TYPE = $default{"TEST_TYPE"}
4260 read_config $ktest_config;
4262 if (defined($opt{"LOG_FILE"})) {
4263 $opt{"LOG_FILE"} = eval_option("LOG_FILE", $opt{"LOG_FILE"}, -1);
4266 # Append any configs entered in manually to the config file.
4267 my @new_configs = keys %entered_configs;
4268 if ($#new_configs >= 0) {
4269 print "\nAppending entered in configs to $ktest_config\n";
4270 open(OUT, ">>$ktest_config") or die "Can not append to $ktest_config";
4271 foreach my $config (@new_configs) {
4272 print OUT "$config = $entered_configs{$config}\n";
4273 $opt{$config} = process_variables($entered_configs{$config});
4277 if (defined($opt{"LOG_FILE"})) {
4278 if ($opt{"CLEAR_LOG"}) {
4279 unlink $opt{"LOG_FILE"};
4281 open(LOG, ">> $opt{LOG_FILE}") or die "Can't write to $opt{LOG_FILE}";
4285 doprint "\n\nSTARTING AUTOMATED TESTS\n\n";
4287 for (my $i = 0, my $repeat = 1; $i <= $opt{"NUM_TESTS"}; $i += $repeat) {
4290 doprint "DEFAULT OPTIONS:\n";
4292 doprint "\nTEST $i OPTIONS";
4293 if (defined($repeat_tests{$i})) {
4294 $repeat = $repeat_tests{$i};
4295 doprint " ITERATE $repeat";
4300 foreach my $option (sort keys %opt) {
4301 if ($option =~ /\[(\d+)\]$/) {
4307 doprint "$option = $opt{$option}\n";
4311 $SIG{INT} = qw(cancel_test);
4313 # First we need to do is the builds
4314 for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
4316 # Do not reboot on failing test options
4318 $reboot_success = 0;
4329 undef %force_config;
4331 my $makecmd = set_test_option("MAKE_CMD", $i);
4333 $outputdir = set_test_option("OUTPUT_DIR", $i);
4334 $builddir = set_test_option("BUILD_DIR", $i);
4336 chdir $builddir || dodie "can't change directory to $builddir";
4338 if (!-d $outputdir) {
4339 mkpath($outputdir) or
4340 dodie "can't create $outputdir";
4343 $make = "$makecmd O=$outputdir";
4345 # Load all the options into their mapped variable names
4346 foreach my $opt (keys %option_map) {
4347 ${$option_map{$opt}} = set_test_option($opt, $i);
4350 $start_minconfig_defined = 1;
4352 # The first test may override the PRE_KTEST option
4354 if (defined($pre_ktest)) {
4356 run_command $pre_ktest;
4358 if ($email_when_started) {
4359 my $name = get_test_name;
4360 send_email("KTEST: Your [$name] test was started",
4361 "Your test was started on $script_start_time");
4365 # Any test can override the POST_KTEST option
4366 # The last test takes precedence.
4367 if (defined($post_ktest)) {
4368 $final_post_ktest = $post_ktest;
4371 if (!defined($start_minconfig)) {
4372 $start_minconfig_defined = 0;
4373 $start_minconfig = $minconfig;
4378 dodie "can't create $tmpdir";
4381 $ENV{"SSH_USER"} = $ssh_user;
4382 $ENV{"MACHINE"} = $machine;
4384 $buildlog = "$tmpdir/buildlog-$machine";
4385 $testlog = "$tmpdir/testlog-$machine";
4386 $dmesg = "$tmpdir/dmesg-$machine";
4387 $output_config = "$outputdir/.config";
4390 $target = "$ssh_user\@$machine";
4391 if (($reboot_type eq "grub") or ($reboot_type eq "grub2bls")) {
4392 dodie "GRUB_MENU not defined" if (!defined($grub_menu));
4393 } elsif ($reboot_type eq "grub2") {
4394 dodie "GRUB_MENU not defined" if (!defined($grub_menu));
4395 dodie "GRUB_FILE not defined" if (!defined($grub_file));
4396 } elsif ($reboot_type eq "syslinux") {
4397 dodie "SYSLINUX_LABEL not defined" if (!defined($syslinux_label));
4401 my $run_type = $build_type;
4402 if ($test_type eq "patchcheck") {
4403 $run_type = $patchcheck_type;
4404 } elsif ($test_type eq "bisect") {
4405 $run_type = $bisect_type;
4406 } elsif ($test_type eq "config_bisect") {
4407 $run_type = $config_bisect_type;
4408 } elsif ($test_type eq "make_min_config") {
4410 } elsif ($test_type eq "make_warnings_file") {
4414 # mistake in config file?
4415 if (!defined($run_type)) {
4416 $run_type = "ERROR";
4420 $installme = " no_install" if ($no_install);
4424 if (defined($test_name)) {
4425 $name = " ($test_name)";
4430 if (defined($opt{"LOG_FILE"})) {
4431 $test_log_start = tell(LOG);
4434 doprint "RUNNING TEST $i of $opt{NUM_TESTS}$name with option $test_type $run_type$installme\n\n";
4436 if (defined($pre_test)) {
4437 my $ret = run_command $pre_test;
4438 if (!$ret && defined($pre_test_die) &&
4440 dodie "failed to pre_test\n";
4448 if (defined($addconfig)) {
4449 my $min = $minconfig;
4450 if (!defined($minconfig)) {
4453 run_command "cat $addconfig $min > $tmpdir/add_config" or
4454 dodie "Failed to create temp config";
4455 $minconfig = "$tmpdir/add_config";
4458 if (defined($checkout)) {
4459 run_command "git checkout $checkout" or
4460 dodie "failed to checkout $checkout";
4465 # A test may opt to not reboot the box
4466 if ($reboot_on_success) {
4467 $reboot_success = 1;
4470 if ($test_type eq "bisect") {
4473 } elsif ($test_type eq "config_bisect") {
4476 } elsif ($test_type eq "patchcheck") {
4479 } elsif ($test_type eq "make_min_config") {
4482 } elsif ($test_type eq "make_warnings_file") {
4484 make_warnings_file $i;
4488 if ($build_type ne "nobuild") {
4489 build $build_type or next;
4490 check_buildlog or next;
4493 if ($test_type eq "install") {
4500 if ($test_type ne "build") {
4502 start_monitor_and_install or $failed = 1;
4504 if (!$failed && $test_type ne "boot" && defined($run_test)) {
4505 do_run_test or $failed = 1;
4519 if (defined($final_post_ktest)) {
4521 my $cp_final_post_ktest = eval_kernel_version $final_post_ktest;
4522 run_command $cp_final_post_ktest;
4525 if ($opt{"POWEROFF_ON_SUCCESS"}) {
4527 } elsif ($opt{"REBOOT_ON_SUCCESS"} && !do_not_reboot && $reboot_success) {
4529 } elsif (defined($switch_to_good)) {
4530 # still need to get to the good kernel
4531 run_command $switch_to_good;
4534 doprint "\n $successes of $opt{NUM_TESTS} tests were successful\n\n";
4536 if ($email_when_finished) {
4537 send_email("KTEST: Your test has finished!",
4538 "$successes of $opt{NUM_TESTS} tests started at $script_start_time were successful!");
4541 if (defined($opt{"LOG_FILE"})) {
4542 print "\n See $opt{LOG_FILE} for the record of results.\n\n";
4549 # The following are here to standardize tabs/spaces/etc across the most likely editors
4555 # vim: softtabstop=4