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 ($var =~ s/^shell\s+//) {
810 doprint "WARNING: $var returned an error\n";
814 } elsif (defined($variable{$var})) {
815 $retval = "$retval$variable{$var}";
816 } elsif (defined($remove_undef) && $remove_undef) {
817 # for if statements, any variable that is not defined,
818 # we simple convert to 0
819 $retval = "${retval}0";
821 # put back the origin piece.
822 $retval = "$retval\$\{$var\}";
823 # This could be an option that is used later, save
824 # it so we don't warn if this option is not one of
826 $used_options{$var} = 1;
830 $retval = "$retval$value";
832 # remove the space added in the beginning
839 my ($lvalue, $rvalue, $override, $overrides, $name) = @_;
841 my $prvalue = process_variables($rvalue);
843 if ($lvalue =~ /^(TEST|BISECT|CONFIG_BISECT)_TYPE(\[.*\])?$/ &&
844 $prvalue !~ /^(config_|)bisect$/ &&
845 $prvalue !~ /^build$/ &&
848 # Note if a test is something other than build, then we
849 # will need other mandatory options.
850 if ($prvalue ne "install") {
853 # install still limits some mandatory options.
858 if (defined($opt{$lvalue})) {
859 if (!$override || defined(${$overrides}{$lvalue})) {
862 $extra = "In the same override section!\n";
864 die "$name: $.: Option $lvalue defined more than once!\n$extra";
866 ${$overrides}{$lvalue} = $prvalue;
869 $opt{$lvalue} = $prvalue;
873 my ($lvalue, $rvalue, $name) = @_;
875 my $prvalue = process_variables($rvalue);
878 if (defined($evals{$lvalue})) {
879 $arr = $evals{$lvalue};
882 $evals{$lvalue} = $arr;
885 push @{$arr}, $rvalue;
889 my ($lvalue, $rvalue) = @_;
891 if ($rvalue =~ /^\s*$/) {
892 delete $variable{$lvalue};
894 $rvalue = process_variables($rvalue);
895 $variable{$lvalue} = $rvalue;
899 sub process_compare {
900 my ($lval, $cmp, $rval) = @_;
911 return $lval eq $rval;
912 } elsif ($cmp eq "!=") {
913 return $lval ne $rval;
914 } elsif ($cmp eq "=~") {
915 return $lval =~ m/$rval/;
916 } elsif ($cmp eq "!~") {
917 return $lval !~ m/$rval/;
920 my $statement = "$lval $cmp $rval";
921 my $ret = eval $statement;
923 # $@ stores error of eval
934 return defined($variable{$2}) ||
938 sub process_expression {
939 my ($name, $val) = @_;
943 while ($val =~ s/\(([^\(]*?)\)/\&\&\&\&VAL\&\&\&\&/) {
946 if (process_expression($name, $express)) {
947 $val =~ s/\&\&\&\&VAL\&\&\&\&/ 1 /;
949 $val =~ s/\&\&\&\&VAL\&\&\&\&/ 0 /;
957 while ($val =~ s/^(.*?)($OR|$AND)//) {
961 if (process_expression($name, $express)) {
972 if ($val =~ /(.*)(==|\!=|>=|<=|>|<|=~|\!~)(.*)/) {
973 my $ret = process_compare($1, $2, $3);
975 die "$name: $.: Unable to process comparison\n";
980 if ($val =~ /^\s*(NOT\s*)?DEFINED\s+(\S+)\s*$/) {
982 return !value_defined($2);
984 return value_defined($2);
988 if ($val =~ s/^\s*NOT\s+(.*)//) {
990 my $ret = process_expression($name, $express);
994 if ($val =~ /^\s*0\s*$/) {
996 } elsif ($val =~ /^\s*\d+\s*$/) {
1000 die ("$name: $.: Undefined content $val in if statement\n");
1004 my ($name, $value) = @_;
1006 # Convert variables and replace undefined ones with 0
1007 my $val = process_variables($value, 1);
1008 my $ret = process_expression $name, $val;
1014 my ($config, $current_test_num) = @_;
1017 open($in, $config) || die "can't read file $config";
1020 $name =~ s,.*/(.*),$1,;
1022 my $test_num = $$current_test_num;
1025 my $num_tests_set = 0;
1038 # ignore blank lines and comments
1039 next if (/^\s*$/ || /\s*\#/);
1041 if (/^\s*(TEST_START|DEFAULTS)\b(.*)/) {
1051 if ($type eq "TEST_START") {
1052 if ($num_tests_set) {
1053 die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
1056 $old_test_num = $test_num;
1057 $old_repeat = $repeat;
1059 $test_num += $repeat;
1066 # If SKIP is anywhere in the line, the command will be skipped
1067 if ($rest =~ s/\s+SKIP\b//) {
1074 if ($rest =~ s/\sELSE\b//) {
1076 die "$name: $.: ELSE found with out matching IF section\n$_";
1087 if ($rest =~ s/\sIF\s+(.*)//) {
1088 if (process_if($name, $1)) {
1100 if ($type eq "TEST_START") {
1101 if ($rest =~ s/\s+ITERATE\s+(\d+)//) {
1103 $repeat_tests{"$test_num"} = $repeat;
1105 } elsif ($rest =~ s/\sOVERRIDE\b//) {
1108 # Clear previous overrides
1113 if (!$skip && $rest !~ /^\s*$/) {
1114 die "$name: $.: Garbage found after $type\n$_";
1117 if ($skip && $type eq "TEST_START") {
1118 $test_num = $old_test_num;
1119 $repeat = $old_repeat;
1121 } elsif (/^\s*ELSE\b(.*)$/) {
1123 die "$name: $.: ELSE found with out matching IF section\n$_";
1132 if ($rest =~ /\sIF\s+(.*)/) {
1133 # May be a ELSE IF section.
1134 if (process_if($name, $1)) {
1145 if ($rest !~ /^\s*$/) {
1146 die "$name: $.: Garbage found after DEFAULTS\n$_";
1149 } elsif (/^\s*INCLUDE\s+(\S+)/) {
1154 die "$name: $.: INCLUDE can only be done in default sections\n$_";
1157 my $file = process_variables($1);
1159 if ($file !~ m,^/,) {
1160 # check the path of the config file first
1161 if ($config =~ m,(.*)/,) {
1162 if (-f "$1/$file") {
1169 die "$name: $.: Can't read file $file\n$_";
1172 if (__read_config($file, \$test_num)) {
1176 } elsif (/^\s*([A-Z_\[\]\d]+)\s*=~\s*(.*?)\s*$/) {
1183 if ($default || $lvalue =~ /\[\d+\]$/) {
1184 set_eval($lvalue, $rvalue, $name);
1186 my $val = "$lvalue\[$test_num\]";
1187 set_eval($val, $rvalue, $name);
1190 } elsif (/^\s*([A-Z_\[\]\d]+)\s*=\s*(.*?)\s*$/) {
1198 ($lvalue eq "NUM_TESTS" ||
1199 $lvalue eq "LOG_FILE" ||
1200 $lvalue eq "CLEAR_LOG")) {
1201 die "$name: $.: $lvalue must be set in DEFAULTS section\n";
1204 if ($lvalue eq "NUM_TESTS") {
1206 die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
1209 die "$name: $.: NUM_TESTS must be set in default section\n";
1214 if ($default || $lvalue =~ /\[\d+\]$/) {
1215 set_value($lvalue, $rvalue, $override, \%overrides, $name);
1217 my $val = "$lvalue\[$test_num\]";
1218 set_value($val, $rvalue, $override, \%overrides, $name);
1221 $repeats{$val} = $repeat;
1224 } elsif (/^\s*([A-Z_\[\]\d]+)\s*:=\s*(.*?)\s*$/) {
1230 # process config variables.
1231 # Config variables are only active while reading the
1232 # config and can be defined anywhere. They also ignore
1233 # TEST_START and DEFAULTS, but are skipped if they are in
1234 # on of these sections that have SKIP defined.
1235 # The save variable can be
1236 # defined multiple times and the new one simply overrides
1238 set_variable($lvalue, $rvalue);
1241 die "$name: $.: Garbage found in config\n$_";
1246 $test_num += $repeat - 1;
1247 $opt{"NUM_TESTS"} = $test_num;
1252 $$current_test_num = $test_num;
1258 print "What test case would you like to run?\n";
1259 print " (build, install or boot)\n";
1260 print " Other tests are available but require editing ktest.conf\n";
1261 print " (see tools/testing/ktest/sample.conf)\n";
1264 $default{"TEST_TYPE"} = $ans;
1273 $test_case = __read_config $config, \$test_num;
1275 # make sure we have all mandatory configs
1276 get_mandatory_configs;
1278 # was a test specified?
1280 print "No test case specified.\n";
1286 foreach my $default (keys %default) {
1287 if (!defined($opt{$default})) {
1288 $opt{$default} = $default{$default};
1292 if ($opt{"IGNORE_UNUSED"} == 1) {
1298 # check if there are any stragglers (typos?)
1299 foreach my $option (keys %opt) {
1301 # remove per test labels.
1303 if (!exists($option_map{$op}) &&
1304 !exists($default{$op}) &&
1305 !exists($used_options{$op})) {
1312 $s = " is" if (keys %not_used == 1);
1313 print "The following option$s not used; could be a typo:\n";
1314 foreach my $option (keys %not_used) {
1317 print "Set IGNORE_UNUSED = 1 to have ktest ignore unused variables\n";
1318 if (!read_yn "Do you want to continue?") {
1325 my ($name, $option, $i) = @_;
1327 # Add space to evaluate the character before $
1328 $option = " $option";
1333 foreach my $test (keys %repeat_tests) {
1335 $i < $test + $repeat_tests{$test}) {
1343 while ($option =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) {
1348 # Append beginning of line
1349 $retval = "$retval$start";
1351 # If the iteration option OPT[$i] exists, then use that.
1352 # otherwise see if the default OPT (without [$i]) exists.
1354 my $o = "$var\[$i\]";
1355 my $parento = "$var\[$parent\]";
1357 # If a variable contains itself, use the default var
1358 if (($var eq $name) && defined($opt{$var})) {
1360 $retval = "$retval$o";
1361 } elsif (defined($opt{$o})) {
1363 $retval = "$retval$o";
1364 } elsif ($repeated && defined($opt{$parento})) {
1365 $o = $opt{$parento};
1366 $retval = "$retval$o";
1367 } elsif (defined($opt{$var})) {
1369 $retval = "$retval$o";
1370 } elsif ($var eq "KERNEL_VERSION" && defined($make)) {
1371 # special option KERNEL_VERSION uses kernel version
1373 $retval = "$retval$version";
1375 $retval = "$retval\$\{$var\}";
1381 $retval = "$retval$option";
1389 my ($name, $option, $i) = @_;
1391 my $option_name = "$name\[$i\]";
1394 my $old_option = $option;
1396 if (defined($evals{$option_name})) {
1397 $ev = $evals{$option_name};
1398 } elsif (defined($evals{$name})) {
1399 $ev = $evals{$name};
1404 for my $e (@{$ev}) {
1405 eval "\$option =~ $e";
1408 if ($option ne $old_option) {
1409 doprint("$name changed from '$old_option' to '$option'\n");
1416 my ($name, $option, $i) = @_;
1420 # Since an option can evaluate to another option,
1421 # keep iterating until we do not evaluate any more
1424 while ($prev ne $option) {
1425 # Check for recursive evaluations.
1426 # 100 deep should be more than enough.
1428 die "Over 100 evaluations occurred with $option\n" .
1429 "Check for recursive variables\n";
1432 $option = __eval_option($name, $option, $i);
1435 $option = process_evals($name, $option, $i);
1444 # test if the machine can be connected to within a few seconds
1445 my $stat = run_ssh("echo check machine status", $connect_timeout);
1447 doprint("power cycle\n");
1452 run_command "$power_cycle";
1455 # flush out current monitor
1456 # May contain the reboot success line
1460 # Make sure everything has been written to disk
1461 run_ssh("sync", 10);
1463 if (defined($time)) {
1465 # flush out current monitor
1466 # May contain the reboot success line
1470 # try to reboot normally
1471 if (run_command $reboot) {
1472 if (defined($powercycle_after_reboot)) {
1473 sleep $powercycle_after_reboot;
1474 run_command "$power_cycle";
1477 # nope? power cycle it.
1478 run_command "$power_cycle";
1482 if (defined($time)) {
1484 # We only want to get to the new kernel, don't fail
1485 # if we stumble over a call trace.
1486 my $save_ignore_errors = $ignore_errors;
1489 # Look for the good kernel to boot
1490 if (wait_for_monitor($time, "Linux version")) {
1492 doprint "Reboot did not finish. Forcing power cycle\n";
1493 run_command "$power_cycle";
1496 $ignore_errors = $save_ignore_errors;
1498 # Still need to wait for the reboot to finish
1499 wait_for_monitor($time, $reboot_success_line);
1501 if ($powercycle || $time) {
1506 sub reboot_to_good {
1509 if (defined($switch_to_good)) {
1510 run_command $switch_to_good;
1519 return $test_type eq "build" || $no_reboot ||
1520 ($test_type eq "patchcheck" && $opt{"PATCHCHECK_TYPE[$i]"} eq "build") ||
1521 ($test_type eq "bisect" && $opt{"BISECT_TYPE[$i]"} eq "build") ||
1522 ($test_type eq "config_bisect" && $opt{"CONFIG_BISECT_TYPE[$i]"} eq "build");
1525 sub get_test_name() {
1528 if (defined($test_name)) {
1529 $name = "$test_name:$test_type";
1538 return if ($in_die);
1542 # restore terminal settings
1543 system("stty $stty_orig");
1548 doprint "CRITICAL FAILURE... [TEST $i] ", @_, "\n";
1550 if ($reboot_on_error && !do_not_reboot) {
1551 doprint "REBOOTING\n";
1553 } elsif ($poweroff_on_error && defined($power_off)) {
1554 doprint "POWERING OFF\n";
1558 if (defined($opt{"LOG_FILE"})) {
1559 print " See $opt{LOG_FILE} for more info.\n";
1562 if ($email_on_error) {
1563 my $name = get_test_name;
1566 if (defined($opt{"LOG_FILE"})) {
1567 my $whence = 2; # End of file
1568 my $log_size = tell LOG;
1569 my $size = $log_size - $test_log_start;
1571 if (defined($mail_max_size)) {
1572 if ($size > $mail_max_size) {
1573 $size = $mail_max_size;
1577 $log_file = "$tmpdir/log";
1578 open (L, "$opt{LOG_FILE}") or die "Can't open $opt{LOG_FILE} to read)";
1579 open (O, "> $tmpdir/log") or die "Can't open $tmpdir/log\n";
1580 seek(L, $pos, $whence);
1588 send_email("KTEST: critical failure for test $i [$name]",
1589 "Your test started at $script_start_time has failed with:\n@_\n", $log_file);
1592 if (defined($post_test)) {
1593 run_command $post_test;
1600 my ($ptm, $pts) = @_;
1602 my $TIOCSPTLCK = 0x40045431;
1603 my $TIOCGPTN = 0x80045430;
1605 sysopen($ptm, "/dev/ptmx", O_RDWR | O_NONBLOCK) or
1606 dodie "Can't open /dev/ptmx";
1609 $tmp = pack("i", 0);
1610 ioctl($ptm, $TIOCSPTLCK, $tmp) or
1611 dodie "ioctl TIOCSPTLCK for /dev/ptmx failed";
1614 ioctl($ptm, $TIOCGPTN, $tmp) or
1615 dodie "ioctl TIOCGPTN for /dev/ptmx failed";
1616 $tmp = unpack("i", $tmp);
1618 sysopen($pts, "/dev/pts/$tmp", O_RDWR | O_NONBLOCK) or
1619 dodie "Can't open /dev/pts/$tmp";
1623 my ($ptm, $pts) = @_;
1631 open(\*STDIN, '<&', $pts);
1632 open(\*STDOUT, '>&', $pts);
1633 open(\*STDERR, '>&', $pts);
1638 dodie "Can't open console $console";
1646 # save terminal settings
1647 $stty_orig = `stty -g`;
1649 # place terminal in cbreak mode so that stdin can be read one character at
1650 # a time without having to wait for a newline
1651 system("stty -icanon -echo -icrnl");
1653 create_pty($ptm, $pts);
1659 exec_console($ptm, $pts)
1667 open(PTSFD, "Stop perl from warning about single use of PTSFD");
1671 my ($fp, $pid) = @_;
1673 doprint "kill child process $pid\n";
1674 kill $close_console_signal, $pid;
1676 doprint "wait for child process $pid to exit\n";
1682 # restore terminal settings
1683 system("stty $stty_orig");
1687 if ($monitor_cnt++) {
1690 $monitor_fp = \*MONFD;
1691 $monitor_pid = open_console $monitor_fp;
1695 open(MONFD, "Stop perl from warning about single use of MONFD");
1699 return if (!defined $console);
1700 if (--$monitor_cnt) {
1703 close_console($monitor_fp, $monitor_pid);
1706 sub wait_for_monitor {
1707 my ($time, $stop) = @_;
1711 my $start_time = time;
1712 my $skip_call_trace = 0;
1714 my $bug_ignored = 0;
1717 doprint "** Wait for monitor to settle down **\n";
1719 # read the monitor and wait for the system to calm down
1721 $line = wait_for_input($monitor_fp, $time);
1722 last if (!defined($line));
1724 $full_line .= $line;
1726 if (defined($stop) && $full_line =~ /$stop/) {
1727 doprint "wait for monitor detected $stop\n";
1731 if ($full_line =~ /\[ backtrace testing \]/) {
1732 $skip_call_trace = 1;
1735 if ($full_line =~ /call trace:/i) {
1736 if (!$bug && !$skip_call_trace) {
1737 if ($ignore_errors) {
1745 if ($full_line =~ /\[ end of backtrace testing \]/) {
1746 $skip_call_trace = 0;
1749 if ($full_line =~ /Kernel panic -/) {
1753 if ($line =~ /\n/) {
1757 if ($now - $start_time >= $max_monitor_wait) {
1758 doprint "Exiting monitor flush due to hitting MAX_MONITOR_WAIT\n";
1762 print "** Monitor flushed **\n";
1764 # if stop is defined but wasn't hit, return error
1765 # used by reboot (which wants to see a reboot)
1766 if (defined($stop) && !$booted) {
1773 my ($result, $basedir) = @_;
1775 my $date = sprintf "%04d%02d%02d%02d%02d%02d",
1776 1900+$t[5],$t[4],$t[3],$t[2],$t[1],$t[0];
1778 my $type = $build_type;
1779 if ($type =~ /useconfig/) {
1780 $type = "useconfig";
1783 my $dir = "$machine-$test_type-$type-$result-$date";
1785 $dir = "$basedir/$dir";
1789 dodie "can't create $dir";
1793 "config" => $output_config,
1794 "buildlog" => $buildlog,
1796 "testlog" => $testlog,
1799 while (my ($name, $source) = each(%files)) {
1801 cp "$source", "$dir/$name" or
1802 dodie "failed to copy $source";
1806 doprint "*** Saved info to $dir ***\n";
1811 if ($die_on_failure) {
1819 # no need to reboot for just building.
1820 if (!do_not_reboot) {
1821 doprint "REBOOTING\n";
1822 reboot_to_good $sleep_time;
1827 if (defined($test_name)) {
1828 $name = " ($test_name)";
1833 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
1834 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
1835 doprint "KTEST RESULT: TEST $i$name Failed: ", @_, "\n";
1836 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
1837 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
1839 if (defined($store_failures)) {
1840 save_logs "fail", $store_failures;
1843 if (defined($post_test)) {
1844 run_command $post_test;
1851 my ($command, $redirect, $timeout) = @_;
1858 my $command_orig = $command;
1860 $command =~ s/\$SSH_USER/$ssh_user/g;
1861 $command =~ s/\$MACHINE/$machine/g;
1863 if (!defined($timeout)) {
1864 $timeout = $run_timeout;
1867 if (!defined($timeout)) {
1868 $timeout = -1; # tell wait_for_input to wait indefinitely
1871 doprint("$command ... ");
1874 $pid = open(CMD, "$command 2>&1 |") or
1875 (fail "unable to exec $command" and return 0);
1877 if (defined($opt{"LOG_FILE"})) {
1881 if (defined($redirect)) {
1882 if ($redirect eq 1) {
1884 # Have the output of the command on its own line
1887 open (RD, ">$redirect") or
1888 dodie "failed to write to redirect $redirect";
1893 my $hit_timeout = 0;
1897 my $line = wait_for_input($fp, $timeout);
1898 if (!defined($line)) {
1900 if ($timeout >= 0 && (($now - $start_time) >= $timeout)) {
1901 doprint "Hit timeout of $timeout, killing process\n";
1907 print LOG $line if ($dolog);
1908 print RD $line if ($dord);
1909 print $line if ($dostdout);
1913 # shift 8 for real exit status
1914 $run_command_status = $? >> 8;
1916 if ($command_orig eq $default{REBOOT} &&
1917 $run_command_status == $reboot_return_code) {
1918 $run_command_status = 0;
1922 close(RD) if ($dord);
1925 my $delta = $end_time - $start_time;
1928 doprint "[1 second] ";
1930 doprint "[$delta seconds] ";
1934 $run_command_status = 1;
1937 if ($run_command_status) {
1938 doprint "FAILED!\n";
1940 doprint "SUCCESS\n";
1943 return !$run_command_status;
1947 my ($cmd, $timeout) = @_;
1948 my $cp_exec = $ssh_exec;
1950 $cp_exec =~ s/\$SSH_COMMAND/$cmd/g;
1951 return run_command "$cp_exec", undef , $timeout;
1955 my ($src, $dst, $cp_scp) = @_;
1957 $cp_scp =~ s/\$SRC_FILE/$src/g;
1958 $cp_scp =~ s/\$DST_FILE/$dst/g;
1960 return run_command "$cp_scp";
1963 sub run_scp_install {
1964 my ($src, $dst) = @_;
1966 my $cp_scp = $scp_to_target_install;
1968 return run_scp($src, $dst, $cp_scp);
1972 my ($src, $dst) = @_;
1974 my $cp_scp = $scp_to_target;
1976 return run_scp($src, $dst, $cp_scp);
1979 sub _get_grub_index {
1981 my ($command, $target, $skip, $submenu) = @_;
1983 return if (defined($grub_number) && defined($last_grub_menu) &&
1984 $last_grub_menu eq $grub_menu && defined($last_machine) &&
1985 $last_machine eq $machine);
1987 doprint "Find $reboot_type menu ... ";
1990 my $ssh_grub = $ssh_exec;
1991 $ssh_grub =~ s,\$SSH_COMMAND,$command,g;
1993 open(IN, "$ssh_grub |") or
1994 dodie "unable to execute $command";
1998 my $submenu_number = 0;
2005 } elsif (defined($submenu) && /$submenu/) {
2014 dodie "Could not find '$grub_menu' through $command on $machine"
2016 if ($submenu_number > 0) {
2017 $grub_number = "$submenu_number>$grub_number";
2019 doprint "$grub_number\n";
2020 $last_grub_menu = $grub_menu;
2021 $last_machine = $machine;
2024 sub get_grub_index {
2032 if ($reboot_type !~ /^grub/) {
2036 $grub_menu_qt = quotemeta($grub_menu);
2038 if ($reboot_type eq "grub") {
2039 $command = "cat /boot/grub/menu.lst";
2040 $target = '^\s*title\s+' . $grub_menu_qt . '\s*$';
2041 $skip = '^\s*title\s';
2042 } elsif ($reboot_type eq "grub2") {
2043 $command = "cat $grub_file";
2044 $target = '^\s*menuentry.*' . $grub_menu_qt;
2045 $skip = '^\s*menuentry';
2046 $submenu = '^\s*submenu\s';
2047 } elsif ($reboot_type eq "grub2bls") {
2048 $command = $grub_bls_get;
2049 $target = '^title=.*' . $grub_menu_qt;
2055 _get_grub_index($command, $target, $skip, $submenu);
2058 sub wait_for_input {
2059 my ($fp, $time) = @_;
2068 if (!defined($time)) {
2073 # Negative number means wait indefinitely
2078 vec($rin, fileno($fp), 1) = 1;
2079 vec($rin, fileno(\*STDIN), 1) = 1;
2084 $nr = select($rout=$rin, undef, undef, $time);
2088 # copy data from stdin to the console
2089 if (vec($rout, fileno(\*STDIN), 1) == 1) {
2090 $nr = sysread(\*STDIN, $buf, 1000);
2091 syswrite($fp, $buf, $nr) if ($nr > 0);
2094 # The timeout is based on time waiting for the fp data
2095 if (vec($rout, fileno($fp), 1) != 1) {
2096 last if (defined($time) && (time - $start_time > $time));
2102 # try to read one char at a time
2103 while (sysread $fp, $ch, 1) {
2105 last if ($ch eq "\n");
2108 last if (!length($line));
2116 if (defined($switch_to_test)) {
2117 run_command $switch_to_test;
2120 if ($reboot_type eq "grub") {
2121 run_ssh "'(echo \"savedefault --default=$grub_number --once\" | grub --batch)'";
2122 } elsif (($reboot_type eq "grub2") or ($reboot_type eq "grub2bls")) {
2123 run_ssh "$grub_reboot \"'$grub_number'\"";
2124 } elsif ($reboot_type eq "syslinux") {
2125 run_ssh "$syslinux --once \\\"$syslinux_label\\\" $syslinux_path";
2126 } elsif (defined $reboot_script) {
2127 run_command "$reboot_script";
2135 doprint "git rev-list --max-count=1 $commit ... ";
2136 my $sha1 = `git rev-list --max-count=1 $commit`;
2143 dodie "Failed to get git $commit";
2156 my $bug_ignored = 0;
2157 my $skip_call_trace = 0;
2160 my $start_time = time;
2167 open(DMESG, "> $dmesg") or
2168 dodie "unable to write to $dmesg";
2174 my $monitor_start = time;
2176 my $version_found = 0;
2179 if ($bug && defined($stop_after_failure) &&
2180 $stop_after_failure >= 0) {
2181 my $time = $stop_after_failure - (time - $failure_start);
2182 $line = wait_for_input($monitor_fp, $time);
2183 if (!defined($line)) {
2184 doprint "bug timed out after $booted_timeout seconds\n";
2185 doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
2189 $line = wait_for_input($monitor_fp, $booted_timeout);
2190 if (!defined($line)) {
2191 my $s = $booted_timeout == 1 ? "" : "s";
2192 doprint "Successful boot found: break after $booted_timeout second$s\n";
2196 $line = wait_for_input($monitor_fp);
2197 if (!defined($line)) {
2198 my $s = $timeout == 1 ? "" : "s";
2199 doprint "Timed out after $timeout second$s\n";
2207 # we are not guaranteed to get a full line
2208 $full_line .= $line;
2210 if ($full_line =~ /$success_line/) {
2212 $success_start = time;
2215 if ($booted && defined($stop_after_success) &&
2216 $stop_after_success >= 0) {
2218 if ($now - $success_start >= $stop_after_success) {
2219 doprint "Test forced to stop after $stop_after_success seconds after success\n";
2224 if ($full_line =~ /\[ backtrace testing \]/) {
2225 $skip_call_trace = 1;
2228 if ($full_line =~ /call trace:/i) {
2229 if (!$bug && !$skip_call_trace) {
2230 if ($ignore_errors) {
2234 $failure_start = time;
2239 if ($bug && defined($stop_after_failure) &&
2240 $stop_after_failure >= 0) {
2242 if ($now - $failure_start >= $stop_after_failure) {
2243 doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
2248 if ($full_line =~ /\[ end of backtrace testing \]/) {
2249 $skip_call_trace = 0;
2252 if ($full_line =~ /Kernel panic -/) {
2253 $failure_start = time;
2257 # Detect triple faults by testing the banner
2258 if ($full_line =~ /\bLinux version (\S+).*\n/) {
2259 if ($1 eq $version) {
2261 } elsif ($version_found && $detect_triplefault) {
2262 # We already booted into the kernel we are testing,
2263 # but now we booted into another kernel?
2264 # Consider this a triple fault.
2265 doprint "Already booted in Linux kernel $version, but now\n";
2266 doprint "we booted into Linux kernel $1.\n";
2267 doprint "Assuming that this is a triple fault.\n";
2268 doprint "To disable this: set DETECT_TRIPLE_FAULT to 0\n";
2273 if ($line =~ /\n/) {
2277 if ($stop_test_after > 0 && !$booted && !$bug) {
2278 if (time - $monitor_start > $stop_test_after) {
2279 doprint "STOP_TEST_AFTER ($stop_test_after seconds) timed out\n";
2285 my $end_time = time;
2286 $reboot_time = $end_time - $start_time;
2291 return 0 if ($in_bisect);
2292 fail "failed - got a bug report" and return 0;
2296 return 0 if ($in_bisect);
2297 fail "failed - never got a boot prompt." and return 0;
2301 doprint "WARNING: Call Trace detected but ignored due to IGNORE_ERRORS=1\n";
2307 sub eval_kernel_version {
2310 $option =~ s/\$KERNEL_VERSION/$version/g;
2315 sub do_post_install {
2317 return if (!defined($post_install));
2319 my $cp_post_install = eval_kernel_version $post_install;
2320 run_command "$cp_post_install" or
2321 dodie "Failed to run post install";
2324 # Sometimes the reboot fails, and will hang. We try to ssh to the box
2325 # and if we fail, we force another reboot, that should powercycle it.
2327 if (!run_ssh "echo testing connection") {
2334 return if ($no_install);
2336 my $start_time = time;
2338 if (defined($pre_install)) {
2339 my $cp_pre_install = eval_kernel_version $pre_install;
2340 run_command "$cp_pre_install" or
2341 dodie "Failed to run pre install";
2344 my $cp_target = eval_kernel_version $target_image;
2348 run_scp_install "$outputdir/$build_target", "$cp_target" or
2349 dodie "failed to copy image";
2351 my $install_mods = 0;
2353 # should we process modules?
2355 open(IN, "$output_config") or dodie("Can't read config file");
2357 if (/CONFIG_MODULES(=y)?/) {
2366 if (!$install_mods) {
2368 doprint "No modules needed\n";
2369 my $end_time = time;
2370 $install_time = $end_time - $start_time;
2374 run_command "$make INSTALL_MOD_STRIP=1 INSTALL_MOD_PATH=$tmpdir modules_install" or
2375 dodie "Failed to install modules";
2377 my $modlib = "/lib/modules/$version";
2378 my $modtar = "ktest-mods.tar.bz2";
2380 run_ssh "rm -rf $modlib" or
2381 dodie "failed to remove old mods: $modlib";
2383 # would be nice if scp -r did not follow symbolic links
2384 run_command "cd $tmpdir && tar -cjf $modtar lib/modules/$version" or
2385 dodie "making tarball";
2387 run_scp_mod "$tmpdir/$modtar", "/tmp" or
2388 dodie "failed to copy modules";
2390 unlink "$tmpdir/$modtar";
2392 run_ssh "'(cd / && tar xjf /tmp/$modtar)'" or
2393 dodie "failed to tar modules";
2395 run_ssh "rm -f /tmp/$modtar";
2399 my $end_time = time;
2400 $install_time = $end_time - $start_time;
2404 # get the release name
2405 return if ($have_version);
2406 doprint "$make kernelrelease ... ";
2407 $version = `$make -s kernelrelease | tail -1`;
2409 doprint "$version\n";
2413 sub start_monitor_and_install {
2414 # Make sure the stable kernel has finished booting
2416 # Install bisects, don't need console
2417 if (defined $console) {
2427 start_monitor if (defined $console);
2431 sub process_warning_line {
2436 # for distcc heterogeneous systems, some compilers
2437 # do things differently causing warning lines
2438 # to be slightly different. This makes an attempt
2439 # to fixe those issues.
2441 # chop off the index into the line
2442 # using distcc, some compilers give different indexes
2443 # depending on white space
2444 $line =~ s/^(\s*\S+:\d+:)\d+/$1/;
2446 # Some compilers use UTF-8 extended for quotes and some don't.
2447 $line =~ s/$utf8_quote/'/g;
2452 # Read buildlog and check against warnings file for any
2457 sub check_buildlog {
2458 return 1 if (!defined $warnings_file);
2462 # Failed builds should not reboot the target
2463 my $save_no_reboot = $no_reboot;
2466 if (-f $warnings_file) {
2467 open(IN, $warnings_file) or
2468 dodie "Error opening $warnings_file";
2471 if (/$check_build_re/) {
2472 my $warning = process_warning_line $_;
2474 $warnings_list{$warning} = 1;
2480 # If warnings file didn't exist, and WARNINGS_FILE exist,
2481 # then we fail on any warning!
2483 open(IN, $buildlog) or dodie "Can't open $buildlog";
2485 if (/$check_build_re/) {
2486 my $warning = process_warning_line $_;
2488 if (!defined $warnings_list{$warning}) {
2489 fail "New warning found (not in $warnings_file)\n$_\n";
2490 $no_reboot = $save_no_reboot;
2495 $no_reboot = $save_no_reboot;
2499 sub check_patch_buildlog {
2502 my @files = `git show $patch | diffstat -l`;
2504 foreach my $file (@files) {
2508 open(IN, "git show $patch |") or
2509 dodie "failed to show $patch";
2511 if (m,^--- a/(.*),) {
2513 $files[$#files] = $1;
2518 open(IN, $buildlog) or dodie "Can't open $buildlog";
2520 if (/^\s*(.*?):.*(warning|error)/) {
2522 foreach my $file (@files) {
2523 my $fullpath = "$builddir/$file";
2524 if ($file eq $err || $fullpath eq $err) {
2525 fail "$file built with warnings" and return 0;
2535 sub apply_min_config {
2536 my $outconfig = "$output_config.new";
2538 # Read the config file and remove anything that
2539 # is in the force_config hash (from minconfig and others)
2540 # then add the force config back.
2542 doprint "Applying minimum configurations into $output_config.new\n";
2544 open (OUT, ">$outconfig") or
2545 dodie "Can't create $outconfig";
2547 if (-f $output_config) {
2548 open (IN, $output_config) or
2549 dodie "Failed to open $output_config";
2551 if (/^(# )?(CONFIG_[^\s=]*)/) {
2552 next if (defined($force_config{$2}));
2558 foreach my $config (keys %force_config) {
2559 print OUT "$force_config{$config}\n";
2563 run_command "mv $outconfig $output_config";
2566 sub make_oldconfig {
2568 my @force_list = keys %force_config;
2570 if ($#force_list >= 0) {
2574 if (!run_command "$make olddefconfig") {
2575 # Perhaps olddefconfig doesn't exist in this version of the kernel
2577 doprint "olddefconfig failed, trying make oldnoconfig\n";
2578 if (!run_command "$make oldnoconfig") {
2579 doprint "oldnoconfig failed, trying yes '' | make oldconfig\n";
2580 # try a yes '' | oldconfig
2581 run_command "yes '' | $make oldconfig" or
2582 dodie "failed make config oldconfig";
2587 # read a config file and use this to force new configs.
2588 sub load_force_config {
2591 doprint "Loading force configs from $config\n";
2592 open(IN, $config) or
2593 dodie "failed to read $config";
2596 if (/^(CONFIG[^\s=]*)(\s*=.*)/) {
2597 $force_config{$1} = $_;
2598 } elsif (/^# (CONFIG_\S*) is not set/) {
2599 $force_config{$1} = $_;
2610 my $start_time = time;
2612 # Failed builds should not reboot the target
2613 my $save_no_reboot = $no_reboot;
2616 # Calculate a new version from here.
2619 if (defined($pre_build)) {
2620 my $ret = run_command $pre_build;
2621 if (!$ret && defined($pre_build_die) &&
2623 dodie "failed to pre_build\n";
2627 if ($type =~ /^useconfig:(.*)/) {
2628 run_command "cp $1 $output_config" or
2629 dodie "could not copy $1 to .config";
2631 $type = "oldconfig";
2634 # old config can ask questions
2635 if ($type eq "oldconfig") {
2636 $type = "olddefconfig";
2638 # allow for empty configs
2639 run_command "touch $output_config";
2642 run_command "mv $output_config $outputdir/config_temp" or
2643 dodie "moving .config";
2645 run_command "$make mrproper" or dodie "make mrproper";
2647 run_command "mv $outputdir/config_temp $output_config" or
2648 dodie "moving config_temp";
2650 } elsif (!$noclean) {
2651 unlink "$output_config";
2652 run_command "$make mrproper" or
2653 dodie "make mrproper";
2656 # add something to distinguish this build
2657 open(OUT, "> $outputdir/localversion") or dodie("Can't make localversion file");
2658 print OUT "$localversion\n";
2661 if (defined($minconfig)) {
2662 load_force_config($minconfig);
2665 if ($type ne "olddefconfig") {
2666 run_command "$make $type" or
2667 dodie "failed make config";
2669 # Run old config regardless, to enforce min configurations
2672 if (not defined($build_options)){
2673 $build_options = "";
2675 my $build_ret = run_command "$make $build_options", $buildlog;
2677 if (defined($post_build)) {
2678 # Because a post build may change the kernel version
2681 my $ret = run_command $post_build;
2682 if (!$ret && defined($post_build_die) &&
2684 dodie "failed to post_build\n";
2689 # bisect may need this to pass
2691 $no_reboot = $save_no_reboot;
2694 fail "failed build" and return 0;
2697 $no_reboot = $save_no_reboot;
2699 my $end_time = time;
2700 $build_time = $end_time - $start_time;
2706 if (!run_ssh "halt" or defined($power_off)) {
2707 if (defined($poweroff_after_halt)) {
2708 sleep $poweroff_after_halt;
2709 run_command "$power_off";
2713 run_command "$power_off";
2724 if (defined($test_name)) {
2725 $name = " ($test_name)";
2731 doprint "*******************************************\n";
2732 doprint "*******************************************\n";
2733 doprint "KTEST RESULT: TEST $i$name SUCCESS!!!! **\n";
2734 doprint "*******************************************\n";
2735 doprint "*******************************************\n";
2737 if (defined($store_successes)) {
2738 save_logs "success", $store_successes;
2741 if ($i != $opt{"NUM_TESTS"} && !do_not_reboot) {
2742 doprint "Reboot and wait $sleep_time seconds\n";
2743 reboot_to_good $sleep_time;
2746 if (defined($post_test)) {
2747 run_command $post_test;
2753 doprint "Pass, fail, or skip? [p/f/s]";
2756 if ($ans eq "p" || $ans eq "P") {
2758 } elsif ($ans eq "f" || $ans eq "F") {
2760 } elsif ($ans eq "s" || $ans eq "S") {
2763 print "Please answer 'p', 'f', or 's'\n";
2768 sub child_run_test {
2770 # child should have no power
2771 $reboot_on_error = 0;
2772 $poweroff_on_error = 0;
2773 $die_on_failure = 1;
2775 run_command $run_test, $testlog;
2777 exit $run_command_status;
2780 sub child_finished {
2790 my $bug_ignored = 0;
2792 my $start_time = time;
2796 doprint "run test $run_test\n";
2800 $SIG{CHLD} = qw(child_finished);
2804 child_run_test if (!$child_pid);
2809 $line = wait_for_input($monitor_fp, 1);
2810 if (defined($line)) {
2812 # we are not guaranteed to get a full line
2813 $full_line .= $line;
2816 if ($full_line =~ /call trace:/i) {
2817 if ($ignore_errors) {
2824 if ($full_line =~ /Kernel panic -/) {
2828 if ($line =~ /\n/) {
2832 } while (!$child_done && !$bug);
2834 if (!$bug && $bug_ignored) {
2835 doprint "WARNING: Call Trace detected but ignored due to IGNORE_ERRORS=1\n";
2839 my $failure_start = time;
2842 $line = wait_for_input($monitor_fp, 1);
2843 if (defined($line)) {
2847 if ($now - $failure_start >= $stop_after_failure) {
2850 } while (defined($line));
2852 doprint "Detected kernel crash!\n";
2853 # kill the child with extreme prejudice
2857 waitpid $child_pid, 0;
2858 $child_exit = $? >> 8;
2860 my $end_time = time;
2861 $test_time = $end_time - $start_time;
2863 if (!$bug && $in_bisect) {
2864 if (defined($bisect_ret_good)) {
2865 if ($child_exit == $bisect_ret_good) {
2869 if (defined($bisect_ret_skip)) {
2870 if ($child_exit == $bisect_ret_skip) {
2874 if (defined($bisect_ret_abort)) {
2875 if ($child_exit == $bisect_ret_abort) {
2876 fail "test abort" and return -2;
2879 if (defined($bisect_ret_bad)) {
2880 if ($child_exit == $bisect_ret_skip) {
2884 if (defined($bisect_ret_default)) {
2885 if ($bisect_ret_default eq "good") {
2887 } elsif ($bisect_ret_default eq "bad") {
2889 } elsif ($bisect_ret_default eq "skip") {
2891 } elsif ($bisect_ret_default eq "abort") {
2894 fail "unknown default action: $bisect_ret_default"
2900 if ($bug || $child_exit) {
2901 return 0 if $in_bisect;
2902 fail "test failed" and return 0;
2907 sub run_git_bisect {
2910 doprint "$command ... ";
2912 my $output = `$command 2>&1`;
2919 dodie "Failed to git bisect";
2922 doprint "SUCCESS\n";
2923 if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\))\s+\[([[:xdigit:]]+)\]/) {
2924 doprint "$1 [$2]\n";
2925 } elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) {
2926 $bisect_bad_commit = $1;
2927 doprint "Found bad commit... $1\n";
2930 # we already logged it, just print it now.
2938 doprint "Reboot and sleep $bisect_sleep_time seconds\n";
2939 reboot_to_good $bisect_sleep_time;
2942 # returns 1 on success, 0 on failure, -1 on skip
2943 sub run_bisect_test {
2944 my ($type, $buildtype) = @_;
2953 build $buildtype or $failed = 1;
2955 if ($type ne "build") {
2956 if ($failed && $bisect_skip) {
2960 dodie "Failed on build" if $failed;
2963 start_monitor_and_install or $failed = 1;
2965 if ($type ne "boot") {
2966 if ($failed && $bisect_skip) {
2972 dodie "Failed on boot" if $failed;
2974 do_run_test or $failed = 1;
2985 # reboot the box to a kernel we can ssh to
2986 if ($type ne "build") {
2996 my $buildtype = "oldconfig";
2998 # We should have a minconfig to use?
2999 if (defined($minconfig)) {
3000 $buildtype = "useconfig:$minconfig";
3003 # If the user sets bisect_tries to less than 1, then no tries
3007 # Still let the user manually decide that though.
3008 if ($bisect_tries < 1 && $bisect_manual) {
3009 $ret = answer_bisect;
3012 for (my $i = 0; $i < $bisect_tries; $i++) {
3013 if ($bisect_tries > 1) {
3015 doprint("Running bisect trial $t of $bisect_tries:\n");
3017 $ret = run_bisect_test $type, $buildtype;
3019 if ($bisect_manual) {
3020 $ret = answer_bisect;
3026 # Are we looking for where it worked, not failed?
3027 if ($reverse_bisect && $ret >= 0) {
3033 } elsif ($ret == 0) {
3035 } elsif ($bisect_skip) {
3036 doprint "HIT A BAD COMMIT ... SKIPPING\n";
3041 sub update_bisect_replay {
3042 my $tmp_log = "$tmpdir/ktest_bisect_log";
3043 run_command "git bisect log > $tmp_log" or
3044 dodie "can't create bisect log";
3053 dodie "BISECT_GOOD[$i] not defined\n" if (!defined($bisect_good));
3054 dodie "BISECT_BAD[$i] not defined\n" if (!defined($bisect_bad));
3055 dodie "BISECT_TYPE[$i] not defined\n" if (!defined($bisect_type));
3057 my $good = $bisect_good;
3058 my $bad = $bisect_bad;
3059 my $type = $bisect_type;
3060 my $start = $bisect_start;
3061 my $replay = $bisect_replay;
3062 my $start_files = $bisect_files;
3064 if (defined($start_files)) {
3065 $start_files = " -- " . $start_files;
3070 # convert to true sha1's
3071 $good = get_sha1($good);
3072 $bad = get_sha1($bad);
3074 if (defined($bisect_reverse) && $bisect_reverse == 1) {
3075 doprint "Performing a reverse bisect (bad is good, good is bad!)\n";
3076 $reverse_bisect = 1;
3078 $reverse_bisect = 0;
3081 # Can't have a test without having a test to run
3082 if ($type eq "test" && !defined($run_test)) {
3086 # Check if a bisect was running
3087 my $bisect_start_file = "$builddir/.git/BISECT_START";
3089 my $check = $bisect_check;
3090 my $do_check = defined($check) && $check ne "0";
3092 if ( -f $bisect_start_file ) {
3093 print "Bisect in progress found\n";
3095 print " If you say yes, then no checks of good or bad will be done\n";
3097 if (defined($replay)) {
3098 print "** BISECT_REPLAY is defined in config file **";
3099 print " Ignore config option and perform new git bisect log?\n";
3100 if (read_ync " (yes, no, or cancel) ") {
3101 $replay = update_bisect_replay;
3104 } elsif (read_yn "read git log and continue?") {
3105 $replay = update_bisect_replay;
3112 my $head = get_sha1("HEAD");
3114 if ($check ne "good") {
3115 doprint "TESTING BISECT BAD [$bad]\n";
3116 run_command "git checkout $bad" or
3117 dodie "Failed to checkout $bad";
3119 $result = run_bisect $type;
3121 if ($result ne "bad") {
3122 fail "Tested BISECT_BAD [$bad] and it succeeded" and return 0;
3126 if ($check ne "bad") {
3127 doprint "TESTING BISECT GOOD [$good]\n";
3128 run_command "git checkout $good" or
3129 dodie "Failed to checkout $good";
3131 $result = run_bisect $type;
3133 if ($result ne "good") {
3134 fail "Tested BISECT_GOOD [$good] and it failed" and return 0;
3138 # checkout where we started
3139 run_command "git checkout $head" or
3140 dodie "Failed to checkout $head";
3143 run_command "git bisect start$start_files" or
3144 dodie "could not start bisect";
3146 if (defined($replay)) {
3147 run_command "git bisect replay $replay" or
3148 dodie "failed to run replay";
3150 run_command "git bisect good $good" or
3151 dodie "could not set bisect good to $good";
3153 run_git_bisect "git bisect bad $bad" or
3154 dodie "could not set bisect bad to $bad";
3157 if (defined($start)) {
3158 run_command "git checkout $start" or
3159 dodie "failed to checkout $start";
3164 $result = run_bisect $type;
3165 $test = run_git_bisect "git bisect $result";
3169 run_command "git bisect log" or
3170 dodie "could not capture git bisect log";
3172 run_command "git bisect reset" or
3173 dodie "could not reset git bisect";
3175 doprint "Bad commit was [$bisect_bad_commit]\n";
3180 sub assign_configs {
3181 my ($hash, $config) = @_;
3183 doprint "Reading configs from $config\n";
3185 open (IN, $config) or
3186 dodie "Failed to read $config";
3190 if (/^((CONFIG\S*)=.*)/) {
3192 } elsif (/^(# (CONFIG\S*) is not set)/) {
3200 sub process_config_ignore {
3203 assign_configs \%config_ignore, $config;
3206 sub get_dependencies {
3209 my $arr = $dependency{$config};
3210 if (!defined($arr)) {
3216 foreach my $dep (@{$arr}) {
3217 print "ADD DEP $dep\n";
3218 @deps = (@deps, get_dependencies $dep);
3225 my ($pc, $file) = @_;
3227 my %configs = %{$pc};
3229 doprint "Saving configs into $file\n";
3231 open(OUT, ">$file") or dodie "Can not write to $file";
3233 foreach my $config (keys %configs) {
3234 print OUT "$configs{$config}\n";
3240 my ($name, $pc) = @_;
3242 doprint "Creating old config from $name configs\n";
3244 save_config $pc, $output_config;
3249 sub run_config_bisect_test {
3252 my $ret = run_bisect_test $type, "oldconfig";
3254 if ($bisect_manual) {
3255 $ret = answer_bisect;
3261 sub config_bisect_end {
3262 my ($good, $bad) = @_;
3263 my $diffexec = "diff -u";
3265 if (-f "$builddir/scripts/diffconfig") {
3266 $diffexec = "$builddir/scripts/diffconfig";
3268 doprint "\n\n***************************************\n";
3269 doprint "No more config bisecting possible.\n";
3270 run_command "$diffexec $good $bad", 1;
3271 doprint "***************************************\n\n";
3274 sub run_config_bisect {
3275 my ($good, $bad, $last_result) = @_;
3280 if (!length($last_result)) {
3283 run_command "$config_bisect_exec $reset -b $outputdir $good $bad $last_result", 1;
3285 # config-bisect returns:
3286 # 0 if there is more to bisect
3287 # 1 for finding a good config
3288 # 2 if it can not find any more configs
3290 if ($run_command_status) {
3291 return $run_command_status;
3294 $ret = run_config_bisect_test $config_bisect_type;
3296 doprint "NEW GOOD CONFIG ($pass)\n";
3297 system("cp $output_config $tmpdir/good_config.tmp.$pass");
3299 # Return 3 for good config
3302 doprint "NEW BAD CONFIG ($pass)\n";
3303 system("cp $output_config $tmpdir/bad_config.tmp.$pass");
3305 # Return 4 for bad config
3316 my $type = $config_bisect_type;
3319 $bad_config = $config_bisect;
3321 if (defined($config_bisect_good)) {
3322 $good_config = $config_bisect_good;
3323 } elsif (defined($minconfig)) {
3324 $good_config = $minconfig;
3326 doprint "No config specified, checking if defconfig works";
3327 $ret = run_bisect_test $type, "defconfig";
3329 fail "Have no good config to compare with, please set CONFIG_BISECT_GOOD";
3332 $good_config = $output_config;
3335 if (!defined($config_bisect_exec)) {
3336 # First check the location that ktest.pl ran
3338 "$pwd/config-bisect.pl",
3339 "$dirname/config-bisect.pl",
3340 "$builddir/tools/testing/ktest/config-bisect.pl",
3342 foreach my $loc (@locations) {
3343 doprint "loc = $loc\n";
3344 $config_bisect_exec = $loc;
3345 last if (defined($config_bisect_exec && -x $config_bisect_exec));
3347 if (!defined($config_bisect_exec)) {
3348 fail "Could not find an executable config-bisect.pl\n",
3349 " Set CONFIG_BISECT_EXEC to point to config-bisect.pl";
3354 # we don't want min configs to cause issues here.
3355 doprint "Disabling 'MIN_CONFIG' for this test\n";
3362 if (-f "$tmpdir/good_config.tmp" || -f "$tmpdir/bad_config.tmp") {
3363 if (read_yn "Interrupted config-bisect. Continue (n - will start new)?") {
3364 if (-f "$tmpdir/good_config.tmp") {
3365 $good_config = "$tmpdir/good_config.tmp";
3367 $good_config = "$tmpdir/good_config";
3369 if (-f "$tmpdir/bad_config.tmp") {
3370 $bad_config = "$tmpdir/bad_config.tmp";
3372 $bad_config = "$tmpdir/bad_config";
3376 doprint "Run good configs through make oldconfig\n";
3377 assign_configs \%tmp_configs, $good_config;
3378 create_config "$good_config", \%tmp_configs;
3379 $good_config = "$tmpdir/good_config";
3380 system("cp $output_config $good_config") == 0 or dodie "cp good config";
3382 doprint "Run bad configs through make oldconfig\n";
3383 assign_configs \%tmp_configs, $bad_config;
3384 create_config "$bad_config", \%tmp_configs;
3385 $bad_config = "$tmpdir/bad_config";
3386 system("cp $output_config $bad_config") == 0 or dodie "cp bad config";
3388 if (defined($config_bisect_check) && $config_bisect_check ne "0") {
3389 if ($config_bisect_check ne "good") {
3390 doprint "Testing bad config\n";
3392 $ret = run_bisect_test $type, "useconfig:$bad_config";
3394 fail "Bad config succeeded when expected to fail!";
3398 if ($config_bisect_check ne "bad") {
3399 doprint "Testing good config\n";
3401 $ret = run_bisect_test $type, "useconfig:$good_config";
3403 fail "Good config failed when expected to succeed!";
3412 $ret = run_config_bisect $good_config, $bad_config, $last_run;
3415 } elsif ($ret == 4) {
3419 } while ($ret == 3 || $ret == 4);
3422 config_bisect_end "$good_config.tmp", "$bad_config.tmp";
3425 return $ret if ($ret < 0);
3430 sub patchcheck_reboot {
3431 doprint "Reboot and sleep $patchcheck_sleep_time seconds\n";
3432 reboot_to_good $patchcheck_sleep_time;
3438 dodie "PATCHCHECK_START[$i] not defined\n"
3439 if (!defined($patchcheck_start));
3440 dodie "PATCHCHECK_TYPE[$i] not defined\n"
3441 if (!defined($patchcheck_type));
3443 my $start = $patchcheck_start;
3445 my $cherry = $patchcheck_cherry;
3446 if (!defined($cherry)) {
3451 if (defined($patchcheck_end)) {
3452 $end = $patchcheck_end;
3454 dodie "PATCHCHECK_END must be defined with PATCHCHECK_CHERRY\n";
3457 # Get the true sha1's since we can use things like HEAD~3
3458 $start = get_sha1($start);
3459 $end = get_sha1($end);
3461 my $type = $patchcheck_type;
3463 # Can't have a test without having a test to run
3464 if ($type eq "test" && !defined($run_test)) {
3469 open (IN, "git cherry -v $start $end|") or
3470 dodie "could not get git list";
3472 open (IN, "git log --pretty=oneline $end|") or
3473 dodie "could not get git list";
3480 # git cherry adds a '+' we want to remove
3482 $list[$#list+1] = $_;
3483 last if (/^$start/);
3488 if ($list[$#list] !~ /^$start/) {
3489 fail "SHA1 $start not found";
3492 # go backwards in the list
3493 @list = reverse @list;
3496 doprint("Going to test the following commits:\n");
3497 foreach my $l (@list) {
3501 my $save_clean = $noclean;
3502 my %ignored_warnings;
3504 if (defined($ignore_warnings)) {
3505 foreach my $sha1 (split /\s+/, $ignore_warnings) {
3506 $ignored_warnings{$sha1} = 1;
3511 foreach my $item (@list) {
3513 $sha1 =~ s/^([[:xdigit:]]+).*/$1/;
3515 doprint "\nProcessing commit \"$item\"\n\n";
3517 run_command "git checkout $sha1" or
3518 dodie "Failed to checkout $sha1";
3520 # only clean on the first and last patch
3521 if ($item eq $list[0] ||
3522 $item eq $list[$#list]) {
3523 $noclean = $save_clean;
3528 if (defined($minconfig)) {
3529 build "useconfig:$minconfig" or return 0;
3531 # ?? no config to use?
3532 build "oldconfig" or return 0;
3535 # No need to do per patch checking if warnings file exists
3536 if (!defined($warnings_file) && !defined($ignored_warnings{$sha1})) {
3537 check_patch_buildlog $sha1 or return 0;
3540 check_buildlog or return 0;
3542 next if ($type eq "build");
3546 start_monitor_and_install or $failed = 1;
3548 if (!$failed && $type ne "boot"){
3549 do_run_test or $failed = 1;
3566 # $config depends on $dep
3567 my ($config, $dep) = @_;
3569 if (defined($depends{$config})) {
3570 $depends{$config} .= " " . $dep;
3572 $depends{$config} = $dep;
3575 # record the number of configs depending on $dep
3576 if (defined $depcount{$dep}) {
3579 $depcount{$dep} = 1;
3583 # taken from streamline_config.pl
3594 if (! -f $kconfig) {
3595 doprint "file $kconfig does not exist, skipping\n";
3599 open(KIN, "$kconfig")
3600 or dodie "Can't open $kconfig";
3604 # Make sure that lines ending with \ continue
3606 $_ = $line . " " . $_;
3617 # collect any Kconfig sources
3618 if (/^source\s*"(.*)"/) {
3619 $kconfigs[$#kconfigs+1] = $1;
3623 if (/^\s*(menu)?config\s+(\S+)\s*$/) {
3627 for (my $i = 0; $i < $iflevel; $i++) {
3628 add_dep $config, $ifdeps[$i];
3631 # collect the depends for the config
3632 } elsif ($state eq "NEW" && /^\s*depends\s+on\s+(.*)$/) {
3634 add_dep $config, $1;
3636 # Get the configs that select this config
3637 } elsif ($state eq "NEW" && /^\s*select\s+(\S+)/) {
3639 # selected by depends on config
3640 add_dep $1, $config;
3642 # Check for if statements
3643 } elsif (/^if\s+(.*\S)\s*$/) {
3645 # remove beginning and ending non text
3646 $deps =~ s/^[^a-zA-Z0-9_]*//;
3647 $deps =~ s/[^a-zA-Z0-9_]*$//;
3649 my @deps = split /[^a-zA-Z0-9_]+/, $deps;
3651 $ifdeps[$iflevel++] = join ':', @deps;
3653 } elsif (/^endif/) {
3655 $iflevel-- if ($iflevel);
3658 } elsif (/^\s*help\s*$/) {
3664 # read in any configs that were found.
3665 foreach $kconfig (@kconfigs) {
3666 if (!defined($read_kconfigs{$kconfig})) {
3667 $read_kconfigs{$kconfig} = 1;
3668 read_kconfig("$builddir/$kconfig");
3674 # find out which arch this is by the kconfig file
3675 open (IN, $output_config) or
3676 dodie "Failed to read $output_config";
3679 if (m,Linux/(\S+)\s+\S+\s+Kernel Configuration,) {
3686 if (!defined($arch)) {
3687 doprint "Could not find arch from config file\n";
3688 doprint "no dependencies used\n";
3692 # arch is really the subarch, we need to know
3693 # what directory to look at.
3694 if ($arch eq "i386" || $arch eq "x86_64") {
3698 my $kconfig = "$builddir/arch/$arch/Kconfig";
3700 if (! -f $kconfig && $arch =~ /\d$/) {
3702 # some subarchs have numbers, truncate them
3704 $kconfig = "$builddir/arch/$arch/Kconfig";
3705 if (! -f $kconfig) {
3706 doprint "No idea what arch dir $orig is for\n";
3707 doprint "no dependencies used\n";
3712 read_kconfig($kconfig);
3715 sub make_new_config {
3718 open (OUT, ">$output_config")
3719 or dodie "Failed to write $output_config";
3721 foreach my $config (@configs) {
3722 print OUT "$config\n";
3730 $config =~ s/CONFIG_//;
3738 my $kconfig = chomp_config $dep;
3740 $dep = $depends{"$kconfig"};
3742 # the dep string we have saves the dependencies as they
3743 # were found, including expressions like ! && ||. We
3744 # want to split this out into just an array of configs.
3746 my $valid = "A-Za-z_0-9";
3750 while ($dep =~ /[$valid]/) {
3751 if ($dep =~ /^[^$valid]*([$valid]+)/) {
3752 my $conf = "CONFIG_" . $1;
3754 $configs[$#configs + 1] = $conf;
3756 $dep =~ s/^[^$valid]*[$valid]+//;
3758 dodie "this should never happen";
3765 sub test_this_config {
3770 # if we already processed this config, skip it
3771 if (defined($processed_configs{$config})) {
3774 $processed_configs{$config} = 1;
3776 # if this config failed during this round, skip it
3777 if (defined($nochange_config{$config})) {
3781 my $kconfig = chomp_config $config;
3783 # Test dependencies first
3784 if (defined($depends{"$kconfig"})) {
3785 my @parents = get_depends $config;
3786 foreach my $parent (@parents) {
3787 # if the parent is in the min config, check it first
3788 next if (!defined($min_configs{$parent}));
3789 $found = test_this_config($parent);
3790 if (defined($found)) {
3796 # Remove this config from the list of configs
3797 # do a make olddefconfig and then read the resulting
3798 # .config to make sure it is missing the config that
3800 my %configs = %min_configs;
3801 $configs{$config} = "# $config is not set";
3802 make_new_config ((values %configs), (values %keep_configs));
3804 delete $configs{$config};
3806 assign_configs \%configs, $output_config;
3808 if (!defined($configs{$config}) || $configs{$config} =~ /^#/) {
3812 doprint "disabling config $config did not change .config\n";
3814 $nochange_config{$config} = 1;
3819 sub make_min_config {
3822 my $type = $minconfig_type;
3823 if ($type ne "boot" && $type ne "test") {
3824 fail "Invalid MIN_CONFIG_TYPE '$minconfig_type'\n" .
3825 " make_min_config works only with 'boot' and 'test'\n" and return;
3828 if (!defined($output_minconfig)) {
3829 fail "OUTPUT_MIN_CONFIG not defined" and return;
3832 # If output_minconfig exists, and the start_minconfig
3833 # came from min_config, than ask if we should use
3835 if (-f $output_minconfig && !$start_minconfig_defined) {
3836 print "$output_minconfig exists\n";
3837 if (!defined($use_output_minconfig)) {
3838 if (read_yn " Use it as minconfig?") {
3839 $start_minconfig = $output_minconfig;
3841 } elsif ($use_output_minconfig > 0) {
3842 doprint "Using $output_minconfig as MIN_CONFIG\n";
3843 $start_minconfig = $output_minconfig;
3845 doprint "Set to still use MIN_CONFIG as starting point\n";
3849 if (!defined($start_minconfig)) {
3850 fail "START_MIN_CONFIG or MIN_CONFIG not defined" and return;
3853 my $temp_config = "$tmpdir/temp_config";
3855 # First things first. We build an allnoconfig to find
3856 # out what the defaults are that we can't touch.
3857 # Some are selections, but we really can't handle selections.
3859 my $save_minconfig = $minconfig;
3862 run_command "$make allnoconfig" or return 0;
3866 process_config_ignore $output_config;
3868 undef %save_configs;
3871 if (defined($ignore_config)) {
3872 # make sure the file exists
3873 `touch $ignore_config`;
3874 assign_configs \%save_configs, $ignore_config;
3877 %keep_configs = %save_configs;
3879 doprint "Load initial configs from $start_minconfig\n";
3881 # Look at the current min configs, and save off all the
3882 # ones that were set via the allnoconfig
3883 assign_configs \%min_configs, $start_minconfig;
3885 my @config_keys = keys %min_configs;
3887 # All configs need a depcount
3888 foreach my $config (@config_keys) {
3889 my $kconfig = chomp_config $config;
3890 if (!defined $depcount{$kconfig}) {
3891 $depcount{$kconfig} = 0;
3895 # Remove anything that was set by the make allnoconfig
3896 # we shouldn't need them as they get set for us anyway.
3897 foreach my $config (@config_keys) {
3898 # Remove anything in the ignore_config
3899 if (defined($keep_configs{$config})) {
3900 my $file = $ignore_config;
3901 $file =~ s,.*/(.*?)$,$1,;
3902 doprint "$config set by $file ... ignored\n";
3903 delete $min_configs{$config};
3906 # But make sure the settings are the same. If a min config
3907 # sets a selection, we do not want to get rid of it if
3908 # it is not the same as what we have. Just move it into
3910 if (defined($config_ignore{$config})) {
3911 if ($config_ignore{$config} ne $min_configs{$config}) {
3912 doprint "$config is in allnoconfig as '$config_ignore{$config}'";
3913 doprint " but it is '$min_configs{$config}' in minconfig .. keeping\n";
3914 $keep_configs{$config} = $min_configs{$config};
3916 doprint "$config set by allnoconfig ... ignored\n";
3918 delete $min_configs{$config};
3929 # Now disable each config one by one and do a make oldconfig
3930 # till we find a config that changes our list.
3932 my @test_configs = keys %min_configs;
3934 # Sort keys by who is most dependent on
3935 @test_configs = sort { $depcount{chomp_config($b)} <=> $depcount{chomp_config($a)} }
3938 # Put configs that did not modify the config at the end.
3940 for (my $i = 0; $i < $#test_configs; $i++) {
3941 if (!defined($nochange_config{$test_configs[0]})) {
3945 # This config didn't change the .config last time.
3946 # Place it at the end
3947 my $config = shift @test_configs;
3948 push @test_configs, $config;
3951 # if every test config has failed to modify the .config file
3952 # in the past, then reset and start over.
3954 undef %nochange_config;
3957 undef %processed_configs;
3959 foreach my $config (@test_configs) {
3961 $found = test_this_config $config;
3963 last if (defined($found));
3965 # oh well, try another config
3968 if (!defined($found)) {
3969 # we could have failed due to the nochange_config hash
3970 # reset and try again
3972 undef %nochange_config;
3976 doprint "No more configs found that we can disable\n";
3984 doprint "Test with $config disabled\n";
3986 # set in_bisect to keep build and monitor from dieing
3990 build "oldconfig" or $failed = 1;
3992 start_monitor_and_install or $failed = 1;
3994 if ($type eq "test" && !$failed) {
3995 do_run_test or $failed = 1;
4004 doprint "$min_configs{$config} is needed to boot the box... keeping\n";
4005 # this config is needed, add it to the ignore list.
4006 $keep_configs{$config} = $min_configs{$config};
4007 $save_configs{$config} = $min_configs{$config};
4008 delete $min_configs{$config};
4010 # update new ignore configs
4011 if (defined($ignore_config)) {
4012 open (OUT, ">$temp_config") or
4013 dodie "Can't write to $temp_config";
4014 foreach my $config (keys %save_configs) {
4015 print OUT "$save_configs{$config}\n";
4018 run_command "mv $temp_config $ignore_config" or
4019 dodie "failed to copy update to $ignore_config";
4023 # We booted without this config, remove it from the minconfigs.
4024 doprint "$config is not needed, disabling\n";
4026 delete $min_configs{$config};
4028 # Also disable anything that is not enabled in this config
4030 assign_configs \%configs, $output_config;
4031 my @config_keys = keys %min_configs;
4032 foreach my $config (@config_keys) {
4033 if (!defined($configs{$config})) {
4034 doprint "$config is not set, disabling\n";
4035 delete $min_configs{$config};
4039 # Save off all the current mandatory configs
4040 open (OUT, ">$temp_config") or
4041 dodie "Can't write to $temp_config";
4042 foreach my $config (keys %keep_configs) {
4043 print OUT "$keep_configs{$config}\n";
4045 foreach my $config (keys %min_configs) {
4046 print OUT "$min_configs{$config}\n";
4050 run_command "mv $temp_config $output_minconfig" or
4051 dodie "failed to copy update to $output_minconfig";
4054 doprint "Reboot and wait $sleep_time seconds\n";
4055 reboot_to_good $sleep_time;
4062 sub make_warnings_file {
4065 if (!defined($warnings_file)) {
4066 dodie "Must define WARNINGS_FILE for make_warnings_file test";
4069 if ($build_type eq "nobuild") {
4070 dodie "BUILD_TYPE can not be 'nobuild' for make_warnings_file test";
4073 build $build_type or dodie "Failed to build";
4075 open(OUT, ">$warnings_file") or dodie "Can't create $warnings_file";
4077 open(IN, $buildlog) or dodie "Can't open $buildlog";
4079 # Some compilers use UTF-8 extended for quotes
4080 # for distcc heterogeneous systems, this causes issues
4083 if (/$check_build_re/) {
4094 sub option_defined {
4097 if (defined($opt{$option}) && $opt{$option} !~ /^\s*$/) {
4104 sub __set_test_option {
4105 my ($name, $i) = @_;
4107 my $option = "$name\[$i\]";
4109 if (option_defined($option)) {
4110 return $opt{$option};
4113 foreach my $test (keys %repeat_tests) {
4115 $i < $test + $repeat_tests{$test}) {
4116 $option = "$name\[$test\]";
4117 if (option_defined($option)) {
4118 return $opt{$option};
4123 if (option_defined($name)) {
4130 sub set_test_option {
4131 my ($name, $i) = @_;
4133 my $option = __set_test_option($name, $i);
4134 return $option if (!defined($option));
4136 return eval_option($name, $option, $i);
4142 my @paths = split /:/, $ENV{PATH};
4144 # sendmail is usually in /usr/sbin
4145 $paths[$#paths + 1] = "/usr/sbin";
4147 foreach my $path (@paths) {
4148 if (-x "$path/$mailer") {
4157 my ($subject, $message, $file) = @_;
4159 if (!defined($mail_path)) {
4161 $mail_path = find_mailer $mailer;
4162 if (!defined($mail_path)) {
4163 die "\nCan not find $mailer in PATH\n";
4167 my $header_file = "$tmpdir/header";
4168 open (HEAD, ">$header_file") or die "Can not create $header_file\n";
4169 print HEAD "To: $mailto\n";
4170 print HEAD "Subject: $subject\n\n";
4171 print HEAD "$message\n";
4174 if (!defined($mail_command)) {
4175 if ($mailer eq "mail" || $mailer eq "mailx") {
4176 $mail_command = "cat \$HEADER_FILE \$BODY_FILE | \$MAIL_PATH/\$MAILER -s \'\$SUBJECT\' \$MAILTO";
4177 } elsif ($mailer eq "sendmail" ) {
4178 $mail_command = "cat \$HEADER_FILE \$BODY_FILE | \$MAIL_PATH/\$MAILER -t \$MAILTO";
4180 die "\nYour mailer: $mailer is not supported.\n";
4184 if (defined($file)) {
4185 $mail_command =~ s/\$BODY_FILE/$file/g;
4187 $mail_command =~ s/\$BODY_FILE//g;
4190 $mail_command =~ s/\$HEADER_FILE/$header_file/g;
4191 $mail_command =~ s/\$MAILER/$mailer/g;
4192 $mail_command =~ s/\$MAIL_PATH/$mail_path/g;
4193 $mail_command =~ s/\$MAILTO/$mailto/g;
4194 $mail_command =~ s/\$SUBJECT/$subject/g;
4195 $mail_command =~ s/\$MESSAGE/$message/g;
4197 my $ret = run_command $mail_command;
4198 if (!$ret && defined($file)) {
4199 # try again without the file
4200 $message .= "\n\n*** FAILED TO SEND LOG ***\n\n";
4201 do_send_email($subject, $message);
4206 if (defined($mailto)) {
4207 if (!defined($mailer)) {
4208 doprint "No email sent: email or mailer not specified in config.\n";
4219 if ($email_when_canceled) {
4220 my $name = get_test_name;
4221 send_email("KTEST: Your [$name] test was cancelled",
4222 "Your test started at $script_start_time was cancelled: sig int");
4224 die "\nCaught Sig Int, test interrupted: $!\n"
4227 $#ARGV < 1 or die "ktest.pl version: $VERSION\n usage: ktest.pl [config-file]\n";
4230 $ktest_config = $ARGV[0];
4231 if (! -f $ktest_config) {
4232 print "$ktest_config does not exist.\n";
4233 if (!read_yn "Create it?") {
4239 if (! -f $ktest_config) {
4242 open(OUT, ">$ktest_config") or die "Can not create $ktest_config";
4244 # Generated by ktest.pl
4247 # PWD is a ktest.pl variable that will result in the process working
4248 # directory that ktest.pl is executed in.
4250 # THIS_DIR is automatically assigned the PWD of the path that generated
4251 # the config file. It is best to use this variable when assigning other
4252 # directory paths within this directory. This allows you to easily
4253 # move the test cases to other locations or to other machines.
4255 THIS_DIR := $variable{"PWD"}
4257 # Define each test with TEST_START
4258 # The config options below it will override the defaults
4260 TEST_TYPE = $default{"TEST_TYPE"}
4267 read_config $ktest_config;
4269 if (defined($opt{"LOG_FILE"})) {
4270 $opt{"LOG_FILE"} = eval_option("LOG_FILE", $opt{"LOG_FILE"}, -1);
4273 # Append any configs entered in manually to the config file.
4274 my @new_configs = keys %entered_configs;
4275 if ($#new_configs >= 0) {
4276 print "\nAppending entered in configs to $ktest_config\n";
4277 open(OUT, ">>$ktest_config") or die "Can not append to $ktest_config";
4278 foreach my $config (@new_configs) {
4279 print OUT "$config = $entered_configs{$config}\n";
4280 $opt{$config} = process_variables($entered_configs{$config});
4284 if (defined($opt{"LOG_FILE"})) {
4285 if ($opt{"CLEAR_LOG"}) {
4286 unlink $opt{"LOG_FILE"};
4288 open(LOG, ">> $opt{LOG_FILE}") or die "Can't write to $opt{LOG_FILE}";
4292 doprint "\n\nSTARTING AUTOMATED TESTS\n\n";
4294 for (my $i = 0, my $repeat = 1; $i <= $opt{"NUM_TESTS"}; $i += $repeat) {
4297 doprint "DEFAULT OPTIONS:\n";
4299 doprint "\nTEST $i OPTIONS";
4300 if (defined($repeat_tests{$i})) {
4301 $repeat = $repeat_tests{$i};
4302 doprint " ITERATE $repeat";
4307 foreach my $option (sort keys %opt) {
4308 if ($option =~ /\[(\d+)\]$/) {
4314 doprint "$option = $opt{$option}\n";
4318 $SIG{INT} = qw(cancel_test);
4320 # First we need to do is the builds
4321 for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
4323 # Do not reboot on failing test options
4325 $reboot_success = 0;
4336 undef %force_config;
4338 my $makecmd = set_test_option("MAKE_CMD", $i);
4340 $outputdir = set_test_option("OUTPUT_DIR", $i);
4341 $builddir = set_test_option("BUILD_DIR", $i);
4343 chdir $builddir || dodie "can't change directory to $builddir";
4345 if (!-d $outputdir) {
4346 mkpath($outputdir) or
4347 dodie "can't create $outputdir";
4350 $make = "$makecmd O=$outputdir";
4352 # Load all the options into their mapped variable names
4353 foreach my $opt (keys %option_map) {
4354 ${$option_map{$opt}} = set_test_option($opt, $i);
4357 $start_minconfig_defined = 1;
4359 # The first test may override the PRE_KTEST option
4361 if (defined($pre_ktest)) {
4363 run_command $pre_ktest;
4365 if ($email_when_started) {
4366 my $name = get_test_name;
4367 send_email("KTEST: Your [$name] test was started",
4368 "Your test was started on $script_start_time");
4372 # Any test can override the POST_KTEST option
4373 # The last test takes precedence.
4374 if (defined($post_ktest)) {
4375 $final_post_ktest = $post_ktest;
4378 if (!defined($start_minconfig)) {
4379 $start_minconfig_defined = 0;
4380 $start_minconfig = $minconfig;
4385 dodie "can't create $tmpdir";
4388 $ENV{"SSH_USER"} = $ssh_user;
4389 $ENV{"MACHINE"} = $machine;
4391 $buildlog = "$tmpdir/buildlog-$machine";
4392 $testlog = "$tmpdir/testlog-$machine";
4393 $dmesg = "$tmpdir/dmesg-$machine";
4394 $output_config = "$outputdir/.config";
4397 $target = "$ssh_user\@$machine";
4398 if (($reboot_type eq "grub") or ($reboot_type eq "grub2bls")) {
4399 dodie "GRUB_MENU not defined" if (!defined($grub_menu));
4400 } elsif ($reboot_type eq "grub2") {
4401 dodie "GRUB_MENU not defined" if (!defined($grub_menu));
4402 dodie "GRUB_FILE not defined" if (!defined($grub_file));
4403 } elsif ($reboot_type eq "syslinux") {
4404 dodie "SYSLINUX_LABEL not defined" if (!defined($syslinux_label));
4408 my $run_type = $build_type;
4409 if ($test_type eq "patchcheck") {
4410 $run_type = $patchcheck_type;
4411 } elsif ($test_type eq "bisect") {
4412 $run_type = $bisect_type;
4413 } elsif ($test_type eq "config_bisect") {
4414 $run_type = $config_bisect_type;
4415 } elsif ($test_type eq "make_min_config") {
4417 } elsif ($test_type eq "make_warnings_file") {
4421 # mistake in config file?
4422 if (!defined($run_type)) {
4423 $run_type = "ERROR";
4427 $installme = " no_install" if ($no_install);
4431 if (defined($test_name)) {
4432 $name = " ($test_name)";
4437 if (defined($opt{"LOG_FILE"})) {
4438 $test_log_start = tell(LOG);
4441 doprint "RUNNING TEST $i of $opt{NUM_TESTS}$name with option $test_type $run_type$installme\n\n";
4443 if (defined($pre_test)) {
4444 my $ret = run_command $pre_test;
4445 if (!$ret && defined($pre_test_die) &&
4447 dodie "failed to pre_test\n";
4455 if (defined($addconfig)) {
4456 my $min = $minconfig;
4457 if (!defined($minconfig)) {
4460 run_command "cat $addconfig $min > $tmpdir/add_config" or
4461 dodie "Failed to create temp config";
4462 $minconfig = "$tmpdir/add_config";
4465 if (defined($checkout)) {
4466 run_command "git checkout $checkout" or
4467 dodie "failed to checkout $checkout";
4472 # A test may opt to not reboot the box
4473 if ($reboot_on_success) {
4474 $reboot_success = 1;
4477 if ($test_type eq "bisect") {
4480 } elsif ($test_type eq "config_bisect") {
4483 } elsif ($test_type eq "patchcheck") {
4486 } elsif ($test_type eq "make_min_config") {
4489 } elsif ($test_type eq "make_warnings_file") {
4491 make_warnings_file $i;
4495 if ($build_type ne "nobuild") {
4496 build $build_type or next;
4497 check_buildlog or next;
4500 if ($test_type eq "install") {
4507 if ($test_type ne "build") {
4509 start_monitor_and_install or $failed = 1;
4511 if (!$failed && $test_type ne "boot" && defined($run_test)) {
4512 do_run_test or $failed = 1;
4526 if (defined($final_post_ktest)) {
4528 my $cp_final_post_ktest = eval_kernel_version $final_post_ktest;
4529 run_command $cp_final_post_ktest;
4532 if ($opt{"POWEROFF_ON_SUCCESS"}) {
4534 } elsif ($opt{"REBOOT_ON_SUCCESS"} && !do_not_reboot && $reboot_success) {
4536 } elsif (defined($switch_to_good)) {
4537 # still need to get to the good kernel
4538 run_command $switch_to_good;
4541 doprint "\n $successes of $opt{NUM_TESTS} tests were successful\n\n";
4543 if ($email_when_finished) {
4544 send_email("KTEST: Your test has finished!",
4545 "$successes of $opt{NUM_TESTS} tests started at $script_start_time were successful!");
4548 if (defined($opt{"LOG_FILE"})) {
4549 print "\n See $opt{LOG_FILE} for the record of results.\n\n";
4556 # The following are here to standardize tabs/spaces/etc across the most likely editors
4562 # vim: softtabstop=4