| .. | .. |
|---|
| 1 | 1 | #!/usr/bin/perl -w |
|---|
| 2 | +# SPDX-License-Identifier: GPL-2.0-only |
|---|
| 2 | 3 | # |
|---|
| 3 | 4 | # Copyright 2010 - Steven Rostedt <srostedt@redhat.com>, Red Hat Inc. |
|---|
| 4 | | -# Licensed under the terms of the GNU GPL License version 2 |
|---|
| 5 | 5 | # |
|---|
| 6 | 6 | |
|---|
| 7 | 7 | use strict; |
|---|
| .. | .. |
|---|
| 11 | 11 | use File::Copy qw(cp); |
|---|
| 12 | 12 | use FileHandle; |
|---|
| 13 | 13 | use FindBin; |
|---|
| 14 | +use IO::Handle; |
|---|
| 14 | 15 | |
|---|
| 15 | 16 | my $VERSION = "0.2"; |
|---|
| 16 | 17 | |
|---|
| .. | .. |
|---|
| 30 | 31 | "EMAIL_WHEN_STARTED" => 0, |
|---|
| 31 | 32 | "NUM_TESTS" => 1, |
|---|
| 32 | 33 | "TEST_TYPE" => "build", |
|---|
| 33 | | - "BUILD_TYPE" => "randconfig", |
|---|
| 34 | + "BUILD_TYPE" => "oldconfig", |
|---|
| 34 | 35 | "MAKE_CMD" => "make", |
|---|
| 35 | 36 | "CLOSE_CONSOLE_SIGNAL" => "INT", |
|---|
| 36 | 37 | "TIMEOUT" => 120, |
|---|
| .. | .. |
|---|
| 58 | 59 | "SCP_TO_TARGET" => "scp \$SRC_FILE \$SSH_USER\@\$MACHINE:\$DST_FILE", |
|---|
| 59 | 60 | "SCP_TO_TARGET_INSTALL" => "\${SCP_TO_TARGET}", |
|---|
| 60 | 61 | "REBOOT" => "ssh \$SSH_USER\@\$MACHINE reboot", |
|---|
| 62 | + "REBOOT_RETURN_CODE" => 255, |
|---|
| 61 | 63 | "STOP_AFTER_SUCCESS" => 10, |
|---|
| 62 | 64 | "STOP_AFTER_FAILURE" => 60, |
|---|
| 63 | 65 | "STOP_TEST_AFTER" => 600, |
|---|
| 64 | 66 | "MAX_MONITOR_WAIT" => 1800, |
|---|
| 65 | 67 | "GRUB_REBOOT" => "grub2-reboot", |
|---|
| 68 | + "GRUB_BLS_GET" => "grubby --info=ALL", |
|---|
| 66 | 69 | "SYSLINUX" => "extlinux", |
|---|
| 67 | 70 | "SYSLINUX_PATH" => "/boot/extlinux", |
|---|
| 68 | 71 | "CONNECT_TIMEOUT" => 25, |
|---|
| .. | .. |
|---|
| 78 | 81 | "LOG_FILE" => undef, |
|---|
| 79 | 82 | "IGNORE_UNUSED" => 0, |
|---|
| 80 | 83 | ); |
|---|
| 84 | + |
|---|
| 85 | +my $test_log_start = 0; |
|---|
| 81 | 86 | |
|---|
| 82 | 87 | my $ktest_config = "ktest.conf"; |
|---|
| 83 | 88 | my $version; |
|---|
| .. | .. |
|---|
| 96 | 101 | my $pre_ktest; |
|---|
| 97 | 102 | my $post_ktest; |
|---|
| 98 | 103 | my $pre_test; |
|---|
| 104 | +my $pre_test_die; |
|---|
| 99 | 105 | my $post_test; |
|---|
| 100 | 106 | my $pre_build; |
|---|
| 101 | 107 | my $post_build; |
|---|
| .. | .. |
|---|
| 105 | 111 | my $reboot_script; |
|---|
| 106 | 112 | my $power_cycle; |
|---|
| 107 | 113 | my $reboot; |
|---|
| 114 | +my $reboot_return_code; |
|---|
| 108 | 115 | my $reboot_on_error; |
|---|
| 109 | 116 | my $switch_to_good; |
|---|
| 110 | 117 | my $switch_to_test; |
|---|
| .. | .. |
|---|
| 123 | 130 | my $grub_file; |
|---|
| 124 | 131 | my $grub_number; |
|---|
| 125 | 132 | my $grub_reboot; |
|---|
| 133 | +my $grub_bls_get; |
|---|
| 126 | 134 | my $syslinux; |
|---|
| 127 | 135 | my $syslinux_path; |
|---|
| 128 | 136 | my $syslinux_label; |
|---|
| .. | .. |
|---|
| 170 | 178 | my $store_successes; |
|---|
| 171 | 179 | my $test_name; |
|---|
| 172 | 180 | my $timeout; |
|---|
| 181 | +my $run_timeout; |
|---|
| 173 | 182 | my $connect_timeout; |
|---|
| 174 | 183 | my $config_bisect_exec; |
|---|
| 175 | 184 | my $booted_timeout; |
|---|
| .. | .. |
|---|
| 219 | 228 | my $mailto; |
|---|
| 220 | 229 | my $mailer; |
|---|
| 221 | 230 | my $mail_path; |
|---|
| 231 | +my $mail_max_size; |
|---|
| 222 | 232 | my $mail_command; |
|---|
| 223 | 233 | my $email_on_error; |
|---|
| 224 | 234 | my $email_when_finished; |
|---|
| .. | .. |
|---|
| 255 | 265 | "MAILTO" => \$mailto, |
|---|
| 256 | 266 | "MAILER" => \$mailer, |
|---|
| 257 | 267 | "MAIL_PATH" => \$mail_path, |
|---|
| 268 | + "MAIL_MAX_SIZE" => \$mail_max_size, |
|---|
| 258 | 269 | "MAIL_COMMAND" => \$mail_command, |
|---|
| 259 | 270 | "EMAIL_ON_ERROR" => \$email_on_error, |
|---|
| 260 | 271 | "EMAIL_WHEN_FINISHED" => \$email_when_finished, |
|---|
| .. | .. |
|---|
| 269 | 280 | "PRE_KTEST" => \$pre_ktest, |
|---|
| 270 | 281 | "POST_KTEST" => \$post_ktest, |
|---|
| 271 | 282 | "PRE_TEST" => \$pre_test, |
|---|
| 283 | + "PRE_TEST_DIE" => \$pre_test_die, |
|---|
| 272 | 284 | "POST_TEST" => \$post_test, |
|---|
| 273 | 285 | "BUILD_TYPE" => \$build_type, |
|---|
| 274 | 286 | "BUILD_OPTIONS" => \$build_options, |
|---|
| .. | .. |
|---|
| 278 | 290 | "POST_BUILD_DIE" => \$post_build_die, |
|---|
| 279 | 291 | "POWER_CYCLE" => \$power_cycle, |
|---|
| 280 | 292 | "REBOOT" => \$reboot, |
|---|
| 293 | + "REBOOT_RETURN_CODE" => \$reboot_return_code, |
|---|
| 281 | 294 | "BUILD_NOCLEAN" => \$noclean, |
|---|
| 282 | 295 | "MIN_CONFIG" => \$minconfig, |
|---|
| 283 | 296 | "OUTPUT_MIN_CONFIG" => \$output_minconfig, |
|---|
| .. | .. |
|---|
| 292 | 305 | "GRUB_MENU" => \$grub_menu, |
|---|
| 293 | 306 | "GRUB_FILE" => \$grub_file, |
|---|
| 294 | 307 | "GRUB_REBOOT" => \$grub_reboot, |
|---|
| 308 | + "GRUB_BLS_GET" => \$grub_bls_get, |
|---|
| 295 | 309 | "SYSLINUX" => \$syslinux, |
|---|
| 296 | 310 | "SYSLINUX_PATH" => \$syslinux_path, |
|---|
| 297 | 311 | "SYSLINUX_LABEL" => \$syslinux_label, |
|---|
| .. | .. |
|---|
| 327 | 341 | "STORE_SUCCESSES" => \$store_successes, |
|---|
| 328 | 342 | "TEST_NAME" => \$test_name, |
|---|
| 329 | 343 | "TIMEOUT" => \$timeout, |
|---|
| 344 | + "RUN_TIMEOUT" => \$run_timeout, |
|---|
| 330 | 345 | "CONNECT_TIMEOUT" => \$connect_timeout, |
|---|
| 331 | 346 | "CONFIG_BISECT_EXEC" => \$config_bisect_exec, |
|---|
| 332 | 347 | "BOOTED_TIMEOUT" => \$booted_timeout, |
|---|
| .. | .. |
|---|
| 437 | 452 | ; |
|---|
| 438 | 453 | $config_help{"REBOOT_TYPE"} = << "EOF" |
|---|
| 439 | 454 | Way to reboot the box to the test kernel. |
|---|
| 440 | | - Only valid options so far are "grub", "grub2", "syslinux", and "script". |
|---|
| 455 | + Only valid options so far are "grub", "grub2", "grub2bls", "syslinux", and "script". |
|---|
| 441 | 456 | |
|---|
| 442 | 457 | If you specify grub, it will assume grub version 1 |
|---|
| 443 | 458 | and will search in /boot/grub/menu.lst for the title \$GRUB_MENU |
|---|
| .. | .. |
|---|
| 450 | 465 | |
|---|
| 451 | 466 | If you specify grub2, then you also need to specify both \$GRUB_MENU |
|---|
| 452 | 467 | and \$GRUB_FILE. |
|---|
| 468 | + |
|---|
| 469 | + If you specify grub2bls, then you also need to specify \$GRUB_MENU. |
|---|
| 453 | 470 | |
|---|
| 454 | 471 | If you specify syslinux, then you may use SYSLINUX to define the syslinux |
|---|
| 455 | 472 | command (defaults to extlinux), and SYSLINUX_PATH to specify the path to |
|---|
| .. | .. |
|---|
| 476 | 493 | menu must be a non-nested menu. Add the quotes used in the menu |
|---|
| 477 | 494 | to guarantee your selection, as the first menuentry with the content |
|---|
| 478 | 495 | of \$GRUB_MENU that is found will be used. |
|---|
| 496 | + |
|---|
| 497 | + For grub2bls, \$GRUB_MENU is searched on the result of \$GRUB_BLS_GET |
|---|
| 498 | + command for the lines that begin with "title". |
|---|
| 479 | 499 | EOF |
|---|
| 480 | 500 | ; |
|---|
| 481 | 501 | $config_help{"GRUB_FILE"} = << "EOF" |
|---|
| .. | .. |
|---|
| 496 | 516 | |
|---|
| 497 | 517 | sub _logit { |
|---|
| 498 | 518 | if (defined($opt{"LOG_FILE"})) { |
|---|
| 499 | | - open(OUT, ">> $opt{LOG_FILE}") or die "Can't write to $opt{LOG_FILE}"; |
|---|
| 500 | | - print OUT @_; |
|---|
| 501 | | - close(OUT); |
|---|
| 519 | + print LOG @_; |
|---|
| 502 | 520 | } |
|---|
| 503 | 521 | } |
|---|
| 504 | 522 | |
|---|
| .. | .. |
|---|
| 692 | 710 | } |
|---|
| 693 | 711 | } |
|---|
| 694 | 712 | |
|---|
| 695 | | - if ($rtype eq "grub") { |
|---|
| 713 | + if (($rtype eq "grub") or ($rtype eq "grub2bls")) { |
|---|
| 696 | 714 | get_mandatory_config("GRUB_MENU"); |
|---|
| 697 | 715 | } |
|---|
| 698 | 716 | |
|---|
| .. | .. |
|---|
| 898 | 916 | } |
|---|
| 899 | 917 | } |
|---|
| 900 | 918 | |
|---|
| 919 | + if ($val =~ s/^\s*NOT\s+(.*)//) { |
|---|
| 920 | + my $express = $1; |
|---|
| 921 | + my $ret = process_expression($name, $express); |
|---|
| 922 | + return !$ret; |
|---|
| 923 | + } |
|---|
| 924 | + |
|---|
| 901 | 925 | if ($val =~ /^\s*0\s*$/) { |
|---|
| 902 | 926 | return 0; |
|---|
| 903 | 927 | } elsif ($val =~ /^\s*\d+\s*$/) { |
|---|
| .. | .. |
|---|
| 1019 | 1043 | } |
|---|
| 1020 | 1044 | |
|---|
| 1021 | 1045 | if (!$skip && $rest !~ /^\s*$/) { |
|---|
| 1022 | | - die "$name: $.: Gargbage found after $type\n$_"; |
|---|
| 1046 | + die "$name: $.: Garbage found after $type\n$_"; |
|---|
| 1023 | 1047 | } |
|---|
| 1024 | 1048 | |
|---|
| 1025 | 1049 | if ($skip && $type eq "TEST_START") { |
|---|
| .. | .. |
|---|
| 1052 | 1076 | } |
|---|
| 1053 | 1077 | |
|---|
| 1054 | 1078 | if ($rest !~ /^\s*$/) { |
|---|
| 1055 | | - die "$name: $.: Gargbage found after DEFAULTS\n$_"; |
|---|
| 1079 | + die "$name: $.: Garbage found after DEFAULTS\n$_"; |
|---|
| 1056 | 1080 | } |
|---|
| 1057 | 1081 | |
|---|
| 1058 | 1082 | } elsif (/^\s*INCLUDE\s+(\S+)/) { |
|---|
| .. | .. |
|---|
| 1143 | 1167 | # on of these sections that have SKIP defined. |
|---|
| 1144 | 1168 | # The save variable can be |
|---|
| 1145 | 1169 | # defined multiple times and the new one simply overrides |
|---|
| 1146 | | - # the prevous one. |
|---|
| 1170 | + # the previous one. |
|---|
| 1147 | 1171 | set_variable($lvalue, $rvalue); |
|---|
| 1148 | 1172 | |
|---|
| 1149 | 1173 | } else { |
|---|
| .. | .. |
|---|
| 1223 | 1247 | foreach my $option (keys %not_used) { |
|---|
| 1224 | 1248 | print "$option\n"; |
|---|
| 1225 | 1249 | } |
|---|
| 1226 | | - print "Set IGRNORE_UNUSED = 1 to have ktest ignore unused variables\n"; |
|---|
| 1250 | + print "Set IGNORE_UNUSED = 1 to have ktest ignore unused variables\n"; |
|---|
| 1227 | 1251 | if (!read_yn "Do you want to continue?") { |
|---|
| 1228 | 1252 | exit -1; |
|---|
| 1229 | 1253 | } |
|---|
| .. | .. |
|---|
| 1334 | 1358 | # Check for recursive evaluations. |
|---|
| 1335 | 1359 | # 100 deep should be more than enough. |
|---|
| 1336 | 1360 | if ($r++ > 100) { |
|---|
| 1337 | | - die "Over 100 evaluations accurred with $option\n" . |
|---|
| 1361 | + die "Over 100 evaluations occurred with $option\n" . |
|---|
| 1338 | 1362 | "Check for recursive variables\n"; |
|---|
| 1339 | 1363 | } |
|---|
| 1340 | 1364 | $prev = $option; |
|---|
| .. | .. |
|---|
| 1411 | 1435 | |
|---|
| 1412 | 1436 | # Still need to wait for the reboot to finish |
|---|
| 1413 | 1437 | wait_for_monitor($time, $reboot_success_line); |
|---|
| 1414 | | - |
|---|
| 1438 | + } |
|---|
| 1439 | + if ($powercycle || $time) { |
|---|
| 1415 | 1440 | end_monitor; |
|---|
| 1416 | 1441 | } |
|---|
| 1417 | 1442 | } |
|---|
| .. | .. |
|---|
| 1437 | 1462 | |
|---|
| 1438 | 1463 | my $in_die = 0; |
|---|
| 1439 | 1464 | |
|---|
| 1465 | +sub get_test_name() { |
|---|
| 1466 | + my $name; |
|---|
| 1467 | + |
|---|
| 1468 | + if (defined($test_name)) { |
|---|
| 1469 | + $name = "$test_name:$test_type"; |
|---|
| 1470 | + } else { |
|---|
| 1471 | + $name = $test_type; |
|---|
| 1472 | + } |
|---|
| 1473 | + return $name; |
|---|
| 1474 | +} |
|---|
| 1475 | + |
|---|
| 1440 | 1476 | sub dodie { |
|---|
| 1441 | 1477 | |
|---|
| 1442 | | - # avoid recusion |
|---|
| 1478 | + # avoid recursion |
|---|
| 1443 | 1479 | return if ($in_die); |
|---|
| 1444 | 1480 | $in_die = 1; |
|---|
| 1445 | 1481 | |
|---|
| 1446 | | - doprint "CRITICAL FAILURE... ", @_, "\n"; |
|---|
| 1447 | | - |
|---|
| 1448 | 1482 | my $i = $iteration; |
|---|
| 1483 | + |
|---|
| 1484 | + doprint "CRITICAL FAILURE... [TEST $i] ", @_, "\n"; |
|---|
| 1449 | 1485 | |
|---|
| 1450 | 1486 | if ($reboot_on_error && !do_not_reboot) { |
|---|
| 1451 | 1487 | |
|---|
| .. | .. |
|---|
| 1462 | 1498 | } |
|---|
| 1463 | 1499 | |
|---|
| 1464 | 1500 | if ($email_on_error) { |
|---|
| 1465 | | - send_email("KTEST: critical failure for your [$test_type] test", |
|---|
| 1466 | | - "Your test started at $script_start_time has failed with:\n@_\n"); |
|---|
| 1501 | + my $name = get_test_name; |
|---|
| 1502 | + my $log_file; |
|---|
| 1503 | + |
|---|
| 1504 | + if (defined($opt{"LOG_FILE"})) { |
|---|
| 1505 | + my $whence = 2; # End of file |
|---|
| 1506 | + my $log_size = tell LOG; |
|---|
| 1507 | + my $size = $log_size - $test_log_start; |
|---|
| 1508 | + |
|---|
| 1509 | + if (defined($mail_max_size)) { |
|---|
| 1510 | + if ($size > $mail_max_size) { |
|---|
| 1511 | + $size = $mail_max_size; |
|---|
| 1512 | + } |
|---|
| 1513 | + } |
|---|
| 1514 | + my $pos = - $size; |
|---|
| 1515 | + $log_file = "$tmpdir/log"; |
|---|
| 1516 | + open (L, "$opt{LOG_FILE}") or die "Can't open $opt{LOG_FILE} to read)"; |
|---|
| 1517 | + open (O, "> $tmpdir/log") or die "Can't open $tmpdir/log\n"; |
|---|
| 1518 | + seek(L, $pos, $whence); |
|---|
| 1519 | + while (<L>) { |
|---|
| 1520 | + print O; |
|---|
| 1521 | + } |
|---|
| 1522 | + close O; |
|---|
| 1523 | + close L; |
|---|
| 1524 | + } |
|---|
| 1525 | + send_email("KTEST: critical failure for test $i [$name]", |
|---|
| 1526 | + "Your test started at $script_start_time has failed with:\n@_\n", $log_file); |
|---|
| 1467 | 1527 | } |
|---|
| 1468 | 1528 | |
|---|
| 1469 | 1529 | if ($monitor_cnt) { |
|---|
| .. | .. |
|---|
| 1485 | 1545 | my $TIOCGPTN = 0x80045430; |
|---|
| 1486 | 1546 | |
|---|
| 1487 | 1547 | sysopen($ptm, "/dev/ptmx", O_RDWR | O_NONBLOCK) or |
|---|
| 1488 | | - dodie "Cant open /dev/ptmx"; |
|---|
| 1548 | + dodie "Can't open /dev/ptmx"; |
|---|
| 1489 | 1549 | |
|---|
| 1490 | 1550 | # unlockpt() |
|---|
| 1491 | 1551 | $tmp = pack("i", 0); |
|---|
| .. | .. |
|---|
| 1737 | 1797 | my $dord = 0; |
|---|
| 1738 | 1798 | my $dostdout = 0; |
|---|
| 1739 | 1799 | my $pid; |
|---|
| 1800 | + my $command_orig = $command; |
|---|
| 1740 | 1801 | |
|---|
| 1741 | 1802 | $command =~ s/\$SSH_USER/$ssh_user/g; |
|---|
| 1742 | 1803 | $command =~ s/\$MACHINE/$machine/g; |
|---|
| 1804 | + |
|---|
| 1805 | + if (!defined($timeout)) { |
|---|
| 1806 | + $timeout = $run_timeout; |
|---|
| 1807 | + } |
|---|
| 1808 | + |
|---|
| 1809 | + if (!defined($timeout)) { |
|---|
| 1810 | + $timeout = -1; # tell wait_for_input to wait indefinitely |
|---|
| 1811 | + } |
|---|
| 1743 | 1812 | |
|---|
| 1744 | 1813 | doprint("$command ... "); |
|---|
| 1745 | 1814 | $start_time = time; |
|---|
| .. | .. |
|---|
| 1748 | 1817 | (fail "unable to exec $command" and return 0); |
|---|
| 1749 | 1818 | |
|---|
| 1750 | 1819 | if (defined($opt{"LOG_FILE"})) { |
|---|
| 1751 | | - open(LOG, ">>$opt{LOG_FILE}") or |
|---|
| 1752 | | - dodie "failed to write to log"; |
|---|
| 1753 | 1820 | $dolog = 1; |
|---|
| 1754 | 1821 | } |
|---|
| 1755 | 1822 | |
|---|
| .. | .. |
|---|
| 1769 | 1836 | |
|---|
| 1770 | 1837 | while (1) { |
|---|
| 1771 | 1838 | my $fp = \*CMD; |
|---|
| 1772 | | - if (defined($timeout)) { |
|---|
| 1773 | | - doprint "timeout = $timeout\n"; |
|---|
| 1774 | | - } |
|---|
| 1775 | 1839 | my $line = wait_for_input($fp, $timeout); |
|---|
| 1776 | 1840 | if (!defined($line)) { |
|---|
| 1777 | 1841 | my $now = time; |
|---|
| 1778 | | - if (defined($timeout) && (($now - $start_time) >= $timeout)) { |
|---|
| 1842 | + if ($timeout >= 0 && (($now - $start_time) >= $timeout)) { |
|---|
| 1779 | 1843 | doprint "Hit timeout of $timeout, killing process\n"; |
|---|
| 1780 | 1844 | $hit_timeout = 1; |
|---|
| 1781 | 1845 | kill 9, $pid; |
|---|
| .. | .. |
|---|
| 1791 | 1855 | # shift 8 for real exit status |
|---|
| 1792 | 1856 | $run_command_status = $? >> 8; |
|---|
| 1793 | 1857 | |
|---|
| 1858 | + if ($command_orig eq $default{REBOOT} && |
|---|
| 1859 | + $run_command_status == $reboot_return_code) { |
|---|
| 1860 | + $run_command_status = 0; |
|---|
| 1861 | + } |
|---|
| 1862 | + |
|---|
| 1794 | 1863 | close(CMD); |
|---|
| 1795 | | - close(LOG) if ($dolog); |
|---|
| 1796 | 1864 | close(RD) if ($dord); |
|---|
| 1797 | 1865 | |
|---|
| 1798 | 1866 | $end_time = time; |
|---|
| .. | .. |
|---|
| 1850 | 1918 | return run_scp($src, $dst, $cp_scp); |
|---|
| 1851 | 1919 | } |
|---|
| 1852 | 1920 | |
|---|
| 1853 | | -sub get_grub2_index { |
|---|
| 1921 | +sub _get_grub_index { |
|---|
| 1922 | + |
|---|
| 1923 | + my ($command, $target, $skip, $submenu) = @_; |
|---|
| 1854 | 1924 | |
|---|
| 1855 | 1925 | return if (defined($grub_number) && defined($last_grub_menu) && |
|---|
| 1856 | 1926 | $last_grub_menu eq $grub_menu && defined($last_machine) && |
|---|
| 1857 | 1927 | $last_machine eq $machine); |
|---|
| 1858 | 1928 | |
|---|
| 1859 | | - doprint "Find grub2 menu ... "; |
|---|
| 1929 | + doprint "Find $reboot_type menu ... "; |
|---|
| 1860 | 1930 | $grub_number = -1; |
|---|
| 1861 | 1931 | |
|---|
| 1862 | 1932 | my $ssh_grub = $ssh_exec; |
|---|
| 1863 | | - $ssh_grub =~ s,\$SSH_COMMAND,cat $grub_file,g; |
|---|
| 1933 | + $ssh_grub =~ s,\$SSH_COMMAND,$command,g; |
|---|
| 1864 | 1934 | |
|---|
| 1865 | 1935 | open(IN, "$ssh_grub |") |
|---|
| 1866 | | - or dodie "unable to get $grub_file"; |
|---|
| 1936 | + or dodie "unable to execute $command"; |
|---|
| 1867 | 1937 | |
|---|
| 1868 | 1938 | my $found = 0; |
|---|
| 1869 | 1939 | |
|---|
| 1940 | + my $submenu_number = 0; |
|---|
| 1941 | + |
|---|
| 1870 | 1942 | while (<IN>) { |
|---|
| 1871 | | - if (/^menuentry.*$grub_menu/) { |
|---|
| 1943 | + if (/$target/) { |
|---|
| 1872 | 1944 | $grub_number++; |
|---|
| 1873 | 1945 | $found = 1; |
|---|
| 1874 | 1946 | last; |
|---|
| 1875 | | - } elsif (/^menuentry\s|^submenu\s/) { |
|---|
| 1947 | + } elsif (defined($submenu) && /$submenu/) { |
|---|
| 1948 | + $submenu_number++; |
|---|
| 1949 | + $grub_number = -1; |
|---|
| 1950 | + } elsif (/$skip/) { |
|---|
| 1876 | 1951 | $grub_number++; |
|---|
| 1877 | 1952 | } |
|---|
| 1878 | 1953 | } |
|---|
| 1879 | 1954 | close(IN); |
|---|
| 1880 | 1955 | |
|---|
| 1881 | | - dodie "Could not find '$grub_menu' in $grub_file on $machine" |
|---|
| 1956 | + dodie "Could not find '$grub_menu' through $command on $machine" |
|---|
| 1882 | 1957 | if (!$found); |
|---|
| 1958 | + if ($submenu_number > 0) { |
|---|
| 1959 | + $grub_number = "$submenu_number>$grub_number"; |
|---|
| 1960 | + } |
|---|
| 1883 | 1961 | doprint "$grub_number\n"; |
|---|
| 1884 | 1962 | $last_grub_menu = $grub_menu; |
|---|
| 1885 | 1963 | $last_machine = $machine; |
|---|
| .. | .. |
|---|
| 1887 | 1965 | |
|---|
| 1888 | 1966 | sub get_grub_index { |
|---|
| 1889 | 1967 | |
|---|
| 1890 | | - if ($reboot_type eq "grub2") { |
|---|
| 1891 | | - get_grub2_index; |
|---|
| 1968 | + my $command; |
|---|
| 1969 | + my $target; |
|---|
| 1970 | + my $skip; |
|---|
| 1971 | + my $submenu; |
|---|
| 1972 | + my $grub_menu_qt; |
|---|
| 1973 | + |
|---|
| 1974 | + if ($reboot_type !~ /^grub/) { |
|---|
| 1892 | 1975 | return; |
|---|
| 1893 | 1976 | } |
|---|
| 1894 | 1977 | |
|---|
| 1895 | | - if ($reboot_type ne "grub") { |
|---|
| 1978 | + $grub_menu_qt = quotemeta($grub_menu); |
|---|
| 1979 | + |
|---|
| 1980 | + if ($reboot_type eq "grub") { |
|---|
| 1981 | + $command = "cat /boot/grub/menu.lst"; |
|---|
| 1982 | + $target = '^\s*title\s+' . $grub_menu_qt . '\s*$'; |
|---|
| 1983 | + $skip = '^\s*title\s'; |
|---|
| 1984 | + } elsif ($reboot_type eq "grub2") { |
|---|
| 1985 | + $command = "cat $grub_file"; |
|---|
| 1986 | + $target = '^\s*menuentry.*' . $grub_menu_qt; |
|---|
| 1987 | + $skip = '^\s*menuentry'; |
|---|
| 1988 | + $submenu = '^\s*submenu\s'; |
|---|
| 1989 | + } elsif ($reboot_type eq "grub2bls") { |
|---|
| 1990 | + $command = $grub_bls_get; |
|---|
| 1991 | + $target = '^title=.*' . $grub_menu_qt; |
|---|
| 1992 | + $skip = '^title='; |
|---|
| 1993 | + } else { |
|---|
| 1896 | 1994 | return; |
|---|
| 1897 | 1995 | } |
|---|
| 1898 | | - return if (defined($grub_number) && defined($last_grub_menu) && |
|---|
| 1899 | | - $last_grub_menu eq $grub_menu && defined($last_machine) && |
|---|
| 1900 | | - $last_machine eq $machine); |
|---|
| 1901 | 1996 | |
|---|
| 1902 | | - doprint "Find grub menu ... "; |
|---|
| 1903 | | - $grub_number = -1; |
|---|
| 1904 | | - |
|---|
| 1905 | | - my $ssh_grub = $ssh_exec; |
|---|
| 1906 | | - $ssh_grub =~ s,\$SSH_COMMAND,cat /boot/grub/menu.lst,g; |
|---|
| 1907 | | - |
|---|
| 1908 | | - open(IN, "$ssh_grub |") |
|---|
| 1909 | | - or dodie "unable to get menu.lst"; |
|---|
| 1910 | | - |
|---|
| 1911 | | - my $found = 0; |
|---|
| 1912 | | - |
|---|
| 1913 | | - while (<IN>) { |
|---|
| 1914 | | - if (/^\s*title\s+$grub_menu\s*$/) { |
|---|
| 1915 | | - $grub_number++; |
|---|
| 1916 | | - $found = 1; |
|---|
| 1917 | | - last; |
|---|
| 1918 | | - } elsif (/^\s*title\s/) { |
|---|
| 1919 | | - $grub_number++; |
|---|
| 1920 | | - } |
|---|
| 1921 | | - } |
|---|
| 1922 | | - close(IN); |
|---|
| 1923 | | - |
|---|
| 1924 | | - dodie "Could not find '$grub_menu' in /boot/grub/menu on $machine" |
|---|
| 1925 | | - if (!$found); |
|---|
| 1926 | | - doprint "$grub_number\n"; |
|---|
| 1927 | | - $last_grub_menu = $grub_menu; |
|---|
| 1928 | | - $last_machine = $machine; |
|---|
| 1997 | + _get_grub_index($command, $target, $skip, $submenu); |
|---|
| 1929 | 1998 | } |
|---|
| 1930 | 1999 | |
|---|
| 1931 | 2000 | sub wait_for_input |
|---|
| .. | .. |
|---|
| 1941 | 2010 | |
|---|
| 1942 | 2011 | if (!defined($time)) { |
|---|
| 1943 | 2012 | $time = $timeout; |
|---|
| 2013 | + } |
|---|
| 2014 | + |
|---|
| 2015 | + if ($time < 0) { |
|---|
| 2016 | + # Negative number means wait indefinitely |
|---|
| 2017 | + undef $time; |
|---|
| 1944 | 2018 | } |
|---|
| 1945 | 2019 | |
|---|
| 1946 | 2020 | $rin = ''; |
|---|
| .. | .. |
|---|
| 1988 | 2062 | |
|---|
| 1989 | 2063 | if ($reboot_type eq "grub") { |
|---|
| 1990 | 2064 | run_ssh "'(echo \"savedefault --default=$grub_number --once\" | grub --batch)'"; |
|---|
| 1991 | | - } elsif ($reboot_type eq "grub2") { |
|---|
| 1992 | | - run_ssh "$grub_reboot $grub_number"; |
|---|
| 2065 | + } elsif (($reboot_type eq "grub2") or ($reboot_type eq "grub2bls")) { |
|---|
| 2066 | + run_ssh "$grub_reboot \"'$grub_number'\""; |
|---|
| 1993 | 2067 | } elsif ($reboot_type eq "syslinux") { |
|---|
| 1994 | 2068 | run_ssh "$syslinux --once \\\"$syslinux_label\\\" $syslinux_path"; |
|---|
| 1995 | 2069 | } elsif (defined $reboot_script) { |
|---|
| .. | .. |
|---|
| 3168 | 3242 | doprint "***************************************\n\n"; |
|---|
| 3169 | 3243 | } |
|---|
| 3170 | 3244 | |
|---|
| 3245 | +my $pass = 1; |
|---|
| 3246 | + |
|---|
| 3171 | 3247 | sub run_config_bisect { |
|---|
| 3172 | 3248 | my ($good, $bad, $last_result) = @_; |
|---|
| 3173 | 3249 | my $reset = ""; |
|---|
| .. | .. |
|---|
| 3190 | 3266 | |
|---|
| 3191 | 3267 | $ret = run_config_bisect_test $config_bisect_type; |
|---|
| 3192 | 3268 | if ($ret) { |
|---|
| 3193 | | - doprint "NEW GOOD CONFIG\n"; |
|---|
| 3269 | + doprint "NEW GOOD CONFIG ($pass)\n"; |
|---|
| 3270 | + system("cp $output_config $tmpdir/good_config.tmp.$pass"); |
|---|
| 3271 | + $pass++; |
|---|
| 3194 | 3272 | # Return 3 for good config |
|---|
| 3195 | 3273 | return 3; |
|---|
| 3196 | 3274 | } else { |
|---|
| 3197 | | - doprint "NEW BAD CONFIG\n"; |
|---|
| 3275 | + doprint "NEW BAD CONFIG ($pass)\n"; |
|---|
| 3276 | + system("cp $output_config $tmpdir/bad_config.tmp.$pass"); |
|---|
| 3277 | + $pass++; |
|---|
| 3198 | 3278 | # Return 4 for bad config |
|---|
| 3199 | 3279 | return 4; |
|---|
| 3200 | 3280 | } |
|---|
| .. | .. |
|---|
| 3706 | 3786 | # .config to make sure it is missing the config that |
|---|
| 3707 | 3787 | # we had before |
|---|
| 3708 | 3788 | my %configs = %min_configs; |
|---|
| 3709 | | - delete $configs{$config}; |
|---|
| 3789 | + $configs{$config} = "# $config is not set"; |
|---|
| 3710 | 3790 | make_new_config ((values %configs), (values %keep_configs)); |
|---|
| 3711 | 3791 | make_oldconfig; |
|---|
| 3792 | + delete $configs{$config}; |
|---|
| 3712 | 3793 | undef %configs; |
|---|
| 3713 | 3794 | assign_configs \%configs, $output_config; |
|---|
| 3714 | 3795 | |
|---|
| .. | .. |
|---|
| 4057 | 4138 | } |
|---|
| 4058 | 4139 | } |
|---|
| 4059 | 4140 | |
|---|
| 4060 | | -if ($opt{"CLEAR_LOG"} && defined($opt{"LOG_FILE"})) { |
|---|
| 4061 | | - unlink $opt{"LOG_FILE"}; |
|---|
| 4141 | +if (defined($opt{"LOG_FILE"})) { |
|---|
| 4142 | + if ($opt{"CLEAR_LOG"}) { |
|---|
| 4143 | + unlink $opt{"LOG_FILE"}; |
|---|
| 4144 | + } |
|---|
| 4145 | + open(LOG, ">> $opt{LOG_FILE}") or die "Can't write to $opt{LOG_FILE}"; |
|---|
| 4146 | + LOG->autoflush(1); |
|---|
| 4062 | 4147 | } |
|---|
| 4063 | 4148 | |
|---|
| 4064 | 4149 | doprint "\n\nSTARTING AUTOMATED TESTS\n\n"; |
|---|
| .. | .. |
|---|
| 4151 | 4236 | } |
|---|
| 4152 | 4237 | |
|---|
| 4153 | 4238 | sub do_send_mail { |
|---|
| 4154 | | - my ($subject, $message) = @_; |
|---|
| 4239 | + my ($subject, $message, $file) = @_; |
|---|
| 4155 | 4240 | |
|---|
| 4156 | 4241 | if (!defined($mail_path)) { |
|---|
| 4157 | 4242 | # find the mailer |
|---|
| .. | .. |
|---|
| 4161 | 4246 | } |
|---|
| 4162 | 4247 | } |
|---|
| 4163 | 4248 | |
|---|
| 4249 | + my $header_file = "$tmpdir/header"; |
|---|
| 4250 | + open (HEAD, ">$header_file") or die "Can not create $header_file\n"; |
|---|
| 4251 | + print HEAD "To: $mailto\n"; |
|---|
| 4252 | + print HEAD "Subject: $subject\n\n"; |
|---|
| 4253 | + print HEAD "$message\n"; |
|---|
| 4254 | + close HEAD; |
|---|
| 4255 | + |
|---|
| 4164 | 4256 | if (!defined($mail_command)) { |
|---|
| 4165 | 4257 | if ($mailer eq "mail" || $mailer eq "mailx") { |
|---|
| 4166 | | - $mail_command = "\$MAIL_PATH/\$MAILER -s \'\$SUBJECT\' \$MAILTO <<< \'\$MESSAGE\'"; |
|---|
| 4258 | + $mail_command = "cat \$HEADER_FILE \$BODY_FILE | \$MAIL_PATH/\$MAILER -s \'\$SUBJECT\' \$MAILTO"; |
|---|
| 4167 | 4259 | } elsif ($mailer eq "sendmail" ) { |
|---|
| 4168 | | - $mail_command = "echo \'Subject: \$SUBJECT\n\n\$MESSAGE\' | \$MAIL_PATH/\$MAILER -t \$MAILTO"; |
|---|
| 4260 | + $mail_command = "cat \$HEADER_FILE \$BODY_FILE | \$MAIL_PATH/\$MAILER -t \$MAILTO"; |
|---|
| 4169 | 4261 | } else { |
|---|
| 4170 | 4262 | die "\nYour mailer: $mailer is not supported.\n"; |
|---|
| 4171 | 4263 | } |
|---|
| 4172 | 4264 | } |
|---|
| 4173 | 4265 | |
|---|
| 4266 | + if (defined($file)) { |
|---|
| 4267 | + $mail_command =~ s/\$BODY_FILE/$file/g; |
|---|
| 4268 | + } else { |
|---|
| 4269 | + $mail_command =~ s/\$BODY_FILE//g; |
|---|
| 4270 | + } |
|---|
| 4271 | + |
|---|
| 4272 | + $mail_command =~ s/\$HEADER_FILE/$header_file/g; |
|---|
| 4174 | 4273 | $mail_command =~ s/\$MAILER/$mailer/g; |
|---|
| 4175 | 4274 | $mail_command =~ s/\$MAIL_PATH/$mail_path/g; |
|---|
| 4176 | 4275 | $mail_command =~ s/\$MAILTO/$mailto/g; |
|---|
| .. | .. |
|---|
| 4197 | 4296 | } |
|---|
| 4198 | 4297 | |
|---|
| 4199 | 4298 | sub cancel_test { |
|---|
| 4299 | + if ($monitor_cnt) { |
|---|
| 4300 | + end_monitor; |
|---|
| 4301 | + } |
|---|
| 4200 | 4302 | if ($email_when_canceled) { |
|---|
| 4201 | | - send_email("KTEST: Your [$test_type] test was cancelled", |
|---|
| 4303 | + my $name = get_test_name; |
|---|
| 4304 | + send_email("KTEST: Your [$name] test was cancelled", |
|---|
| 4202 | 4305 | "Your test started at $script_start_time was cancelled: sig int"); |
|---|
| 4203 | 4306 | } |
|---|
| 4204 | 4307 | die "\nCaught Sig Int, test interrupted: $!\n" |
|---|
| .. | .. |
|---|
| 4252 | 4355 | run_command $pre_ktest; |
|---|
| 4253 | 4356 | } |
|---|
| 4254 | 4357 | if ($email_when_started) { |
|---|
| 4255 | | - send_email("KTEST: Your [$test_type] test was started", |
|---|
| 4358 | + my $name = get_test_name; |
|---|
| 4359 | + send_email("KTEST: Your [$name] test was started", |
|---|
| 4256 | 4360 | "Your test was started on $script_start_time"); |
|---|
| 4257 | 4361 | } |
|---|
| 4258 | 4362 | } |
|---|
| .. | .. |
|---|
| 4283 | 4387 | |
|---|
| 4284 | 4388 | if (!$buildonly) { |
|---|
| 4285 | 4389 | $target = "$ssh_user\@$machine"; |
|---|
| 4286 | | - if ($reboot_type eq "grub") { |
|---|
| 4390 | + if (($reboot_type eq "grub") or ($reboot_type eq "grub2bls")) { |
|---|
| 4287 | 4391 | dodie "GRUB_MENU not defined" if (!defined($grub_menu)); |
|---|
| 4288 | 4392 | } elsif ($reboot_type eq "grub2") { |
|---|
| 4289 | 4393 | dodie "GRUB_MENU not defined" if (!defined($grub_menu)); |
|---|
| .. | .. |
|---|
| 4321 | 4425 | } |
|---|
| 4322 | 4426 | |
|---|
| 4323 | 4427 | doprint "\n\n"; |
|---|
| 4428 | + |
|---|
| 4429 | + if (defined($opt{"LOG_FILE"})) { |
|---|
| 4430 | + $test_log_start = tell(LOG); |
|---|
| 4431 | + } |
|---|
| 4432 | + |
|---|
| 4324 | 4433 | doprint "RUNNING TEST $i of $opt{NUM_TESTS}$name with option $test_type $run_type$installme\n\n"; |
|---|
| 4325 | 4434 | |
|---|
| 4326 | 4435 | if (defined($pre_test)) { |
|---|
| 4327 | | - run_command $pre_test; |
|---|
| 4436 | + my $ret = run_command $pre_test; |
|---|
| 4437 | + if (!$ret && defined($pre_test_die) && |
|---|
| 4438 | + $pre_test_die) { |
|---|
| 4439 | + dodie "failed to pre_test\n"; |
|---|
| 4440 | + } |
|---|
| 4328 | 4441 | } |
|---|
| 4329 | 4442 | |
|---|
| 4330 | 4443 | unlink $dmesg; |
|---|
| .. | .. |
|---|
| 4403 | 4516 | } |
|---|
| 4404 | 4517 | |
|---|
| 4405 | 4518 | if (defined($final_post_ktest)) { |
|---|
| 4406 | | - run_command $final_post_ktest; |
|---|
| 4519 | + |
|---|
| 4520 | + my $cp_final_post_ktest = eval_kernel_version $final_post_ktest; |
|---|
| 4521 | + run_command $cp_final_post_ktest; |
|---|
| 4407 | 4522 | } |
|---|
| 4408 | 4523 | |
|---|
| 4409 | 4524 | if ($opt{"POWEROFF_ON_SUCCESS"}) { |
|---|
| .. | .. |
|---|
| 4419 | 4534 | doprint "\n $successes of $opt{NUM_TESTS} tests were successful\n\n"; |
|---|
| 4420 | 4535 | |
|---|
| 4421 | 4536 | if ($email_when_finished) { |
|---|
| 4422 | | - send_email("KTEST: Your [$test_type] test has finished!", |
|---|
| 4537 | + send_email("KTEST: Your test has finished!", |
|---|
| 4423 | 4538 | "$successes of $opt{NUM_TESTS} tests started at $script_start_time were successful!"); |
|---|
| 4424 | 4539 | } |
|---|
| 4540 | + |
|---|
| 4541 | +if (defined($opt{"LOG_FILE"})) { |
|---|
| 4542 | + print "\n See $opt{LOG_FILE} for the record of results.\n\n"; |
|---|
| 4543 | + close LOG; |
|---|
| 4544 | +} |
|---|
| 4545 | + |
|---|
| 4425 | 4546 | exit 0; |
|---|