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