|
@@ -37,6 +37,8 @@ $default{"POWEROFF_ON_SUCCESS"} = 0;
|
|
|
$default{"BUILD_OPTIONS"} = "";
|
|
|
$default{"BISECT_SLEEP_TIME"} = 60; # sleep time between bisects
|
|
|
$default{"CLEAR_LOG"} = 0;
|
|
|
+$default{"BISECT_MANUAL"} = 0;
|
|
|
+$default{"BISECT_SKIP"} = 1;
|
|
|
$default{"SUCCESS_LINE"} = "login:";
|
|
|
$default{"BOOTED_TIMEOUT"} = 1;
|
|
|
$default{"DIE_ON_FAILURE"} = 1;
|
|
@@ -45,6 +47,7 @@ $default{"SCP_TO_TARGET"} = "scp \$SRC_FILE \$SSH_USER\@\$MACHINE:\$DST_FILE";
|
|
|
$default{"REBOOT"} = "ssh \$SSH_USER\@\$MACHINE reboot";
|
|
|
$default{"STOP_AFTER_SUCCESS"} = 10;
|
|
|
$default{"STOP_AFTER_FAILURE"} = 60;
|
|
|
+$default{"STOP_TEST_AFTER"} = 600;
|
|
|
$default{"LOCALVERSION"} = "-test";
|
|
|
|
|
|
my $ktest_config;
|
|
@@ -81,6 +84,8 @@ my $addconfig;
|
|
|
my $in_bisect = 0;
|
|
|
my $bisect_bad = "";
|
|
|
my $reverse_bisect;
|
|
|
+my $bisect_manual;
|
|
|
+my $bisect_skip;
|
|
|
my $in_patchcheck = 0;
|
|
|
my $run_test;
|
|
|
my $redirect;
|
|
@@ -98,6 +103,7 @@ my $console;
|
|
|
my $success_line;
|
|
|
my $stop_after_success;
|
|
|
my $stop_after_failure;
|
|
|
+my $stop_test_after;
|
|
|
my $build_target;
|
|
|
my $target_image;
|
|
|
my $localversion;
|
|
@@ -462,6 +468,10 @@ sub dodie {
|
|
|
`$power_off`;
|
|
|
}
|
|
|
|
|
|
+ if (defined($opt{"LOG_FILE"})) {
|
|
|
+ print " See $opt{LOG_FILE} for more info.\n";
|
|
|
+ }
|
|
|
+
|
|
|
die @_, "\n";
|
|
|
}
|
|
|
|
|
@@ -760,8 +770,10 @@ sub monitor {
|
|
|
|
|
|
my $success_start;
|
|
|
my $failure_start;
|
|
|
+ my $monitor_start = time;
|
|
|
+ my $done = 0;
|
|
|
|
|
|
- for (;;) {
|
|
|
+ while (!$done) {
|
|
|
|
|
|
if ($booted) {
|
|
|
$line = wait_for_input($monitor_fp, $booted_timeout);
|
|
@@ -796,7 +808,7 @@ sub monitor {
|
|
|
}
|
|
|
|
|
|
if ($full_line =~ /call trace:/i) {
|
|
|
- if (!$skip_call_trace) {
|
|
|
+ if (!$bug && !$skip_call_trace) {
|
|
|
$bug = 1;
|
|
|
$failure_start = time;
|
|
|
}
|
|
@@ -816,12 +828,19 @@ sub monitor {
|
|
|
}
|
|
|
|
|
|
if ($full_line =~ /Kernel panic -/) {
|
|
|
+ $failure_start = time;
|
|
|
$bug = 1;
|
|
|
}
|
|
|
|
|
|
if ($line =~ /\n/) {
|
|
|
$full_line = "";
|
|
|
}
|
|
|
+
|
|
|
+ if ($stop_test_after > 0 && !$booted && !$bug) {
|
|
|
+ if (time - $monitor_start > $stop_test_after) {
|
|
|
+ $done = 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
close(DMESG);
|
|
@@ -925,6 +944,18 @@ sub check_buildlog {
|
|
|
return 1;
|
|
|
}
|
|
|
|
|
|
+sub make_oldconfig {
|
|
|
+ my ($defconfig) = @_;
|
|
|
+
|
|
|
+ if (!run_command "$defconfig $make oldnoconfig") {
|
|
|
+ # Perhaps oldnoconfig doesn't exist in this version of the kernel
|
|
|
+ # try a yes '' | oldconfig
|
|
|
+ doprint "oldnoconfig failed, trying yes '' | make oldconfig\n";
|
|
|
+ run_command "yes '' | $defconfig $make oldconfig" or
|
|
|
+ dodie "failed make config oldconfig";
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
sub build {
|
|
|
my ($type) = @_;
|
|
|
my $defconfig = "";
|
|
@@ -970,8 +1001,12 @@ sub build {
|
|
|
$defconfig = "KCONFIG_ALLCONFIG=$minconfig";
|
|
|
}
|
|
|
|
|
|
- run_command "$defconfig $make $type" or
|
|
|
- dodie "failed make config";
|
|
|
+ if ($type eq "oldnoconfig") {
|
|
|
+ make_oldconfig $defconfig;
|
|
|
+ } else {
|
|
|
+ run_command "$defconfig $make $type" or
|
|
|
+ dodie "failed make config";
|
|
|
+ }
|
|
|
|
|
|
$redirect = "$buildlog";
|
|
|
if (!run_command "$make $build_options") {
|
|
@@ -1025,6 +1060,21 @@ sub get_version {
|
|
|
doprint "$version\n";
|
|
|
}
|
|
|
|
|
|
+sub answer_bisect {
|
|
|
+ for (;;) {
|
|
|
+ doprint "Pass or fail? [p/f]";
|
|
|
+ my $ans = <STDIN>;
|
|
|
+ chomp $ans;
|
|
|
+ if ($ans eq "p" || $ans eq "P") {
|
|
|
+ return 1;
|
|
|
+ } elsif ($ans eq "f" || $ans eq "F") {
|
|
|
+ return 0;
|
|
|
+ } else {
|
|
|
+ print "Please answer 'P' or 'F'\n";
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
sub child_run_test {
|
|
|
my $failed = 0;
|
|
|
|
|
@@ -1070,6 +1120,7 @@ sub do_run_test {
|
|
|
|
|
|
# we are not guaranteed to get a full line
|
|
|
$full_line .= $line;
|
|
|
+ doprint $line;
|
|
|
|
|
|
if ($full_line =~ /call trace:/i) {
|
|
|
$bug = 1;
|
|
@@ -1086,6 +1137,19 @@ sub do_run_test {
|
|
|
} while (!$child_done && !$bug);
|
|
|
|
|
|
if ($bug) {
|
|
|
+ my $failure_start = time;
|
|
|
+ my $now;
|
|
|
+ do {
|
|
|
+ $line = wait_for_input($monitor_fp, 1);
|
|
|
+ if (defined($line)) {
|
|
|
+ doprint $line;
|
|
|
+ }
|
|
|
+ $now = time;
|
|
|
+ if ($now - $failure_start >= $stop_after_failure) {
|
|
|
+ last;
|
|
|
+ }
|
|
|
+ } while (defined($line));
|
|
|
+
|
|
|
doprint "Detected kernel crash!\n";
|
|
|
# kill the child with extreme prejudice
|
|
|
kill 9, $child_pid;
|
|
@@ -1131,7 +1195,15 @@ sub run_git_bisect {
|
|
|
return 1;
|
|
|
}
|
|
|
|
|
|
-# returns 1 on success, 0 on failure
|
|
|
+sub bisect_reboot {
|
|
|
+ doprint "Reboot and sleep $bisect_sleep_time seconds\n";
|
|
|
+ reboot;
|
|
|
+ start_monitor;
|
|
|
+ wait_for_monitor $bisect_sleep_time;
|
|
|
+ end_monitor;
|
|
|
+}
|
|
|
+
|
|
|
+# returns 1 on success, 0 on failure, -1 on skip
|
|
|
sub run_bisect_test {
|
|
|
my ($type, $buildtype) = @_;
|
|
|
|
|
@@ -1145,6 +1217,10 @@ sub run_bisect_test {
|
|
|
build $buildtype or $failed = 1;
|
|
|
|
|
|
if ($type ne "build") {
|
|
|
+ if ($failed && $bisect_skip) {
|
|
|
+ $in_bisect = 0;
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
dodie "Failed on build" if $failed;
|
|
|
|
|
|
# Now boot the box
|
|
@@ -1156,6 +1232,12 @@ sub run_bisect_test {
|
|
|
monitor or $failed = 1;
|
|
|
|
|
|
if ($type ne "boot") {
|
|
|
+ if ($failed && $bisect_skip) {
|
|
|
+ end_monitor;
|
|
|
+ bisect_reboot;
|
|
|
+ $in_bisect = 0;
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
dodie "Failed on boot" if $failed;
|
|
|
|
|
|
do_run_test or $failed = 1;
|
|
@@ -1168,11 +1250,7 @@ sub run_bisect_test {
|
|
|
|
|
|
# reboot the box to a good kernel
|
|
|
if ($type ne "build") {
|
|
|
- doprint "Reboot and sleep $bisect_sleep_time seconds\n";
|
|
|
- reboot;
|
|
|
- start_monitor;
|
|
|
- wait_for_monitor $bisect_sleep_time;
|
|
|
- end_monitor;
|
|
|
+ bisect_reboot;
|
|
|
}
|
|
|
} else {
|
|
|
$result = 1;
|
|
@@ -1193,16 +1271,22 @@ sub run_bisect {
|
|
|
|
|
|
my $ret = run_bisect_test $type, $buildtype;
|
|
|
|
|
|
+ if ($bisect_manual) {
|
|
|
+ $ret = answer_bisect;
|
|
|
+ }
|
|
|
|
|
|
# Are we looking for where it worked, not failed?
|
|
|
if ($reverse_bisect) {
|
|
|
$ret = !$ret;
|
|
|
}
|
|
|
|
|
|
- if ($ret) {
|
|
|
+ if ($ret > 0) {
|
|
|
return "good";
|
|
|
- } else {
|
|
|
+ } elsif ($ret == 0) {
|
|
|
return "bad";
|
|
|
+ } elsif ($bisect_skip) {
|
|
|
+ doprint "HIT A BAD COMMIT ... SKIPPING\n";
|
|
|
+ return "skip";
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -1220,6 +1304,13 @@ sub bisect {
|
|
|
my $type = $opt{"BISECT_TYPE[$i]"};
|
|
|
my $start = $opt{"BISECT_START[$i]"};
|
|
|
my $replay = $opt{"BISECT_REPLAY[$i]"};
|
|
|
+ my $start_files = $opt{"BISECT_FILES[$i]"};
|
|
|
+
|
|
|
+ if (defined($start_files)) {
|
|
|
+ $start_files = " -- " . $start_files;
|
|
|
+ } else {
|
|
|
+ $start_files = "";
|
|
|
+ }
|
|
|
|
|
|
# convert to true sha1's
|
|
|
$good = get_sha1($good);
|
|
@@ -1273,7 +1364,7 @@ sub bisect {
|
|
|
die "Failed to checkout $head";
|
|
|
}
|
|
|
|
|
|
- run_command "git bisect start" or
|
|
|
+ run_command "git bisect start$start_files" or
|
|
|
dodie "could not start bisect";
|
|
|
|
|
|
run_command "git bisect good $good" or
|
|
@@ -1390,9 +1481,7 @@ sub create_config {
|
|
|
close(OUT);
|
|
|
|
|
|
# exit;
|
|
|
- run_command "$make oldnoconfig" or
|
|
|
- dodie "failed make config oldconfig";
|
|
|
-
|
|
|
+ make_oldconfig "";
|
|
|
}
|
|
|
|
|
|
sub compare_configs {
|
|
@@ -1505,7 +1594,9 @@ sub run_config_bisect {
|
|
|
}
|
|
|
|
|
|
$ret = run_config_bisect_test $type;
|
|
|
-
|
|
|
+ if ($bisect_manual) {
|
|
|
+ $ret = answer_bisect;
|
|
|
+ }
|
|
|
if ($ret) {
|
|
|
process_passed %current_config;
|
|
|
return 0;
|
|
@@ -1536,7 +1627,13 @@ sub run_config_bisect {
|
|
|
$half = int($#start_list / 2);
|
|
|
} while ($half > 0);
|
|
|
|
|
|
- # we found a single config, try it again
|
|
|
+ # we found a single config, try it again unless we are running manually
|
|
|
+
|
|
|
+ if ($bisect_manual) {
|
|
|
+ process_failed $start_list[0];
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
+
|
|
|
my @tophalf = @start_list[0 .. 0];
|
|
|
|
|
|
$ret = run_config_bisect_test $type;
|
|
@@ -1594,8 +1691,7 @@ sub config_bisect {
|
|
|
close(IN);
|
|
|
|
|
|
# Now run oldconfig with the minconfig (and addconfigs)
|
|
|
- run_command "$defconfig $make oldnoconfig" or
|
|
|
- dodie "failed make config oldconfig";
|
|
|
+ make_oldconfig $defconfig;
|
|
|
|
|
|
# check to see what we lost (or gained)
|
|
|
open (IN, $output_config)
|
|
@@ -1907,6 +2003,8 @@ for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
|
|
|
$poweroff_after_halt = set_test_option("POWEROFF_AFTER_HALT", $i);
|
|
|
$sleep_time = set_test_option("SLEEP_TIME", $i);
|
|
|
$bisect_sleep_time = set_test_option("BISECT_SLEEP_TIME", $i);
|
|
|
+ $bisect_manual = set_test_option("BISECT_MANUAL", $i);
|
|
|
+ $bisect_skip = set_test_option("BISECT_SKIP", $i);
|
|
|
$store_failures = set_test_option("STORE_FAILURES", $i);
|
|
|
$timeout = set_test_option("TIMEOUT", $i);
|
|
|
$booted_timeout = set_test_option("BOOTED_TIMEOUT", $i);
|
|
@@ -1914,6 +2012,7 @@ for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
|
|
|
$success_line = set_test_option("SUCCESS_LINE", $i);
|
|
|
$stop_after_success = set_test_option("STOP_AFTER_SUCCESS", $i);
|
|
|
$stop_after_failure = set_test_option("STOP_AFTER_FAILURE", $i);
|
|
|
+ $stop_test_after = set_test_option("STOP_TEST_AFTER", $i);
|
|
|
$build_target = set_test_option("BUILD_TARGET", $i);
|
|
|
$ssh_exec = set_test_option("SSH_EXEC", $i);
|
|
|
$scp_to_target = set_test_option("SCP_TO_TARGET", $i);
|