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