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