3 # Copyright 2010 - Steven Rostedt <srostedt@redhat.com>, Red Hat Inc.
4 # Licensed under the terms of the GNU GPL License version 2
9 use Fcntl qw(F_GETFL F_SETFL O_NONBLOCK);
10 use File::Path qw(mkpath);
11 use File::Copy qw(cp);
24 $default{"NUM_TESTS"} = 1;
25 $default{"REBOOT_TYPE"} = "grub";
26 $default{"TEST_TYPE"} = "test";
27 $default{"BUILD_TYPE"} = "randconfig";
28 $default{"MAKE_CMD"} = "make";
29 $default{"TIMEOUT"} = 120;
30 $default{"TMP_DIR"} = "/tmp/ktest/\${MACHINE}";
31 $default{"SLEEP_TIME"} = 60; # sleep time between tests
32 $default{"BUILD_NOCLEAN"} = 0;
33 $default{"REBOOT_ON_ERROR"} = 0;
34 $default{"POWEROFF_ON_ERROR"} = 0;
35 $default{"REBOOT_ON_SUCCESS"} = 1;
36 $default{"POWEROFF_ON_SUCCESS"} = 0;
37 $default{"BUILD_OPTIONS"} = "";
38 $default{"BISECT_SLEEP_TIME"} = 60; # sleep time between bisects
39 $default{"PATCHCHECK_SLEEP_TIME"} = 60; # sleep time between patch checks
40 $default{"CLEAR_LOG"} = 0;
41 $default{"BISECT_MANUAL"} = 0;
42 $default{"BISECT_SKIP"} = 1;
43 $default{"SUCCESS_LINE"} = "login:";
44 $default{"DETECT_TRIPLE_FAULT"} = 1;
45 $default{"BOOTED_TIMEOUT"} = 1;
46 $default{"DIE_ON_FAILURE"} = 1;
47 $default{"SSH_EXEC"} = "ssh \$SSH_USER\@\$MACHINE \$SSH_COMMAND";
48 $default{"SCP_TO_TARGET"} = "scp \$SRC_FILE \$SSH_USER\@\$MACHINE:\$DST_FILE";
49 $default{"REBOOT"} = "ssh \$SSH_USER\@\$MACHINE reboot";
50 $default{"STOP_AFTER_SUCCESS"} = 10;
51 $default{"STOP_AFTER_FAILURE"} = 60;
52 $default{"STOP_TEST_AFTER"} = 600;
53 $default{"LOCALVERSION"} = "-test";
75 my $poweroff_on_error;
77 my $powercycle_after_reboot;
78 my $poweroff_after_halt;
90 my $start_minconfig_defined;
99 my $config_bisect_good;
100 my $in_patchcheck = 0;
109 my $bisect_sleep_time;
110 my $patchcheck_sleep_time;
116 my $detect_triplefault;
119 my $stop_after_success;
120 my $stop_after_failure;
133 $config_help{"MACHINE"} = << "EOF"
134 The machine hostname that you will test.
137 $config_help{"SSH_USER"} = << "EOF"
138 The box is expected to have ssh on normal bootup, provide the user
139 (most likely root, since you need privileged operations)
142 $config_help{"BUILD_DIR"} = << "EOF"
143 The directory that contains the Linux source code (full path).
146 $config_help{"OUTPUT_DIR"} = << "EOF"
147 The directory that the objects will be built (full path).
148 (can not be same as BUILD_DIR)
151 $config_help{"BUILD_TARGET"} = << "EOF"
152 The location of the compiled file to copy to the target.
153 (relative to OUTPUT_DIR)
156 $config_help{"TARGET_IMAGE"} = << "EOF"
157 The place to put your image on the test machine.
160 $config_help{"POWER_CYCLE"} = << "EOF"
161 A script or command to reboot the box.
163 Here is a digital loggers power switch example
164 POWER_CYCLE = wget --no-proxy -O /dev/null -q --auth-no-challenge 'http://admin:admin\@power/outlet?5=CCL'
166 Here is an example to reboot a virtual box on the current host
167 with the name "Guest".
168 POWER_CYCLE = virsh destroy Guest; sleep 5; virsh start Guest
171 $config_help{"CONSOLE"} = << "EOF"
172 The script or command that reads the console
174 If you use ttywatch server, something like the following would work.
175 CONSOLE = nc -d localhost 3001
177 For a virtual machine with guest name "Guest".
178 CONSOLE = virsh console Guest
181 $config_help{"LOCALVERSION"} = << "EOF"
182 Required version ending to differentiate the test
183 from other linux builds on the system.
186 $config_help{"REBOOT_TYPE"} = << "EOF"
187 Way to reboot the box to the test kernel.
188 Only valid options so far are "grub" and "script".
190 If you specify grub, it will assume grub version 1
191 and will search in /boot/grub/menu.lst for the title \$GRUB_MENU
192 and select that target to reboot to the kernel. If this is not
193 your setup, then specify "script" and have a command or script
194 specified in REBOOT_SCRIPT to boot to the target.
196 The entry in /boot/grub/menu.lst must be entered in manually.
197 The test will not modify that file.
200 $config_help{"GRUB_MENU"} = << "EOF"
201 The grub title name for the test kernel to boot
202 (Only mandatory if REBOOT_TYPE = grub)
204 Note, ktest.pl will not update the grub menu.lst, you need to
205 manually add an option for the test. ktest.pl will search
206 the grub menu.lst for this option to find what kernel to
209 For example, if in the /boot/grub/menu.lst the test kernel title has:
212 GRUB_MENU = Test Kernel
215 $config_help{"REBOOT_SCRIPT"} = << "EOF"
216 A script to reboot the target into the test kernel
217 (Only mandatory if REBOOT_TYPE = script)
227 print "$prompt [Y/n] ";
230 if ($ans =~ /^\s*$/) {
233 last if ($ans =~ /^y$/i || $ans =~ /^n$/i);
234 print "Please answer either 'y' or 'n'.\n";
236 if ($ans !~ /^y$/i) {
242 sub get_ktest_config {
245 return if (defined($opt{$config}));
247 if (defined($config_help{$config})) {
249 print $config_help{$config};
254 if (defined($default{$config})) {
255 print "\[$default{$config}\] ";
257 $entered_configs{$config} = <STDIN>;
258 $entered_configs{$config} =~ s/^\s*(.*\S)\s*$/$1/;
259 if ($entered_configs{$config} =~ /^\s*$/) {
260 if ($default{$config}) {
261 $entered_configs{$config} = $default{$config};
263 print "Your answer can not be blank\n";
271 sub get_ktest_configs {
272 get_ktest_config("MACHINE");
273 get_ktest_config("SSH_USER");
274 get_ktest_config("BUILD_DIR");
275 get_ktest_config("OUTPUT_DIR");
276 get_ktest_config("BUILD_TARGET");
277 get_ktest_config("TARGET_IMAGE");
278 get_ktest_config("POWER_CYCLE");
279 get_ktest_config("CONSOLE");
280 get_ktest_config("LOCALVERSION");
282 my $rtype = $opt{"REBOOT_TYPE"};
284 if (!defined($rtype)) {
285 if (!defined($opt{"GRUB_MENU"})) {
286 get_ktest_config("REBOOT_TYPE");
287 $rtype = $entered_configs{"REBOOT_TYPE"};
293 if ($rtype eq "grub") {
294 get_ktest_config("GRUB_MENU");
296 get_ktest_config("REBOOT_SCRIPT");
300 sub process_variables {
304 # We want to check for '\', and it is just easier
305 # to check the previous characet of '$' and not need
306 # to worry if '$' is the first character. By adding
307 # a space to $value, we can just check [^\\]\$ and
308 # it will still work.
311 while ($value =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) {
315 # append beginning of value to retval
316 $retval = "$retval$begin";
317 if (defined($variable{$var})) {
318 $retval = "$retval$variable{$var}";
320 # put back the origin piece.
321 $retval = "$retval\$\{$var\}";
325 $retval = "$retval$value";
327 # remove the space added in the beginning
334 my ($lvalue, $rvalue) = @_;
336 if (defined($opt{$lvalue})) {
337 die "Error: Option $lvalue defined more than once!\n";
339 if ($rvalue =~ /^\s*$/) {
340 delete $opt{$lvalue};
342 $rvalue = process_variables($rvalue);
343 $opt{$lvalue} = $rvalue;
348 my ($lvalue, $rvalue) = @_;
350 if ($rvalue =~ /^\s*$/) {
351 delete $variable{$lvalue};
353 $rvalue = process_variables($rvalue);
354 $variable{$lvalue} = $rvalue;
361 open(IN, $config) || die "can't read file $config";
364 $name =~ s,.*/(.*),$1,;
369 my $num_tests_set = 0;
376 # ignore blank lines and comments
377 next if (/^\s*$/ || /\s*\#/);
379 if (/^\s*TEST_START(.*)/) {
383 if ($num_tests_set) {
384 die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
387 my $old_test_num = $test_num;
388 my $old_repeat = $repeat;
390 $test_num += $repeat;
394 if ($rest =~ /\s+SKIP(.*)/) {
402 if ($rest =~ /\s+ITERATE\s+(\d+)(.*)$/) {
405 $repeat_tests{"$test_num"} = $repeat;
408 if ($rest =~ /\s+SKIP(.*)/) {
413 if ($rest !~ /^\s*$/) {
414 die "$name: $.: Gargbage found after TEST_START\n$_";
418 $test_num = $old_test_num;
419 $repeat = $old_repeat;
422 } elsif (/^\s*DEFAULTS(.*)$/) {
427 if ($rest =~ /\s+SKIP(.*)/) {
434 if ($rest !~ /^\s*$/) {
435 die "$name: $.: Gargbage found after DEFAULTS\n$_";
438 } elsif (/^\s*([A-Z_\[\]\d]+)\s*=\s*(.*?)\s*$/) {
446 ($lvalue eq "NUM_TESTS" ||
447 $lvalue eq "LOG_FILE" ||
448 $lvalue eq "CLEAR_LOG")) {
449 die "$name: $.: $lvalue must be set in DEFAULTS section\n";
452 if ($lvalue eq "NUM_TESTS") {
454 die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
457 die "$name: $.: NUM_TESTS must be set in default section\n";
462 if ($default || $lvalue =~ /\[\d+\]$/) {
463 set_value($lvalue, $rvalue);
465 my $val = "$lvalue\[$test_num\]";
466 set_value($val, $rvalue);
469 $repeats{$val} = $repeat;
472 } elsif (/^\s*([A-Z_\[\]\d]+)\s*:=\s*(.*?)\s*$/) {
478 # process config variables.
479 # Config variables are only active while reading the
480 # config and can be defined anywhere. They also ignore
481 # TEST_START and DEFAULTS, but are skipped if they are in
482 # on of these sections that have SKIP defined.
483 # The save variable can be
484 # defined multiple times and the new one simply overrides
486 set_variable($lvalue, $rvalue);
489 die "$name: $.: Garbage found in config\n$_";
496 $test_num += $repeat - 1;
497 $opt{"NUM_TESTS"} = $test_num;
500 # make sure we have all mandatory configs
503 # was a test specified?
505 print "No test case specified.\n";
506 print "What test case would you like to run?\n";
509 $default{"TEST_TYPE"} = $ans;
514 foreach my $default (keys %default) {
515 if (!defined($opt{$default})) {
516 $opt{$default} = $default{$default};
522 my ($option, $i) = @_;
524 # Add space to evaluate the character before $
525 $option = " $option";
528 while ($option =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) {
533 # Append beginning of line
534 $retval = "$retval$start";
536 # If the iteration option OPT[$i] exists, then use that.
537 # otherwise see if the default OPT (without [$i]) exists.
539 my $o = "$var\[$i\]";
541 if (defined($opt{$o})) {
543 $retval = "$retval$o";
544 } elsif (defined($opt{$var})) {
546 $retval = "$retval$o";
548 $retval = "$retval\$\{$var\}";
554 $retval = "$retval$option";
562 my ($option, $i) = @_;
566 # Since an option can evaluate to another option,
567 # keep iterating until we do not evaluate any more
570 while ($prev ne $option) {
571 # Check for recursive evaluations.
572 # 100 deep should be more than enough.
574 die "Over 100 evaluations accurred with $option\n" .
575 "Check for recursive variables\n";
578 $option = __eval_option($option, $i);
585 if (defined($opt{"LOG_FILE"})) {
586 open(OUT, ">> $opt{LOG_FILE}") or die "Can't write to $opt{LOG_FILE}";
593 if (defined($opt{"LOG_FILE"})) {
608 sub wait_for_monitor;
613 # try to reboot normally
614 if (run_command $reboot) {
615 if (defined($powercycle_after_reboot)) {
616 sleep $powercycle_after_reboot;
617 run_command "$power_cycle";
620 # nope? power cycle it.
621 run_command "$power_cycle";
624 if (defined($time)) {
626 wait_for_monitor $time;
634 return $test_type eq "build" ||
635 ($test_type eq "patchcheck" && $opt{"PATCHCHECK_TYPE[$i]"} eq "build") ||
636 ($test_type eq "bisect" && $opt{"BISECT_TYPE[$i]"} eq "build");
640 doprint "CRITICAL FAILURE... ", @_, "\n";
644 if ($reboot_on_error && !do_not_reboot) {
646 doprint "REBOOTING\n";
649 } elsif ($poweroff_on_error && defined($power_off)) {
650 doprint "POWERING OFF\n";
654 if (defined($opt{"LOG_FILE"})) {
655 print " See $opt{LOG_FILE} for more info.\n";
666 my $pid = open($fp, "$console|") or
667 dodie "Can't open console $console";
669 $flags = fcntl($fp, F_GETFL, 0) or
670 dodie "Can't get flags for the socket: $!";
671 $flags = fcntl($fp, F_SETFL, $flags | O_NONBLOCK) or
672 dodie "Can't set flags for the socket: $!";
680 doprint "kill child process $pid\n";
688 if ($monitor_cnt++) {
691 $monitor_fp = \*MONFD;
692 $monitor_pid = open_console $monitor_fp;
696 open(MONFD, "Stop perl from warning about single use of MONFD");
700 if (--$monitor_cnt) {
703 close_console($monitor_fp, $monitor_pid);
706 sub wait_for_monitor {
710 doprint "** Wait for monitor to settle down **\n";
712 # read the monitor and wait for the system to calm down
714 $line = wait_for_input($monitor_fp, $time);
715 print "$line" if (defined($line));
716 } while (defined($line));
717 print "** Monitor flushed **\n";
722 if ($die_on_failure) {
730 # no need to reboot for just building.
731 if (!do_not_reboot) {
732 doprint "REBOOTING\n";
738 if (defined($test_name)) {
739 $name = " ($test_name)";
742 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
743 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
744 doprint "KTEST RESULT: TEST $i$name Failed: ", @_, "\n";
745 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
746 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
748 return 1 if (!defined($store_failures));
751 my $date = sprintf "%04d%02d%02d%02d%02d%02d",
752 1900+$t[5],$t[4],$t[3],$t[2],$t[1],$t[0];
754 my $type = $build_type;
755 if ($type =~ /useconfig/) {
759 my $dir = "$machine-$test_type-$type-fail-$date";
760 my $faildir = "$store_failures/$dir";
764 die "can't create $faildir";
766 if (-f "$output_config") {
767 cp "$output_config", "$faildir/config" or
768 die "failed to copy .config";
771 cp $buildlog, "$faildir/buildlog" or
772 die "failed to move $buildlog";
775 cp $dmesg, "$faildir/dmesg" or
776 die "failed to move $dmesg";
779 doprint "*** Saved info to $faildir ***\n";
790 $command =~ s/\$SSH_USER/$ssh_user/g;
791 $command =~ s/\$MACHINE/$machine/g;
793 doprint("$command ... ");
795 $pid = open(CMD, "$command 2>&1 |") or
796 (fail "unable to exec $command" and return 0);
798 if (defined($opt{"LOG_FILE"})) {
799 open(LOG, ">>$opt{LOG_FILE}") or
800 dodie "failed to write to log";
804 if (defined($redirect)) {
805 open (RD, ">$redirect") or
806 dodie "failed to write to redirect $redirect";
811 print LOG if ($dolog);
819 close(LOG) if ($dolog);
820 close(RD) if ($dord);
833 my $cp_exec = $ssh_exec;
835 $cp_exec =~ s/\$SSH_COMMAND/$cmd/g;
836 return run_command "$cp_exec";
840 my ($src, $dst) = @_;
841 my $cp_scp = $scp_to_target;
843 $cp_scp =~ s/\$SRC_FILE/$src/g;
844 $cp_scp =~ s/\$DST_FILE/$dst/g;
846 return run_command "$cp_scp";
851 if ($reboot_type ne "grub") {
854 return if (defined($grub_number));
856 doprint "Find grub menu ... ";
859 my $ssh_grub = $ssh_exec;
860 $ssh_grub =~ s,\$SSH_COMMAND,cat /boot/grub/menu.lst,g;
862 open(IN, "$ssh_grub |")
863 or die "unable to get menu.lst";
868 if (/^\s*title\s+$grub_menu\s*$/) {
872 } elsif (/^\s*title\s/) {
878 die "Could not find '$grub_menu' in /boot/grub/menu on $machine"
880 doprint "$grub_number\n";
885 my ($fp, $time) = @_;
891 if (!defined($time)) {
896 vec($rin, fileno($fp), 1) = 1;
897 $ready = select($rin, undef, undef, $time);
901 # try to read one char at a time
902 while (sysread $fp, $ch, 1) {
904 last if ($ch eq "\n");
907 if (!length($line)) {
915 if ($reboot_type eq "grub") {
916 run_ssh "'(echo \"savedefault --default=$grub_number --once\" | grub --batch && reboot)'";
920 run_command "$reboot_script";
926 doprint "git rev-list --max-count=1 $commit ... ";
927 my $sha1 = `git rev-list --max-count=1 $commit`;
934 dodie "Failed to get git $commit";
947 my $skip_call_trace = 0;
955 open(DMESG, "> $dmesg") or
956 die "unable to write to $dmesg";
962 my $monitor_start = time;
964 my $version_found = 0;
968 if ($bug && defined($stop_after_failure) &&
969 $stop_after_failure >= 0) {
970 my $time = $stop_after_failure - (time - $failure_start);
971 $line = wait_for_input($monitor_fp, $time);
972 if (!defined($line)) {
973 doprint "bug timed out after $booted_timeout seconds\n";
974 doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
978 $line = wait_for_input($monitor_fp, $booted_timeout);
979 if (!defined($line)) {
980 my $s = $booted_timeout == 1 ? "" : "s";
981 doprint "Successful boot found: break after $booted_timeout second$s\n";
985 $line = wait_for_input($monitor_fp);
986 if (!defined($line)) {
987 my $s = $timeout == 1 ? "" : "s";
988 doprint "Timed out after $timeout second$s\n";
996 # we are not guaranteed to get a full line
999 if ($full_line =~ /$success_line/) {
1001 $success_start = time;
1004 if ($booted && defined($stop_after_success) &&
1005 $stop_after_success >= 0) {
1007 if ($now - $success_start >= $stop_after_success) {
1008 doprint "Test forced to stop after $stop_after_success seconds after success\n";
1013 if ($full_line =~ /\[ backtrace testing \]/) {
1014 $skip_call_trace = 1;
1017 if ($full_line =~ /call trace:/i) {
1018 if (!$bug && !$skip_call_trace) {
1020 $failure_start = time;
1024 if ($bug && defined($stop_after_failure) &&
1025 $stop_after_failure >= 0) {
1027 if ($now - $failure_start >= $stop_after_failure) {
1028 doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
1033 if ($full_line =~ /\[ end of backtrace testing \]/) {
1034 $skip_call_trace = 0;
1037 if ($full_line =~ /Kernel panic -/) {
1038 $failure_start = time;
1042 # Detect triple faults by testing the banner
1043 if ($full_line =~ /\bLinux version (\S+).*\n/) {
1044 if ($1 eq $version) {
1046 } elsif ($version_found && $detect_triplefault) {
1047 # We already booted into the kernel we are testing,
1048 # but now we booted into another kernel?
1049 # Consider this a triple fault.
1050 doprint "Aleady booted in Linux kernel $version, but now\n";
1051 doprint "we booted into Linux kernel $1.\n";
1052 doprint "Assuming that this is a triple fault.\n";
1053 doprint "To disable this: set DETECT_TRIPLE_FAULT to 0\n";
1058 if ($line =~ /\n/) {
1062 if ($stop_test_after > 0 && !$booted && !$bug) {
1063 if (time - $monitor_start > $stop_test_after) {
1064 doprint "STOP_TEST_AFTER ($stop_test_after seconds) timed out\n";
1073 return 0 if ($in_bisect);
1074 fail "failed - got a bug report" and return 0;
1078 return 0 if ($in_bisect);
1079 fail "failed - never got a boot prompt." and return 0;
1085 sub do_post_install {
1087 return if (!defined($post_install));
1089 my $cp_post_install = $post_install;
1090 $cp_post_install =~ s/\$KERNEL_VERSION/$version/g;
1091 run_command "$cp_post_install" or
1092 dodie "Failed to run post install";
1097 run_scp "$outputdir/$build_target", "$target_image" or
1098 dodie "failed to copy image";
1100 my $install_mods = 0;
1102 # should we process modules?
1104 open(IN, "$output_config") or dodie("Can't read config file");
1106 if (/CONFIG_MODULES(=y)?/) {
1107 $install_mods = 1 if (defined($1));
1113 if (!$install_mods) {
1115 doprint "No modules needed\n";
1119 run_command "$make INSTALL_MOD_PATH=$tmpdir modules_install" or
1120 dodie "Failed to install modules";
1122 my $modlib = "/lib/modules/$version";
1123 my $modtar = "ktest-mods.tar.bz2";
1125 run_ssh "rm -rf $modlib" or
1126 dodie "failed to remove old mods: $modlib";
1128 # would be nice if scp -r did not follow symbolic links
1129 run_command "cd $tmpdir && tar -cjf $modtar lib/modules/$version" or
1130 dodie "making tarball";
1132 run_scp "$tmpdir/$modtar", "/tmp" or
1133 dodie "failed to copy modules";
1135 unlink "$tmpdir/$modtar";
1137 run_ssh "'(cd / && tar xjf /tmp/$modtar)'" or
1138 dodie "failed to tar modules";
1140 run_ssh "rm -f /tmp/$modtar";
1146 # get the release name
1147 doprint "$make kernelrelease ... ";
1148 $version = `$make kernelrelease | tail -1`;
1150 doprint "$version\n";
1153 sub start_monitor_and_boot {
1162 sub check_buildlog {
1165 my @files = `git show $patch | diffstat -l`;
1167 open(IN, "git show $patch |") or
1168 dodie "failed to show $patch";
1170 if (m,^--- a/(.*),) {
1172 $files[$#files] = $1;
1177 open(IN, $buildlog) or dodie "Can't open $buildlog";
1179 if (/^\s*(.*?):.*(warning|error)/) {
1181 foreach my $file (@files) {
1182 my $fullpath = "$builddir/$file";
1183 if ($file eq $err || $fullpath eq $err) {
1184 fail "$file built with warnings" and return 0;
1194 sub apply_min_config {
1195 my $outconfig = "$output_config.new";
1197 # Read the config file and remove anything that
1198 # is in the force_config hash (from minconfig and others)
1199 # then add the force config back.
1201 doprint "Applying minimum configurations into $output_config.new\n";
1203 open (OUT, ">$outconfig") or
1204 dodie "Can't create $outconfig";
1206 if (-f $output_config) {
1207 open (IN, $output_config) or
1208 dodie "Failed to open $output_config";
1210 if (/^(# )?(CONFIG_[^\s=]*)/) {
1211 next if (defined($force_config{$2}));
1217 foreach my $config (keys %force_config) {
1218 print OUT "$force_config{$config}\n";
1222 run_command "mv $outconfig $output_config";
1225 sub make_oldconfig {
1227 my @force_list = keys %force_config;
1229 if ($#force_list >= 0) {
1233 if (!run_command "$make oldnoconfig") {
1234 # Perhaps oldnoconfig doesn't exist in this version of the kernel
1235 # try a yes '' | oldconfig
1236 doprint "oldnoconfig failed, trying yes '' | make oldconfig\n";
1237 run_command "yes '' | $make oldconfig" or
1238 dodie "failed make config oldconfig";
1242 # read a config file and use this to force new configs.
1243 sub load_force_config {
1246 open(IN, $config) or
1247 dodie "failed to read $config";
1250 if (/^(CONFIG[^\s=]*)(\s*=.*)/) {
1251 $force_config{$1} = $_;
1252 } elsif (/^# (CONFIG_\S*) is not set/) {
1253 $force_config{$1} = $_;
1264 if (defined($pre_build)) {
1265 my $ret = run_command $pre_build;
1266 if (!$ret && defined($pre_build_die) &&
1268 dodie "failed to pre_build\n";
1272 if ($type =~ /^useconfig:(.*)/) {
1273 run_command "cp $1 $output_config" or
1274 dodie "could not copy $1 to .config";
1276 $type = "oldconfig";
1279 # old config can ask questions
1280 if ($type eq "oldconfig") {
1281 $type = "oldnoconfig";
1283 # allow for empty configs
1284 run_command "touch $output_config";
1287 run_command "mv $output_config $outputdir/config_temp" or
1288 dodie "moving .config";
1290 run_command "$make mrproper" or dodie "make mrproper";
1292 run_command "mv $outputdir/config_temp $output_config" or
1293 dodie "moving config_temp";
1296 } elsif (!$noclean) {
1297 unlink "$output_config";
1298 run_command "$make mrproper" or
1299 dodie "make mrproper";
1302 # add something to distinguish this build
1303 open(OUT, "> $outputdir/localversion") or dodie("Can't make localversion file");
1304 print OUT "$localversion\n";
1307 if (defined($minconfig)) {
1308 load_force_config($minconfig);
1311 if ($type ne "oldnoconfig") {
1312 run_command "$make $type" or
1313 dodie "failed make config";
1315 # Run old config regardless, to enforce min configurations
1318 $redirect = "$buildlog";
1319 my $build_ret = run_command "$make $build_options";
1322 if (defined($post_build)) {
1323 my $ret = run_command $post_build;
1324 if (!$ret && defined($post_build_die) &&
1326 dodie "failed to post_build\n";
1331 # bisect may need this to pass
1332 return 0 if ($in_bisect);
1333 fail "failed build" and return 0;
1340 if (!run_ssh "halt" or defined($power_off)) {
1341 if (defined($poweroff_after_halt)) {
1342 sleep $poweroff_after_halt;
1343 run_command "$power_off";
1347 run_command "$power_off";
1358 if (defined($test_name)) {
1359 $name = " ($test_name)";
1362 doprint "\n\n*******************************************\n";
1363 doprint "*******************************************\n";
1364 doprint "KTEST RESULT: TEST $i$name SUCCESS!!!! **\n";
1365 doprint "*******************************************\n";
1366 doprint "*******************************************\n";
1368 if ($i != $opt{"NUM_TESTS"} && !do_not_reboot) {
1369 doprint "Reboot and wait $sleep_time seconds\n";
1376 doprint "Pass or fail? [p/f]";
1379 if ($ans eq "p" || $ans eq "P") {
1381 } elsif ($ans eq "f" || $ans eq "F") {
1384 print "Please answer 'P' or 'F'\n";
1389 sub child_run_test {
1392 # child should have no power
1393 $reboot_on_error = 0;
1394 $poweroff_on_error = 0;
1395 $die_on_failure = 1;
1397 run_command $run_test or $failed = 1;
1403 sub child_finished {
1416 doprint "run test $run_test\n";
1420 $SIG{CHLD} = qw(child_finished);
1424 child_run_test if (!$child_pid);
1429 $line = wait_for_input($monitor_fp, 1);
1430 if (defined($line)) {
1432 # we are not guaranteed to get a full line
1433 $full_line .= $line;
1436 if ($full_line =~ /call trace:/i) {
1440 if ($full_line =~ /Kernel panic -/) {
1444 if ($line =~ /\n/) {
1448 } while (!$child_done && !$bug);
1451 my $failure_start = time;
1454 $line = wait_for_input($monitor_fp, 1);
1455 if (defined($line)) {
1459 if ($now - $failure_start >= $stop_after_failure) {
1462 } while (defined($line));
1464 doprint "Detected kernel crash!\n";
1465 # kill the child with extreme prejudice
1469 waitpid $child_pid, 0;
1472 if ($bug || $child_exit) {
1473 return 0 if $in_bisect;
1474 fail "test failed" and return 0;
1479 sub run_git_bisect {
1482 doprint "$command ... ";
1484 my $output = `$command 2>&1`;
1491 dodie "Failed to git bisect";
1494 doprint "SUCCESS\n";
1495 if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\))\s+\[([[:xdigit:]]+)\]/) {
1496 doprint "$1 [$2]\n";
1497 } elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) {
1499 doprint "Found bad commit... $1\n";
1502 # we already logged it, just print it now.
1510 doprint "Reboot and sleep $bisect_sleep_time seconds\n";
1511 reboot $bisect_sleep_time;
1514 # returns 1 on success, 0 on failure, -1 on skip
1515 sub run_bisect_test {
1516 my ($type, $buildtype) = @_;
1525 build $buildtype or $failed = 1;
1527 if ($type ne "build") {
1528 if ($failed && $bisect_skip) {
1532 dodie "Failed on build" if $failed;
1535 start_monitor_and_boot or $failed = 1;
1537 if ($type ne "boot") {
1538 if ($failed && $bisect_skip) {
1544 dodie "Failed on boot" if $failed;
1546 do_run_test or $failed = 1;
1557 # reboot the box to a kernel we can ssh to
1558 if ($type ne "build") {
1568 my $buildtype = "oldconfig";
1570 # We should have a minconfig to use?
1571 if (defined($minconfig)) {
1572 $buildtype = "useconfig:$minconfig";
1575 my $ret = run_bisect_test $type, $buildtype;
1577 if ($bisect_manual) {
1578 $ret = answer_bisect;
1581 # Are we looking for where it worked, not failed?
1582 if ($reverse_bisect) {
1588 } elsif ($ret == 0) {
1590 } elsif ($bisect_skip) {
1591 doprint "HIT A BAD COMMIT ... SKIPPING\n";
1601 die "BISECT_GOOD[$i] not defined\n" if (!defined($opt{"BISECT_GOOD[$i]"}));
1602 die "BISECT_BAD[$i] not defined\n" if (!defined($opt{"BISECT_BAD[$i]"}));
1603 die "BISECT_TYPE[$i] not defined\n" if (!defined($opt{"BISECT_TYPE[$i]"}));
1605 my $good = $opt{"BISECT_GOOD[$i]"};
1606 my $bad = $opt{"BISECT_BAD[$i]"};
1607 my $type = $opt{"BISECT_TYPE[$i]"};
1608 my $start = $opt{"BISECT_START[$i]"};
1609 my $replay = $opt{"BISECT_REPLAY[$i]"};
1610 my $start_files = $opt{"BISECT_FILES[$i]"};
1612 if (defined($start_files)) {
1613 $start_files = " -- " . $start_files;
1618 # convert to true sha1's
1619 $good = get_sha1($good);
1620 $bad = get_sha1($bad);
1622 if (defined($opt{"BISECT_REVERSE[$i]"}) &&
1623 $opt{"BISECT_REVERSE[$i]"} == 1) {
1624 doprint "Performing a reverse bisect (bad is good, good is bad!)\n";
1625 $reverse_bisect = 1;
1627 $reverse_bisect = 0;
1630 # Can't have a test without having a test to run
1631 if ($type eq "test" && !defined($run_test)) {
1635 my $check = $opt{"BISECT_CHECK[$i]"};
1636 if (defined($check) && $check ne "0") {
1639 my $head = get_sha1("HEAD");
1641 if ($check ne "good") {
1642 doprint "TESTING BISECT BAD [$bad]\n";
1643 run_command "git checkout $bad" or
1644 die "Failed to checkout $bad";
1646 $result = run_bisect $type;
1648 if ($result ne "bad") {
1649 fail "Tested BISECT_BAD [$bad] and it succeeded" and return 0;
1653 if ($check ne "bad") {
1654 doprint "TESTING BISECT GOOD [$good]\n";
1655 run_command "git checkout $good" or
1656 die "Failed to checkout $good";
1658 $result = run_bisect $type;
1660 if ($result ne "good") {
1661 fail "Tested BISECT_GOOD [$good] and it failed" and return 0;
1665 # checkout where we started
1666 run_command "git checkout $head" or
1667 die "Failed to checkout $head";
1670 run_command "git bisect start$start_files" or
1671 dodie "could not start bisect";
1673 run_command "git bisect good $good" or
1674 dodie "could not set bisect good to $good";
1676 run_git_bisect "git bisect bad $bad" or
1677 dodie "could not set bisect bad to $bad";
1679 if (defined($replay)) {
1680 run_command "git bisect replay $replay" or
1681 dodie "failed to run replay";
1684 if (defined($start)) {
1685 run_command "git checkout $start" or
1686 dodie "failed to checkout $start";
1691 $result = run_bisect $type;
1692 $test = run_git_bisect "git bisect $result";
1695 run_command "git bisect log" or
1696 dodie "could not capture git bisect log";
1698 run_command "git bisect reset" or
1699 dodie "could not reset git bisect";
1701 doprint "Bad commit was [$bisect_bad]\n";
1714 sub assign_configs {
1715 my ($hash, $config) = @_;
1718 or dodie "Failed to read $config";
1721 if (/^((CONFIG\S*)=.*)/) {
1729 sub process_config_ignore {
1732 assign_configs \%config_ignore, $config;
1735 sub read_current_config {
1736 my ($config_ref) = @_;
1738 %{$config_ref} = ();
1739 undef %{$config_ref};
1741 my @key = keys %{$config_ref};
1743 print "did not delete!\n";
1746 open (IN, "$output_config");
1749 if (/^(CONFIG\S+)=(.*)/) {
1750 ${$config_ref}{$1} = $2;
1756 sub get_dependencies {
1759 my $arr = $dependency{$config};
1760 if (!defined($arr)) {
1766 foreach my $dep (@{$arr}) {
1767 print "ADD DEP $dep\n";
1768 @deps = (@deps, get_dependencies $dep);
1777 open(OUT, ">$output_config") or dodie "Can not write to $output_config";
1779 foreach my $config (@configs) {
1780 print OUT "$config_set{$config}\n";
1781 my @deps = get_dependencies $config;
1782 foreach my $dep (@deps) {
1783 print OUT "$config_set{$dep}\n";
1787 foreach my $config (keys %config_ignore) {
1788 print OUT "$config_ignore{$config}\n";
1796 sub compare_configs {
1799 foreach my $item (keys %a) {
1800 if (!defined($b{$item})) {
1801 print "diff $item\n";
1809 print "diff2 $keys[0]\n";
1811 return -1 if ($#keys >= 0);
1816 sub run_config_bisect_test {
1819 return run_bisect_test $type, "oldconfig";
1822 sub process_passed {
1825 doprint "These configs had no failure: (Enabling them for further compiles)\n";
1826 # Passed! All these configs are part of a good compile.
1827 # Add them to the min options.
1828 foreach my $config (keys %configs) {
1829 if (defined($config_list{$config})) {
1830 doprint " removing $config\n";
1831 $config_ignore{$config} = $config_list{$config};
1832 delete $config_list{$config};
1835 doprint "config copied to $outputdir/config_good\n";
1836 run_command "cp -f $output_config $outputdir/config_good";
1839 sub process_failed {
1842 doprint "\n\n***************************************\n";
1843 doprint "Found bad config: $config\n";
1844 doprint "***************************************\n\n";
1847 sub run_config_bisect {
1849 my @start_list = keys %config_list;
1851 if ($#start_list < 0) {
1852 doprint "No more configs to test!!!\n";
1856 doprint "***** RUN TEST ***\n";
1857 my $type = $opt{"CONFIG_BISECT_TYPE[$iteration]"};
1861 my $count = $#start_list + 1;
1862 doprint " $count configs to test\n";
1864 my $half = int($#start_list / 2);
1867 my @tophalf = @start_list[0 .. $half];
1869 create_config @tophalf;
1870 read_current_config \%current_config;
1872 $count = $#tophalf + 1;
1873 doprint "Testing $count configs\n";
1875 # make sure we test something
1876 foreach my $config (@tophalf) {
1877 if (defined($current_config{$config})) {
1883 # try the other half
1884 doprint "Top half produced no set configs, trying bottom half\n";
1885 @tophalf = @start_list[$half + 1 .. $#start_list];
1886 create_config @tophalf;
1887 read_current_config \%current_config;
1888 foreach my $config (@tophalf) {
1889 if (defined($current_config{$config})) {
1895 doprint "Failed: Can't make new config with current configs\n";
1896 foreach my $config (@start_list) {
1897 doprint " CONFIG: $config\n";
1901 $count = $#tophalf + 1;
1902 doprint "Testing $count configs\n";
1905 $ret = run_config_bisect_test $type;
1906 if ($bisect_manual) {
1907 $ret = answer_bisect;
1910 process_passed %current_config;
1914 doprint "This config had a failure.\n";
1915 doprint "Removing these configs that were not set in this config:\n";
1916 doprint "config copied to $outputdir/config_bad\n";
1917 run_command "cp -f $output_config $outputdir/config_bad";
1919 # A config exists in this group that was bad.
1920 foreach my $config (keys %config_list) {
1921 if (!defined($current_config{$config})) {
1922 doprint " removing $config\n";
1923 delete $config_list{$config};
1927 @start_list = @tophalf;
1929 if ($#start_list == 0) {
1930 process_failed $start_list[0];
1934 # remove half the configs we are looking at and see if
1936 $half = int($#start_list / 2);
1937 } while ($#start_list > 0);
1939 # we found a single config, try it again unless we are running manually
1941 if ($bisect_manual) {
1942 process_failed $start_list[0];
1946 my @tophalf = @start_list[0 .. 0];
1948 $ret = run_config_bisect_test $type;
1950 process_passed %current_config;
1954 process_failed $start_list[0];
1961 my $start_config = $opt{"CONFIG_BISECT[$i]"};
1963 my $tmpconfig = "$tmpdir/use_config";
1965 if (defined($config_bisect_good)) {
1966 process_config_ignore $config_bisect_good;
1969 # Make the file with the bad config and the min config
1970 if (defined($minconfig)) {
1971 # read the min config for things to ignore
1972 run_command "cp $minconfig $tmpconfig" or
1973 dodie "failed to copy $minconfig to $tmpconfig";
1978 if (-f $tmpconfig) {
1979 load_force_config($tmpconfig);
1980 process_config_ignore $tmpconfig;
1983 # now process the start config
1984 run_command "cp $start_config $output_config" or
1985 dodie "failed to copy $start_config to $output_config";
1987 # read directly what we want to check
1989 open (IN, $output_config)
1990 or dodie "faied to open $output_config";
1993 if (/^((CONFIG\S*)=.*)/) {
1994 $config_check{$2} = $1;
1999 # Now run oldconfig with the minconfig
2002 # check to see what we lost (or gained)
2003 open (IN, $output_config)
2004 or dodie "Failed to read $start_config";
2006 my %removed_configs;
2010 if (/^((CONFIG\S*)=.*)/) {
2011 # save off all options
2012 $config_set{$2} = $1;
2013 if (defined($config_check{$2})) {
2014 if (defined($config_ignore{$2})) {
2015 $removed_configs{$2} = $1;
2017 $config_list{$2} = $1;
2019 } elsif (!defined($config_ignore{$2})) {
2020 $added_configs{$2} = $1;
2021 $config_list{$2} = $1;
2027 my @confs = keys %removed_configs;
2029 doprint "Configs overridden by default configs and removed from check:\n";
2030 foreach my $config (@confs) {
2031 doprint " $config\n";
2034 @confs = keys %added_configs;
2036 doprint "Configs appearing in make oldconfig and added:\n";
2037 foreach my $config (@confs) {
2038 doprint " $config\n";
2045 # Sometimes kconfig does weird things. We must make sure
2046 # that the config we autocreate has everything we need
2047 # to test, otherwise we may miss testing configs, or
2048 # may not be able to create a new config.
2049 # Here we create a config with everything set.
2050 create_config (keys %config_list);
2051 read_current_config \%config_test;
2052 foreach my $config (keys %config_list) {
2053 if (!defined($config_test{$config})) {
2056 doprint "Configs not produced by kconfig (will not be checked):\n";
2058 doprint " $config\n";
2059 delete $config_list{$config};
2064 $ret = run_config_bisect;
2067 return $ret if ($ret < 0);
2072 sub patchcheck_reboot {
2073 doprint "Reboot and sleep $patchcheck_sleep_time seconds\n";
2074 reboot $patchcheck_sleep_time;
2080 die "PATCHCHECK_START[$i] not defined\n"
2081 if (!defined($opt{"PATCHCHECK_START[$i]"}));
2082 die "PATCHCHECK_TYPE[$i] not defined\n"
2083 if (!defined($opt{"PATCHCHECK_TYPE[$i]"}));
2085 my $start = $opt{"PATCHCHECK_START[$i]"};
2088 if (defined($opt{"PATCHCHECK_END[$i]"})) {
2089 $end = $opt{"PATCHCHECK_END[$i]"};
2092 # Get the true sha1's since we can use things like HEAD~3
2093 $start = get_sha1($start);
2094 $end = get_sha1($end);
2096 my $type = $opt{"PATCHCHECK_TYPE[$i]"};
2098 # Can't have a test without having a test to run
2099 if ($type eq "test" && !defined($run_test)) {
2103 open (IN, "git log --pretty=oneline $end|") or
2104 dodie "could not get git list";
2110 $list[$#list+1] = $_;
2111 last if (/^$start/);
2115 if ($list[$#list] !~ /^$start/) {
2116 fail "SHA1 $start not found";
2119 # go backwards in the list
2120 @list = reverse @list;
2122 my $save_clean = $noclean;
2123 my %ignored_warnings;
2125 if (defined($ignore_warnings)) {
2126 foreach my $sha1 (split /\s+/, $ignore_warnings) {
2127 $ignored_warnings{$sha1} = 1;
2132 foreach my $item (@list) {
2134 $sha1 =~ s/^([[:xdigit:]]+).*/$1/;
2136 doprint "\nProcessing commit $item\n\n";
2138 run_command "git checkout $sha1" or
2139 die "Failed to checkout $sha1";
2141 # only clean on the first and last patch
2142 if ($item eq $list[0] ||
2143 $item eq $list[$#list]) {
2144 $noclean = $save_clean;
2149 if (defined($minconfig)) {
2150 build "useconfig:$minconfig" or return 0;
2152 # ?? no config to use?
2153 build "oldconfig" or return 0;
2157 if (!defined($ignored_warnings{$sha1})) {
2158 check_buildlog $sha1 or return 0;
2161 next if ($type eq "build");
2165 start_monitor_and_boot or $failed = 1;
2167 if (!$failed && $type ne "boot"){
2168 do_run_test or $failed = 1;
2171 return 0 if ($failed);
2189 # taken from streamline_config.pl
2201 if (! -f $kconfig) {
2202 doprint "file $kconfig does not exist, skipping\n";
2206 open(KIN, "$kconfig")
2207 or die "Can't open $kconfig";
2211 # Make sure that lines ending with \ continue
2213 $_ = $line . " " . $_;
2224 # collect any Kconfig sources
2225 if (/^source\s*"(.*)"/) {
2226 $kconfigs[$#kconfigs+1] = $1;
2230 if (/^\s*(menu)?config\s+(\S+)\s*$/) {
2234 for (my $i = 0; $i < $iflevel; $i++) {
2236 $depends{$config} .= " " . $ifdeps[$i];
2238 $depends{$config} = $ifdeps[$i];
2243 # collect the depends for the config
2244 } elsif ($state eq "NEW" && /^\s*depends\s+on\s+(.*)$/) {
2246 if (defined($depends{$1})) {
2247 $depends{$config} .= " " . $1;
2249 $depends{$config} = $1;
2252 # Get the configs that select this config
2253 } elsif ($state ne "NONE" && /^\s*select\s+(\S+)/) {
2254 if (defined($depends{$1})) {
2255 $depends{$1} .= " " . $config;
2257 $depends{$1} = $config;
2260 # Check for if statements
2261 } elsif (/^if\s+(.*\S)\s*$/) {
2263 # remove beginning and ending non text
2264 $deps =~ s/^[^a-zA-Z0-9_]*//;
2265 $deps =~ s/[^a-zA-Z0-9_]*$//;
2267 my @deps = split /[^a-zA-Z0-9_]+/, $deps;
2269 $ifdeps[$iflevel++] = join ':', @deps;
2271 } elsif (/^endif/) {
2273 $iflevel-- if ($iflevel);
2276 } elsif (/^\s*help\s*$/) {
2282 # read in any configs that were found.
2283 foreach $kconfig (@kconfigs) {
2284 if (!defined($read_kconfigs{$kconfig})) {
2285 $read_kconfigs{$kconfig} = 1;
2286 read_kconfig("$builddir/$kconfig");
2292 # find out which arch this is by the kconfig file
2293 open (IN, $output_config)
2294 or dodie "Failed to read $output_config";
2297 if (m,Linux/(\S+)\s+\S+\s+Kernel Configuration,) {
2304 if (!defined($arch)) {
2305 doprint "Could not find arch from config file\n";
2306 doprint "no dependencies used\n";
2310 # arch is really the subarch, we need to know
2311 # what directory to look at.
2312 if ($arch eq "i386" || $arch eq "x86_64") {
2314 } elsif ($arch =~ /^tile/) {
2318 my $kconfig = "$builddir/arch/$arch/Kconfig";
2320 if (! -f $kconfig && $arch =~ /\d$/) {
2322 # some subarchs have numbers, truncate them
2324 $kconfig = "$builddir/arch/$arch/Kconfig";
2325 if (! -f $kconfig) {
2326 doprint "No idea what arch dir $orig is for\n";
2327 doprint "no dependencies used\n";
2332 read_kconfig($kconfig);
2335 sub read_config_list {
2339 or dodie "Failed to read $config";
2342 if (/^((CONFIG\S*)=.*)/) {
2343 if (!defined($config_ignore{$2})) {
2344 $config_list{$2} = $1;
2352 sub read_output_config {
2355 assign_configs \%config_ignore, $config;
2358 sub make_new_config {
2361 open (OUT, ">$output_config")
2362 or dodie "Failed to write $output_config";
2364 foreach my $config (@configs) {
2365 print OUT "$config\n";
2374 $kconfig =~ s/CONFIG_//;
2376 $dep = $depends{"$kconfig"};
2378 # the dep string we have saves the dependencies as they
2379 # were found, including expressions like ! && ||. We
2380 # want to split this out into just an array of configs.
2382 my $valid = "A-Za-z_0-9";
2386 while ($dep =~ /[$valid]/) {
2388 if ($dep =~ /^[^$valid]*([$valid]+)/) {
2389 my $conf = "CONFIG_" . $1;
2391 $configs[$#configs + 1] = $conf;
2393 $dep =~ s/^[^$valid]*[$valid]+//;
2395 die "this should never happen";
2405 my %processed_configs;
2406 my %nochange_config;
2408 sub test_this_config {
2413 # if we already processed this config, skip it
2414 if (defined($processed_configs{$config})) {
2417 $processed_configs{$config} = 1;
2419 # if this config failed during this round, skip it
2420 if (defined($nochange_config{$config})) {
2424 my $kconfig = $config;
2425 $kconfig =~ s/CONFIG_//;
2427 # Test dependencies first
2428 if (defined($depends{"$kconfig"})) {
2429 my @parents = get_depends $config;
2430 foreach my $parent (@parents) {
2431 # if the parent is in the min config, check it first
2432 next if (!defined($min_configs{$parent}));
2433 $found = test_this_config($parent);
2434 if (defined($found)) {
2440 # Remove this config from the list of configs
2441 # do a make oldnoconfig and then read the resulting
2442 # .config to make sure it is missing the config that
2444 my %configs = %min_configs;
2445 delete $configs{$config};
2446 make_new_config ((values %configs), (values %keep_configs));
2449 assign_configs \%configs, $output_config;
2451 return $config if (!defined($configs{$config}));
2453 doprint "disabling config $config did not change .config\n";
2455 $nochange_config{$config} = 1;
2460 sub make_min_config {
2463 if (!defined($output_minconfig)) {
2464 fail "OUTPUT_MIN_CONFIG not defined" and return;
2467 # If output_minconfig exists, and the start_minconfig
2468 # came from min_config, than ask if we should use
2470 if (-f $output_minconfig && !$start_minconfig_defined) {
2471 print "$output_minconfig exists\n";
2472 if (read_yn " Use it as minconfig?") {
2473 $start_minconfig = $output_minconfig;
2477 if (!defined($start_minconfig)) {
2478 fail "START_MIN_CONFIG or MIN_CONFIG not defined" and return;
2481 my $temp_config = "$tmpdir/temp_config";
2483 # First things first. We build an allnoconfig to find
2484 # out what the defaults are that we can't touch.
2485 # Some are selections, but we really can't handle selections.
2487 my $save_minconfig = $minconfig;
2490 run_command "$make allnoconfig" or return 0;
2494 process_config_ignore $output_config;
2496 undef %save_configs;
2499 if (defined($ignore_config)) {
2500 # make sure the file exists
2501 `touch $ignore_config`;
2502 assign_configs \%save_configs, $ignore_config;
2505 %keep_configs = %save_configs;
2507 doprint "Load initial configs from $start_minconfig\n";
2509 # Look at the current min configs, and save off all the
2510 # ones that were set via the allnoconfig
2511 assign_configs \%min_configs, $start_minconfig;
2513 my @config_keys = keys %min_configs;
2515 # Remove anything that was set by the make allnoconfig
2516 # we shouldn't need them as they get set for us anyway.
2517 foreach my $config (@config_keys) {
2518 # Remove anything in the ignore_config
2519 if (defined($keep_configs{$config})) {
2520 my $file = $ignore_config;
2521 $file =~ s,.*/(.*?)$,$1,;
2522 doprint "$config set by $file ... ignored\n";
2523 delete $min_configs{$config};
2526 # But make sure the settings are the same. If a min config
2527 # sets a selection, we do not want to get rid of it if
2528 # it is not the same as what we have. Just move it into
2530 if (defined($config_ignore{$config})) {
2531 if ($config_ignore{$config} ne $min_configs{$config}) {
2532 doprint "$config is in allnoconfig as '$config_ignore{$config}'";
2533 doprint " but it is '$min_configs{$config}' in minconfig .. keeping\n";
2534 $keep_configs{$config} = $min_configs{$config};
2536 doprint "$config set by allnoconfig ... ignored\n";
2538 delete $min_configs{$config};
2550 # Now disable each config one by one and do a make oldconfig
2551 # till we find a config that changes our list.
2553 # Put configs that did not modify the config at the end.
2554 my @test_configs = keys %min_configs;
2556 for (my $i = 0; $i < $#test_configs; $i++) {
2557 if (!defined($nochange_config{$test_configs[0]})) {
2561 # This config didn't change the .config last time.
2562 # Place it at the end
2563 my $config = shift @test_configs;
2564 push @test_configs, $config;
2567 # if every test config has failed to modify the .config file
2568 # in the past, then reset and start over.
2570 undef %nochange_config;
2573 undef %processed_configs;
2575 foreach my $config (@test_configs) {
2577 $found = test_this_config $config;
2579 last if (defined($found));
2581 # oh well, try another config
2584 if (!defined($found)) {
2585 # we could have failed due to the nochange_config hash
2586 # reset and try again
2588 undef %nochange_config;
2592 doprint "No more configs found that we can disable\n";
2600 doprint "Test with $config disabled\n";
2602 # set in_bisect to keep build and monitor from dieing
2607 start_monitor_and_boot or $failed = 1;
2613 doprint "$min_configs{$config} is needed to boot the box... keeping\n";
2614 # this config is needed, add it to the ignore list.
2615 $keep_configs{$config} = $min_configs{$config};
2616 $save_configs{$config} = $min_configs{$config};
2617 delete $min_configs{$config};
2619 # update new ignore configs
2620 if (defined($ignore_config)) {
2621 open (OUT, ">$temp_config")
2622 or die "Can't write to $temp_config";
2623 foreach my $config (keys %save_configs) {
2624 print OUT "$save_configs{$config}\n";
2627 run_command "mv $temp_config $ignore_config" or
2628 dodie "failed to copy update to $ignore_config";
2632 # We booted without this config, remove it from the minconfigs.
2633 doprint "$config is not needed, disabling\n";
2635 delete $min_configs{$config};
2637 # Also disable anything that is not enabled in this config
2639 assign_configs \%configs, $output_config;
2640 my @config_keys = keys %min_configs;
2641 foreach my $config (@config_keys) {
2642 if (!defined($configs{$config})) {
2643 doprint "$config is not set, disabling\n";
2644 delete $min_configs{$config};
2648 # Save off all the current mandidory configs
2649 open (OUT, ">$temp_config")
2650 or die "Can't write to $temp_config";
2651 foreach my $config (keys %keep_configs) {
2652 print OUT "$keep_configs{$config}\n";
2654 foreach my $config (keys %min_configs) {
2655 print OUT "$min_configs{$config}\n";
2659 run_command "mv $temp_config $output_minconfig" or
2660 dodie "failed to copy update to $output_minconfig";
2663 doprint "Reboot and wait $sleep_time seconds\n";
2671 $#ARGV < 1 or die "ktest.pl version: $VERSION\n usage: ktest.pl config-file\n";
2674 $ktest_config = $ARGV[0];
2675 if (! -f $ktest_config) {
2676 print "$ktest_config does not exist.\n";
2677 if (!read_yn "Create it?") {
2682 $ktest_config = "ktest.conf";
2685 if (! -f $ktest_config) {
2686 open(OUT, ">$ktest_config") or die "Can not create $ktest_config";
2688 # Generated by ktest.pl
2690 # Define each test with TEST_START
2691 # The config options below it will override the defaults
2699 read_config $ktest_config;
2701 if (defined($opt{"LOG_FILE"})) {
2702 $opt{"LOG_FILE"} = eval_option($opt{"LOG_FILE"}, -1);
2705 # Append any configs entered in manually to the config file.
2706 my @new_configs = keys %entered_configs;
2707 if ($#new_configs >= 0) {
2708 print "\nAppending entered in configs to $ktest_config\n";
2709 open(OUT, ">>$ktest_config") or die "Can not append to $ktest_config";
2710 foreach my $config (@new_configs) {
2711 print OUT "$config = $entered_configs{$config}\n";
2712 $opt{$config} = $entered_configs{$config};
2716 if ($opt{"CLEAR_LOG"} && defined($opt{"LOG_FILE"})) {
2717 unlink $opt{"LOG_FILE"};
2720 doprint "\n\nSTARTING AUTOMATED TESTS\n\n";
2722 for (my $i = 0, my $repeat = 1; $i <= $opt{"NUM_TESTS"}; $i += $repeat) {
2725 doprint "DEFAULT OPTIONS:\n";
2727 doprint "\nTEST $i OPTIONS";
2728 if (defined($repeat_tests{$i})) {
2729 $repeat = $repeat_tests{$i};
2730 doprint " ITERATE $repeat";
2735 foreach my $option (sort keys %opt) {
2737 if ($option =~ /\[(\d+)\]$/) {
2743 doprint "$option = $opt{$option}\n";
2747 sub __set_test_option {
2748 my ($name, $i) = @_;
2750 my $option = "$name\[$i\]";
2752 if (defined($opt{$option})) {
2753 return $opt{$option};
2756 foreach my $test (keys %repeat_tests) {
2758 $i < $test + $repeat_tests{$test}) {
2759 $option = "$name\[$test\]";
2760 if (defined($opt{$option})) {
2761 return $opt{$option};
2766 if (defined($opt{$name})) {
2773 sub set_test_option {
2774 my ($name, $i) = @_;
2776 my $option = __set_test_option($name, $i);
2777 return $option if (!defined($option));
2779 return eval_option($option, $i);
2782 # First we need to do is the builds
2783 for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
2787 my $makecmd = set_test_option("MAKE_CMD", $i);
2789 $machine = set_test_option("MACHINE", $i);
2790 $ssh_user = set_test_option("SSH_USER", $i);
2791 $tmpdir = set_test_option("TMP_DIR", $i);
2792 $outputdir = set_test_option("OUTPUT_DIR", $i);
2793 $builddir = set_test_option("BUILD_DIR", $i);
2794 $test_type = set_test_option("TEST_TYPE", $i);
2795 $build_type = set_test_option("BUILD_TYPE", $i);
2796 $build_options = set_test_option("BUILD_OPTIONS", $i);
2797 $pre_build = set_test_option("PRE_BUILD", $i);
2798 $post_build = set_test_option("POST_BUILD", $i);
2799 $pre_build_die = set_test_option("PRE_BUILD_DIE", $i);
2800 $post_build_die = set_test_option("POST_BUILD_DIE", $i);
2801 $power_cycle = set_test_option("POWER_CYCLE", $i);
2802 $reboot = set_test_option("REBOOT", $i);
2803 $noclean = set_test_option("BUILD_NOCLEAN", $i);
2804 $minconfig = set_test_option("MIN_CONFIG", $i);
2805 $output_minconfig = set_test_option("OUTPUT_MIN_CONFIG", $i);
2806 $start_minconfig = set_test_option("START_MIN_CONFIG", $i);
2807 $ignore_config = set_test_option("IGNORE_CONFIG", $i);
2808 $run_test = set_test_option("TEST", $i);
2809 $addconfig = set_test_option("ADD_CONFIG", $i);
2810 $reboot_type = set_test_option("REBOOT_TYPE", $i);
2811 $grub_menu = set_test_option("GRUB_MENU", $i);
2812 $post_install = set_test_option("POST_INSTALL", $i);
2813 $reboot_script = set_test_option("REBOOT_SCRIPT", $i);
2814 $reboot_on_error = set_test_option("REBOOT_ON_ERROR", $i);
2815 $poweroff_on_error = set_test_option("POWEROFF_ON_ERROR", $i);
2816 $die_on_failure = set_test_option("DIE_ON_FAILURE", $i);
2817 $power_off = set_test_option("POWER_OFF", $i);
2818 $powercycle_after_reboot = set_test_option("POWERCYCLE_AFTER_REBOOT", $i);
2819 $poweroff_after_halt = set_test_option("POWEROFF_AFTER_HALT", $i);
2820 $sleep_time = set_test_option("SLEEP_TIME", $i);
2821 $bisect_sleep_time = set_test_option("BISECT_SLEEP_TIME", $i);
2822 $patchcheck_sleep_time = set_test_option("PATCHCHECK_SLEEP_TIME", $i);
2823 $ignore_warnings = set_test_option("IGNORE_WARNINGS", $i);
2824 $bisect_manual = set_test_option("BISECT_MANUAL", $i);
2825 $bisect_skip = set_test_option("BISECT_SKIP", $i);
2826 $config_bisect_good = set_test_option("CONFIG_BISECT_GOOD", $i);
2827 $store_failures = set_test_option("STORE_FAILURES", $i);
2828 $test_name = set_test_option("TEST_NAME", $i);
2829 $timeout = set_test_option("TIMEOUT", $i);
2830 $booted_timeout = set_test_option("BOOTED_TIMEOUT", $i);
2831 $console = set_test_option("CONSOLE", $i);
2832 $detect_triplefault = set_test_option("DETECT_TRIPLE_FAULT", $i);
2833 $success_line = set_test_option("SUCCESS_LINE", $i);
2834 $stop_after_success = set_test_option("STOP_AFTER_SUCCESS", $i);
2835 $stop_after_failure = set_test_option("STOP_AFTER_FAILURE", $i);
2836 $stop_test_after = set_test_option("STOP_TEST_AFTER", $i);
2837 $build_target = set_test_option("BUILD_TARGET", $i);
2838 $ssh_exec = set_test_option("SSH_EXEC", $i);
2839 $scp_to_target = set_test_option("SCP_TO_TARGET", $i);
2840 $target_image = set_test_option("TARGET_IMAGE", $i);
2841 $localversion = set_test_option("LOCALVERSION", $i);
2843 $start_minconfig_defined = 1;
2845 if (!defined($start_minconfig)) {
2846 $start_minconfig_defined = 0;
2847 $start_minconfig = $minconfig;
2850 chdir $builddir || die "can't change directory to $builddir";
2852 foreach my $dir ($tmpdir, $outputdir) {
2855 die "can't create $dir";
2859 $ENV{"SSH_USER"} = $ssh_user;
2860 $ENV{"MACHINE"} = $machine;
2862 $target = "$ssh_user\@$machine";
2864 $buildlog = "$tmpdir/buildlog-$machine";
2865 $dmesg = "$tmpdir/dmesg-$machine";
2866 $make = "$makecmd O=$outputdir";
2867 $output_config = "$outputdir/.config";
2869 if ($reboot_type eq "grub") {
2870 dodie "GRUB_MENU not defined" if (!defined($grub_menu));
2871 } elsif (!defined($reboot_script)) {
2872 dodie "REBOOT_SCRIPT not defined"
2875 my $run_type = $build_type;
2876 if ($test_type eq "patchcheck") {
2877 $run_type = $opt{"PATCHCHECK_TYPE[$i]"};
2878 } elsif ($test_type eq "bisect") {
2879 $run_type = $opt{"BISECT_TYPE[$i]"};
2880 } elsif ($test_type eq "config_bisect") {
2881 $run_type = $opt{"CONFIG_BISECT_TYPE[$i]"};
2884 if ($test_type eq "make_min_config") {
2888 # mistake in config file?
2889 if (!defined($run_type)) {
2890 $run_type = "ERROR";
2894 doprint "RUNNING TEST $i of $opt{NUM_TESTS} with option $test_type $run_type\n\n";
2899 if (defined($addconfig)) {
2900 my $min = $minconfig;
2901 if (!defined($minconfig)) {
2904 run_command "cat $addconfig $min > $tmpdir/add_config" or
2905 dodie "Failed to create temp config";
2906 $minconfig = "$tmpdir/add_config";
2909 my $checkout = $opt{"CHECKOUT[$i]"};
2910 if (defined($checkout)) {
2911 run_command "git checkout $checkout" or
2912 die "failed to checkout $checkout";
2915 if ($test_type eq "bisect") {
2918 } elsif ($test_type eq "config_bisect") {
2921 } elsif ($test_type eq "patchcheck") {
2924 } elsif ($test_type eq "make_min_config") {
2929 if ($build_type ne "nobuild") {
2930 build $build_type or next;
2933 if ($test_type eq "install") {
2940 if ($test_type ne "build") {
2942 start_monitor_and_boot or $failed = 1;
2944 if (!$failed && $test_type ne "boot" && defined($run_test)) {
2945 do_run_test or $failed = 1;
2954 if ($opt{"POWEROFF_ON_SUCCESS"}) {
2956 } elsif ($opt{"REBOOT_ON_SUCCESS"} && !do_not_reboot) {
2960 doprint "\n $successes of $opt{NUM_TESTS} tests were successful\n\n";