1#!/usr/bin/perl -w 2# 3# Copyright 2010 - Steven Rostedt <srostedt@redhat.com>, Red Hat Inc. 4# Licensed under the terms of the GNU GPL License version 2 5# 6 7use strict; 8use IPC::Open2; 9use Fcntl qw(F_GETFL F_SETFL O_NONBLOCK); 10use File::Path qw(mkpath); 11use File::Copy qw(cp); 12use FileHandle; 13 14my $VERSION = "0.2"; 15 16$| = 1; 17 18my %opt; 19my %repeat_tests; 20my %repeats; 21my %evals; 22 23#default opts 24my %default = ( 25 "NUM_TESTS" => 1, 26 "TEST_TYPE" => "build", 27 "BUILD_TYPE" => "randconfig", 28 "MAKE_CMD" => "make", 29 "CLOSE_CONSOLE_SIGNAL" => "INT", 30 "TIMEOUT" => 120, 31 "TMP_DIR" => "/tmp/ktest/\${MACHINE}", 32 "SLEEP_TIME" => 60, # sleep time between tests 33 "BUILD_NOCLEAN" => 0, 34 "REBOOT_ON_ERROR" => 0, 35 "POWEROFF_ON_ERROR" => 0, 36 "REBOOT_ON_SUCCESS" => 1, 37 "POWEROFF_ON_SUCCESS" => 0, 38 "BUILD_OPTIONS" => "", 39 "BISECT_SLEEP_TIME" => 60, # sleep time between bisects 40 "PATCHCHECK_SLEEP_TIME" => 60, # sleep time between patch checks 41 "CLEAR_LOG" => 0, 42 "BISECT_MANUAL" => 0, 43 "BISECT_SKIP" => 1, 44 "BISECT_TRIES" => 1, 45 "MIN_CONFIG_TYPE" => "boot", 46 "SUCCESS_LINE" => "login:", 47 "DETECT_TRIPLE_FAULT" => 1, 48 "NO_INSTALL" => 0, 49 "BOOTED_TIMEOUT" => 1, 50 "DIE_ON_FAILURE" => 1, 51 "SSH_EXEC" => "ssh \$SSH_USER\@\$MACHINE \$SSH_COMMAND", 52 "SCP_TO_TARGET" => "scp \$SRC_FILE \$SSH_USER\@\$MACHINE:\$DST_FILE", 53 "SCP_TO_TARGET_INSTALL" => "\${SCP_TO_TARGET}", 54 "REBOOT" => "ssh \$SSH_USER\@\$MACHINE reboot", 55 "STOP_AFTER_SUCCESS" => 10, 56 "STOP_AFTER_FAILURE" => 60, 57 "STOP_TEST_AFTER" => 600, 58 "MAX_MONITOR_WAIT" => 1800, 59 "GRUB_REBOOT" => "grub2-reboot", 60 "SYSLINUX" => "extlinux", 61 "SYSLINUX_PATH" => "/boot/extlinux", 62 63# required, and we will ask users if they don't have them but we keep the default 64# value something that is common. 65 "REBOOT_TYPE" => "grub", 66 "LOCALVERSION" => "-test", 67 "SSH_USER" => "root", 68 "BUILD_TARGET" => "arch/x86/boot/bzImage", 69 "TARGET_IMAGE" => "/boot/vmlinuz-test", 70 71 "LOG_FILE" => undef, 72 "IGNORE_UNUSED" => 0, 73); 74 75my $ktest_config = "ktest.conf"; 76my $version; 77my $have_version = 0; 78my $machine; 79my $last_machine; 80my $ssh_user; 81my $tmpdir; 82my $builddir; 83my $outputdir; 84my $output_config; 85my $test_type; 86my $build_type; 87my $build_options; 88my $final_post_ktest; 89my $pre_ktest; 90my $post_ktest; 91my $pre_test; 92my $post_test; 93my $pre_build; 94my $post_build; 95my $pre_build_die; 96my $post_build_die; 97my $reboot_type; 98my $reboot_script; 99my $power_cycle; 100my $reboot; 101my $reboot_on_error; 102my $switch_to_good; 103my $switch_to_test; 104my $poweroff_on_error; 105my $reboot_on_success; 106my $die_on_failure; 107my $powercycle_after_reboot; 108my $poweroff_after_halt; 109my $max_monitor_wait; 110my $ssh_exec; 111my $scp_to_target; 112my $scp_to_target_install; 113my $power_off; 114my $grub_menu; 115my $last_grub_menu; 116my $grub_file; 117my $grub_number; 118my $grub_reboot; 119my $syslinux; 120my $syslinux_path; 121my $syslinux_label; 122my $target; 123my $make; 124my $pre_install; 125my $post_install; 126my $no_install; 127my $noclean; 128my $minconfig; 129my $start_minconfig; 130my $start_minconfig_defined; 131my $output_minconfig; 132my $minconfig_type; 133my $use_output_minconfig; 134my $warnings_file; 135my $ignore_config; 136my $ignore_errors; 137my $addconfig; 138my $in_bisect = 0; 139my $bisect_bad_commit = ""; 140my $reverse_bisect; 141my $bisect_manual; 142my $bisect_skip; 143my $bisect_tries; 144my $config_bisect_good; 145my $bisect_ret_good; 146my $bisect_ret_bad; 147my $bisect_ret_skip; 148my $bisect_ret_abort; 149my $bisect_ret_default; 150my $in_patchcheck = 0; 151my $run_test; 152my $buildlog; 153my $testlog; 154my $dmesg; 155my $monitor_fp; 156my $monitor_pid; 157my $monitor_cnt = 0; 158my $sleep_time; 159my $bisect_sleep_time; 160my $patchcheck_sleep_time; 161my $ignore_warnings; 162my $store_failures; 163my $store_successes; 164my $test_name; 165my $timeout; 166my $booted_timeout; 167my $detect_triplefault; 168my $console; 169my $close_console_signal; 170my $reboot_success_line; 171my $success_line; 172my $stop_after_success; 173my $stop_after_failure; 174my $stop_test_after; 175my $build_target; 176my $target_image; 177my $checkout; 178my $localversion; 179my $iteration = 0; 180my $successes = 0; 181 182my $bisect_good; 183my $bisect_bad; 184my $bisect_type; 185my $bisect_start; 186my $bisect_replay; 187my $bisect_files; 188my $bisect_reverse; 189my $bisect_check; 190 191my $config_bisect; 192my $config_bisect_type; 193my $config_bisect_check; 194 195my $patchcheck_type; 196my $patchcheck_start; 197my $patchcheck_cherry; 198my $patchcheck_end; 199 200# set when a test is something other that just building or install 201# which would require more options. 202my $buildonly = 1; 203 204# tell build not to worry about warnings, even when WARNINGS_FILE is set 205my $warnings_ok = 0; 206 207# set when creating a new config 208my $newconfig = 0; 209 210my %entered_configs; 211my %config_help; 212my %variable; 213 214# force_config is the list of configs that we force enabled (or disabled) 215# in a .config file. The MIN_CONFIG and ADD_CONFIG configs. 216my %force_config; 217 218# do not force reboots on config problems 219my $no_reboot = 1; 220 221# reboot on success 222my $reboot_success = 0; 223 224my %option_map = ( 225 "MACHINE" => \$machine, 226 "SSH_USER" => \$ssh_user, 227 "TMP_DIR" => \$tmpdir, 228 "OUTPUT_DIR" => \$outputdir, 229 "BUILD_DIR" => \$builddir, 230 "TEST_TYPE" => \$test_type, 231 "PRE_KTEST" => \$pre_ktest, 232 "POST_KTEST" => \$post_ktest, 233 "PRE_TEST" => \$pre_test, 234 "POST_TEST" => \$post_test, 235 "BUILD_TYPE" => \$build_type, 236 "BUILD_OPTIONS" => \$build_options, 237 "PRE_BUILD" => \$pre_build, 238 "POST_BUILD" => \$post_build, 239 "PRE_BUILD_DIE" => \$pre_build_die, 240 "POST_BUILD_DIE" => \$post_build_die, 241 "POWER_CYCLE" => \$power_cycle, 242 "REBOOT" => \$reboot, 243 "BUILD_NOCLEAN" => \$noclean, 244 "MIN_CONFIG" => \$minconfig, 245 "OUTPUT_MIN_CONFIG" => \$output_minconfig, 246 "START_MIN_CONFIG" => \$start_minconfig, 247 "MIN_CONFIG_TYPE" => \$minconfig_type, 248 "USE_OUTPUT_MIN_CONFIG" => \$use_output_minconfig, 249 "WARNINGS_FILE" => \$warnings_file, 250 "IGNORE_CONFIG" => \$ignore_config, 251 "TEST" => \$run_test, 252 "ADD_CONFIG" => \$addconfig, 253 "REBOOT_TYPE" => \$reboot_type, 254 "GRUB_MENU" => \$grub_menu, 255 "GRUB_FILE" => \$grub_file, 256 "GRUB_REBOOT" => \$grub_reboot, 257 "SYSLINUX" => \$syslinux, 258 "SYSLINUX_PATH" => \$syslinux_path, 259 "SYSLINUX_LABEL" => \$syslinux_label, 260 "PRE_INSTALL" => \$pre_install, 261 "POST_INSTALL" => \$post_install, 262 "NO_INSTALL" => \$no_install, 263 "REBOOT_SCRIPT" => \$reboot_script, 264 "REBOOT_ON_ERROR" => \$reboot_on_error, 265 "SWITCH_TO_GOOD" => \$switch_to_good, 266 "SWITCH_TO_TEST" => \$switch_to_test, 267 "POWEROFF_ON_ERROR" => \$poweroff_on_error, 268 "REBOOT_ON_SUCCESS" => \$reboot_on_success, 269 "DIE_ON_FAILURE" => \$die_on_failure, 270 "POWER_OFF" => \$power_off, 271 "POWERCYCLE_AFTER_REBOOT" => \$powercycle_after_reboot, 272 "POWEROFF_AFTER_HALT" => \$poweroff_after_halt, 273 "MAX_MONITOR_WAIT" => \$max_monitor_wait, 274 "SLEEP_TIME" => \$sleep_time, 275 "BISECT_SLEEP_TIME" => \$bisect_sleep_time, 276 "PATCHCHECK_SLEEP_TIME" => \$patchcheck_sleep_time, 277 "IGNORE_WARNINGS" => \$ignore_warnings, 278 "IGNORE_ERRORS" => \$ignore_errors, 279 "BISECT_MANUAL" => \$bisect_manual, 280 "BISECT_SKIP" => \$bisect_skip, 281 "BISECT_TRIES" => \$bisect_tries, 282 "CONFIG_BISECT_GOOD" => \$config_bisect_good, 283 "BISECT_RET_GOOD" => \$bisect_ret_good, 284 "BISECT_RET_BAD" => \$bisect_ret_bad, 285 "BISECT_RET_SKIP" => \$bisect_ret_skip, 286 "BISECT_RET_ABORT" => \$bisect_ret_abort, 287 "BISECT_RET_DEFAULT" => \$bisect_ret_default, 288 "STORE_FAILURES" => \$store_failures, 289 "STORE_SUCCESSES" => \$store_successes, 290 "TEST_NAME" => \$test_name, 291 "TIMEOUT" => \$timeout, 292 "BOOTED_TIMEOUT" => \$booted_timeout, 293 "CONSOLE" => \$console, 294 "CLOSE_CONSOLE_SIGNAL" => \$close_console_signal, 295 "DETECT_TRIPLE_FAULT" => \$detect_triplefault, 296 "SUCCESS_LINE" => \$success_line, 297 "REBOOT_SUCCESS_LINE" => \$reboot_success_line, 298 "STOP_AFTER_SUCCESS" => \$stop_after_success, 299 "STOP_AFTER_FAILURE" => \$stop_after_failure, 300 "STOP_TEST_AFTER" => \$stop_test_after, 301 "BUILD_TARGET" => \$build_target, 302 "SSH_EXEC" => \$ssh_exec, 303 "SCP_TO_TARGET" => \$scp_to_target, 304 "SCP_TO_TARGET_INSTALL" => \$scp_to_target_install, 305 "CHECKOUT" => \$checkout, 306 "TARGET_IMAGE" => \$target_image, 307 "LOCALVERSION" => \$localversion, 308 309 "BISECT_GOOD" => \$bisect_good, 310 "BISECT_BAD" => \$bisect_bad, 311 "BISECT_TYPE" => \$bisect_type, 312 "BISECT_START" => \$bisect_start, 313 "BISECT_REPLAY" => \$bisect_replay, 314 "BISECT_FILES" => \$bisect_files, 315 "BISECT_REVERSE" => \$bisect_reverse, 316 "BISECT_CHECK" => \$bisect_check, 317 318 "CONFIG_BISECT" => \$config_bisect, 319 "CONFIG_BISECT_TYPE" => \$config_bisect_type, 320 "CONFIG_BISECT_CHECK" => \$config_bisect_check, 321 322 "PATCHCHECK_TYPE" => \$patchcheck_type, 323 "PATCHCHECK_START" => \$patchcheck_start, 324 "PATCHCHECK_CHERRY" => \$patchcheck_cherry, 325 "PATCHCHECK_END" => \$patchcheck_end, 326); 327 328# Options may be used by other options, record them. 329my %used_options; 330 331# default variables that can be used 332chomp ($variable{"PWD"} = `pwd`); 333 334$config_help{"MACHINE"} = << "EOF" 335 The machine hostname that you will test. 336 For build only tests, it is still needed to differentiate log files. 337EOF 338 ; 339$config_help{"SSH_USER"} = << "EOF" 340 The box is expected to have ssh on normal bootup, provide the user 341 (most likely root, since you need privileged operations) 342EOF 343 ; 344$config_help{"BUILD_DIR"} = << "EOF" 345 The directory that contains the Linux source code (full path). 346 You can use \${PWD} that will be the path where ktest.pl is run, or use 347 \${THIS_DIR} which is assigned \${PWD} but may be changed later. 348EOF 349 ; 350$config_help{"OUTPUT_DIR"} = << "EOF" 351 The directory that the objects will be built (full path). 352 (can not be same as BUILD_DIR) 353 You can use \${PWD} that will be the path where ktest.pl is run, or use 354 \${THIS_DIR} which is assigned \${PWD} but may be changed later. 355EOF 356 ; 357$config_help{"BUILD_TARGET"} = << "EOF" 358 The location of the compiled file to copy to the target. 359 (relative to OUTPUT_DIR) 360EOF 361 ; 362$config_help{"BUILD_OPTIONS"} = << "EOF" 363 Options to add to \"make\" when building. 364 i.e. -j20 365EOF 366 ; 367$config_help{"TARGET_IMAGE"} = << "EOF" 368 The place to put your image on the test machine. 369EOF 370 ; 371$config_help{"POWER_CYCLE"} = << "EOF" 372 A script or command to reboot the box. 373 374 Here is a digital loggers power switch example 375 POWER_CYCLE = wget --no-proxy -O /dev/null -q --auth-no-challenge 'http://admin:admin\@power/outlet?5=CCL' 376 377 Here is an example to reboot a virtual box on the current host 378 with the name "Guest". 379 POWER_CYCLE = virsh destroy Guest; sleep 5; virsh start Guest 380EOF 381 ; 382$config_help{"CONSOLE"} = << "EOF" 383 The script or command that reads the console 384 385 If you use ttywatch server, something like the following would work. 386CONSOLE = nc -d localhost 3001 387 388 For a virtual machine with guest name "Guest". 389CONSOLE = virsh console Guest 390EOF 391 ; 392$config_help{"LOCALVERSION"} = << "EOF" 393 Required version ending to differentiate the test 394 from other linux builds on the system. 395EOF 396 ; 397$config_help{"REBOOT_TYPE"} = << "EOF" 398 Way to reboot the box to the test kernel. 399 Only valid options so far are "grub", "grub2", "syslinux", and "script". 400 401 If you specify grub, it will assume grub version 1 402 and will search in /boot/grub/menu.lst for the title \$GRUB_MENU 403 and select that target to reboot to the kernel. If this is not 404 your setup, then specify "script" and have a command or script 405 specified in REBOOT_SCRIPT to boot to the target. 406 407 The entry in /boot/grub/menu.lst must be entered in manually. 408 The test will not modify that file. 409 410 If you specify grub2, then you also need to specify both \$GRUB_MENU 411 and \$GRUB_FILE. 412 413 If you specify syslinux, then you may use SYSLINUX to define the syslinux 414 command (defaults to extlinux), and SYSLINUX_PATH to specify the path to 415 the syslinux install (defaults to /boot/extlinux). But you have to specify 416 SYSLINUX_LABEL to define the label to boot to for the test kernel. 417EOF 418 ; 419$config_help{"GRUB_MENU"} = << "EOF" 420 The grub title name for the test kernel to boot 421 (Only mandatory if REBOOT_TYPE = grub or grub2) 422 423 Note, ktest.pl will not update the grub menu.lst, you need to 424 manually add an option for the test. ktest.pl will search 425 the grub menu.lst for this option to find what kernel to 426 reboot into. 427 428 For example, if in the /boot/grub/menu.lst the test kernel title has: 429 title Test Kernel 430 kernel vmlinuz-test 431 GRUB_MENU = Test Kernel 432 433 For grub2, a search of \$GRUB_FILE is performed for the lines 434 that begin with "menuentry". It will not detect submenus. The 435 menu must be a non-nested menu. Add the quotes used in the menu 436 to guarantee your selection, as the first menuentry with the content 437 of \$GRUB_MENU that is found will be used. 438EOF 439 ; 440$config_help{"GRUB_FILE"} = << "EOF" 441 If grub2 is used, the full path for the grub.cfg file is placed 442 here. Use something like /boot/grub2/grub.cfg to search. 443EOF 444 ; 445$config_help{"SYSLINUX_LABEL"} = << "EOF" 446 If syslinux is used, the label that boots the target kernel must 447 be specified with SYSLINUX_LABEL. 448EOF 449 ; 450$config_help{"REBOOT_SCRIPT"} = << "EOF" 451 A script to reboot the target into the test kernel 452 (Only mandatory if REBOOT_TYPE = script) 453EOF 454 ; 455 456sub _logit { 457 if (defined($opt{"LOG_FILE"})) { 458 open(OUT, ">> $opt{LOG_FILE}") or die "Can't write to $opt{LOG_FILE}"; 459 print OUT @_; 460 close(OUT); 461 } 462} 463 464sub logit { 465 if (defined($opt{"LOG_FILE"})) { 466 _logit @_; 467 } else { 468 print @_; 469 } 470} 471 472sub doprint { 473 print @_; 474 _logit @_; 475} 476 477sub read_prompt { 478 my ($cancel, $prompt) = @_; 479 480 my $ans; 481 482 for (;;) { 483 if ($cancel) { 484 print "$prompt [y/n/C] "; 485 } else { 486 print "$prompt [Y/n] "; 487 } 488 $ans = <STDIN>; 489 chomp $ans; 490 if ($ans =~ /^\s*$/) { 491 if ($cancel) { 492 $ans = "c"; 493 } else { 494 $ans = "y"; 495 } 496 } 497 last if ($ans =~ /^y$/i || $ans =~ /^n$/i); 498 if ($cancel) { 499 last if ($ans =~ /^c$/i); 500 print "Please answer either 'y', 'n' or 'c'.\n"; 501 } else { 502 print "Please answer either 'y' or 'n'.\n"; 503 } 504 } 505 if ($ans =~ /^c/i) { 506 exit; 507 } 508 if ($ans !~ /^y$/i) { 509 return 0; 510 } 511 return 1; 512} 513 514sub read_yn { 515 my ($prompt) = @_; 516 517 return read_prompt 0, $prompt; 518} 519 520sub read_ync { 521 my ($prompt) = @_; 522 523 return read_prompt 1, $prompt; 524} 525 526sub get_mandatory_config { 527 my ($config) = @_; 528 my $ans; 529 530 return if (defined($opt{$config})); 531 532 if (defined($config_help{$config})) { 533 print "\n"; 534 print $config_help{$config}; 535 } 536 537 for (;;) { 538 print "$config = "; 539 if (defined($default{$config}) && length($default{$config})) { 540 print "\[$default{$config}\] "; 541 } 542 $ans = <STDIN>; 543 $ans =~ s/^\s*(.*\S)\s*$/$1/; 544 if ($ans =~ /^\s*$/) { 545 if ($default{$config}) { 546 $ans = $default{$config}; 547 } else { 548 print "Your answer can not be blank\n"; 549 next; 550 } 551 } 552 $entered_configs{$config} = ${ans}; 553 last; 554 } 555} 556 557sub get_mandatory_configs { 558 get_mandatory_config("MACHINE"); 559 get_mandatory_config("BUILD_DIR"); 560 get_mandatory_config("OUTPUT_DIR"); 561 562 if ($newconfig) { 563 get_mandatory_config("BUILD_OPTIONS"); 564 } 565 566 # options required for other than just building a kernel 567 if (!$buildonly) { 568 get_mandatory_config("POWER_CYCLE"); 569 get_mandatory_config("CONSOLE"); 570 } 571 572 # options required for install and more 573 if ($buildonly != 1) { 574 get_mandatory_config("SSH_USER"); 575 get_mandatory_config("BUILD_TARGET"); 576 get_mandatory_config("TARGET_IMAGE"); 577 } 578 579 get_mandatory_config("LOCALVERSION"); 580 581 return if ($buildonly); 582 583 my $rtype = $opt{"REBOOT_TYPE"}; 584 585 if (!defined($rtype)) { 586 if (!defined($opt{"GRUB_MENU"})) { 587 get_mandatory_config("REBOOT_TYPE"); 588 $rtype = $entered_configs{"REBOOT_TYPE"}; 589 } else { 590 $rtype = "grub"; 591 } 592 } 593 594 if ($rtype eq "grub") { 595 get_mandatory_config("GRUB_MENU"); 596 } 597 598 if ($rtype eq "grub2") { 599 get_mandatory_config("GRUB_MENU"); 600 get_mandatory_config("GRUB_FILE"); 601 } 602 603 if ($rtype eq "syslinux") { 604 get_mandatory_config("SYSLINUX_LABEL"); 605 } 606} 607 608sub process_variables { 609 my ($value, $remove_undef) = @_; 610 my $retval = ""; 611 612 # We want to check for '\', and it is just easier 613 # to check the previous characet of '$' and not need 614 # to worry if '$' is the first character. By adding 615 # a space to $value, we can just check [^\\]\$ and 616 # it will still work. 617 $value = " $value"; 618 619 while ($value =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) { 620 my $begin = $1; 621 my $var = $2; 622 my $end = $3; 623 # append beginning of value to retval 624 $retval = "$retval$begin"; 625 if (defined($variable{$var})) { 626 $retval = "$retval$variable{$var}"; 627 } elsif (defined($remove_undef) && $remove_undef) { 628 # for if statements, any variable that is not defined, 629 # we simple convert to 0 630 $retval = "${retval}0"; 631 } else { 632 # put back the origin piece. 633 $retval = "$retval\$\{$var\}"; 634 # This could be an option that is used later, save 635 # it so we don't warn if this option is not one of 636 # ktests options. 637 $used_options{$var} = 1; 638 } 639 $value = $end; 640 } 641 $retval = "$retval$value"; 642 643 # remove the space added in the beginning 644 $retval =~ s/ //; 645 646 return "$retval" 647} 648 649sub set_value { 650 my ($lvalue, $rvalue, $override, $overrides, $name) = @_; 651 652 my $prvalue = process_variables($rvalue); 653 654 if ($buildonly && $lvalue =~ /^TEST_TYPE(\[.*\])?$/ && $prvalue ne "build") { 655 # Note if a test is something other than build, then we 656 # will need other manditory options. 657 if ($prvalue ne "install") { 658 # for bisect, we need to check BISECT_TYPE 659 if ($prvalue ne "bisect") { 660 $buildonly = 0; 661 } 662 } else { 663 # install still limits some manditory options. 664 $buildonly = 2; 665 } 666 } 667 668 if ($buildonly && $lvalue =~ /^BISECT_TYPE(\[.*\])?$/ && $prvalue ne "build") { 669 if ($prvalue ne "install") { 670 $buildonly = 0; 671 } else { 672 # install still limits some manditory options. 673 $buildonly = 2; 674 } 675 } 676 677 if (defined($opt{$lvalue})) { 678 if (!$override || defined(${$overrides}{$lvalue})) { 679 my $extra = ""; 680 if ($override) { 681 $extra = "In the same override section!\n"; 682 } 683 die "$name: $.: Option $lvalue defined more than once!\n$extra"; 684 } 685 ${$overrides}{$lvalue} = $prvalue; 686 } 687 688 $opt{$lvalue} = $prvalue; 689} 690 691sub set_eval { 692 my ($lvalue, $rvalue, $name) = @_; 693 694 my $prvalue = process_variables($rvalue); 695 my $arr; 696 697 if (defined($evals{$lvalue})) { 698 $arr = $evals{$lvalue}; 699 } else { 700 $arr = []; 701 $evals{$lvalue} = $arr; 702 } 703 704 push @{$arr}, $rvalue; 705} 706 707sub set_variable { 708 my ($lvalue, $rvalue) = @_; 709 710 if ($rvalue =~ /^\s*$/) { 711 delete $variable{$lvalue}; 712 } else { 713 $rvalue = process_variables($rvalue); 714 $variable{$lvalue} = $rvalue; 715 } 716} 717 718sub process_compare { 719 my ($lval, $cmp, $rval) = @_; 720 721 # remove whitespace 722 723 $lval =~ s/^\s*//; 724 $lval =~ s/\s*$//; 725 726 $rval =~ s/^\s*//; 727 $rval =~ s/\s*$//; 728 729 if ($cmp eq "==") { 730 return $lval eq $rval; 731 } elsif ($cmp eq "!=") { 732 return $lval ne $rval; 733 } elsif ($cmp eq "=~") { 734 return $lval =~ m/$rval/; 735 } elsif ($cmp eq "!~") { 736 return $lval !~ m/$rval/; 737 } 738 739 my $statement = "$lval $cmp $rval"; 740 my $ret = eval $statement; 741 742 # $@ stores error of eval 743 if ($@) { 744 return -1; 745 } 746 747 return $ret; 748} 749 750sub value_defined { 751 my ($val) = @_; 752 753 return defined($variable{$2}) || 754 defined($opt{$2}); 755} 756 757my $d = 0; 758sub process_expression { 759 my ($name, $val) = @_; 760 761 my $c = $d++; 762 763 while ($val =~ s/\(([^\(]*?)\)/\&\&\&\&VAL\&\&\&\&/) { 764 my $express = $1; 765 766 if (process_expression($name, $express)) { 767 $val =~ s/\&\&\&\&VAL\&\&\&\&/ 1 /; 768 } else { 769 $val =~ s/\&\&\&\&VAL\&\&\&\&/ 0 /; 770 } 771 } 772 773 $d--; 774 my $OR = "\\|\\|"; 775 my $AND = "\\&\\&"; 776 777 while ($val =~ s/^(.*?)($OR|$AND)//) { 778 my $express = $1; 779 my $op = $2; 780 781 if (process_expression($name, $express)) { 782 if ($op eq "||") { 783 return 1; 784 } 785 } else { 786 if ($op eq "&&") { 787 return 0; 788 } 789 } 790 } 791 792 if ($val =~ /(.*)(==|\!=|>=|<=|>|<|=~|\!~)(.*)/) { 793 my $ret = process_compare($1, $2, $3); 794 if ($ret < 0) { 795 die "$name: $.: Unable to process comparison\n"; 796 } 797 return $ret; 798 } 799 800 if ($val =~ /^\s*(NOT\s*)?DEFINED\s+(\S+)\s*$/) { 801 if (defined $1) { 802 return !value_defined($2); 803 } else { 804 return value_defined($2); 805 } 806 } 807 808 if ($val =~ /^\s*0\s*$/) { 809 return 0; 810 } elsif ($val =~ /^\s*\d+\s*$/) { 811 return 1; 812 } 813 814 die ("$name: $.: Undefined content $val in if statement\n"); 815} 816 817sub process_if { 818 my ($name, $value) = @_; 819 820 # Convert variables and replace undefined ones with 0 821 my $val = process_variables($value, 1); 822 my $ret = process_expression $name, $val; 823 824 return $ret; 825} 826 827sub __read_config { 828 my ($config, $current_test_num) = @_; 829 830 my $in; 831 open($in, $config) || die "can't read file $config"; 832 833 my $name = $config; 834 $name =~ s,.*/(.*),$1,; 835 836 my $test_num = $$current_test_num; 837 my $default = 1; 838 my $repeat = 1; 839 my $num_tests_set = 0; 840 my $skip = 0; 841 my $rest; 842 my $line; 843 my $test_case = 0; 844 my $if = 0; 845 my $if_set = 0; 846 my $override = 0; 847 848 my %overrides; 849 850 while (<$in>) { 851 852 # ignore blank lines and comments 853 next if (/^\s*$/ || /\s*\#/); 854 855 if (/^\s*(TEST_START|DEFAULTS)\b(.*)/) { 856 857 my $type = $1; 858 $rest = $2; 859 $line = $2; 860 861 my $old_test_num; 862 my $old_repeat; 863 $override = 0; 864 865 if ($type eq "TEST_START") { 866 867 if ($num_tests_set) { 868 die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n"; 869 } 870 871 $old_test_num = $test_num; 872 $old_repeat = $repeat; 873 874 $test_num += $repeat; 875 $default = 0; 876 $repeat = 1; 877 } else { 878 $default = 1; 879 } 880 881 # If SKIP is anywhere in the line, the command will be skipped 882 if ($rest =~ s/\s+SKIP\b//) { 883 $skip = 1; 884 } else { 885 $test_case = 1; 886 $skip = 0; 887 } 888 889 if ($rest =~ s/\sELSE\b//) { 890 if (!$if) { 891 die "$name: $.: ELSE found with out matching IF section\n$_"; 892 } 893 $if = 0; 894 895 if ($if_set) { 896 $skip = 1; 897 } else { 898 $skip = 0; 899 } 900 } 901 902 if ($rest =~ s/\sIF\s+(.*)//) { 903 if (process_if($name, $1)) { 904 $if_set = 1; 905 } else { 906 $skip = 1; 907 } 908 $if = 1; 909 } else { 910 $if = 0; 911 $if_set = 0; 912 } 913 914 if (!$skip) { 915 if ($type eq "TEST_START") { 916 if ($rest =~ s/\s+ITERATE\s+(\d+)//) { 917 $repeat = $1; 918 $repeat_tests{"$test_num"} = $repeat; 919 } 920 } elsif ($rest =~ s/\sOVERRIDE\b//) { 921 # DEFAULT only 922 $override = 1; 923 # Clear previous overrides 924 %overrides = (); 925 } 926 } 927 928 if (!$skip && $rest !~ /^\s*$/) { 929 die "$name: $.: Gargbage found after $type\n$_"; 930 } 931 932 if ($skip && $type eq "TEST_START") { 933 $test_num = $old_test_num; 934 $repeat = $old_repeat; 935 } 936 937 } elsif (/^\s*ELSE\b(.*)$/) { 938 if (!$if) { 939 die "$name: $.: ELSE found with out matching IF section\n$_"; 940 } 941 $rest = $1; 942 if ($if_set) { 943 $skip = 1; 944 $rest = ""; 945 } else { 946 $skip = 0; 947 948 if ($rest =~ /\sIF\s+(.*)/) { 949 # May be a ELSE IF section. 950 if (process_if($name, $1)) { 951 $if_set = 1; 952 } else { 953 $skip = 1; 954 } 955 $rest = ""; 956 } else { 957 $if = 0; 958 } 959 } 960 961 if ($rest !~ /^\s*$/) { 962 die "$name: $.: Gargbage found after DEFAULTS\n$_"; 963 } 964 965 } elsif (/^\s*INCLUDE\s+(\S+)/) { 966 967 next if ($skip); 968 969 if (!$default) { 970 die "$name: $.: INCLUDE can only be done in default sections\n$_"; 971 } 972 973 my $file = process_variables($1); 974 975 if ($file !~ m,^/,) { 976 # check the path of the config file first 977 if ($config =~ m,(.*)/,) { 978 if (-f "$1/$file") { 979 $file = "$1/$file"; 980 } 981 } 982 } 983 984 if ( ! -r $file ) { 985 die "$name: $.: Can't read file $file\n$_"; 986 } 987 988 if (__read_config($file, \$test_num)) { 989 $test_case = 1; 990 } 991 992 } elsif (/^\s*([A-Z_\[\]\d]+)\s*=~\s*(.*?)\s*$/) { 993 994 next if ($skip); 995 996 my $lvalue = $1; 997 my $rvalue = $2; 998 999 if ($default || $lvalue =~ /\[\d+\]$/) { 1000 set_eval($lvalue, $rvalue, $name); 1001 } else { 1002 my $val = "$lvalue\[$test_num\]"; 1003 set_eval($val, $rvalue, $name); 1004 } 1005 1006 } elsif (/^\s*([A-Z_\[\]\d]+)\s*=\s*(.*?)\s*$/) { 1007 1008 next if ($skip); 1009 1010 my $lvalue = $1; 1011 my $rvalue = $2; 1012 1013 if (!$default && 1014 ($lvalue eq "NUM_TESTS" || 1015 $lvalue eq "LOG_FILE" || 1016 $lvalue eq "CLEAR_LOG")) { 1017 die "$name: $.: $lvalue must be set in DEFAULTS section\n"; 1018 } 1019 1020 if ($lvalue eq "NUM_TESTS") { 1021 if ($test_num) { 1022 die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n"; 1023 } 1024 if (!$default) { 1025 die "$name: $.: NUM_TESTS must be set in default section\n"; 1026 } 1027 $num_tests_set = 1; 1028 } 1029 1030 if ($default || $lvalue =~ /\[\d+\]$/) { 1031 set_value($lvalue, $rvalue, $override, \%overrides, $name); 1032 } else { 1033 my $val = "$lvalue\[$test_num\]"; 1034 set_value($val, $rvalue, $override, \%overrides, $name); 1035 1036 if ($repeat > 1) { 1037 $repeats{$val} = $repeat; 1038 } 1039 } 1040 } elsif (/^\s*([A-Z_\[\]\d]+)\s*:=\s*(.*?)\s*$/) { 1041 next if ($skip); 1042 1043 my $lvalue = $1; 1044 my $rvalue = $2; 1045 1046 # process config variables. 1047 # Config variables are only active while reading the 1048 # config and can be defined anywhere. They also ignore 1049 # TEST_START and DEFAULTS, but are skipped if they are in 1050 # on of these sections that have SKIP defined. 1051 # The save variable can be 1052 # defined multiple times and the new one simply overrides 1053 # the prevous one. 1054 set_variable($lvalue, $rvalue); 1055 1056 } else { 1057 die "$name: $.: Garbage found in config\n$_"; 1058 } 1059 } 1060 1061 if ($test_num) { 1062 $test_num += $repeat - 1; 1063 $opt{"NUM_TESTS"} = $test_num; 1064 } 1065 1066 close($in); 1067 1068 $$current_test_num = $test_num; 1069 1070 return $test_case; 1071} 1072 1073sub get_test_case { 1074 print "What test case would you like to run?\n"; 1075 print " (build, install or boot)\n"; 1076 print " Other tests are available but require editing the config file\n"; 1077 my $ans = <STDIN>; 1078 chomp $ans; 1079 $default{"TEST_TYPE"} = $ans; 1080} 1081 1082sub read_config { 1083 my ($config) = @_; 1084 1085 my $test_case; 1086 my $test_num = 0; 1087 1088 $test_case = __read_config $config, \$test_num; 1089 1090 # make sure we have all mandatory configs 1091 get_mandatory_configs; 1092 1093 # was a test specified? 1094 if (!$test_case) { 1095 print "No test case specified.\n"; 1096 get_test_case; 1097 } 1098 1099 # set any defaults 1100 1101 foreach my $default (keys %default) { 1102 if (!defined($opt{$default})) { 1103 $opt{$default} = $default{$default}; 1104 } 1105 } 1106 1107 if ($opt{"IGNORE_UNUSED"} == 1) { 1108 return; 1109 } 1110 1111 my %not_used; 1112 1113 # check if there are any stragglers (typos?) 1114 foreach my $option (keys %opt) { 1115 my $op = $option; 1116 # remove per test labels. 1117 $op =~ s/\[.*\]//; 1118 if (!exists($option_map{$op}) && 1119 !exists($default{$op}) && 1120 !exists($used_options{$op})) { 1121 $not_used{$op} = 1; 1122 } 1123 } 1124 1125 if (%not_used) { 1126 my $s = "s are"; 1127 $s = " is" if (keys %not_used == 1); 1128 print "The following option$s not used; could be a typo:\n"; 1129 foreach my $option (keys %not_used) { 1130 print "$option\n"; 1131 } 1132 print "Set IGRNORE_UNUSED = 1 to have ktest ignore unused variables\n"; 1133 if (!read_yn "Do you want to continue?") { 1134 exit -1; 1135 } 1136 } 1137} 1138 1139sub __eval_option { 1140 my ($name, $option, $i) = @_; 1141 1142 # Add space to evaluate the character before $ 1143 $option = " $option"; 1144 my $retval = ""; 1145 my $repeated = 0; 1146 my $parent = 0; 1147 1148 foreach my $test (keys %repeat_tests) { 1149 if ($i >= $test && 1150 $i < $test + $repeat_tests{$test}) { 1151 1152 $repeated = 1; 1153 $parent = $test; 1154 last; 1155 } 1156 } 1157 1158 while ($option =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) { 1159 my $start = $1; 1160 my $var = $2; 1161 my $end = $3; 1162 1163 # Append beginning of line 1164 $retval = "$retval$start"; 1165 1166 # If the iteration option OPT[$i] exists, then use that. 1167 # otherwise see if the default OPT (without [$i]) exists. 1168 1169 my $o = "$var\[$i\]"; 1170 my $parento = "$var\[$parent\]"; 1171 1172 # If a variable contains itself, use the default var 1173 if (($var eq $name) && defined($opt{$var})) { 1174 $o = $opt{$var}; 1175 $retval = "$retval$o"; 1176 } elsif (defined($opt{$o})) { 1177 $o = $opt{$o}; 1178 $retval = "$retval$o"; 1179 } elsif ($repeated && defined($opt{$parento})) { 1180 $o = $opt{$parento}; 1181 $retval = "$retval$o"; 1182 } elsif (defined($opt{$var})) { 1183 $o = $opt{$var}; 1184 $retval = "$retval$o"; 1185 } elsif ($var eq "KERNEL_VERSION" && defined($make)) { 1186 # special option KERNEL_VERSION uses kernel version 1187 get_version(); 1188 $retval = "$retval$version"; 1189 } else { 1190 $retval = "$retval\$\{$var\}"; 1191 } 1192 1193 $option = $end; 1194 } 1195 1196 $retval = "$retval$option"; 1197 1198 $retval =~ s/^ //; 1199 1200 return $retval; 1201} 1202 1203sub process_evals { 1204 my ($name, $option, $i) = @_; 1205 1206 my $option_name = "$name\[$i\]"; 1207 my $ev; 1208 1209 my $old_option = $option; 1210 1211 if (defined($evals{$option_name})) { 1212 $ev = $evals{$option_name}; 1213 } elsif (defined($evals{$name})) { 1214 $ev = $evals{$name}; 1215 } else { 1216 return $option; 1217 } 1218 1219 for my $e (@{$ev}) { 1220 eval "\$option =~ $e"; 1221 } 1222 1223 if ($option ne $old_option) { 1224 doprint("$name changed from '$old_option' to '$option'\n"); 1225 } 1226 1227 return $option; 1228} 1229 1230sub eval_option { 1231 my ($name, $option, $i) = @_; 1232 1233 my $prev = ""; 1234 1235 # Since an option can evaluate to another option, 1236 # keep iterating until we do not evaluate any more 1237 # options. 1238 my $r = 0; 1239 while ($prev ne $option) { 1240 # Check for recursive evaluations. 1241 # 100 deep should be more than enough. 1242 if ($r++ > 100) { 1243 die "Over 100 evaluations accurred with $option\n" . 1244 "Check for recursive variables\n"; 1245 } 1246 $prev = $option; 1247 $option = __eval_option($name, $option, $i); 1248 } 1249 1250 $option = process_evals($name, $option, $i); 1251 1252 return $option; 1253} 1254 1255sub run_command; 1256sub start_monitor; 1257sub end_monitor; 1258sub wait_for_monitor; 1259 1260sub reboot { 1261 my ($time) = @_; 1262 1263 # Make sure everything has been written to disk 1264 run_ssh("sync"); 1265 1266 if (defined($time)) { 1267 start_monitor; 1268 # flush out current monitor 1269 # May contain the reboot success line 1270 wait_for_monitor 1; 1271 } 1272 1273 # try to reboot normally 1274 if (run_command $reboot) { 1275 if (defined($powercycle_after_reboot)) { 1276 sleep $powercycle_after_reboot; 1277 run_command "$power_cycle"; 1278 } 1279 } else { 1280 # nope? power cycle it. 1281 run_command "$power_cycle"; 1282 } 1283 1284 if (defined($time)) { 1285 1286 # We only want to get to the new kernel, don't fail 1287 # if we stumble over a call trace. 1288 my $save_ignore_errors = $ignore_errors; 1289 $ignore_errors = 1; 1290 1291 # Look for the good kernel to boot 1292 if (wait_for_monitor($time, "Linux version")) { 1293 # reboot got stuck? 1294 doprint "Reboot did not finish. Forcing power cycle\n"; 1295 run_command "$power_cycle"; 1296 } 1297 1298 $ignore_errors = $save_ignore_errors; 1299 1300 # Still need to wait for the reboot to finish 1301 wait_for_monitor($time, $reboot_success_line); 1302 1303 end_monitor; 1304 } 1305} 1306 1307sub reboot_to_good { 1308 my ($time) = @_; 1309 1310 if (defined($switch_to_good)) { 1311 run_command $switch_to_good; 1312 } 1313 1314 reboot $time; 1315} 1316 1317sub do_not_reboot { 1318 my $i = $iteration; 1319 1320 return $test_type eq "build" || $no_reboot || 1321 ($test_type eq "patchcheck" && $opt{"PATCHCHECK_TYPE[$i]"} eq "build") || 1322 ($test_type eq "bisect" && $opt{"BISECT_TYPE[$i]"} eq "build"); 1323} 1324 1325sub dodie { 1326 doprint "CRITICAL FAILURE... ", @_, "\n"; 1327 1328 my $i = $iteration; 1329 1330 if ($reboot_on_error && !do_not_reboot) { 1331 1332 doprint "REBOOTING\n"; 1333 reboot_to_good; 1334 1335 } elsif ($poweroff_on_error && defined($power_off)) { 1336 doprint "POWERING OFF\n"; 1337 `$power_off`; 1338 } 1339 1340 if (defined($opt{"LOG_FILE"})) { 1341 print " See $opt{LOG_FILE} for more info.\n"; 1342 } 1343 1344 die @_, "\n"; 1345} 1346 1347sub open_console { 1348 my ($fp) = @_; 1349 1350 my $flags; 1351 1352 my $pid = open($fp, "$console|") or 1353 dodie "Can't open console $console"; 1354 1355 $flags = fcntl($fp, F_GETFL, 0) or 1356 dodie "Can't get flags for the socket: $!"; 1357 $flags = fcntl($fp, F_SETFL, $flags | O_NONBLOCK) or 1358 dodie "Can't set flags for the socket: $!"; 1359 1360 return $pid; 1361} 1362 1363sub close_console { 1364 my ($fp, $pid) = @_; 1365 1366 doprint "kill child process $pid\n"; 1367 kill $close_console_signal, $pid; 1368 1369 print "closing!\n"; 1370 close($fp); 1371} 1372 1373sub start_monitor { 1374 if ($monitor_cnt++) { 1375 return; 1376 } 1377 $monitor_fp = \*MONFD; 1378 $monitor_pid = open_console $monitor_fp; 1379 1380 return; 1381 1382 open(MONFD, "Stop perl from warning about single use of MONFD"); 1383} 1384 1385sub end_monitor { 1386 return if (!defined $console); 1387 if (--$monitor_cnt) { 1388 return; 1389 } 1390 close_console($monitor_fp, $monitor_pid); 1391} 1392 1393sub wait_for_monitor { 1394 my ($time, $stop) = @_; 1395 my $full_line = ""; 1396 my $line; 1397 my $booted = 0; 1398 my $start_time = time; 1399 my $skip_call_trace = 0; 1400 my $bug = 0; 1401 my $bug_ignored = 0; 1402 my $now; 1403 1404 doprint "** Wait for monitor to settle down **\n"; 1405 1406 # read the monitor and wait for the system to calm down 1407 while (!$booted) { 1408 $line = wait_for_input($monitor_fp, $time); 1409 last if (!defined($line)); 1410 print "$line"; 1411 $full_line .= $line; 1412 1413 if (defined($stop) && $full_line =~ /$stop/) { 1414 doprint "wait for monitor detected $stop\n"; 1415 $booted = 1; 1416 } 1417 1418 if ($full_line =~ /\[ backtrace testing \]/) { 1419 $skip_call_trace = 1; 1420 } 1421 1422 if ($full_line =~ /call trace:/i) { 1423 if (!$bug && !$skip_call_trace) { 1424 if ($ignore_errors) { 1425 $bug_ignored = 1; 1426 } else { 1427 $bug = 1; 1428 } 1429 } 1430 } 1431 1432 if ($full_line =~ /\[ end of backtrace testing \]/) { 1433 $skip_call_trace = 0; 1434 } 1435 1436 if ($full_line =~ /Kernel panic -/) { 1437 $bug = 1; 1438 } 1439 1440 if ($line =~ /\n/) { 1441 $full_line = ""; 1442 } 1443 $now = time; 1444 if ($now - $start_time >= $max_monitor_wait) { 1445 doprint "Exiting monitor flush due to hitting MAX_MONITOR_WAIT\n"; 1446 return 1; 1447 } 1448 } 1449 print "** Monitor flushed **\n"; 1450 1451 # if stop is defined but wasn't hit, return error 1452 # used by reboot (which wants to see a reboot) 1453 if (defined($stop) && !$booted) { 1454 $bug = 1; 1455 } 1456 return $bug; 1457} 1458 1459sub save_logs { 1460 my ($result, $basedir) = @_; 1461 my @t = localtime; 1462 my $date = sprintf "%04d%02d%02d%02d%02d%02d", 1463 1900+$t[5],$t[4],$t[3],$t[2],$t[1],$t[0]; 1464 1465 my $type = $build_type; 1466 if ($type =~ /useconfig/) { 1467 $type = "useconfig"; 1468 } 1469 1470 my $dir = "$machine-$test_type-$type-$result-$date"; 1471 1472 $dir = "$basedir/$dir"; 1473 1474 if (!-d $dir) { 1475 mkpath($dir) or 1476 die "can't create $dir"; 1477 } 1478 1479 my %files = ( 1480 "config" => $output_config, 1481 "buildlog" => $buildlog, 1482 "dmesg" => $dmesg, 1483 "testlog" => $testlog, 1484 ); 1485 1486 while (my ($name, $source) = each(%files)) { 1487 if (-f "$source") { 1488 cp "$source", "$dir/$name" or 1489 die "failed to copy $source"; 1490 } 1491 } 1492 1493 doprint "*** Saved info to $dir ***\n"; 1494} 1495 1496sub fail { 1497 1498 if (defined($post_test)) { 1499 run_command $post_test; 1500 } 1501 1502 if ($die_on_failure) { 1503 dodie @_; 1504 } 1505 1506 doprint "FAILED\n"; 1507 1508 my $i = $iteration; 1509 1510 # no need to reboot for just building. 1511 if (!do_not_reboot) { 1512 doprint "REBOOTING\n"; 1513 reboot_to_good $sleep_time; 1514 } 1515 1516 my $name = ""; 1517 1518 if (defined($test_name)) { 1519 $name = " ($test_name)"; 1520 } 1521 1522 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"; 1523 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"; 1524 doprint "KTEST RESULT: TEST $i$name Failed: ", @_, "\n"; 1525 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"; 1526 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"; 1527 1528 if (defined($store_failures)) { 1529 save_logs "fail", $store_failures; 1530 } 1531 1532 return 1; 1533} 1534 1535sub run_command { 1536 my ($command, $redirect) = @_; 1537 my $dolog = 0; 1538 my $dord = 0; 1539 my $pid; 1540 1541 $command =~ s/\$SSH_USER/$ssh_user/g; 1542 $command =~ s/\$MACHINE/$machine/g; 1543 1544 doprint("$command ... "); 1545 1546 $pid = open(CMD, "$command 2>&1 |") or 1547 (fail "unable to exec $command" and return 0); 1548 1549 if (defined($opt{"LOG_FILE"})) { 1550 open(LOG, ">>$opt{LOG_FILE}") or 1551 dodie "failed to write to log"; 1552 $dolog = 1; 1553 } 1554 1555 if (defined($redirect)) { 1556 open (RD, ">$redirect") or 1557 dodie "failed to write to redirect $redirect"; 1558 $dord = 1; 1559 } 1560 1561 while (<CMD>) { 1562 print LOG if ($dolog); 1563 print RD if ($dord); 1564 } 1565 1566 waitpid($pid, 0); 1567 my $failed = $?; 1568 1569 close(CMD); 1570 close(LOG) if ($dolog); 1571 close(RD) if ($dord); 1572 1573 if ($failed) { 1574 doprint "FAILED!\n"; 1575 } else { 1576 doprint "SUCCESS\n"; 1577 } 1578 1579 return !$failed; 1580} 1581 1582sub run_ssh { 1583 my ($cmd) = @_; 1584 my $cp_exec = $ssh_exec; 1585 1586 $cp_exec =~ s/\$SSH_COMMAND/$cmd/g; 1587 return run_command "$cp_exec"; 1588} 1589 1590sub run_scp { 1591 my ($src, $dst, $cp_scp) = @_; 1592 1593 $cp_scp =~ s/\$SRC_FILE/$src/g; 1594 $cp_scp =~ s/\$DST_FILE/$dst/g; 1595 1596 return run_command "$cp_scp"; 1597} 1598 1599sub run_scp_install { 1600 my ($src, $dst) = @_; 1601 1602 my $cp_scp = $scp_to_target_install; 1603 1604 return run_scp($src, $dst, $cp_scp); 1605} 1606 1607sub run_scp_mod { 1608 my ($src, $dst) = @_; 1609 1610 my $cp_scp = $scp_to_target; 1611 1612 return run_scp($src, $dst, $cp_scp); 1613} 1614 1615sub get_grub2_index { 1616 1617 return if (defined($grub_number) && defined($last_grub_menu) && 1618 $last_grub_menu eq $grub_menu && defined($last_machine) && 1619 $last_machine eq $machine); 1620 1621 doprint "Find grub2 menu ... "; 1622 $grub_number = -1; 1623 1624 my $ssh_grub = $ssh_exec; 1625 $ssh_grub =~ s,\$SSH_COMMAND,cat $grub_file,g; 1626 1627 open(IN, "$ssh_grub |") 1628 or die "unable to get $grub_file"; 1629 1630 my $found = 0; 1631 1632 while (<IN>) { 1633 if (/^menuentry.*$grub_menu/) { 1634 $grub_number++; 1635 $found = 1; 1636 last; 1637 } elsif (/^menuentry\s/) { 1638 $grub_number++; 1639 } 1640 } 1641 close(IN); 1642 1643 die "Could not find '$grub_menu' in $grub_file on $machine" 1644 if (!$found); 1645 doprint "$grub_number\n"; 1646 $last_grub_menu = $grub_menu; 1647 $last_machine = $machine; 1648} 1649 1650sub get_grub_index { 1651 1652 if ($reboot_type eq "grub2") { 1653 get_grub2_index; 1654 return; 1655 } 1656 1657 if ($reboot_type ne "grub") { 1658 return; 1659 } 1660 return if (defined($grub_number) && defined($last_grub_menu) && 1661 $last_grub_menu eq $grub_menu && defined($last_machine) && 1662 $last_machine eq $machine); 1663 1664 doprint "Find grub menu ... "; 1665 $grub_number = -1; 1666 1667 my $ssh_grub = $ssh_exec; 1668 $ssh_grub =~ s,\$SSH_COMMAND,cat /boot/grub/menu.lst,g; 1669 1670 open(IN, "$ssh_grub |") 1671 or die "unable to get menu.lst"; 1672 1673 my $found = 0; 1674 1675 while (<IN>) { 1676 if (/^\s*title\s+$grub_menu\s*$/) { 1677 $grub_number++; 1678 $found = 1; 1679 last; 1680 } elsif (/^\s*title\s/) { 1681 $grub_number++; 1682 } 1683 } 1684 close(IN); 1685 1686 die "Could not find '$grub_menu' in /boot/grub/menu on $machine" 1687 if (!$found); 1688 doprint "$grub_number\n"; 1689 $last_grub_menu = $grub_menu; 1690 $last_machine = $machine; 1691} 1692 1693sub wait_for_input 1694{ 1695 my ($fp, $time) = @_; 1696 my $rin; 1697 my $ready; 1698 my $line; 1699 my $ch; 1700 1701 if (!defined($time)) { 1702 $time = $timeout; 1703 } 1704 1705 $rin = ''; 1706 vec($rin, fileno($fp), 1) = 1; 1707 ($ready, $time) = select($rin, undef, undef, $time); 1708 1709 $line = ""; 1710 1711 # try to read one char at a time 1712 while (sysread $fp, $ch, 1) { 1713 $line .= $ch; 1714 last if ($ch eq "\n"); 1715 } 1716 1717 if (!length($line)) { 1718 return undef; 1719 } 1720 1721 return $line; 1722} 1723 1724sub reboot_to { 1725 if (defined($switch_to_test)) { 1726 run_command $switch_to_test; 1727 } 1728 1729 if ($reboot_type eq "grub") { 1730 run_ssh "'(echo \"savedefault --default=$grub_number --once\" | grub --batch)'"; 1731 } elsif ($reboot_type eq "grub2") { 1732 run_ssh "$grub_reboot $grub_number"; 1733 } elsif ($reboot_type eq "syslinux") { 1734 run_ssh "$syslinux --once \\\"$syslinux_label\\\" $syslinux_path"; 1735 } elsif (defined $reboot_script) { 1736 run_command "$reboot_script"; 1737 } 1738 reboot; 1739} 1740 1741sub get_sha1 { 1742 my ($commit) = @_; 1743 1744 doprint "git rev-list --max-count=1 $commit ... "; 1745 my $sha1 = `git rev-list --max-count=1 $commit`; 1746 my $ret = $?; 1747 1748 logit $sha1; 1749 1750 if ($ret) { 1751 doprint "FAILED\n"; 1752 dodie "Failed to get git $commit"; 1753 } 1754 1755 print "SUCCESS\n"; 1756 1757 chomp $sha1; 1758 1759 return $sha1; 1760} 1761 1762sub monitor { 1763 my $booted = 0; 1764 my $bug = 0; 1765 my $bug_ignored = 0; 1766 my $skip_call_trace = 0; 1767 my $loops; 1768 1769 wait_for_monitor 5; 1770 1771 my $line; 1772 my $full_line = ""; 1773 1774 open(DMESG, "> $dmesg") or 1775 die "unable to write to $dmesg"; 1776 1777 reboot_to; 1778 1779 my $success_start; 1780 my $failure_start; 1781 my $monitor_start = time; 1782 my $done = 0; 1783 my $version_found = 0; 1784 1785 while (!$done) { 1786 1787 if ($bug && defined($stop_after_failure) && 1788 $stop_after_failure >= 0) { 1789 my $time = $stop_after_failure - (time - $failure_start); 1790 $line = wait_for_input($monitor_fp, $time); 1791 if (!defined($line)) { 1792 doprint "bug timed out after $booted_timeout seconds\n"; 1793 doprint "Test forced to stop after $stop_after_failure seconds after failure\n"; 1794 last; 1795 } 1796 } elsif ($booted) { 1797 $line = wait_for_input($monitor_fp, $booted_timeout); 1798 if (!defined($line)) { 1799 my $s = $booted_timeout == 1 ? "" : "s"; 1800 doprint "Successful boot found: break after $booted_timeout second$s\n"; 1801 last; 1802 } 1803 } else { 1804 $line = wait_for_input($monitor_fp); 1805 if (!defined($line)) { 1806 my $s = $timeout == 1 ? "" : "s"; 1807 doprint "Timed out after $timeout second$s\n"; 1808 last; 1809 } 1810 } 1811 1812 doprint $line; 1813 print DMESG $line; 1814 1815 # we are not guaranteed to get a full line 1816 $full_line .= $line; 1817 1818 if ($full_line =~ /$success_line/) { 1819 $booted = 1; 1820 $success_start = time; 1821 } 1822 1823 if ($booted && defined($stop_after_success) && 1824 $stop_after_success >= 0) { 1825 my $now = time; 1826 if ($now - $success_start >= $stop_after_success) { 1827 doprint "Test forced to stop after $stop_after_success seconds after success\n"; 1828 last; 1829 } 1830 } 1831 1832 if ($full_line =~ /\[ backtrace testing \]/) { 1833 $skip_call_trace = 1; 1834 } 1835 1836 if ($full_line =~ /call trace:/i) { 1837 if (!$bug && !$skip_call_trace) { 1838 if ($ignore_errors) { 1839 $bug_ignored = 1; 1840 } else { 1841 $bug = 1; 1842 $failure_start = time; 1843 } 1844 } 1845 } 1846 1847 if ($bug && defined($stop_after_failure) && 1848 $stop_after_failure >= 0) { 1849 my $now = time; 1850 if ($now - $failure_start >= $stop_after_failure) { 1851 doprint "Test forced to stop after $stop_after_failure seconds after failure\n"; 1852 last; 1853 } 1854 } 1855 1856 if ($full_line =~ /\[ end of backtrace testing \]/) { 1857 $skip_call_trace = 0; 1858 } 1859 1860 if ($full_line =~ /Kernel panic -/) { 1861 $failure_start = time; 1862 $bug = 1; 1863 } 1864 1865 # Detect triple faults by testing the banner 1866 if ($full_line =~ /\bLinux version (\S+).*\n/) { 1867 if ($1 eq $version) { 1868 $version_found = 1; 1869 } elsif ($version_found && $detect_triplefault) { 1870 # We already booted into the kernel we are testing, 1871 # but now we booted into another kernel? 1872 # Consider this a triple fault. 1873 doprint "Already booted in Linux kernel $version, but now\n"; 1874 doprint "we booted into Linux kernel $1.\n"; 1875 doprint "Assuming that this is a triple fault.\n"; 1876 doprint "To disable this: set DETECT_TRIPLE_FAULT to 0\n"; 1877 last; 1878 } 1879 } 1880 1881 if ($line =~ /\n/) { 1882 $full_line = ""; 1883 } 1884 1885 if ($stop_test_after > 0 && !$booted && !$bug) { 1886 if (time - $monitor_start > $stop_test_after) { 1887 doprint "STOP_TEST_AFTER ($stop_test_after seconds) timed out\n"; 1888 $done = 1; 1889 } 1890 } 1891 } 1892 1893 close(DMESG); 1894 1895 if ($bug) { 1896 return 0 if ($in_bisect); 1897 fail "failed - got a bug report" and return 0; 1898 } 1899 1900 if (!$booted) { 1901 return 0 if ($in_bisect); 1902 fail "failed - never got a boot prompt." and return 0; 1903 } 1904 1905 if ($bug_ignored) { 1906 doprint "WARNING: Call Trace detected but ignored due to IGNORE_ERRORS=1\n"; 1907 } 1908 1909 return 1; 1910} 1911 1912sub eval_kernel_version { 1913 my ($option) = @_; 1914 1915 $option =~ s/\$KERNEL_VERSION/$version/g; 1916 1917 return $option; 1918} 1919 1920sub do_post_install { 1921 1922 return if (!defined($post_install)); 1923 1924 my $cp_post_install = eval_kernel_version $post_install; 1925 run_command "$cp_post_install" or 1926 dodie "Failed to run post install"; 1927} 1928 1929# Sometimes the reboot fails, and will hang. We try to ssh to the box 1930# and if we fail, we force another reboot, that should powercycle it. 1931sub test_booted { 1932 if (!run_ssh "echo testing connection") { 1933 reboot $sleep_time; 1934 } 1935} 1936 1937sub install { 1938 1939 return if ($no_install); 1940 1941 if (defined($pre_install)) { 1942 my $cp_pre_install = eval_kernel_version $pre_install; 1943 run_command "$cp_pre_install" or 1944 dodie "Failed to run pre install"; 1945 } 1946 1947 my $cp_target = eval_kernel_version $target_image; 1948 1949 test_booted; 1950 1951 run_scp_install "$outputdir/$build_target", "$cp_target" or 1952 dodie "failed to copy image"; 1953 1954 my $install_mods = 0; 1955 1956 # should we process modules? 1957 $install_mods = 0; 1958 open(IN, "$output_config") or dodie("Can't read config file"); 1959 while (<IN>) { 1960 if (/CONFIG_MODULES(=y)?/) { 1961 if (defined($1)) { 1962 $install_mods = 1; 1963 last; 1964 } 1965 } 1966 } 1967 close(IN); 1968 1969 if (!$install_mods) { 1970 do_post_install; 1971 doprint "No modules needed\n"; 1972 return; 1973 } 1974 1975 run_command "$make INSTALL_MOD_STRIP=1 INSTALL_MOD_PATH=$tmpdir modules_install" or 1976 dodie "Failed to install modules"; 1977 1978 my $modlib = "/lib/modules/$version"; 1979 my $modtar = "ktest-mods.tar.bz2"; 1980 1981 run_ssh "rm -rf $modlib" or 1982 dodie "failed to remove old mods: $modlib"; 1983 1984 # would be nice if scp -r did not follow symbolic links 1985 run_command "cd $tmpdir && tar -cjf $modtar lib/modules/$version" or 1986 dodie "making tarball"; 1987 1988 run_scp_mod "$tmpdir/$modtar", "/tmp" or 1989 dodie "failed to copy modules"; 1990 1991 unlink "$tmpdir/$modtar"; 1992 1993 run_ssh "'(cd / && tar xjf /tmp/$modtar)'" or 1994 dodie "failed to tar modules"; 1995 1996 run_ssh "rm -f /tmp/$modtar"; 1997 1998 do_post_install; 1999} 2000 2001sub get_version { 2002 # get the release name 2003 return if ($have_version); 2004 doprint "$make kernelrelease ... "; 2005 $version = `$make -s kernelrelease | tail -1`; 2006 chomp($version); 2007 doprint "$version\n"; 2008 $have_version = 1; 2009} 2010 2011sub start_monitor_and_boot { 2012 # Make sure the stable kernel has finished booting 2013 2014 # Install bisects, don't need console 2015 if (defined $console) { 2016 start_monitor; 2017 wait_for_monitor 5; 2018 end_monitor; 2019 } 2020 2021 get_grub_index; 2022 get_version; 2023 install; 2024 2025 start_monitor if (defined $console); 2026 return monitor; 2027} 2028 2029my $check_build_re = ".*:.*(warning|error|Error):.*"; 2030my $utf8_quote = "\\x{e2}\\x{80}(\\x{98}|\\x{99})"; 2031 2032sub process_warning_line { 2033 my ($line) = @_; 2034 2035 chomp $line; 2036 2037 # for distcc heterogeneous systems, some compilers 2038 # do things differently causing warning lines 2039 # to be slightly different. This makes an attempt 2040 # to fixe those issues. 2041 2042 # chop off the index into the line 2043 # using distcc, some compilers give different indexes 2044 # depending on white space 2045 $line =~ s/^(\s*\S+:\d+:)\d+/$1/; 2046 2047 # Some compilers use UTF-8 extended for quotes and some don't. 2048 $line =~ s/$utf8_quote/'/g; 2049 2050 return $line; 2051} 2052 2053# Read buildlog and check against warnings file for any 2054# new warnings. 2055# 2056# Returns 1 if OK 2057# 0 otherwise 2058sub check_buildlog { 2059 return 1 if (!defined $warnings_file); 2060 2061 my %warnings_list; 2062 2063 # Failed builds should not reboot the target 2064 my $save_no_reboot = $no_reboot; 2065 $no_reboot = 1; 2066 2067 if (-f $warnings_file) { 2068 open(IN, $warnings_file) or 2069 dodie "Error opening $warnings_file"; 2070 2071 while (<IN>) { 2072 if (/$check_build_re/) { 2073 my $warning = process_warning_line $_; 2074 2075 $warnings_list{$warning} = 1; 2076 } 2077 } 2078 close(IN); 2079 } 2080 2081 # If warnings file didn't exist, and WARNINGS_FILE exist, 2082 # then we fail on any warning! 2083 2084 open(IN, $buildlog) or dodie "Can't open $buildlog"; 2085 while (<IN>) { 2086 if (/$check_build_re/) { 2087 my $warning = process_warning_line $_; 2088 2089 if (!defined $warnings_list{$warning}) { 2090 fail "New warning found (not in $warnings_file)\n$_\n"; 2091 $no_reboot = $save_no_reboot; 2092 return 0; 2093 } 2094 } 2095 } 2096 $no_reboot = $save_no_reboot; 2097 close(IN); 2098} 2099 2100sub check_patch_buildlog { 2101 my ($patch) = @_; 2102 2103 my @files = `git show $patch | diffstat -l`; 2104 2105 foreach my $file (@files) { 2106 chomp $file; 2107 } 2108 2109 open(IN, "git show $patch |") or 2110 dodie "failed to show $patch"; 2111 while (<IN>) { 2112 if (m,^--- a/(.*),) { 2113 chomp $1; 2114 $files[$#files] = $1; 2115 } 2116 } 2117 close(IN); 2118 2119 open(IN, $buildlog) or dodie "Can't open $buildlog"; 2120 while (<IN>) { 2121 if (/^\s*(.*?):.*(warning|error)/) { 2122 my $err = $1; 2123 foreach my $file (@files) { 2124 my $fullpath = "$builddir/$file"; 2125 if ($file eq $err || $fullpath eq $err) { 2126 fail "$file built with warnings" and return 0; 2127 } 2128 } 2129 } 2130 } 2131 close(IN); 2132 2133 return 1; 2134} 2135 2136sub apply_min_config { 2137 my $outconfig = "$output_config.new"; 2138 2139 # Read the config file and remove anything that 2140 # is in the force_config hash (from minconfig and others) 2141 # then add the force config back. 2142 2143 doprint "Applying minimum configurations into $output_config.new\n"; 2144 2145 open (OUT, ">$outconfig") or 2146 dodie "Can't create $outconfig"; 2147 2148 if (-f $output_config) { 2149 open (IN, $output_config) or 2150 dodie "Failed to open $output_config"; 2151 while (<IN>) { 2152 if (/^(# )?(CONFIG_[^\s=]*)/) { 2153 next if (defined($force_config{$2})); 2154 } 2155 print OUT; 2156 } 2157 close IN; 2158 } 2159 foreach my $config (keys %force_config) { 2160 print OUT "$force_config{$config}\n"; 2161 } 2162 close OUT; 2163 2164 run_command "mv $outconfig $output_config"; 2165} 2166 2167sub make_oldconfig { 2168 2169 my @force_list = keys %force_config; 2170 2171 if ($#force_list >= 0) { 2172 apply_min_config; 2173 } 2174 2175 if (!run_command "$make olddefconfig") { 2176 # Perhaps olddefconfig doesn't exist in this version of the kernel 2177 # try oldnoconfig 2178 doprint "olddefconfig failed, trying make oldnoconfig\n"; 2179 if (!run_command "$make oldnoconfig") { 2180 doprint "oldnoconfig failed, trying yes '' | make oldconfig\n"; 2181 # try a yes '' | oldconfig 2182 run_command "yes '' | $make oldconfig" or 2183 dodie "failed make config oldconfig"; 2184 } 2185 } 2186} 2187 2188# read a config file and use this to force new configs. 2189sub load_force_config { 2190 my ($config) = @_; 2191 2192 doprint "Loading force configs from $config\n"; 2193 open(IN, $config) or 2194 dodie "failed to read $config"; 2195 while (<IN>) { 2196 chomp; 2197 if (/^(CONFIG[^\s=]*)(\s*=.*)/) { 2198 $force_config{$1} = $_; 2199 } elsif (/^# (CONFIG_\S*) is not set/) { 2200 $force_config{$1} = $_; 2201 } 2202 } 2203 close IN; 2204} 2205 2206sub build { 2207 my ($type) = @_; 2208 2209 unlink $buildlog; 2210 2211 # Failed builds should not reboot the target 2212 my $save_no_reboot = $no_reboot; 2213 $no_reboot = 1; 2214 2215 # Calculate a new version from here. 2216 $have_version = 0; 2217 2218 if (defined($pre_build)) { 2219 my $ret = run_command $pre_build; 2220 if (!$ret && defined($pre_build_die) && 2221 $pre_build_die) { 2222 dodie "failed to pre_build\n"; 2223 } 2224 } 2225 2226 if ($type =~ /^useconfig:(.*)/) { 2227 run_command "cp $1 $output_config" or 2228 dodie "could not copy $1 to .config"; 2229 2230 $type = "oldconfig"; 2231 } 2232 2233 # old config can ask questions 2234 if ($type eq "oldconfig") { 2235 $type = "olddefconfig"; 2236 2237 # allow for empty configs 2238 run_command "touch $output_config"; 2239 2240 if (!$noclean) { 2241 run_command "mv $output_config $outputdir/config_temp" or 2242 dodie "moving .config"; 2243 2244 run_command "$make mrproper" or dodie "make mrproper"; 2245 2246 run_command "mv $outputdir/config_temp $output_config" or 2247 dodie "moving config_temp"; 2248 } 2249 2250 } elsif (!$noclean) { 2251 unlink "$output_config"; 2252 run_command "$make mrproper" or 2253 dodie "make mrproper"; 2254 } 2255 2256 # add something to distinguish this build 2257 open(OUT, "> $outputdir/localversion") or dodie("Can't make localversion file"); 2258 print OUT "$localversion\n"; 2259 close(OUT); 2260 2261 if (defined($minconfig)) { 2262 load_force_config($minconfig); 2263 } 2264 2265 if ($type ne "olddefconfig") { 2266 run_command "$make $type" or 2267 dodie "failed make config"; 2268 } 2269 # Run old config regardless, to enforce min configurations 2270 make_oldconfig; 2271 2272 my $build_ret = run_command "$make $build_options", $buildlog; 2273 2274 if (defined($post_build)) { 2275 # Because a post build may change the kernel version 2276 # do it now. 2277 get_version; 2278 my $ret = run_command $post_build; 2279 if (!$ret && defined($post_build_die) && 2280 $post_build_die) { 2281 dodie "failed to post_build\n"; 2282 } 2283 } 2284 2285 if (!$build_ret) { 2286 # bisect may need this to pass 2287 if ($in_bisect) { 2288 $no_reboot = $save_no_reboot; 2289 return 0; 2290 } 2291 fail "failed build" and return 0; 2292 } 2293 2294 $no_reboot = $save_no_reboot; 2295 2296 return 1; 2297} 2298 2299sub halt { 2300 if (!run_ssh "halt" or defined($power_off)) { 2301 if (defined($poweroff_after_halt)) { 2302 sleep $poweroff_after_halt; 2303 run_command "$power_off"; 2304 } 2305 } else { 2306 # nope? the zap it! 2307 run_command "$power_off"; 2308 } 2309} 2310 2311sub success { 2312 my ($i) = @_; 2313 2314 if (defined($post_test)) { 2315 run_command $post_test; 2316 } 2317 2318 $successes++; 2319 2320 my $name = ""; 2321 2322 if (defined($test_name)) { 2323 $name = " ($test_name)"; 2324 } 2325 2326 doprint "\n\n*******************************************\n"; 2327 doprint "*******************************************\n"; 2328 doprint "KTEST RESULT: TEST $i$name SUCCESS!!!! **\n"; 2329 doprint "*******************************************\n"; 2330 doprint "*******************************************\n"; 2331 2332 if (defined($store_successes)) { 2333 save_logs "success", $store_successes; 2334 } 2335 2336 if ($i != $opt{"NUM_TESTS"} && !do_not_reboot) { 2337 doprint "Reboot and wait $sleep_time seconds\n"; 2338 reboot_to_good $sleep_time; 2339 } 2340} 2341 2342sub answer_bisect { 2343 for (;;) { 2344 doprint "Pass, fail, or skip? [p/f/s]"; 2345 my $ans = <STDIN>; 2346 chomp $ans; 2347 if ($ans eq "p" || $ans eq "P") { 2348 return 1; 2349 } elsif ($ans eq "f" || $ans eq "F") { 2350 return 0; 2351 } elsif ($ans eq "s" || $ans eq "S") { 2352 return -1; 2353 } else { 2354 print "Please answer 'p', 'f', or 's'\n"; 2355 } 2356 } 2357} 2358 2359sub child_run_test { 2360 my $failed = 0; 2361 2362 # child should have no power 2363 $reboot_on_error = 0; 2364 $poweroff_on_error = 0; 2365 $die_on_failure = 1; 2366 2367 run_command $run_test, $testlog or $failed = 1; 2368 2369 exit $failed; 2370} 2371 2372my $child_done; 2373 2374sub child_finished { 2375 $child_done = 1; 2376} 2377 2378sub do_run_test { 2379 my $child_pid; 2380 my $child_exit; 2381 my $line; 2382 my $full_line; 2383 my $bug = 0; 2384 my $bug_ignored = 0; 2385 2386 wait_for_monitor 1; 2387 2388 doprint "run test $run_test\n"; 2389 2390 $child_done = 0; 2391 2392 $SIG{CHLD} = qw(child_finished); 2393 2394 $child_pid = fork; 2395 2396 child_run_test if (!$child_pid); 2397 2398 $full_line = ""; 2399 2400 do { 2401 $line = wait_for_input($monitor_fp, 1); 2402 if (defined($line)) { 2403 2404 # we are not guaranteed to get a full line 2405 $full_line .= $line; 2406 doprint $line; 2407 2408 if ($full_line =~ /call trace:/i) { 2409 if ($ignore_errors) { 2410 $bug_ignored = 1; 2411 } else { 2412 $bug = 1; 2413 } 2414 } 2415 2416 if ($full_line =~ /Kernel panic -/) { 2417 $bug = 1; 2418 } 2419 2420 if ($line =~ /\n/) { 2421 $full_line = ""; 2422 } 2423 } 2424 } while (!$child_done && !$bug); 2425 2426 if (!$bug && $bug_ignored) { 2427 doprint "WARNING: Call Trace detected but ignored due to IGNORE_ERRORS=1\n"; 2428 } 2429 2430 if ($bug) { 2431 my $failure_start = time; 2432 my $now; 2433 do { 2434 $line = wait_for_input($monitor_fp, 1); 2435 if (defined($line)) { 2436 doprint $line; 2437 } 2438 $now = time; 2439 if ($now - $failure_start >= $stop_after_failure) { 2440 last; 2441 } 2442 } while (defined($line)); 2443 2444 doprint "Detected kernel crash!\n"; 2445 # kill the child with extreme prejudice 2446 kill 9, $child_pid; 2447 } 2448 2449 waitpid $child_pid, 0; 2450 $child_exit = $?; 2451 2452 if (!$bug && $in_bisect) { 2453 if (defined($bisect_ret_good)) { 2454 if ($child_exit == $bisect_ret_good) { 2455 return 1; 2456 } 2457 } 2458 if (defined($bisect_ret_skip)) { 2459 if ($child_exit == $bisect_ret_skip) { 2460 return -1; 2461 } 2462 } 2463 if (defined($bisect_ret_abort)) { 2464 if ($child_exit == $bisect_ret_abort) { 2465 fail "test abort" and return -2; 2466 } 2467 } 2468 if (defined($bisect_ret_bad)) { 2469 if ($child_exit == $bisect_ret_skip) { 2470 return 0; 2471 } 2472 } 2473 if (defined($bisect_ret_default)) { 2474 if ($bisect_ret_default eq "good") { 2475 return 1; 2476 } elsif ($bisect_ret_default eq "bad") { 2477 return 0; 2478 } elsif ($bisect_ret_default eq "skip") { 2479 return -1; 2480 } elsif ($bisect_ret_default eq "abort") { 2481 return -2; 2482 } else { 2483 fail "unknown default action: $bisect_ret_default" 2484 and return -2; 2485 } 2486 } 2487 } 2488 2489 if ($bug || $child_exit) { 2490 return 0 if $in_bisect; 2491 fail "test failed" and return 0; 2492 } 2493 return 1; 2494} 2495 2496sub run_git_bisect { 2497 my ($command) = @_; 2498 2499 doprint "$command ... "; 2500 2501 my $output = `$command 2>&1`; 2502 my $ret = $?; 2503 2504 logit $output; 2505 2506 if ($ret) { 2507 doprint "FAILED\n"; 2508 dodie "Failed to git bisect"; 2509 } 2510 2511 doprint "SUCCESS\n"; 2512 if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\))\s+\[([[:xdigit:]]+)\]/) { 2513 doprint "$1 [$2]\n"; 2514 } elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) { 2515 $bisect_bad_commit = $1; 2516 doprint "Found bad commit... $1\n"; 2517 return 0; 2518 } else { 2519 # we already logged it, just print it now. 2520 print $output; 2521 } 2522 2523 return 1; 2524} 2525 2526sub bisect_reboot { 2527 doprint "Reboot and sleep $bisect_sleep_time seconds\n"; 2528 reboot_to_good $bisect_sleep_time; 2529} 2530 2531# returns 1 on success, 0 on failure, -1 on skip 2532sub run_bisect_test { 2533 my ($type, $buildtype) = @_; 2534 2535 my $failed = 0; 2536 my $result; 2537 my $output; 2538 my $ret; 2539 2540 $in_bisect = 1; 2541 2542 build $buildtype or $failed = 1; 2543 2544 if ($type ne "build") { 2545 if ($failed && $bisect_skip) { 2546 $in_bisect = 0; 2547 return -1; 2548 } 2549 dodie "Failed on build" if $failed; 2550 2551 # Now boot the box 2552 start_monitor_and_boot or $failed = 1; 2553 2554 if ($type ne "boot") { 2555 if ($failed && $bisect_skip) { 2556 end_monitor; 2557 bisect_reboot; 2558 $in_bisect = 0; 2559 return -1; 2560 } 2561 dodie "Failed on boot" if $failed; 2562 2563 do_run_test or $failed = 1; 2564 } 2565 end_monitor; 2566 } 2567 2568 if ($failed) { 2569 $result = 0; 2570 } else { 2571 $result = 1; 2572 } 2573 2574 # reboot the box to a kernel we can ssh to 2575 if ($type ne "build") { 2576 bisect_reboot; 2577 } 2578 $in_bisect = 0; 2579 2580 return $result; 2581} 2582 2583sub run_bisect { 2584 my ($type) = @_; 2585 my $buildtype = "oldconfig"; 2586 2587 # We should have a minconfig to use? 2588 if (defined($minconfig)) { 2589 $buildtype = "useconfig:$minconfig"; 2590 } 2591 2592 # If the user sets bisect_tries to less than 1, then no tries 2593 # is a success. 2594 my $ret = 1; 2595 2596 # Still let the user manually decide that though. 2597 if ($bisect_tries < 1 && $bisect_manual) { 2598 $ret = answer_bisect; 2599 } 2600 2601 for (my $i = 0; $i < $bisect_tries; $i++) { 2602 if ($bisect_tries > 1) { 2603 my $t = $i + 1; 2604 doprint("Running bisect trial $t of $bisect_tries:\n"); 2605 } 2606 $ret = run_bisect_test $type, $buildtype; 2607 2608 if ($bisect_manual) { 2609 $ret = answer_bisect; 2610 } 2611 2612 last if (!$ret); 2613 } 2614 2615 # Are we looking for where it worked, not failed? 2616 if ($reverse_bisect && $ret >= 0) { 2617 $ret = !$ret; 2618 } 2619 2620 if ($ret > 0) { 2621 return "good"; 2622 } elsif ($ret == 0) { 2623 return "bad"; 2624 } elsif ($bisect_skip) { 2625 doprint "HIT A BAD COMMIT ... SKIPPING\n"; 2626 return "skip"; 2627 } 2628} 2629 2630sub update_bisect_replay { 2631 my $tmp_log = "$tmpdir/ktest_bisect_log"; 2632 run_command "git bisect log > $tmp_log" or 2633 die "can't create bisect log"; 2634 return $tmp_log; 2635} 2636 2637sub bisect { 2638 my ($i) = @_; 2639 2640 my $result; 2641 2642 die "BISECT_GOOD[$i] not defined\n" if (!defined($bisect_good)); 2643 die "BISECT_BAD[$i] not defined\n" if (!defined($bisect_bad)); 2644 die "BISECT_TYPE[$i] not defined\n" if (!defined($bisect_type)); 2645 2646 my $good = $bisect_good; 2647 my $bad = $bisect_bad; 2648 my $type = $bisect_type; 2649 my $start = $bisect_start; 2650 my $replay = $bisect_replay; 2651 my $start_files = $bisect_files; 2652 2653 if (defined($start_files)) { 2654 $start_files = " -- " . $start_files; 2655 } else { 2656 $start_files = ""; 2657 } 2658 2659 # convert to true sha1's 2660 $good = get_sha1($good); 2661 $bad = get_sha1($bad); 2662 2663 if (defined($bisect_reverse) && $bisect_reverse == 1) { 2664 doprint "Performing a reverse bisect (bad is good, good is bad!)\n"; 2665 $reverse_bisect = 1; 2666 } else { 2667 $reverse_bisect = 0; 2668 } 2669 2670 # Can't have a test without having a test to run 2671 if ($type eq "test" && !defined($run_test)) { 2672 $type = "boot"; 2673 } 2674 2675 # Check if a bisect was running 2676 my $bisect_start_file = "$builddir/.git/BISECT_START"; 2677 2678 my $check = $bisect_check; 2679 my $do_check = defined($check) && $check ne "0"; 2680 2681 if ( -f $bisect_start_file ) { 2682 print "Bisect in progress found\n"; 2683 if ($do_check) { 2684 print " If you say yes, then no checks of good or bad will be done\n"; 2685 } 2686 if (defined($replay)) { 2687 print "** BISECT_REPLAY is defined in config file **"; 2688 print " Ignore config option and perform new git bisect log?\n"; 2689 if (read_ync " (yes, no, or cancel) ") { 2690 $replay = update_bisect_replay; 2691 $do_check = 0; 2692 } 2693 } elsif (read_yn "read git log and continue?") { 2694 $replay = update_bisect_replay; 2695 $do_check = 0; 2696 } 2697 } 2698 2699 if ($do_check) { 2700 2701 # get current HEAD 2702 my $head = get_sha1("HEAD"); 2703 2704 if ($check ne "good") { 2705 doprint "TESTING BISECT BAD [$bad]\n"; 2706 run_command "git checkout $bad" or 2707 die "Failed to checkout $bad"; 2708 2709 $result = run_bisect $type; 2710 2711 if ($result ne "bad") { 2712 fail "Tested BISECT_BAD [$bad] and it succeeded" and return 0; 2713 } 2714 } 2715 2716 if ($check ne "bad") { 2717 doprint "TESTING BISECT GOOD [$good]\n"; 2718 run_command "git checkout $good" or 2719 die "Failed to checkout $good"; 2720 2721 $result = run_bisect $type; 2722 2723 if ($result ne "good") { 2724 fail "Tested BISECT_GOOD [$good] and it failed" and return 0; 2725 } 2726 } 2727 2728 # checkout where we started 2729 run_command "git checkout $head" or 2730 die "Failed to checkout $head"; 2731 } 2732 2733 run_command "git bisect start$start_files" or 2734 dodie "could not start bisect"; 2735 2736 if (defined($replay)) { 2737 run_command "git bisect replay $replay" or 2738 dodie "failed to run replay"; 2739 } else { 2740 2741 run_command "git bisect good $good" or 2742 dodie "could not set bisect good to $good"; 2743 2744 run_git_bisect "git bisect bad $bad" or 2745 dodie "could not set bisect bad to $bad"; 2746 2747 } 2748 2749 if (defined($start)) { 2750 run_command "git checkout $start" or 2751 dodie "failed to checkout $start"; 2752 } 2753 2754 my $test; 2755 do { 2756 $result = run_bisect $type; 2757 $test = run_git_bisect "git bisect $result"; 2758 } while ($test); 2759 2760 run_command "git bisect log" or 2761 dodie "could not capture git bisect log"; 2762 2763 run_command "git bisect reset" or 2764 dodie "could not reset git bisect"; 2765 2766 doprint "Bad commit was [$bisect_bad_commit]\n"; 2767 2768 success $i; 2769} 2770 2771# config_ignore holds the configs that were set (or unset) for 2772# a good config and we will ignore these configs for the rest 2773# of a config bisect. These configs stay as they were. 2774my %config_ignore; 2775 2776# config_set holds what all configs were set as. 2777my %config_set; 2778 2779# config_off holds the set of configs that the bad config had disabled. 2780# We need to record them and set them in the .config when running 2781# olddefconfig, because olddefconfig keeps the defaults. 2782my %config_off; 2783 2784# config_off_tmp holds a set of configs to turn off for now 2785my @config_off_tmp; 2786 2787# config_list is the set of configs that are being tested 2788my %config_list; 2789my %null_config; 2790 2791my %dependency; 2792 2793sub assign_configs { 2794 my ($hash, $config) = @_; 2795 2796 doprint "Reading configs from $config\n"; 2797 2798 open (IN, $config) 2799 or dodie "Failed to read $config"; 2800 2801 while (<IN>) { 2802 chomp; 2803 if (/^((CONFIG\S*)=.*)/) { 2804 ${$hash}{$2} = $1; 2805 } elsif (/^(# (CONFIG\S*) is not set)/) { 2806 ${$hash}{$2} = $1; 2807 } 2808 } 2809 2810 close(IN); 2811} 2812 2813sub process_config_ignore { 2814 my ($config) = @_; 2815 2816 assign_configs \%config_ignore, $config; 2817} 2818 2819sub get_dependencies { 2820 my ($config) = @_; 2821 2822 my $arr = $dependency{$config}; 2823 if (!defined($arr)) { 2824 return (); 2825 } 2826 2827 my @deps = @{$arr}; 2828 2829 foreach my $dep (@{$arr}) { 2830 print "ADD DEP $dep\n"; 2831 @deps = (@deps, get_dependencies $dep); 2832 } 2833 2834 return @deps; 2835} 2836 2837sub save_config { 2838 my ($pc, $file) = @_; 2839 2840 my %configs = %{$pc}; 2841 2842 doprint "Saving configs into $file\n"; 2843 2844 open(OUT, ">$file") or dodie "Can not write to $file"; 2845 2846 foreach my $config (keys %configs) { 2847 print OUT "$configs{$config}\n"; 2848 } 2849 close(OUT); 2850} 2851 2852sub create_config { 2853 my ($name, $pc) = @_; 2854 2855 doprint "Creating old config from $name configs\n"; 2856 2857 save_config $pc, $output_config; 2858 2859 make_oldconfig; 2860} 2861 2862# compare two config hashes, and return configs with different vals. 2863# It returns B's config values, but you can use A to see what A was. 2864sub diff_config_vals { 2865 my ($pa, $pb) = @_; 2866 2867 # crappy Perl way to pass in hashes. 2868 my %a = %{$pa}; 2869 my %b = %{$pb}; 2870 2871 my %ret; 2872 2873 foreach my $item (keys %a) { 2874 if (defined($b{$item}) && $b{$item} ne $a{$item}) { 2875 $ret{$item} = $b{$item}; 2876 } 2877 } 2878 2879 return %ret; 2880} 2881 2882# compare two config hashes and return the configs in B but not A 2883sub diff_configs { 2884 my ($pa, $pb) = @_; 2885 2886 my %ret; 2887 2888 # crappy Perl way to pass in hashes. 2889 my %a = %{$pa}; 2890 my %b = %{$pb}; 2891 2892 foreach my $item (keys %b) { 2893 if (!defined($a{$item})) { 2894 $ret{$item} = $b{$item}; 2895 } 2896 } 2897 2898 return %ret; 2899} 2900 2901# return if two configs are equal or not 2902# 0 is equal +1 b has something a does not 2903# +1 if a and b have a different item. 2904# -1 if a has something b does not 2905sub compare_configs { 2906 my ($pa, $pb) = @_; 2907 2908 my %ret; 2909 2910 # crappy Perl way to pass in hashes. 2911 my %a = %{$pa}; 2912 my %b = %{$pb}; 2913 2914 foreach my $item (keys %b) { 2915 if (!defined($a{$item})) { 2916 return 1; 2917 } 2918 if ($a{$item} ne $b{$item}) { 2919 return 1; 2920 } 2921 } 2922 2923 foreach my $item (keys %a) { 2924 if (!defined($b{$item})) { 2925 return -1; 2926 } 2927 } 2928 2929 return 0; 2930} 2931 2932sub run_config_bisect_test { 2933 my ($type) = @_; 2934 2935 my $ret = run_bisect_test $type, "oldconfig"; 2936 2937 if ($bisect_manual) { 2938 $ret = answer_bisect; 2939 } 2940 2941 return $ret; 2942} 2943 2944sub process_failed { 2945 my ($config) = @_; 2946 2947 doprint "\n\n***************************************\n"; 2948 doprint "Found bad config: $config\n"; 2949 doprint "***************************************\n\n"; 2950} 2951 2952# used for config bisecting 2953my $good_config; 2954my $bad_config; 2955 2956sub process_new_config { 2957 my ($tc, $nc, $gc, $bc) = @_; 2958 2959 my %tmp_config = %{$tc}; 2960 my %good_configs = %{$gc}; 2961 my %bad_configs = %{$bc}; 2962 2963 my %new_configs; 2964 2965 my $runtest = 1; 2966 my $ret; 2967 2968 create_config "tmp_configs", \%tmp_config; 2969 assign_configs \%new_configs, $output_config; 2970 2971 $ret = compare_configs \%new_configs, \%bad_configs; 2972 if (!$ret) { 2973 doprint "New config equals bad config, try next test\n"; 2974 $runtest = 0; 2975 } 2976 2977 if ($runtest) { 2978 $ret = compare_configs \%new_configs, \%good_configs; 2979 if (!$ret) { 2980 doprint "New config equals good config, try next test\n"; 2981 $runtest = 0; 2982 } 2983 } 2984 2985 %{$nc} = %new_configs; 2986 2987 return $runtest; 2988} 2989 2990sub run_config_bisect { 2991 my ($pgood, $pbad) = @_; 2992 2993 my $type = $config_bisect_type; 2994 2995 my %good_configs = %{$pgood}; 2996 my %bad_configs = %{$pbad}; 2997 2998 my %diff_configs = diff_config_vals \%good_configs, \%bad_configs; 2999 my %b_configs = diff_configs \%good_configs, \%bad_configs; 3000 my %g_configs = diff_configs \%bad_configs, \%good_configs; 3001 3002 my @diff_arr = keys %diff_configs; 3003 my $len_diff = $#diff_arr + 1; 3004 3005 my @b_arr = keys %b_configs; 3006 my $len_b = $#b_arr + 1; 3007 3008 my @g_arr = keys %g_configs; 3009 my $len_g = $#g_arr + 1; 3010 3011 my $runtest = 1; 3012 my %new_configs; 3013 my $ret; 3014 3015 # First, lets get it down to a single subset. 3016 # Is the problem with a difference in values? 3017 # Is the problem with a missing config? 3018 # Is the problem with a config that breaks things? 3019 3020 # Enable all of one set and see if we get a new bad 3021 # or good config. 3022 3023 # first set the good config to the bad values. 3024 3025 doprint "d=$len_diff g=$len_g b=$len_b\n"; 3026 3027 # first lets enable things in bad config that are enabled in good config 3028 3029 if ($len_diff > 0) { 3030 if ($len_b > 0 || $len_g > 0) { 3031 my %tmp_config = %bad_configs; 3032 3033 doprint "Set tmp config to be bad config with good config values\n"; 3034 foreach my $item (@diff_arr) { 3035 $tmp_config{$item} = $good_configs{$item}; 3036 } 3037 3038 $runtest = process_new_config \%tmp_config, \%new_configs, 3039 \%good_configs, \%bad_configs; 3040 } 3041 } 3042 3043 if (!$runtest && $len_diff > 0) { 3044 3045 if ($len_diff == 1) { 3046 process_failed $diff_arr[0]; 3047 return 1; 3048 } 3049 my %tmp_config = %bad_configs; 3050 3051 my $half = int($#diff_arr / 2); 3052 my @tophalf = @diff_arr[0 .. $half]; 3053 3054 doprint "Settings bisect with top half:\n"; 3055 doprint "Set tmp config to be bad config with some good config values\n"; 3056 foreach my $item (@tophalf) { 3057 $tmp_config{$item} = $good_configs{$item}; 3058 } 3059 3060 $runtest = process_new_config \%tmp_config, \%new_configs, 3061 \%good_configs, \%bad_configs; 3062 3063 if (!$runtest) { 3064 my %tmp_config = %bad_configs; 3065 3066 doprint "Try bottom half\n"; 3067 3068 my @bottomhalf = @diff_arr[$half+1 .. $#diff_arr]; 3069 3070 foreach my $item (@bottomhalf) { 3071 $tmp_config{$item} = $good_configs{$item}; 3072 } 3073 3074 $runtest = process_new_config \%tmp_config, \%new_configs, 3075 \%good_configs, \%bad_configs; 3076 } 3077 } 3078 3079 if ($runtest) { 3080 $ret = run_config_bisect_test $type; 3081 if ($ret) { 3082 doprint "NEW GOOD CONFIG\n"; 3083 %good_configs = %new_configs; 3084 run_command "mv $good_config ${good_config}.last"; 3085 save_config \%good_configs, $good_config; 3086 %{$pgood} = %good_configs; 3087 } else { 3088 doprint "NEW BAD CONFIG\n"; 3089 %bad_configs = %new_configs; 3090 run_command "mv $bad_config ${bad_config}.last"; 3091 save_config \%bad_configs, $bad_config; 3092 %{$pbad} = %bad_configs; 3093 } 3094 return 0; 3095 } 3096 3097 fail "Hmm, need to do a mix match?\n"; 3098 return -1; 3099} 3100 3101sub config_bisect { 3102 my ($i) = @_; 3103 3104 my $type = $config_bisect_type; 3105 my $ret; 3106 3107 $bad_config = $config_bisect; 3108 3109 if (defined($config_bisect_good)) { 3110 $good_config = $config_bisect_good; 3111 } elsif (defined($minconfig)) { 3112 $good_config = $minconfig; 3113 } else { 3114 doprint "No config specified, checking if defconfig works"; 3115 $ret = run_bisect_test $type, "defconfig"; 3116 if (!$ret) { 3117 fail "Have no good config to compare with, please set CONFIG_BISECT_GOOD"; 3118 return 1; 3119 } 3120 $good_config = $output_config; 3121 } 3122 3123 # we don't want min configs to cause issues here. 3124 doprint "Disabling 'MIN_CONFIG' for this test\n"; 3125 undef $minconfig; 3126 3127 my %good_configs; 3128 my %bad_configs; 3129 my %tmp_configs; 3130 3131 doprint "Run good configs through make oldconfig\n"; 3132 assign_configs \%tmp_configs, $good_config; 3133 create_config "$good_config", \%tmp_configs; 3134 assign_configs \%good_configs, $output_config; 3135 3136 doprint "Run bad configs through make oldconfig\n"; 3137 assign_configs \%tmp_configs, $bad_config; 3138 create_config "$bad_config", \%tmp_configs; 3139 assign_configs \%bad_configs, $output_config; 3140 3141 $good_config = "$tmpdir/good_config"; 3142 $bad_config = "$tmpdir/bad_config"; 3143 3144 save_config \%good_configs, $good_config; 3145 save_config \%bad_configs, $bad_config; 3146 3147 3148 if (defined($config_bisect_check) && $config_bisect_check ne "0") { 3149 if ($config_bisect_check ne "good") { 3150 doprint "Testing bad config\n"; 3151 3152 $ret = run_bisect_test $type, "useconfig:$bad_config"; 3153 if ($ret) { 3154 fail "Bad config succeeded when expected to fail!"; 3155 return 0; 3156 } 3157 } 3158 if ($config_bisect_check ne "bad") { 3159 doprint "Testing good config\n"; 3160 3161 $ret = run_bisect_test $type, "useconfig:$good_config"; 3162 if (!$ret) { 3163 fail "Good config failed when expected to succeed!"; 3164 return 0; 3165 } 3166 } 3167 } 3168 3169 do { 3170 $ret = run_config_bisect \%good_configs, \%bad_configs; 3171 } while (!$ret); 3172 3173 return $ret if ($ret < 0); 3174 3175 success $i; 3176} 3177 3178sub patchcheck_reboot { 3179 doprint "Reboot and sleep $patchcheck_sleep_time seconds\n"; 3180 reboot_to_good $patchcheck_sleep_time; 3181} 3182 3183sub patchcheck { 3184 my ($i) = @_; 3185 3186 die "PATCHCHECK_START[$i] not defined\n" 3187 if (!defined($patchcheck_start)); 3188 die "PATCHCHECK_TYPE[$i] not defined\n" 3189 if (!defined($patchcheck_type)); 3190 3191 my $start = $patchcheck_start; 3192 3193 my $cherry = $patchcheck_cherry; 3194 if (!defined($cherry)) { 3195 $cherry = 0; 3196 } 3197 3198 my $end = "HEAD"; 3199 if (defined($patchcheck_end)) { 3200 $end = $patchcheck_end; 3201 } elsif ($cherry) { 3202 die "PATCHCHECK_END must be defined with PATCHCHECK_CHERRY\n"; 3203 } 3204 3205 # Get the true sha1's since we can use things like HEAD~3 3206 $start = get_sha1($start); 3207 $end = get_sha1($end); 3208 3209 my $type = $patchcheck_type; 3210 3211 # Can't have a test without having a test to run 3212 if ($type eq "test" && !defined($run_test)) { 3213 $type = "boot"; 3214 } 3215 3216 if ($cherry) { 3217 open (IN, "git cherry -v $start $end|") or 3218 dodie "could not get git list"; 3219 } else { 3220 open (IN, "git log --pretty=oneline $end|") or 3221 dodie "could not get git list"; 3222 } 3223 3224 my @list; 3225 3226 while (<IN>) { 3227 chomp; 3228 # git cherry adds a '+' we want to remove 3229 s/^\+ //; 3230 $list[$#list+1] = $_; 3231 last if (/^$start/); 3232 } 3233 close(IN); 3234 3235 if (!$cherry) { 3236 if ($list[$#list] !~ /^$start/) { 3237 fail "SHA1 $start not found"; 3238 } 3239 3240 # go backwards in the list 3241 @list = reverse @list; 3242 } 3243 3244 doprint("Going to test the following commits:\n"); 3245 foreach my $l (@list) { 3246 doprint "$l\n"; 3247 } 3248 3249 my $save_clean = $noclean; 3250 my %ignored_warnings; 3251 3252 if (defined($ignore_warnings)) { 3253 foreach my $sha1 (split /\s+/, $ignore_warnings) { 3254 $ignored_warnings{$sha1} = 1; 3255 } 3256 } 3257 3258 $in_patchcheck = 1; 3259 foreach my $item (@list) { 3260 my $sha1 = $item; 3261 $sha1 =~ s/^([[:xdigit:]]+).*/$1/; 3262 3263 doprint "\nProcessing commit $item\n\n"; 3264 3265 run_command "git checkout $sha1" or 3266 die "Failed to checkout $sha1"; 3267 3268 # only clean on the first and last patch 3269 if ($item eq $list[0] || 3270 $item eq $list[$#list]) { 3271 $noclean = $save_clean; 3272 } else { 3273 $noclean = 1; 3274 } 3275 3276 if (defined($minconfig)) { 3277 build "useconfig:$minconfig" or return 0; 3278 } else { 3279 # ?? no config to use? 3280 build "oldconfig" or return 0; 3281 } 3282 3283 # No need to do per patch checking if warnings file exists 3284 if (!defined($warnings_file) && !defined($ignored_warnings{$sha1})) { 3285 check_patch_buildlog $sha1 or return 0; 3286 } 3287 3288 check_buildlog or return 0; 3289 3290 next if ($type eq "build"); 3291 3292 my $failed = 0; 3293 3294 start_monitor_and_boot or $failed = 1; 3295 3296 if (!$failed && $type ne "boot"){ 3297 do_run_test or $failed = 1; 3298 } 3299 end_monitor; 3300 return 0 if ($failed); 3301 3302 patchcheck_reboot; 3303 3304 } 3305 $in_patchcheck = 0; 3306 success $i; 3307 3308 return 1; 3309} 3310 3311my %depends; 3312my %depcount; 3313my $iflevel = 0; 3314my @ifdeps; 3315 3316# prevent recursion 3317my %read_kconfigs; 3318 3319sub add_dep { 3320 # $config depends on $dep 3321 my ($config, $dep) = @_; 3322 3323 if (defined($depends{$config})) { 3324 $depends{$config} .= " " . $dep; 3325 } else { 3326 $depends{$config} = $dep; 3327 } 3328 3329 # record the number of configs depending on $dep 3330 if (defined $depcount{$dep}) { 3331 $depcount{$dep}++; 3332 } else { 3333 $depcount{$dep} = 1; 3334 } 3335} 3336 3337# taken from streamline_config.pl 3338sub read_kconfig { 3339 my ($kconfig) = @_; 3340 3341 my $state = "NONE"; 3342 my $config; 3343 my @kconfigs; 3344 3345 my $cont = 0; 3346 my $line; 3347 3348 3349 if (! -f $kconfig) { 3350 doprint "file $kconfig does not exist, skipping\n"; 3351 return; 3352 } 3353 3354 open(KIN, "$kconfig") 3355 or die "Can't open $kconfig"; 3356 while (<KIN>) { 3357 chomp; 3358 3359 # Make sure that lines ending with \ continue 3360 if ($cont) { 3361 $_ = $line . " " . $_; 3362 } 3363 3364 if (s/\\$//) { 3365 $cont = 1; 3366 $line = $_; 3367 next; 3368 } 3369 3370 $cont = 0; 3371 3372 # collect any Kconfig sources 3373 if (/^source\s*"(.*)"/) { 3374 $kconfigs[$#kconfigs+1] = $1; 3375 } 3376 3377 # configs found 3378 if (/^\s*(menu)?config\s+(\S+)\s*$/) { 3379 $state = "NEW"; 3380 $config = $2; 3381 3382 for (my $i = 0; $i < $iflevel; $i++) { 3383 add_dep $config, $ifdeps[$i]; 3384 } 3385 3386 # collect the depends for the config 3387 } elsif ($state eq "NEW" && /^\s*depends\s+on\s+(.*)$/) { 3388 3389 add_dep $config, $1; 3390 3391 # Get the configs that select this config 3392 } elsif ($state eq "NEW" && /^\s*select\s+(\S+)/) { 3393 3394 # selected by depends on config 3395 add_dep $1, $config; 3396 3397 # Check for if statements 3398 } elsif (/^if\s+(.*\S)\s*$/) { 3399 my $deps = $1; 3400 # remove beginning and ending non text 3401 $deps =~ s/^[^a-zA-Z0-9_]*//; 3402 $deps =~ s/[^a-zA-Z0-9_]*$//; 3403 3404 my @deps = split /[^a-zA-Z0-9_]+/, $deps; 3405 3406 $ifdeps[$iflevel++] = join ':', @deps; 3407 3408 } elsif (/^endif/) { 3409 3410 $iflevel-- if ($iflevel); 3411 3412 # stop on "help" 3413 } elsif (/^\s*help\s*$/) { 3414 $state = "NONE"; 3415 } 3416 } 3417 close(KIN); 3418 3419 # read in any configs that were found. 3420 foreach $kconfig (@kconfigs) { 3421 if (!defined($read_kconfigs{$kconfig})) { 3422 $read_kconfigs{$kconfig} = 1; 3423 read_kconfig("$builddir/$kconfig"); 3424 } 3425 } 3426} 3427 3428sub read_depends { 3429 # find out which arch this is by the kconfig file 3430 open (IN, $output_config) 3431 or dodie "Failed to read $output_config"; 3432 my $arch; 3433 while (<IN>) { 3434 if (m,Linux/(\S+)\s+\S+\s+Kernel Configuration,) { 3435 $arch = $1; 3436 last; 3437 } 3438 } 3439 close IN; 3440 3441 if (!defined($arch)) { 3442 doprint "Could not find arch from config file\n"; 3443 doprint "no dependencies used\n"; 3444 return; 3445 } 3446 3447 # arch is really the subarch, we need to know 3448 # what directory to look at. 3449 if ($arch eq "i386" || $arch eq "x86_64") { 3450 $arch = "x86"; 3451 } elsif ($arch =~ /^tile/) { 3452 $arch = "tile"; 3453 } 3454 3455 my $kconfig = "$builddir/arch/$arch/Kconfig"; 3456 3457 if (! -f $kconfig && $arch =~ /\d$/) { 3458 my $orig = $arch; 3459 # some subarchs have numbers, truncate them 3460 $arch =~ s/\d*$//; 3461 $kconfig = "$builddir/arch/$arch/Kconfig"; 3462 if (! -f $kconfig) { 3463 doprint "No idea what arch dir $orig is for\n"; 3464 doprint "no dependencies used\n"; 3465 return; 3466 } 3467 } 3468 3469 read_kconfig($kconfig); 3470} 3471 3472sub make_new_config { 3473 my @configs = @_; 3474 3475 open (OUT, ">$output_config") 3476 or dodie "Failed to write $output_config"; 3477 3478 foreach my $config (@configs) { 3479 print OUT "$config\n"; 3480 } 3481 close OUT; 3482} 3483 3484sub chomp_config { 3485 my ($config) = @_; 3486 3487 $config =~ s/CONFIG_//; 3488 3489 return $config; 3490} 3491 3492sub get_depends { 3493 my ($dep) = @_; 3494 3495 my $kconfig = chomp_config $dep; 3496 3497 $dep = $depends{"$kconfig"}; 3498 3499 # the dep string we have saves the dependencies as they 3500 # were found, including expressions like ! && ||. We 3501 # want to split this out into just an array of configs. 3502 3503 my $valid = "A-Za-z_0-9"; 3504 3505 my @configs; 3506 3507 while ($dep =~ /[$valid]/) { 3508 3509 if ($dep =~ /^[^$valid]*([$valid]+)/) { 3510 my $conf = "CONFIG_" . $1; 3511 3512 $configs[$#configs + 1] = $conf; 3513 3514 $dep =~ s/^[^$valid]*[$valid]+//; 3515 } else { 3516 die "this should never happen"; 3517 } 3518 } 3519 3520 return @configs; 3521} 3522 3523my %min_configs; 3524my %keep_configs; 3525my %save_configs; 3526my %processed_configs; 3527my %nochange_config; 3528 3529sub test_this_config { 3530 my ($config) = @_; 3531 3532 my $found; 3533 3534 # if we already processed this config, skip it 3535 if (defined($processed_configs{$config})) { 3536 return undef; 3537 } 3538 $processed_configs{$config} = 1; 3539 3540 # if this config failed during this round, skip it 3541 if (defined($nochange_config{$config})) { 3542 return undef; 3543 } 3544 3545 my $kconfig = chomp_config $config; 3546 3547 # Test dependencies first 3548 if (defined($depends{"$kconfig"})) { 3549 my @parents = get_depends $config; 3550 foreach my $parent (@parents) { 3551 # if the parent is in the min config, check it first 3552 next if (!defined($min_configs{$parent})); 3553 $found = test_this_config($parent); 3554 if (defined($found)) { 3555 return $found; 3556 } 3557 } 3558 } 3559 3560 # Remove this config from the list of configs 3561 # do a make olddefconfig and then read the resulting 3562 # .config to make sure it is missing the config that 3563 # we had before 3564 my %configs = %min_configs; 3565 delete $configs{$config}; 3566 make_new_config ((values %configs), (values %keep_configs)); 3567 make_oldconfig; 3568 undef %configs; 3569 assign_configs \%configs, $output_config; 3570 3571 if (!defined($configs{$config}) || $configs{$config} =~ /^#/) { 3572 return $config; 3573 } 3574 3575 doprint "disabling config $config did not change .config\n"; 3576 3577 $nochange_config{$config} = 1; 3578 3579 return undef; 3580} 3581 3582sub make_min_config { 3583 my ($i) = @_; 3584 3585 my $type = $minconfig_type; 3586 if ($type ne "boot" && $type ne "test") { 3587 fail "Invalid MIN_CONFIG_TYPE '$minconfig_type'\n" . 3588 " make_min_config works only with 'boot' and 'test'\n" and return; 3589 } 3590 3591 if (!defined($output_minconfig)) { 3592 fail "OUTPUT_MIN_CONFIG not defined" and return; 3593 } 3594 3595 # If output_minconfig exists, and the start_minconfig 3596 # came from min_config, than ask if we should use 3597 # that instead. 3598 if (-f $output_minconfig && !$start_minconfig_defined) { 3599 print "$output_minconfig exists\n"; 3600 if (!defined($use_output_minconfig)) { 3601 if (read_yn " Use it as minconfig?") { 3602 $start_minconfig = $output_minconfig; 3603 } 3604 } elsif ($use_output_minconfig > 0) { 3605 doprint "Using $output_minconfig as MIN_CONFIG\n"; 3606 $start_minconfig = $output_minconfig; 3607 } else { 3608 doprint "Set to still use MIN_CONFIG as starting point\n"; 3609 } 3610 } 3611 3612 if (!defined($start_minconfig)) { 3613 fail "START_MIN_CONFIG or MIN_CONFIG not defined" and return; 3614 } 3615 3616 my $temp_config = "$tmpdir/temp_config"; 3617 3618 # First things first. We build an allnoconfig to find 3619 # out what the defaults are that we can't touch. 3620 # Some are selections, but we really can't handle selections. 3621 3622 my $save_minconfig = $minconfig; 3623 undef $minconfig; 3624 3625 run_command "$make allnoconfig" or return 0; 3626 3627 read_depends; 3628 3629 process_config_ignore $output_config; 3630 3631 undef %save_configs; 3632 undef %min_configs; 3633 3634 if (defined($ignore_config)) { 3635 # make sure the file exists 3636 `touch $ignore_config`; 3637 assign_configs \%save_configs, $ignore_config; 3638 } 3639 3640 %keep_configs = %save_configs; 3641 3642 doprint "Load initial configs from $start_minconfig\n"; 3643 3644 # Look at the current min configs, and save off all the 3645 # ones that were set via the allnoconfig 3646 assign_configs \%min_configs, $start_minconfig; 3647 3648 my @config_keys = keys %min_configs; 3649 3650 # All configs need a depcount 3651 foreach my $config (@config_keys) { 3652 my $kconfig = chomp_config $config; 3653 if (!defined $depcount{$kconfig}) { 3654 $depcount{$kconfig} = 0; 3655 } 3656 } 3657 3658 # Remove anything that was set by the make allnoconfig 3659 # we shouldn't need them as they get set for us anyway. 3660 foreach my $config (@config_keys) { 3661 # Remove anything in the ignore_config 3662 if (defined($keep_configs{$config})) { 3663 my $file = $ignore_config; 3664 $file =~ s,.*/(.*?)$,$1,; 3665 doprint "$config set by $file ... ignored\n"; 3666 delete $min_configs{$config}; 3667 next; 3668 } 3669 # But make sure the settings are the same. If a min config 3670 # sets a selection, we do not want to get rid of it if 3671 # it is not the same as what we have. Just move it into 3672 # the keep configs. 3673 if (defined($config_ignore{$config})) { 3674 if ($config_ignore{$config} ne $min_configs{$config}) { 3675 doprint "$config is in allnoconfig as '$config_ignore{$config}'"; 3676 doprint " but it is '$min_configs{$config}' in minconfig .. keeping\n"; 3677 $keep_configs{$config} = $min_configs{$config}; 3678 } else { 3679 doprint "$config set by allnoconfig ... ignored\n"; 3680 } 3681 delete $min_configs{$config}; 3682 } 3683 } 3684 3685 my $done = 0; 3686 my $take_two = 0; 3687 3688 while (!$done) { 3689 3690 my $config; 3691 my $found; 3692 3693 # Now disable each config one by one and do a make oldconfig 3694 # till we find a config that changes our list. 3695 3696 my @test_configs = keys %min_configs; 3697 3698 # Sort keys by who is most dependent on 3699 @test_configs = sort { $depcount{chomp_config($b)} <=> $depcount{chomp_config($a)} } 3700 @test_configs ; 3701 3702 # Put configs that did not modify the config at the end. 3703 my $reset = 1; 3704 for (my $i = 0; $i < $#test_configs; $i++) { 3705 if (!defined($nochange_config{$test_configs[0]})) { 3706 $reset = 0; 3707 last; 3708 } 3709 # This config didn't change the .config last time. 3710 # Place it at the end 3711 my $config = shift @test_configs; 3712 push @test_configs, $config; 3713 } 3714 3715 # if every test config has failed to modify the .config file 3716 # in the past, then reset and start over. 3717 if ($reset) { 3718 undef %nochange_config; 3719 } 3720 3721 undef %processed_configs; 3722 3723 foreach my $config (@test_configs) { 3724 3725 $found = test_this_config $config; 3726 3727 last if (defined($found)); 3728 3729 # oh well, try another config 3730 } 3731 3732 if (!defined($found)) { 3733 # we could have failed due to the nochange_config hash 3734 # reset and try again 3735 if (!$take_two) { 3736 undef %nochange_config; 3737 $take_two = 1; 3738 next; 3739 } 3740 doprint "No more configs found that we can disable\n"; 3741 $done = 1; 3742 last; 3743 } 3744 $take_two = 0; 3745 3746 $config = $found; 3747 3748 doprint "Test with $config disabled\n"; 3749 3750 # set in_bisect to keep build and monitor from dieing 3751 $in_bisect = 1; 3752 3753 my $failed = 0; 3754 build "oldconfig" or $failed = 1; 3755 if (!$failed) { 3756 start_monitor_and_boot or $failed = 1; 3757 3758 if ($type eq "test" && !$failed) { 3759 do_run_test or $failed = 1; 3760 } 3761 3762 end_monitor; 3763 } 3764 3765 $in_bisect = 0; 3766 3767 if ($failed) { 3768 doprint "$min_configs{$config} is needed to boot the box... keeping\n"; 3769 # this config is needed, add it to the ignore list. 3770 $keep_configs{$config} = $min_configs{$config}; 3771 $save_configs{$config} = $min_configs{$config}; 3772 delete $min_configs{$config}; 3773 3774 # update new ignore configs 3775 if (defined($ignore_config)) { 3776 open (OUT, ">$temp_config") 3777 or die "Can't write to $temp_config"; 3778 foreach my $config (keys %save_configs) { 3779 print OUT "$save_configs{$config}\n"; 3780 } 3781 close OUT; 3782 run_command "mv $temp_config $ignore_config" or 3783 dodie "failed to copy update to $ignore_config"; 3784 } 3785 3786 } else { 3787 # We booted without this config, remove it from the minconfigs. 3788 doprint "$config is not needed, disabling\n"; 3789 3790 delete $min_configs{$config}; 3791 3792 # Also disable anything that is not enabled in this config 3793 my %configs; 3794 assign_configs \%configs, $output_config; 3795 my @config_keys = keys %min_configs; 3796 foreach my $config (@config_keys) { 3797 if (!defined($configs{$config})) { 3798 doprint "$config is not set, disabling\n"; 3799 delete $min_configs{$config}; 3800 } 3801 } 3802 3803 # Save off all the current mandidory configs 3804 open (OUT, ">$temp_config") 3805 or die "Can't write to $temp_config"; 3806 foreach my $config (keys %keep_configs) { 3807 print OUT "$keep_configs{$config}\n"; 3808 } 3809 foreach my $config (keys %min_configs) { 3810 print OUT "$min_configs{$config}\n"; 3811 } 3812 close OUT; 3813 3814 run_command "mv $temp_config $output_minconfig" or 3815 dodie "failed to copy update to $output_minconfig"; 3816 } 3817 3818 doprint "Reboot and wait $sleep_time seconds\n"; 3819 reboot_to_good $sleep_time; 3820 } 3821 3822 success $i; 3823 return 1; 3824} 3825 3826sub make_warnings_file { 3827 my ($i) = @_; 3828 3829 if (!defined($warnings_file)) { 3830 dodie "Must define WARNINGS_FILE for make_warnings_file test"; 3831 } 3832 3833 if ($build_type eq "nobuild") { 3834 dodie "BUILD_TYPE can not be 'nobuild' for make_warnings_file test"; 3835 } 3836 3837 build $build_type or dodie "Failed to build"; 3838 3839 open(OUT, ">$warnings_file") or dodie "Can't create $warnings_file"; 3840 3841 open(IN, $buildlog) or dodie "Can't open $buildlog"; 3842 while (<IN>) { 3843 3844 # Some compilers use UTF-8 extended for quotes 3845 # for distcc heterogeneous systems, this causes issues 3846 s/$utf8_quote/'/g; 3847 3848 if (/$check_build_re/) { 3849 print OUT; 3850 } 3851 } 3852 close(IN); 3853 3854 close(OUT); 3855 3856 success $i; 3857} 3858 3859$#ARGV < 1 or die "ktest.pl version: $VERSION\n usage: ktest.pl [config-file]\n"; 3860 3861if ($#ARGV == 0) { 3862 $ktest_config = $ARGV[0]; 3863 if (! -f $ktest_config) { 3864 print "$ktest_config does not exist.\n"; 3865 if (!read_yn "Create it?") { 3866 exit 0; 3867 } 3868 } 3869} 3870 3871if (! -f $ktest_config) { 3872 $newconfig = 1; 3873 get_test_case; 3874 open(OUT, ">$ktest_config") or die "Can not create $ktest_config"; 3875 print OUT << "EOF" 3876# Generated by ktest.pl 3877# 3878 3879# PWD is a ktest.pl variable that will result in the process working 3880# directory that ktest.pl is executed in. 3881 3882# THIS_DIR is automatically assigned the PWD of the path that generated 3883# the config file. It is best to use this variable when assigning other 3884# directory paths within this directory. This allows you to easily 3885# move the test cases to other locations or to other machines. 3886# 3887THIS_DIR := $variable{"PWD"} 3888 3889# Define each test with TEST_START 3890# The config options below it will override the defaults 3891TEST_START 3892TEST_TYPE = $default{"TEST_TYPE"} 3893 3894DEFAULTS 3895EOF 3896; 3897 close(OUT); 3898} 3899read_config $ktest_config; 3900 3901if (defined($opt{"LOG_FILE"})) { 3902 $opt{"LOG_FILE"} = eval_option("LOG_FILE", $opt{"LOG_FILE"}, -1); 3903} 3904 3905# Append any configs entered in manually to the config file. 3906my @new_configs = keys %entered_configs; 3907if ($#new_configs >= 0) { 3908 print "\nAppending entered in configs to $ktest_config\n"; 3909 open(OUT, ">>$ktest_config") or die "Can not append to $ktest_config"; 3910 foreach my $config (@new_configs) { 3911 print OUT "$config = $entered_configs{$config}\n"; 3912 $opt{$config} = process_variables($entered_configs{$config}); 3913 } 3914} 3915 3916if ($opt{"CLEAR_LOG"} && defined($opt{"LOG_FILE"})) { 3917 unlink $opt{"LOG_FILE"}; 3918} 3919 3920doprint "\n\nSTARTING AUTOMATED TESTS\n\n"; 3921 3922for (my $i = 0, my $repeat = 1; $i <= $opt{"NUM_TESTS"}; $i += $repeat) { 3923 3924 if (!$i) { 3925 doprint "DEFAULT OPTIONS:\n"; 3926 } else { 3927 doprint "\nTEST $i OPTIONS"; 3928 if (defined($repeat_tests{$i})) { 3929 $repeat = $repeat_tests{$i}; 3930 doprint " ITERATE $repeat"; 3931 } 3932 doprint "\n"; 3933 } 3934 3935 foreach my $option (sort keys %opt) { 3936 3937 if ($option =~ /\[(\d+)\]$/) { 3938 next if ($i != $1); 3939 } else { 3940 next if ($i); 3941 } 3942 3943 doprint "$option = $opt{$option}\n"; 3944 } 3945} 3946 3947sub option_defined { 3948 my ($option) = @_; 3949 3950 if (defined($opt{$option}) && $opt{$option} !~ /^\s*$/) { 3951 return 1; 3952 } 3953 3954 return 0; 3955} 3956 3957sub __set_test_option { 3958 my ($name, $i) = @_; 3959 3960 my $option = "$name\[$i\]"; 3961 3962 if (option_defined($option)) { 3963 return $opt{$option}; 3964 } 3965 3966 foreach my $test (keys %repeat_tests) { 3967 if ($i >= $test && 3968 $i < $test + $repeat_tests{$test}) { 3969 $option = "$name\[$test\]"; 3970 if (option_defined($option)) { 3971 return $opt{$option}; 3972 } 3973 } 3974 } 3975 3976 if (option_defined($name)) { 3977 return $opt{$name}; 3978 } 3979 3980 return undef; 3981} 3982 3983sub set_test_option { 3984 my ($name, $i) = @_; 3985 3986 my $option = __set_test_option($name, $i); 3987 return $option if (!defined($option)); 3988 3989 return eval_option($name, $option, $i); 3990} 3991 3992# First we need to do is the builds 3993for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) { 3994 3995 # Do not reboot on failing test options 3996 $no_reboot = 1; 3997 $reboot_success = 0; 3998 3999 $have_version = 0; 4000 4001 $iteration = $i; 4002 4003 undef %force_config; 4004 4005 my $makecmd = set_test_option("MAKE_CMD", $i); 4006 4007 $outputdir = set_test_option("OUTPUT_DIR", $i); 4008 $builddir = set_test_option("BUILD_DIR", $i); 4009 4010 chdir $builddir || die "can't change directory to $builddir"; 4011 4012 if (!-d $outputdir) { 4013 mkpath($outputdir) or 4014 die "can't create $outputdir"; 4015 } 4016 4017 $make = "$makecmd O=$outputdir"; 4018 4019 # Load all the options into their mapped variable names 4020 foreach my $opt (keys %option_map) { 4021 ${$option_map{$opt}} = set_test_option($opt, $i); 4022 } 4023 4024 $start_minconfig_defined = 1; 4025 4026 # The first test may override the PRE_KTEST option 4027 if (defined($pre_ktest) && $i == 1) { 4028 doprint "\n"; 4029 run_command $pre_ktest; 4030 } 4031 4032 # Any test can override the POST_KTEST option 4033 # The last test takes precedence. 4034 if (defined($post_ktest)) { 4035 $final_post_ktest = $post_ktest; 4036 } 4037 4038 if (!defined($start_minconfig)) { 4039 $start_minconfig_defined = 0; 4040 $start_minconfig = $minconfig; 4041 } 4042 4043 if (!-d $tmpdir) { 4044 mkpath($tmpdir) or 4045 die "can't create $tmpdir"; 4046 } 4047 4048 $ENV{"SSH_USER"} = $ssh_user; 4049 $ENV{"MACHINE"} = $machine; 4050 4051 $buildlog = "$tmpdir/buildlog-$machine"; 4052 $testlog = "$tmpdir/testlog-$machine"; 4053 $dmesg = "$tmpdir/dmesg-$machine"; 4054 $output_config = "$outputdir/.config"; 4055 4056 if (!$buildonly) { 4057 $target = "$ssh_user\@$machine"; 4058 if ($reboot_type eq "grub") { 4059 dodie "GRUB_MENU not defined" if (!defined($grub_menu)); 4060 } elsif ($reboot_type eq "grub2") { 4061 dodie "GRUB_MENU not defined" if (!defined($grub_menu)); 4062 dodie "GRUB_FILE not defined" if (!defined($grub_file)); 4063 } elsif ($reboot_type eq "syslinux") { 4064 dodie "SYSLINUX_LABEL not defined" if (!defined($syslinux_label)); 4065 } 4066 } 4067 4068 my $run_type = $build_type; 4069 if ($test_type eq "patchcheck") { 4070 $run_type = $patchcheck_type; 4071 } elsif ($test_type eq "bisect") { 4072 $run_type = $bisect_type; 4073 } elsif ($test_type eq "config_bisect") { 4074 $run_type = $config_bisect_type; 4075 } elsif ($test_type eq "make_min_config") { 4076 $run_type = ""; 4077 } elsif ($test_type eq "make_warnings_file") { 4078 $run_type = ""; 4079 } 4080 4081 # mistake in config file? 4082 if (!defined($run_type)) { 4083 $run_type = "ERROR"; 4084 } 4085 4086 my $installme = ""; 4087 $installme = " no_install" if ($no_install); 4088 4089 my $name = ""; 4090 4091 if (defined($test_name)) { 4092 $name = " ($test_name)"; 4093 } 4094 4095 doprint "\n\n"; 4096 doprint "RUNNING TEST $i of $opt{NUM_TESTS}$name with option $test_type $run_type$installme\n\n"; 4097 4098 if (defined($pre_test)) { 4099 run_command $pre_test; 4100 } 4101 4102 unlink $dmesg; 4103 unlink $buildlog; 4104 unlink $testlog; 4105 4106 if (defined($addconfig)) { 4107 my $min = $minconfig; 4108 if (!defined($minconfig)) { 4109 $min = ""; 4110 } 4111 run_command "cat $addconfig $min > $tmpdir/add_config" or 4112 dodie "Failed to create temp config"; 4113 $minconfig = "$tmpdir/add_config"; 4114 } 4115 4116 if (defined($checkout)) { 4117 run_command "git checkout $checkout" or 4118 die "failed to checkout $checkout"; 4119 } 4120 4121 $no_reboot = 0; 4122 4123 # A test may opt to not reboot the box 4124 if ($reboot_on_success) { 4125 $reboot_success = 1; 4126 } 4127 4128 if ($test_type eq "bisect") { 4129 bisect $i; 4130 next; 4131 } elsif ($test_type eq "config_bisect") { 4132 config_bisect $i; 4133 next; 4134 } elsif ($test_type eq "patchcheck") { 4135 patchcheck $i; 4136 next; 4137 } elsif ($test_type eq "make_min_config") { 4138 make_min_config $i; 4139 next; 4140 } elsif ($test_type eq "make_warnings_file") { 4141 $no_reboot = 1; 4142 make_warnings_file $i; 4143 next; 4144 } 4145 4146 if ($build_type ne "nobuild") { 4147 build $build_type or next; 4148 check_buildlog or next; 4149 } 4150 4151 if ($test_type eq "install") { 4152 get_version; 4153 install; 4154 success $i; 4155 next; 4156 } 4157 4158 if ($test_type ne "build") { 4159 my $failed = 0; 4160 start_monitor_and_boot or $failed = 1; 4161 4162 if (!$failed && $test_type ne "boot" && defined($run_test)) { 4163 do_run_test or $failed = 1; 4164 } 4165 end_monitor; 4166 next if ($failed); 4167 } 4168 4169 success $i; 4170} 4171 4172if (defined($final_post_ktest)) { 4173 run_command $final_post_ktest; 4174} 4175 4176if ($opt{"POWEROFF_ON_SUCCESS"}) { 4177 halt; 4178} elsif ($opt{"REBOOT_ON_SUCCESS"} && !do_not_reboot && $reboot_success) { 4179 reboot_to_good; 4180} elsif (defined($switch_to_good)) { 4181 # still need to get to the good kernel 4182 run_command $switch_to_good; 4183} 4184 4185 4186doprint "\n $successes of $opt{NUM_TESTS} tests were successful\n\n"; 4187 4188exit 0; 4189