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;
98 my $config_bisect_good;
99 my $in_patchcheck = 0;
108 my $bisect_sleep_time;
109 my $patchcheck_sleep_time;
115 my $detect_triplefault;
118 my $stop_after_success;
119 my $stop_after_failure;
132 $config_help{"MACHINE"} = << "EOF"
133 The machine hostname that you will test.
136 $config_help{"SSH_USER"} = << "EOF"
137 The box is expected to have ssh on normal bootup, provide the user
138 (most likely root, since you need privileged operations)
141 $config_help{"BUILD_DIR"} = << "EOF"
142 The directory that contains the Linux source code (full path).
145 $config_help{"OUTPUT_DIR"} = << "EOF"
146 The directory that the objects will be built (full path).
147 (can not be same as BUILD_DIR)
150 $config_help{"BUILD_TARGET"} = << "EOF"
151 The location of the compiled file to copy to the target.
152 (relative to OUTPUT_DIR)
155 $config_help{"TARGET_IMAGE"} = << "EOF"
156 The place to put your image on the test machine.
159 $config_help{"POWER_CYCLE"} = << "EOF"
160 A script or command to reboot the box.
162 Here is a digital loggers power switch example
163 POWER_CYCLE = wget --no-proxy -O /dev/null -q --auth-no-challenge 'http://admin:admin\@power/outlet?5=CCL'
165 Here is an example to reboot a virtual box on the current host
166 with the name "Guest".
167 POWER_CYCLE = virsh destroy Guest; sleep 5; virsh start Guest
170 $config_help{"CONSOLE"} = << "EOF"
171 The script or command that reads the console
173 If you use ttywatch server, something like the following would work.
174 CONSOLE = nc -d localhost 3001
176 For a virtual machine with guest name "Guest".
177 CONSOLE = virsh console Guest
180 $config_help{"LOCALVERSION"} = << "EOF"
181 Required version ending to differentiate the test
182 from other linux builds on the system.
185 $config_help{"REBOOT_TYPE"} = << "EOF"
186 Way to reboot the box to the test kernel.
187 Only valid options so far are "grub" and "script".
189 If you specify grub, it will assume grub version 1
190 and will search in /boot/grub/menu.lst for the title \$GRUB_MENU
191 and select that target to reboot to the kernel. If this is not
192 your setup, then specify "script" and have a command or script
193 specified in REBOOT_SCRIPT to boot to the target.
195 The entry in /boot/grub/menu.lst must be entered in manually.
196 The test will not modify that file.
199 $config_help{"GRUB_MENU"} = << "EOF"
200 The grub title name for the test kernel to boot
201 (Only mandatory if REBOOT_TYPE = grub)
203 Note, ktest.pl will not update the grub menu.lst, you need to
204 manually add an option for the test. ktest.pl will search
205 the grub menu.lst for this option to find what kernel to
208 For example, if in the /boot/grub/menu.lst the test kernel title has:
211 GRUB_MENU = Test Kernel
214 $config_help{"REBOOT_SCRIPT"} = << "EOF"
215 A script to reboot the target into the test kernel
216 (Only mandatory if REBOOT_TYPE = script)
221 sub get_ktest_config {
224 return if (defined($opt{$config}));
226 if (defined($config_help{$config})) {
228 print $config_help{$config};
233 if (defined($default{$config})) {
234 print "\[$default{$config}\] ";
236 $entered_configs{$config} = <STDIN>;
237 $entered_configs{$config} =~ s/^\s*(.*\S)\s*$/$1/;
238 if ($entered_configs{$config} =~ /^\s*$/) {
239 if ($default{$config}) {
240 $entered_configs{$config} = $default{$config};
242 print "Your answer can not be blank\n";
250 sub get_ktest_configs {
251 get_ktest_config("MACHINE");
252 get_ktest_config("SSH_USER");
253 get_ktest_config("BUILD_DIR");
254 get_ktest_config("OUTPUT_DIR");
255 get_ktest_config("BUILD_TARGET");
256 get_ktest_config("TARGET_IMAGE");
257 get_ktest_config("POWER_CYCLE");
258 get_ktest_config("CONSOLE");
259 get_ktest_config("LOCALVERSION");
261 my $rtype = $opt{"REBOOT_TYPE"};
263 if (!defined($rtype)) {
264 if (!defined($opt{"GRUB_MENU"})) {
265 get_ktest_config("REBOOT_TYPE");
266 $rtype = $entered_configs{"REBOOT_TYPE"};
272 if ($rtype eq "grub") {
273 get_ktest_config("GRUB_MENU");
275 get_ktest_config("REBOOT_SCRIPT");
279 sub process_variables {
283 # We want to check for '\', and it is just easier
284 # to check the previous characet of '$' and not need
285 # to worry if '$' is the first character. By adding
286 # a space to $value, we can just check [^\\]\$ and
287 # it will still work.
290 while ($value =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) {
294 # append beginning of value to retval
295 $retval = "$retval$begin";
296 if (defined($variable{$var})) {
297 $retval = "$retval$variable{$var}";
299 # put back the origin piece.
300 $retval = "$retval\$\{$var\}";
304 $retval = "$retval$value";
306 # remove the space added in the beginning
313 my ($lvalue, $rvalue) = @_;
315 if (defined($opt{$lvalue})) {
316 die "Error: Option $lvalue defined more than once!\n";
318 if ($rvalue =~ /^\s*$/) {
319 delete $opt{$lvalue};
321 $rvalue = process_variables($rvalue);
322 $opt{$lvalue} = $rvalue;
327 my ($lvalue, $rvalue) = @_;
329 if ($rvalue =~ /^\s*$/) {
330 delete $variable{$lvalue};
332 $rvalue = process_variables($rvalue);
333 $variable{$lvalue} = $rvalue;
340 open(IN, $config) || die "can't read file $config";
343 $name =~ s,.*/(.*),$1,;
348 my $num_tests_set = 0;
355 # ignore blank lines and comments
356 next if (/^\s*$/ || /\s*\#/);
358 if (/^\s*TEST_START(.*)/) {
362 if ($num_tests_set) {
363 die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
366 my $old_test_num = $test_num;
367 my $old_repeat = $repeat;
369 $test_num += $repeat;
373 if ($rest =~ /\s+SKIP(.*)/) {
381 if ($rest =~ /\s+ITERATE\s+(\d+)(.*)$/) {
384 $repeat_tests{"$test_num"} = $repeat;
387 if ($rest =~ /\s+SKIP(.*)/) {
392 if ($rest !~ /^\s*$/) {
393 die "$name: $.: Gargbage found after TEST_START\n$_";
397 $test_num = $old_test_num;
398 $repeat = $old_repeat;
401 } elsif (/^\s*DEFAULTS(.*)$/) {
406 if ($rest =~ /\s+SKIP(.*)/) {
413 if ($rest !~ /^\s*$/) {
414 die "$name: $.: Gargbage found after DEFAULTS\n$_";
417 } elsif (/^\s*([A-Z_\[\]\d]+)\s*=\s*(.*?)\s*$/) {
425 ($lvalue eq "NUM_TESTS" ||
426 $lvalue eq "LOG_FILE" ||
427 $lvalue eq "CLEAR_LOG")) {
428 die "$name: $.: $lvalue must be set in DEFAULTS section\n";
431 if ($lvalue eq "NUM_TESTS") {
433 die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
436 die "$name: $.: NUM_TESTS must be set in default section\n";
441 if ($default || $lvalue =~ /\[\d+\]$/) {
442 set_value($lvalue, $rvalue);
444 my $val = "$lvalue\[$test_num\]";
445 set_value($val, $rvalue);
448 $repeats{$val} = $repeat;
451 } elsif (/^\s*([A-Z_\[\]\d]+)\s*:=\s*(.*?)\s*$/) {
457 # process config variables.
458 # Config variables are only active while reading the
459 # config and can be defined anywhere. They also ignore
460 # TEST_START and DEFAULTS, but are skipped if they are in
461 # on of these sections that have SKIP defined.
462 # The save variable can be
463 # defined multiple times and the new one simply overrides
465 set_variable($lvalue, $rvalue);
468 die "$name: $.: Garbage found in config\n$_";
475 $test_num += $repeat - 1;
476 $opt{"NUM_TESTS"} = $test_num;
479 # make sure we have all mandatory configs
482 # was a test specified?
484 print "No test case specified.\n";
485 print "What test case would you like to run?\n";
488 $default{"TEST_TYPE"} = $ans;
493 foreach my $default (keys %default) {
494 if (!defined($opt{$default})) {
495 $opt{$default} = $default{$default};
501 my ($option, $i) = @_;
503 # Add space to evaluate the character before $
504 $option = " $option";
507 while ($option =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) {
512 # Append beginning of line
513 $retval = "$retval$start";
515 # If the iteration option OPT[$i] exists, then use that.
516 # otherwise see if the default OPT (without [$i]) exists.
518 my $o = "$var\[$i\]";
520 if (defined($opt{$o})) {
522 $retval = "$retval$o";
523 } elsif (defined($opt{$var})) {
525 $retval = "$retval$o";
527 $retval = "$retval\$\{$var\}";
533 $retval = "$retval$option";
541 my ($option, $i) = @_;
545 # Since an option can evaluate to another option,
546 # keep iterating until we do not evaluate any more
549 while ($prev ne $option) {
550 # Check for recursive evaluations.
551 # 100 deep should be more than enough.
553 die "Over 100 evaluations accurred with $option\n" .
554 "Check for recursive variables\n";
557 $option = __eval_option($option, $i);
564 if (defined($opt{"LOG_FILE"})) {
565 open(OUT, ">> $opt{LOG_FILE}") or die "Can't write to $opt{LOG_FILE}";
572 if (defined($opt{"LOG_FILE"})) {
587 # try to reboot normally
588 if (run_command $reboot) {
589 if (defined($powercycle_after_reboot)) {
590 sleep $powercycle_after_reboot;
591 run_command "$power_cycle";
594 # nope? power cycle it.
595 run_command "$power_cycle";
602 return $test_type eq "build" ||
603 ($test_type eq "patchcheck" && $opt{"PATCHCHECK_TYPE[$i]"} eq "build") ||
604 ($test_type eq "bisect" && $opt{"BISECT_TYPE[$i]"} eq "build");
608 doprint "CRITICAL FAILURE... ", @_, "\n";
612 if ($reboot_on_error && !do_not_reboot) {
614 doprint "REBOOTING\n";
617 } elsif ($poweroff_on_error && defined($power_off)) {
618 doprint "POWERING OFF\n";
622 if (defined($opt{"LOG_FILE"})) {
623 print " See $opt{LOG_FILE} for more info.\n";
634 my $pid = open($fp, "$console|") or
635 dodie "Can't open console $console";
637 $flags = fcntl($fp, F_GETFL, 0) or
638 dodie "Can't get flags for the socket: $!";
639 $flags = fcntl($fp, F_SETFL, $flags | O_NONBLOCK) or
640 dodie "Can't set flags for the socket: $!";
648 doprint "kill child process $pid\n";
656 if ($monitor_cnt++) {
659 $monitor_fp = \*MONFD;
660 $monitor_pid = open_console $monitor_fp;
664 open(MONFD, "Stop perl from warning about single use of MONFD");
668 if (--$monitor_cnt) {
671 close_console($monitor_fp, $monitor_pid);
674 sub wait_for_monitor {
678 doprint "** Wait for monitor to settle down **\n";
680 # read the monitor and wait for the system to calm down
682 $line = wait_for_input($monitor_fp, $time);
683 print "$line" if (defined($line));
684 } while (defined($line));
685 print "** Monitor flushed **\n";
690 if ($die_on_failure) {
698 # no need to reboot for just building.
699 if (!do_not_reboot) {
700 doprint "REBOOTING\n";
703 wait_for_monitor $sleep_time;
709 if (defined($test_name)) {
710 $name = " ($test_name)";
713 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
714 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
715 doprint "KTEST RESULT: TEST $i$name Failed: ", @_, "\n";
716 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
717 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
719 return 1 if (!defined($store_failures));
722 my $date = sprintf "%04d%02d%02d%02d%02d%02d",
723 1900+$t[5],$t[4],$t[3],$t[2],$t[1],$t[0];
725 my $type = $build_type;
726 if ($type =~ /useconfig/) {
730 my $dir = "$machine-$test_type-$type-fail-$date";
731 my $faildir = "$store_failures/$dir";
735 die "can't create $faildir";
737 if (-f "$output_config") {
738 cp "$output_config", "$faildir/config" or
739 die "failed to copy .config";
742 cp $buildlog, "$faildir/buildlog" or
743 die "failed to move $buildlog";
746 cp $dmesg, "$faildir/dmesg" or
747 die "failed to move $dmesg";
750 doprint "*** Saved info to $faildir ***\n";
761 $command =~ s/\$SSH_USER/$ssh_user/g;
762 $command =~ s/\$MACHINE/$machine/g;
764 doprint("$command ... ");
766 $pid = open(CMD, "$command 2>&1 |") or
767 (fail "unable to exec $command" and return 0);
769 if (defined($opt{"LOG_FILE"})) {
770 open(LOG, ">>$opt{LOG_FILE}") or
771 dodie "failed to write to log";
775 if (defined($redirect)) {
776 open (RD, ">$redirect") or
777 dodie "failed to write to redirect $redirect";
782 print LOG if ($dolog);
790 close(LOG) if ($dolog);
791 close(RD) if ($dord);
804 my $cp_exec = $ssh_exec;
806 $cp_exec =~ s/\$SSH_COMMAND/$cmd/g;
807 return run_command "$cp_exec";
811 my ($src, $dst) = @_;
812 my $cp_scp = $scp_to_target;
814 $cp_scp =~ s/\$SRC_FILE/$src/g;
815 $cp_scp =~ s/\$DST_FILE/$dst/g;
817 return run_command "$cp_scp";
822 if ($reboot_type ne "grub") {
825 return if (defined($grub_number));
827 doprint "Find grub menu ... ";
830 my $ssh_grub = $ssh_exec;
831 $ssh_grub =~ s,\$SSH_COMMAND,cat /boot/grub/menu.lst,g;
833 open(IN, "$ssh_grub |")
834 or die "unable to get menu.lst";
837 if (/^\s*title\s+$grub_menu\s*$/) {
840 } elsif (/^\s*title\s/) {
846 die "Could not find '$grub_menu' in /boot/grub/menu on $machine"
847 if ($grub_number < 0);
848 doprint "$grub_number\n";
853 my ($fp, $time) = @_;
859 if (!defined($time)) {
864 vec($rin, fileno($fp), 1) = 1;
865 $ready = select($rin, undef, undef, $time);
869 # try to read one char at a time
870 while (sysread $fp, $ch, 1) {
872 last if ($ch eq "\n");
875 if (!length($line)) {
883 if ($reboot_type eq "grub") {
884 run_ssh "'(echo \"savedefault --default=$grub_number --once\" | grub --batch && reboot)'";
888 run_command "$reboot_script";
894 doprint "git rev-list --max-count=1 $commit ... ";
895 my $sha1 = `git rev-list --max-count=1 $commit`;
902 dodie "Failed to get git $commit";
915 my $skip_call_trace = 0;
923 open(DMESG, "> $dmesg") or
924 die "unable to write to $dmesg";
930 my $monitor_start = time;
932 my $version_found = 0;
936 if ($bug && defined($stop_after_failure) &&
937 $stop_after_failure >= 0) {
938 my $time = $stop_after_failure - (time - $failure_start);
939 $line = wait_for_input($monitor_fp, $time);
940 if (!defined($line)) {
941 doprint "bug timed out after $booted_timeout seconds\n";
942 doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
946 $line = wait_for_input($monitor_fp, $booted_timeout);
947 if (!defined($line)) {
948 my $s = $booted_timeout == 1 ? "" : "s";
949 doprint "Successful boot found: break after $booted_timeout second$s\n";
953 $line = wait_for_input($monitor_fp);
954 if (!defined($line)) {
955 my $s = $timeout == 1 ? "" : "s";
956 doprint "Timed out after $timeout second$s\n";
964 # we are not guaranteed to get a full line
967 if ($full_line =~ /$success_line/) {
969 $success_start = time;
972 if ($booted && defined($stop_after_success) &&
973 $stop_after_success >= 0) {
975 if ($now - $success_start >= $stop_after_success) {
976 doprint "Test forced to stop after $stop_after_success seconds after success\n";
981 if ($full_line =~ /\[ backtrace testing \]/) {
982 $skip_call_trace = 1;
985 if ($full_line =~ /call trace:/i) {
986 if (!$bug && !$skip_call_trace) {
988 $failure_start = time;
992 if ($bug && defined($stop_after_failure) &&
993 $stop_after_failure >= 0) {
995 if ($now - $failure_start >= $stop_after_failure) {
996 doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
1001 if ($full_line =~ /\[ end of backtrace testing \]/) {
1002 $skip_call_trace = 0;
1005 if ($full_line =~ /Kernel panic -/) {
1006 $failure_start = time;
1010 # Detect triple faults by testing the banner
1011 if ($full_line =~ /\bLinux version (\S+).*\n/) {
1012 if ($1 eq $version) {
1014 } elsif ($version_found && $detect_triplefault) {
1015 # We already booted into the kernel we are testing,
1016 # but now we booted into another kernel?
1017 # Consider this a triple fault.
1018 doprint "Aleady booted in Linux kernel $version, but now\n";
1019 doprint "we booted into Linux kernel $1.\n";
1020 doprint "Assuming that this is a triple fault.\n";
1021 doprint "To disable this: set DETECT_TRIPLE_FAULT to 0\n";
1026 if ($line =~ /\n/) {
1030 if ($stop_test_after > 0 && !$booted && !$bug) {
1031 if (time - $monitor_start > $stop_test_after) {
1032 doprint "STOP_TEST_AFTER ($stop_test_after seconds) timed out\n";
1041 return 0 if ($in_bisect);
1042 fail "failed - got a bug report" and return 0;
1046 return 0 if ($in_bisect);
1047 fail "failed - never got a boot prompt." and return 0;
1053 sub do_post_install {
1055 return if (!defined($post_install));
1057 my $cp_post_install = $post_install;
1058 $cp_post_install =~ s/\$KERNEL_VERSION/$version/g;
1059 run_command "$cp_post_install" or
1060 dodie "Failed to run post install";
1065 run_scp "$outputdir/$build_target", "$target_image" or
1066 dodie "failed to copy image";
1068 my $install_mods = 0;
1070 # should we process modules?
1072 open(IN, "$output_config") or dodie("Can't read config file");
1074 if (/CONFIG_MODULES(=y)?/) {
1075 $install_mods = 1 if (defined($1));
1081 if (!$install_mods) {
1083 doprint "No modules needed\n";
1087 run_command "$make INSTALL_MOD_PATH=$tmpdir modules_install" or
1088 dodie "Failed to install modules";
1090 my $modlib = "/lib/modules/$version";
1091 my $modtar = "ktest-mods.tar.bz2";
1093 run_ssh "rm -rf $modlib" or
1094 dodie "failed to remove old mods: $modlib";
1096 # would be nice if scp -r did not follow symbolic links
1097 run_command "cd $tmpdir && tar -cjf $modtar lib/modules/$version" or
1098 dodie "making tarball";
1100 run_scp "$tmpdir/$modtar", "/tmp" or
1101 dodie "failed to copy modules";
1103 unlink "$tmpdir/$modtar";
1105 run_ssh "'(cd / && tar xjf /tmp/$modtar)'" or
1106 dodie "failed to tar modules";
1108 run_ssh "rm -f /tmp/$modtar";
1114 # get the release name
1115 doprint "$make kernelrelease ... ";
1116 $version = `$make kernelrelease | tail -1`;
1118 doprint "$version\n";
1121 sub start_monitor_and_boot {
1130 sub check_buildlog {
1133 my @files = `git show $patch | diffstat -l`;
1135 open(IN, "git show $patch |") or
1136 dodie "failed to show $patch";
1138 if (m,^--- a/(.*),) {
1140 $files[$#files] = $1;
1145 open(IN, $buildlog) or dodie "Can't open $buildlog";
1147 if (/^\s*(.*?):.*(warning|error)/) {
1149 foreach my $file (@files) {
1150 my $fullpath = "$builddir/$file";
1151 if ($file eq $err || $fullpath eq $err) {
1152 fail "$file built with warnings" and return 0;
1162 sub apply_min_config {
1163 my $outconfig = "$output_config.new";
1165 # Read the config file and remove anything that
1166 # is in the force_config hash (from minconfig and others)
1167 # then add the force config back.
1169 doprint "Applying minimum configurations into $output_config.new\n";
1171 open (OUT, ">$outconfig") or
1172 dodie "Can't create $outconfig";
1174 if (-f $output_config) {
1175 open (IN, $output_config) or
1176 dodie "Failed to open $output_config";
1178 if (/^(# )?(CONFIG_[^\s=]*)/) {
1179 next if (defined($force_config{$2}));
1185 foreach my $config (keys %force_config) {
1186 print OUT "$force_config{$config}\n";
1190 run_command "mv $outconfig $output_config";
1193 sub make_oldconfig {
1195 my @force_list = keys %force_config;
1197 if ($#force_list >= 0) {
1201 if (!run_command "$make oldnoconfig") {
1202 # Perhaps oldnoconfig doesn't exist in this version of the kernel
1203 # try a yes '' | oldconfig
1204 doprint "oldnoconfig failed, trying yes '' | make oldconfig\n";
1205 run_command "yes '' | $make oldconfig" or
1206 dodie "failed make config oldconfig";
1210 # read a config file and use this to force new configs.
1211 sub load_force_config {
1214 open(IN, $config) or
1215 dodie "failed to read $config";
1218 if (/^(CONFIG[^\s=]*)(\s*=.*)/) {
1219 $force_config{$1} = $_;
1220 } elsif (/^# (CONFIG_\S*) is not set/) {
1221 $force_config{$1} = $_;
1232 if (defined($pre_build)) {
1233 my $ret = run_command $pre_build;
1234 if (!$ret && defined($pre_build_die) &&
1236 dodie "failed to pre_build\n";
1240 if ($type =~ /^useconfig:(.*)/) {
1241 run_command "cp $1 $output_config" or
1242 dodie "could not copy $1 to .config";
1244 $type = "oldconfig";
1247 # old config can ask questions
1248 if ($type eq "oldconfig") {
1249 $type = "oldnoconfig";
1251 # allow for empty configs
1252 run_command "touch $output_config";
1254 run_command "mv $output_config $outputdir/config_temp" or
1255 dodie "moving .config";
1257 if (!$noclean && !run_command "$make mrproper") {
1258 dodie "make mrproper";
1261 run_command "mv $outputdir/config_temp $output_config" or
1262 dodie "moving config_temp";
1264 } elsif (!$noclean) {
1265 unlink "$output_config";
1266 run_command "$make mrproper" or
1267 dodie "make mrproper";
1270 # add something to distinguish this build
1271 open(OUT, "> $outputdir/localversion") or dodie("Can't make localversion file");
1272 print OUT "$localversion\n";
1275 if (defined($minconfig)) {
1276 load_force_config($minconfig);
1279 if ($type ne "oldnoconfig") {
1280 run_command "$make $type" or
1281 dodie "failed make config";
1283 # Run old config regardless, to enforce min configurations
1286 $redirect = "$buildlog";
1287 my $build_ret = run_command "$make $build_options";
1290 if (defined($post_build)) {
1291 my $ret = run_command $post_build;
1292 if (!$ret && defined($post_build_die) &&
1294 dodie "failed to post_build\n";
1299 # bisect may need this to pass
1300 return 0 if ($in_bisect);
1301 fail "failed build" and return 0;
1308 if (!run_ssh "halt" or defined($power_off)) {
1309 if (defined($poweroff_after_halt)) {
1310 sleep $poweroff_after_halt;
1311 run_command "$power_off";
1315 run_command "$power_off";
1326 if (defined($test_name)) {
1327 $name = " ($test_name)";
1330 doprint "\n\n*******************************************\n";
1331 doprint "*******************************************\n";
1332 doprint "KTEST RESULT: TEST $i$name SUCCESS!!!! **\n";
1333 doprint "*******************************************\n";
1334 doprint "*******************************************\n";
1336 if ($i != $opt{"NUM_TESTS"} && !do_not_reboot) {
1337 doprint "Reboot and wait $sleep_time seconds\n";
1340 wait_for_monitor $sleep_time;
1347 doprint "Pass or fail? [p/f]";
1350 if ($ans eq "p" || $ans eq "P") {
1352 } elsif ($ans eq "f" || $ans eq "F") {
1355 print "Please answer 'P' or 'F'\n";
1360 sub child_run_test {
1363 # child should have no power
1364 $reboot_on_error = 0;
1365 $poweroff_on_error = 0;
1366 $die_on_failure = 1;
1368 run_command $run_test or $failed = 1;
1374 sub child_finished {
1387 doprint "run test $run_test\n";
1391 $SIG{CHLD} = qw(child_finished);
1395 child_run_test if (!$child_pid);
1400 $line = wait_for_input($monitor_fp, 1);
1401 if (defined($line)) {
1403 # we are not guaranteed to get a full line
1404 $full_line .= $line;
1407 if ($full_line =~ /call trace:/i) {
1411 if ($full_line =~ /Kernel panic -/) {
1415 if ($line =~ /\n/) {
1419 } while (!$child_done && !$bug);
1422 my $failure_start = time;
1425 $line = wait_for_input($monitor_fp, 1);
1426 if (defined($line)) {
1430 if ($now - $failure_start >= $stop_after_failure) {
1433 } while (defined($line));
1435 doprint "Detected kernel crash!\n";
1436 # kill the child with extreme prejudice
1440 waitpid $child_pid, 0;
1443 if ($bug || $child_exit) {
1444 return 0 if $in_bisect;
1445 fail "test failed" and return 0;
1450 sub run_git_bisect {
1453 doprint "$command ... ";
1455 my $output = `$command 2>&1`;
1462 dodie "Failed to git bisect";
1465 doprint "SUCCESS\n";
1466 if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\))\s+\[([[:xdigit:]]+)\]/) {
1467 doprint "$1 [$2]\n";
1468 } elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) {
1470 doprint "Found bad commit... $1\n";
1473 # we already logged it, just print it now.
1481 doprint "Reboot and sleep $bisect_sleep_time seconds\n";
1484 wait_for_monitor $bisect_sleep_time;
1488 # returns 1 on success, 0 on failure, -1 on skip
1489 sub run_bisect_test {
1490 my ($type, $buildtype) = @_;
1499 build $buildtype or $failed = 1;
1501 if ($type ne "build") {
1502 if ($failed && $bisect_skip) {
1506 dodie "Failed on build" if $failed;
1509 start_monitor_and_boot or $failed = 1;
1511 if ($type ne "boot") {
1512 if ($failed && $bisect_skip) {
1518 dodie "Failed on boot" if $failed;
1520 do_run_test or $failed = 1;
1531 # reboot the box to a kernel we can ssh to
1532 if ($type ne "build") {
1542 my $buildtype = "oldconfig";
1544 # We should have a minconfig to use?
1545 if (defined($minconfig)) {
1546 $buildtype = "useconfig:$minconfig";
1549 my $ret = run_bisect_test $type, $buildtype;
1551 if ($bisect_manual) {
1552 $ret = answer_bisect;
1555 # Are we looking for where it worked, not failed?
1556 if ($reverse_bisect) {
1562 } elsif ($ret == 0) {
1564 } elsif ($bisect_skip) {
1565 doprint "HIT A BAD COMMIT ... SKIPPING\n";
1575 die "BISECT_GOOD[$i] not defined\n" if (!defined($opt{"BISECT_GOOD[$i]"}));
1576 die "BISECT_BAD[$i] not defined\n" if (!defined($opt{"BISECT_BAD[$i]"}));
1577 die "BISECT_TYPE[$i] not defined\n" if (!defined($opt{"BISECT_TYPE[$i]"}));
1579 my $good = $opt{"BISECT_GOOD[$i]"};
1580 my $bad = $opt{"BISECT_BAD[$i]"};
1581 my $type = $opt{"BISECT_TYPE[$i]"};
1582 my $start = $opt{"BISECT_START[$i]"};
1583 my $replay = $opt{"BISECT_REPLAY[$i]"};
1584 my $start_files = $opt{"BISECT_FILES[$i]"};
1586 if (defined($start_files)) {
1587 $start_files = " -- " . $start_files;
1592 # convert to true sha1's
1593 $good = get_sha1($good);
1594 $bad = get_sha1($bad);
1596 if (defined($opt{"BISECT_REVERSE[$i]"}) &&
1597 $opt{"BISECT_REVERSE[$i]"} == 1) {
1598 doprint "Performing a reverse bisect (bad is good, good is bad!)\n";
1599 $reverse_bisect = 1;
1601 $reverse_bisect = 0;
1604 # Can't have a test without having a test to run
1605 if ($type eq "test" && !defined($run_test)) {
1609 my $check = $opt{"BISECT_CHECK[$i]"};
1610 if (defined($check) && $check ne "0") {
1613 my $head = get_sha1("HEAD");
1615 if ($check ne "good") {
1616 doprint "TESTING BISECT BAD [$bad]\n";
1617 run_command "git checkout $bad" or
1618 die "Failed to checkout $bad";
1620 $result = run_bisect $type;
1622 if ($result ne "bad") {
1623 fail "Tested BISECT_BAD [$bad] and it succeeded" and return 0;
1627 if ($check ne "bad") {
1628 doprint "TESTING BISECT GOOD [$good]\n";
1629 run_command "git checkout $good" or
1630 die "Failed to checkout $good";
1632 $result = run_bisect $type;
1634 if ($result ne "good") {
1635 fail "Tested BISECT_GOOD [$good] and it failed" and return 0;
1639 # checkout where we started
1640 run_command "git checkout $head" or
1641 die "Failed to checkout $head";
1644 run_command "git bisect start$start_files" or
1645 dodie "could not start bisect";
1647 run_command "git bisect good $good" or
1648 dodie "could not set bisect good to $good";
1650 run_git_bisect "git bisect bad $bad" or
1651 dodie "could not set bisect bad to $bad";
1653 if (defined($replay)) {
1654 run_command "git bisect replay $replay" or
1655 dodie "failed to run replay";
1658 if (defined($start)) {
1659 run_command "git checkout $start" or
1660 dodie "failed to checkout $start";
1665 $result = run_bisect $type;
1666 $test = run_git_bisect "git bisect $result";
1669 run_command "git bisect log" or
1670 dodie "could not capture git bisect log";
1672 run_command "git bisect reset" or
1673 dodie "could not reset git bisect";
1675 doprint "Bad commit was [$bisect_bad]\n";
1688 sub assign_configs {
1689 my ($hash, $config) = @_;
1692 or dodie "Failed to read $config";
1695 if (/^((CONFIG\S*)=.*)/) {
1703 sub process_config_ignore {
1706 assign_configs \%config_ignore, $config;
1709 sub read_current_config {
1710 my ($config_ref) = @_;
1712 %{$config_ref} = ();
1713 undef %{$config_ref};
1715 my @key = keys %{$config_ref};
1717 print "did not delete!\n";
1720 open (IN, "$output_config");
1723 if (/^(CONFIG\S+)=(.*)/) {
1724 ${$config_ref}{$1} = $2;
1730 sub get_dependencies {
1733 my $arr = $dependency{$config};
1734 if (!defined($arr)) {
1740 foreach my $dep (@{$arr}) {
1741 print "ADD DEP $dep\n";
1742 @deps = (@deps, get_dependencies $dep);
1751 open(OUT, ">$output_config") or dodie "Can not write to $output_config";
1753 foreach my $config (@configs) {
1754 print OUT "$config_set{$config}\n";
1755 my @deps = get_dependencies $config;
1756 foreach my $dep (@deps) {
1757 print OUT "$config_set{$dep}\n";
1761 foreach my $config (keys %config_ignore) {
1762 print OUT "$config_ignore{$config}\n";
1770 sub compare_configs {
1773 foreach my $item (keys %a) {
1774 if (!defined($b{$item})) {
1775 print "diff $item\n";
1783 print "diff2 $keys[0]\n";
1785 return -1 if ($#keys >= 0);
1790 sub run_config_bisect_test {
1793 return run_bisect_test $type, "oldconfig";
1796 sub process_passed {
1799 doprint "These configs had no failure: (Enabling them for further compiles)\n";
1800 # Passed! All these configs are part of a good compile.
1801 # Add them to the min options.
1802 foreach my $config (keys %configs) {
1803 if (defined($config_list{$config})) {
1804 doprint " removing $config\n";
1805 $config_ignore{$config} = $config_list{$config};
1806 delete $config_list{$config};
1809 doprint "config copied to $outputdir/config_good\n";
1810 run_command "cp -f $output_config $outputdir/config_good";
1813 sub process_failed {
1816 doprint "\n\n***************************************\n";
1817 doprint "Found bad config: $config\n";
1818 doprint "***************************************\n\n";
1821 sub run_config_bisect {
1823 my @start_list = keys %config_list;
1825 if ($#start_list < 0) {
1826 doprint "No more configs to test!!!\n";
1830 doprint "***** RUN TEST ***\n";
1831 my $type = $opt{"CONFIG_BISECT_TYPE[$iteration]"};
1835 my $count = $#start_list + 1;
1836 doprint " $count configs to test\n";
1838 my $half = int($#start_list / 2);
1841 my @tophalf = @start_list[0 .. $half];
1843 create_config @tophalf;
1844 read_current_config \%current_config;
1846 $count = $#tophalf + 1;
1847 doprint "Testing $count configs\n";
1849 # make sure we test something
1850 foreach my $config (@tophalf) {
1851 if (defined($current_config{$config})) {
1857 # try the other half
1858 doprint "Top half produced no set configs, trying bottom half\n";
1859 @tophalf = @start_list[$half + 1 .. $#start_list];
1860 create_config @tophalf;
1861 read_current_config \%current_config;
1862 foreach my $config (@tophalf) {
1863 if (defined($current_config{$config})) {
1869 doprint "Failed: Can't make new config with current configs\n";
1870 foreach my $config (@start_list) {
1871 doprint " CONFIG: $config\n";
1875 $count = $#tophalf + 1;
1876 doprint "Testing $count configs\n";
1879 $ret = run_config_bisect_test $type;
1880 if ($bisect_manual) {
1881 $ret = answer_bisect;
1884 process_passed %current_config;
1888 doprint "This config had a failure.\n";
1889 doprint "Removing these configs that were not set in this config:\n";
1890 doprint "config copied to $outputdir/config_bad\n";
1891 run_command "cp -f $output_config $outputdir/config_bad";
1893 # A config exists in this group that was bad.
1894 foreach my $config (keys %config_list) {
1895 if (!defined($current_config{$config})) {
1896 doprint " removing $config\n";
1897 delete $config_list{$config};
1901 @start_list = @tophalf;
1903 if ($#start_list == 0) {
1904 process_failed $start_list[0];
1908 # remove half the configs we are looking at and see if
1910 $half = int($#start_list / 2);
1911 } while ($#start_list > 0);
1913 # we found a single config, try it again unless we are running manually
1915 if ($bisect_manual) {
1916 process_failed $start_list[0];
1920 my @tophalf = @start_list[0 .. 0];
1922 $ret = run_config_bisect_test $type;
1924 process_passed %current_config;
1928 process_failed $start_list[0];
1935 my $start_config = $opt{"CONFIG_BISECT[$i]"};
1937 my $tmpconfig = "$tmpdir/use_config";
1939 if (defined($config_bisect_good)) {
1940 process_config_ignore $config_bisect_good;
1943 # Make the file with the bad config and the min config
1944 if (defined($minconfig)) {
1945 # read the min config for things to ignore
1946 run_command "cp $minconfig $tmpconfig" or
1947 dodie "failed to copy $minconfig to $tmpconfig";
1953 if (defined($addconfig)) {
1954 run_command "cat $addconfig >> $tmpconfig" or
1955 dodie "failed to append $addconfig";
1958 if (-f $tmpconfig) {
1959 load_force_config($tmpconfig);
1960 process_config_ignore $tmpconfig;
1963 # now process the start config
1964 run_command "cp $start_config $output_config" or
1965 dodie "failed to copy $start_config to $output_config";
1967 # read directly what we want to check
1969 open (IN, $output_config)
1970 or dodie "faied to open $output_config";
1973 if (/^((CONFIG\S*)=.*)/) {
1974 $config_check{$2} = $1;
1979 # Now run oldconfig with the minconfig (and addconfigs)
1982 # check to see what we lost (or gained)
1983 open (IN, $output_config)
1984 or dodie "Failed to read $start_config";
1986 my %removed_configs;
1990 if (/^((CONFIG\S*)=.*)/) {
1991 # save off all options
1992 $config_set{$2} = $1;
1993 if (defined($config_check{$2})) {
1994 if (defined($config_ignore{$2})) {
1995 $removed_configs{$2} = $1;
1997 $config_list{$2} = $1;
1999 } elsif (!defined($config_ignore{$2})) {
2000 $added_configs{$2} = $1;
2001 $config_list{$2} = $1;
2007 my @confs = keys %removed_configs;
2009 doprint "Configs overridden by default configs and removed from check:\n";
2010 foreach my $config (@confs) {
2011 doprint " $config\n";
2014 @confs = keys %added_configs;
2016 doprint "Configs appearing in make oldconfig and added:\n";
2017 foreach my $config (@confs) {
2018 doprint " $config\n";
2025 # Sometimes kconfig does weird things. We must make sure
2026 # that the config we autocreate has everything we need
2027 # to test, otherwise we may miss testing configs, or
2028 # may not be able to create a new config.
2029 # Here we create a config with everything set.
2030 create_config (keys %config_list);
2031 read_current_config \%config_test;
2032 foreach my $config (keys %config_list) {
2033 if (!defined($config_test{$config})) {
2036 doprint "Configs not produced by kconfig (will not be checked):\n";
2038 doprint " $config\n";
2039 delete $config_list{$config};
2044 $ret = run_config_bisect;
2047 return $ret if ($ret < 0);
2052 sub patchcheck_reboot {
2053 doprint "Reboot and sleep $patchcheck_sleep_time seconds\n";
2056 wait_for_monitor $patchcheck_sleep_time;
2063 die "PATCHCHECK_START[$i] not defined\n"
2064 if (!defined($opt{"PATCHCHECK_START[$i]"}));
2065 die "PATCHCHECK_TYPE[$i] not defined\n"
2066 if (!defined($opt{"PATCHCHECK_TYPE[$i]"}));
2068 my $start = $opt{"PATCHCHECK_START[$i]"};
2071 if (defined($opt{"PATCHCHECK_END[$i]"})) {
2072 $end = $opt{"PATCHCHECK_END[$i]"};
2075 # Get the true sha1's since we can use things like HEAD~3
2076 $start = get_sha1($start);
2077 $end = get_sha1($end);
2079 my $type = $opt{"PATCHCHECK_TYPE[$i]"};
2081 # Can't have a test without having a test to run
2082 if ($type eq "test" && !defined($run_test)) {
2086 open (IN, "git log --pretty=oneline $end|") or
2087 dodie "could not get git list";
2093 $list[$#list+1] = $_;
2094 last if (/^$start/);
2098 if ($list[$#list] !~ /^$start/) {
2099 fail "SHA1 $start not found";
2102 # go backwards in the list
2103 @list = reverse @list;
2105 my $save_clean = $noclean;
2106 my %ignored_warnings;
2108 if (defined($ignore_warnings)) {
2109 foreach my $sha1 (split /\s+/, $ignore_warnings) {
2110 $ignored_warnings{$sha1} = 1;
2115 foreach my $item (@list) {
2117 $sha1 =~ s/^([[:xdigit:]]+).*/$1/;
2119 doprint "\nProcessing commit $item\n\n";
2121 run_command "git checkout $sha1" or
2122 die "Failed to checkout $sha1";
2124 # only clean on the first and last patch
2125 if ($item eq $list[0] ||
2126 $item eq $list[$#list]) {
2127 $noclean = $save_clean;
2132 if (defined($minconfig)) {
2133 build "useconfig:$minconfig" or return 0;
2135 # ?? no config to use?
2136 build "oldconfig" or return 0;
2140 if (!defined($ignored_warnings{$sha1})) {
2141 check_buildlog $sha1 or return 0;
2144 next if ($type eq "build");
2148 start_monitor_and_boot or $failed = 1;
2150 if (!$failed && $type ne "boot"){
2151 do_run_test or $failed = 1;
2154 return 0 if ($failed);
2172 # taken from streamline_config.pl
2184 if (! -f $kconfig) {
2185 doprint "file $kconfig does not exist, skipping\n";
2189 open(KIN, "$kconfig")
2190 or die "Can't open $kconfig";
2194 # Make sure that lines ending with \ continue
2196 $_ = $line . " " . $_;
2207 # collect any Kconfig sources
2208 if (/^source\s*"(.*)"/) {
2209 $kconfigs[$#kconfigs+1] = $1;
2213 if (/^\s*(menu)?config\s+(\S+)\s*$/) {
2217 for (my $i = 0; $i < $iflevel; $i++) {
2219 $depends{$config} .= " " . $ifdeps[$i];
2221 $depends{$config} = $ifdeps[$i];
2226 # collect the depends for the config
2227 } elsif ($state eq "NEW" && /^\s*depends\s+on\s+(.*)$/) {
2229 if (defined($depends{$1})) {
2230 $depends{$config} .= " " . $1;
2232 $depends{$config} = $1;
2235 # Get the configs that select this config
2236 } elsif ($state ne "NONE" && /^\s*select\s+(\S+)/) {
2237 if (defined($depends{$1})) {
2238 $depends{$1} .= " " . $config;
2240 $depends{$1} = $config;
2243 # Check for if statements
2244 } elsif (/^if\s+(.*\S)\s*$/) {
2246 # remove beginning and ending non text
2247 $deps =~ s/^[^a-zA-Z0-9_]*//;
2248 $deps =~ s/[^a-zA-Z0-9_]*$//;
2250 my @deps = split /[^a-zA-Z0-9_]+/, $deps;
2252 $ifdeps[$iflevel++] = join ':', @deps;
2254 } elsif (/^endif/) {
2256 $iflevel-- if ($iflevel);
2259 } elsif (/^\s*help\s*$/) {
2265 # read in any configs that were found.
2266 foreach $kconfig (@kconfigs) {
2267 if (!defined($read_kconfigs{$kconfig})) {
2268 $read_kconfigs{$kconfig} = 1;
2269 read_kconfig("$builddir/$kconfig");
2275 # find out which arch this is by the kconfig file
2276 open (IN, $output_config)
2277 or dodie "Failed to read $output_config";
2280 if (m,Linux/(\S+)\s+\S+\s+Kernel Configuration,) {
2287 if (!defined($arch)) {
2288 doprint "Could not find arch from config file\n";
2289 doprint "no dependencies used\n";
2293 # arch is really the subarch, we need to know
2294 # what directory to look at.
2295 if ($arch eq "i386" || $arch eq "x86_64") {
2297 } elsif ($arch =~ /^tile/) {
2301 my $kconfig = "$builddir/arch/$arch/Kconfig";
2303 if (! -f $kconfig && $arch =~ /\d$/) {
2305 # some subarchs have numbers, truncate them
2307 $kconfig = "$builddir/arch/$arch/Kconfig";
2308 if (! -f $kconfig) {
2309 doprint "No idea what arch dir $orig is for\n";
2310 doprint "no dependencies used\n";
2315 read_kconfig($kconfig);
2318 sub read_config_list {
2322 or dodie "Failed to read $config";
2325 if (/^((CONFIG\S*)=.*)/) {
2326 if (!defined($config_ignore{$2})) {
2327 $config_list{$2} = $1;
2335 sub read_output_config {
2338 assign_configs \%config_ignore, $config;
2341 sub make_new_config {
2344 open (OUT, ">$output_config")
2345 or dodie "Failed to write $output_config";
2347 foreach my $config (@configs) {
2348 print OUT "$config\n";
2357 $kconfig =~ s/CONFIG_//;
2359 $dep = $depends{"$kconfig"};
2361 # the dep string we have saves the dependencies as they
2362 # were found, including expressions like ! && ||. We
2363 # want to split this out into just an array of configs.
2365 my $valid = "A-Za-z_0-9";
2369 while ($dep =~ /[$valid]/) {
2371 if ($dep =~ /^[^$valid]*([$valid]+)/) {
2372 my $conf = "CONFIG_" . $1;
2374 $configs[$#configs + 1] = $conf;
2376 $dep =~ s/^[^$valid]*[$valid]+//;
2378 die "this should never happen";
2387 my %processed_configs;
2388 my %nochange_config;
2390 sub test_this_config {
2395 # if we already processed this config, skip it
2396 if (defined($processed_configs{$config})) {
2399 $processed_configs{$config} = 1;
2401 # if this config failed during this round, skip it
2402 if (defined($nochange_config{$config})) {
2406 my $kconfig = $config;
2407 $kconfig =~ s/CONFIG_//;
2409 # Test dependencies first
2410 if (defined($depends{"$kconfig"})) {
2411 my @parents = get_depends $config;
2412 foreach my $parent (@parents) {
2413 # if the parent is in the min config, check it first
2414 next if (!defined($min_configs{$parent}));
2415 $found = test_this_config($parent);
2416 if (defined($found)) {
2422 # Remove this config from the list of configs
2423 # do a make oldnoconfig and then read the resulting
2424 # .config to make sure it is missing the config that
2426 my %configs = %min_configs;
2427 delete $configs{$config};
2428 make_new_config ((values %configs), (values %keep_configs));
2431 assign_configs \%configs, $output_config;
2433 return $config if (!defined($configs{$config}));
2435 doprint "disabling config $config did not change .config\n";
2437 $nochange_config{$config} = 1;
2442 sub make_min_config {
2445 if (!defined($output_minconfig)) {
2446 fail "OUTPUT_MIN_CONFIG not defined" and return;
2448 if (!defined($start_minconfig)) {
2449 fail "START_MIN_CONFIG or MIN_CONFIG not defined" and return;
2452 # First things first. We build an allnoconfig to find
2453 # out what the defaults are that we can't touch.
2454 # Some are selections, but we really can't handle selections.
2456 my $save_minconfig = $minconfig;
2459 run_command "$make allnoconfig" or return 0;
2463 process_config_ignore $output_config;
2465 undef %keep_configs;
2468 if (defined($ignore_config)) {
2469 # make sure the file exists
2470 `touch $ignore_config`;
2471 assign_configs \%keep_configs, $ignore_config;
2474 doprint "Load initial configs from $start_minconfig\n";
2476 # Look at the current min configs, and save off all the
2477 # ones that were set via the allnoconfig
2478 assign_configs \%min_configs, $start_minconfig;
2480 my @config_keys = keys %min_configs;
2482 # Remove anything that was set by the make allnoconfig
2483 # we shouldn't need them as they get set for us anyway.
2484 foreach my $config (@config_keys) {
2485 # Remove anything in the ignore_config
2486 if (defined($keep_configs{$config})) {
2487 my $file = $ignore_config;
2488 $file =~ s,.*/(.*?)$,$1,;
2489 doprint "$config set by $file ... ignored\n";
2490 delete $min_configs{$config};
2493 # But make sure the settings are the same. If a min config
2494 # sets a selection, we do not want to get rid of it if
2495 # it is not the same as what we have. Just move it into
2497 if (defined($config_ignore{$config})) {
2498 if ($config_ignore{$config} ne $min_configs{$config}) {
2499 doprint "$config is in allnoconfig as '$config_ignore{$config}'";
2500 doprint " but it is '$min_configs{$config}' in minconfig .. keeping\n";
2501 $keep_configs{$config} = $min_configs{$config};
2503 doprint "$config set by allnoconfig ... ignored\n";
2505 delete $min_configs{$config};
2517 # Now disable each config one by one and do a make oldconfig
2518 # till we find a config that changes our list.
2520 # Put configs that did not modify the config at the end.
2521 my @test_configs = keys %min_configs;
2523 for (my $i = 0; $i < $#test_configs; $i++) {
2524 if (!defined($nochange_config{$test_configs[0]})) {
2528 # This config didn't change the .config last time.
2529 # Place it at the end
2530 my $config = shift @test_configs;
2531 push @test_configs, $config;
2534 # if every test config has failed to modify the .config file
2535 # in the past, then reset and start over.
2537 undef %nochange_config;
2540 undef %processed_configs;
2542 foreach my $config (@test_configs) {
2544 $found = test_this_config $config;
2546 last if (defined($found));
2548 # oh well, try another config
2551 if (!defined($found)) {
2552 # we could have failed due to the nochange_config hash
2553 # reset and try again
2555 undef %nochange_config;
2559 doprint "No more configs found that we can disable\n";
2567 doprint "Test with $config disabled\n";
2569 # set in_bisect to keep build and monitor from dieing
2574 start_monitor_and_boot or $failed = 1;
2580 doprint "$min_configs{$config} is needed to boot the box... keeping\n";
2581 # this config is needed, add it to the ignore list.
2582 $keep_configs{$config} = $min_configs{$config};
2583 delete $min_configs{$config};
2585 # We booted without this config, remove it from the minconfigs.
2586 doprint "$config is not needed, disabling\n";
2588 delete $min_configs{$config};
2590 # Also disable anything that is not enabled in this config
2592 assign_configs \%configs, $output_config;
2593 my @config_keys = keys %min_configs;
2594 foreach my $config (@config_keys) {
2595 if (!defined($configs{$config})) {
2596 doprint "$config is not set, disabling\n";
2597 delete $min_configs{$config};
2601 # Save off all the current mandidory configs
2602 open (OUT, ">$output_minconfig")
2603 or die "Can't write to $output_minconfig";
2604 foreach my $config (keys %keep_configs) {
2605 print OUT "$keep_configs{$config}\n";
2607 foreach my $config (keys %min_configs) {
2608 print OUT "$min_configs{$config}\n";
2613 doprint "Reboot and wait $sleep_time seconds\n";
2616 wait_for_monitor $sleep_time;
2624 $#ARGV < 1 or die "ktest.pl version: $VERSION\n usage: ktest.pl config-file\n";
2627 $ktest_config = $ARGV[0];
2628 if (! -f $ktest_config) {
2629 print "$ktest_config does not exist.\n";
2632 print "Create it? [Y/n] ";
2635 if ($ans =~ /^\s*$/) {
2638 last if ($ans =~ /^y$/i || $ans =~ /^n$/i);
2639 print "Please answer either 'y' or 'n'.\n";
2641 if ($ans !~ /^y$/i) {
2646 $ktest_config = "ktest.conf";
2649 if (! -f $ktest_config) {
2650 open(OUT, ">$ktest_config") or die "Can not create $ktest_config";
2652 # Generated by ktest.pl
2654 # Define each test with TEST_START
2655 # The config options below it will override the defaults
2663 read_config $ktest_config;
2665 if (defined($opt{"LOG_FILE"})) {
2666 $opt{"LOG_FILE"} = eval_option($opt{"LOG_FILE"}, -1);
2669 # Append any configs entered in manually to the config file.
2670 my @new_configs = keys %entered_configs;
2671 if ($#new_configs >= 0) {
2672 print "\nAppending entered in configs to $ktest_config\n";
2673 open(OUT, ">>$ktest_config") or die "Can not append to $ktest_config";
2674 foreach my $config (@new_configs) {
2675 print OUT "$config = $entered_configs{$config}\n";
2676 $opt{$config} = $entered_configs{$config};
2680 if ($opt{"CLEAR_LOG"} && defined($opt{"LOG_FILE"})) {
2681 unlink $opt{"LOG_FILE"};
2684 doprint "\n\nSTARTING AUTOMATED TESTS\n\n";
2686 for (my $i = 0, my $repeat = 1; $i <= $opt{"NUM_TESTS"}; $i += $repeat) {
2689 doprint "DEFAULT OPTIONS:\n";
2691 doprint "\nTEST $i OPTIONS";
2692 if (defined($repeat_tests{$i})) {
2693 $repeat = $repeat_tests{$i};
2694 doprint " ITERATE $repeat";
2699 foreach my $option (sort keys %opt) {
2701 if ($option =~ /\[(\d+)\]$/) {
2707 doprint "$option = $opt{$option}\n";
2711 sub __set_test_option {
2712 my ($name, $i) = @_;
2714 my $option = "$name\[$i\]";
2716 if (defined($opt{$option})) {
2717 return $opt{$option};
2720 foreach my $test (keys %repeat_tests) {
2722 $i < $test + $repeat_tests{$test}) {
2723 $option = "$name\[$test\]";
2724 if (defined($opt{$option})) {
2725 return $opt{$option};
2730 if (defined($opt{$name})) {
2737 sub set_test_option {
2738 my ($name, $i) = @_;
2740 my $option = __set_test_option($name, $i);
2741 return $option if (!defined($option));
2743 return eval_option($option, $i);
2746 # First we need to do is the builds
2747 for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
2751 my $makecmd = set_test_option("MAKE_CMD", $i);
2753 $machine = set_test_option("MACHINE", $i);
2754 $ssh_user = set_test_option("SSH_USER", $i);
2755 $tmpdir = set_test_option("TMP_DIR", $i);
2756 $outputdir = set_test_option("OUTPUT_DIR", $i);
2757 $builddir = set_test_option("BUILD_DIR", $i);
2758 $test_type = set_test_option("TEST_TYPE", $i);
2759 $build_type = set_test_option("BUILD_TYPE", $i);
2760 $build_options = set_test_option("BUILD_OPTIONS", $i);
2761 $pre_build = set_test_option("PRE_BUILD", $i);
2762 $post_build = set_test_option("POST_BUILD", $i);
2763 $pre_build_die = set_test_option("PRE_BUILD_DIE", $i);
2764 $post_build_die = set_test_option("POST_BUILD_DIE", $i);
2765 $power_cycle = set_test_option("POWER_CYCLE", $i);
2766 $reboot = set_test_option("REBOOT", $i);
2767 $noclean = set_test_option("BUILD_NOCLEAN", $i);
2768 $minconfig = set_test_option("MIN_CONFIG", $i);
2769 $output_minconfig = set_test_option("OUTPUT_MIN_CONFIG", $i);
2770 $start_minconfig = set_test_option("START_MIN_CONFIG", $i);
2771 $ignore_config = set_test_option("IGNORE_CONFIG", $i);
2772 $run_test = set_test_option("TEST", $i);
2773 $addconfig = set_test_option("ADD_CONFIG", $i);
2774 $reboot_type = set_test_option("REBOOT_TYPE", $i);
2775 $grub_menu = set_test_option("GRUB_MENU", $i);
2776 $post_install = set_test_option("POST_INSTALL", $i);
2777 $reboot_script = set_test_option("REBOOT_SCRIPT", $i);
2778 $reboot_on_error = set_test_option("REBOOT_ON_ERROR", $i);
2779 $poweroff_on_error = set_test_option("POWEROFF_ON_ERROR", $i);
2780 $die_on_failure = set_test_option("DIE_ON_FAILURE", $i);
2781 $power_off = set_test_option("POWER_OFF", $i);
2782 $powercycle_after_reboot = set_test_option("POWERCYCLE_AFTER_REBOOT", $i);
2783 $poweroff_after_halt = set_test_option("POWEROFF_AFTER_HALT", $i);
2784 $sleep_time = set_test_option("SLEEP_TIME", $i);
2785 $bisect_sleep_time = set_test_option("BISECT_SLEEP_TIME", $i);
2786 $patchcheck_sleep_time = set_test_option("PATCHCHECK_SLEEP_TIME", $i);
2787 $ignore_warnings = set_test_option("IGNORE_WARNINGS", $i);
2788 $bisect_manual = set_test_option("BISECT_MANUAL", $i);
2789 $bisect_skip = set_test_option("BISECT_SKIP", $i);
2790 $config_bisect_good = set_test_option("CONFIG_BISECT_GOOD", $i);
2791 $store_failures = set_test_option("STORE_FAILURES", $i);
2792 $test_name = set_test_option("TEST_NAME", $i);
2793 $timeout = set_test_option("TIMEOUT", $i);
2794 $booted_timeout = set_test_option("BOOTED_TIMEOUT", $i);
2795 $console = set_test_option("CONSOLE", $i);
2796 $detect_triplefault = set_test_option("DETECT_TRIPLE_FAULT", $i);
2797 $success_line = set_test_option("SUCCESS_LINE", $i);
2798 $stop_after_success = set_test_option("STOP_AFTER_SUCCESS", $i);
2799 $stop_after_failure = set_test_option("STOP_AFTER_FAILURE", $i);
2800 $stop_test_after = set_test_option("STOP_TEST_AFTER", $i);
2801 $build_target = set_test_option("BUILD_TARGET", $i);
2802 $ssh_exec = set_test_option("SSH_EXEC", $i);
2803 $scp_to_target = set_test_option("SCP_TO_TARGET", $i);
2804 $target_image = set_test_option("TARGET_IMAGE", $i);
2805 $localversion = set_test_option("LOCALVERSION", $i);
2807 if (!defined($start_minconfig)) {
2808 $start_minconfig = $minconfig;
2811 chdir $builddir || die "can't change directory to $builddir";
2815 die "can't create $tmpdir";
2818 $ENV{"SSH_USER"} = $ssh_user;
2819 $ENV{"MACHINE"} = $machine;
2821 $target = "$ssh_user\@$machine";
2823 $buildlog = "$tmpdir/buildlog-$machine";
2824 $dmesg = "$tmpdir/dmesg-$machine";
2825 $make = "$makecmd O=$outputdir";
2826 $output_config = "$outputdir/.config";
2828 if ($reboot_type eq "grub") {
2829 dodie "GRUB_MENU not defined" if (!defined($grub_menu));
2830 } elsif (!defined($reboot_script)) {
2831 dodie "REBOOT_SCRIPT not defined"
2834 my $run_type = $build_type;
2835 if ($test_type eq "patchcheck") {
2836 $run_type = $opt{"PATCHCHECK_TYPE[$i]"};
2837 } elsif ($test_type eq "bisect") {
2838 $run_type = $opt{"BISECT_TYPE[$i]"};
2839 } elsif ($test_type eq "config_bisect") {
2840 $run_type = $opt{"CONFIG_BISECT_TYPE[$i]"};
2843 if ($test_type eq "make_min_config") {
2847 # mistake in config file?
2848 if (!defined($run_type)) {
2849 $run_type = "ERROR";
2853 doprint "RUNNING TEST $i of $opt{NUM_TESTS} with option $test_type $run_type\n\n";
2858 if (!defined($minconfig)) {
2859 $minconfig = $addconfig;
2861 } elsif (defined($addconfig)) {
2862 run_command "cat $addconfig $minconfig > $tmpdir/add_config" or
2863 dodie "Failed to create temp config";
2864 $minconfig = "$tmpdir/add_config";
2867 my $checkout = $opt{"CHECKOUT[$i]"};
2868 if (defined($checkout)) {
2869 run_command "git checkout $checkout" or
2870 die "failed to checkout $checkout";
2873 if ($test_type eq "bisect") {
2876 } elsif ($test_type eq "config_bisect") {
2879 } elsif ($test_type eq "patchcheck") {
2882 } elsif ($test_type eq "make_min_config") {
2887 if ($build_type ne "nobuild") {
2888 build $build_type or next;
2891 if ($test_type ne "build") {
2893 start_monitor_and_boot or $failed = 1;
2895 if (!$failed && $test_type ne "boot" && defined($run_test)) {
2896 do_run_test or $failed = 1;
2905 if ($opt{"POWEROFF_ON_SUCCESS"}) {
2907 } elsif ($opt{"REBOOT_ON_SUCCESS"} && !do_not_reboot) {
2911 doprint "\n $successes of $opt{NUM_TESTS} tests were successful\n\n";