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