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{"NO_INSTALL"} = 0;
46 $default{"BOOTED_TIMEOUT"} = 1;
47 $default{"DIE_ON_FAILURE"} = 1;
48 $default{"SSH_EXEC"} = "ssh \$SSH_USER\@\$MACHINE \$SSH_COMMAND";
49 $default{"SCP_TO_TARGET"} = "scp \$SRC_FILE \$SSH_USER\@\$MACHINE:\$DST_FILE";
50 $default{"REBOOT"} = "ssh \$SSH_USER\@\$MACHINE reboot";
51 $default{"STOP_AFTER_SUCCESS"} = 10;
52 $default{"STOP_AFTER_FAILURE"} = 60;
53 $default{"STOP_TEST_AFTER"} = 600;
54 $default{"LOCALVERSION"} = "-test";
76 my $poweroff_on_error;
78 my $powercycle_after_reboot;
79 my $poweroff_after_halt;
92 my $start_minconfig_defined;
101 my $config_bisect_good;
102 my $in_patchcheck = 0;
111 my $bisect_sleep_time;
112 my $patchcheck_sleep_time;
118 my $detect_triplefault;
120 my $reboot_success_line;
122 my $stop_after_success;
123 my $stop_after_failure;
136 # do not force reboots on config problems
139 # default variables that can be used
140 chomp ($variable{"PWD"} = `pwd`);
142 $config_help{"MACHINE"} = << "EOF"
143 The machine hostname that you will test.
146 $config_help{"SSH_USER"} = << "EOF"
147 The box is expected to have ssh on normal bootup, provide the user
148 (most likely root, since you need privileged operations)
151 $config_help{"BUILD_DIR"} = << "EOF"
152 The directory that contains the Linux source code (full path).
155 $config_help{"OUTPUT_DIR"} = << "EOF"
156 The directory that the objects will be built (full path).
157 (can not be same as BUILD_DIR)
160 $config_help{"BUILD_TARGET"} = << "EOF"
161 The location of the compiled file to copy to the target.
162 (relative to OUTPUT_DIR)
165 $config_help{"TARGET_IMAGE"} = << "EOF"
166 The place to put your image on the test machine.
169 $config_help{"POWER_CYCLE"} = << "EOF"
170 A script or command to reboot the box.
172 Here is a digital loggers power switch example
173 POWER_CYCLE = wget --no-proxy -O /dev/null -q --auth-no-challenge 'http://admin:admin\@power/outlet?5=CCL'
175 Here is an example to reboot a virtual box on the current host
176 with the name "Guest".
177 POWER_CYCLE = virsh destroy Guest; sleep 5; virsh start Guest
180 $config_help{"CONSOLE"} = << "EOF"
181 The script or command that reads the console
183 If you use ttywatch server, something like the following would work.
184 CONSOLE = nc -d localhost 3001
186 For a virtual machine with guest name "Guest".
187 CONSOLE = virsh console Guest
190 $config_help{"LOCALVERSION"} = << "EOF"
191 Required version ending to differentiate the test
192 from other linux builds on the system.
195 $config_help{"REBOOT_TYPE"} = << "EOF"
196 Way to reboot the box to the test kernel.
197 Only valid options so far are "grub" and "script".
199 If you specify grub, it will assume grub version 1
200 and will search in /boot/grub/menu.lst for the title \$GRUB_MENU
201 and select that target to reboot to the kernel. If this is not
202 your setup, then specify "script" and have a command or script
203 specified in REBOOT_SCRIPT to boot to the target.
205 The entry in /boot/grub/menu.lst must be entered in manually.
206 The test will not modify that file.
209 $config_help{"GRUB_MENU"} = << "EOF"
210 The grub title name for the test kernel to boot
211 (Only mandatory if REBOOT_TYPE = grub)
213 Note, ktest.pl will not update the grub menu.lst, you need to
214 manually add an option for the test. ktest.pl will search
215 the grub menu.lst for this option to find what kernel to
218 For example, if in the /boot/grub/menu.lst the test kernel title has:
221 GRUB_MENU = Test Kernel
224 $config_help{"REBOOT_SCRIPT"} = << "EOF"
225 A script to reboot the target into the test kernel
226 (Only mandatory if REBOOT_TYPE = script)
236 print "$prompt [Y/n] ";
239 if ($ans =~ /^\s*$/) {
242 last if ($ans =~ /^y$/i || $ans =~ /^n$/i);
243 print "Please answer either 'y' or 'n'.\n";
245 if ($ans !~ /^y$/i) {
251 sub get_ktest_config {
254 return if (defined($opt{$config}));
256 if (defined($config_help{$config})) {
258 print $config_help{$config};
263 if (defined($default{$config})) {
264 print "\[$default{$config}\] ";
266 $entered_configs{$config} = <STDIN>;
267 $entered_configs{$config} =~ s/^\s*(.*\S)\s*$/$1/;
268 if ($entered_configs{$config} =~ /^\s*$/) {
269 if ($default{$config}) {
270 $entered_configs{$config} = $default{$config};
272 print "Your answer can not be blank\n";
280 sub get_ktest_configs {
281 get_ktest_config("MACHINE");
282 get_ktest_config("SSH_USER");
283 get_ktest_config("BUILD_DIR");
284 get_ktest_config("OUTPUT_DIR");
285 get_ktest_config("BUILD_TARGET");
286 get_ktest_config("TARGET_IMAGE");
287 get_ktest_config("POWER_CYCLE");
288 get_ktest_config("CONSOLE");
289 get_ktest_config("LOCALVERSION");
291 my $rtype = $opt{"REBOOT_TYPE"};
293 if (!defined($rtype)) {
294 if (!defined($opt{"GRUB_MENU"})) {
295 get_ktest_config("REBOOT_TYPE");
296 $rtype = $entered_configs{"REBOOT_TYPE"};
302 if ($rtype eq "grub") {
303 get_ktest_config("GRUB_MENU");
305 get_ktest_config("REBOOT_SCRIPT");
309 sub process_variables {
310 my ($value, $remove_undef) = @_;
313 # We want to check for '\', and it is just easier
314 # to check the previous characet of '$' and not need
315 # to worry if '$' is the first character. By adding
316 # a space to $value, we can just check [^\\]\$ and
317 # it will still work.
320 while ($value =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) {
324 # append beginning of value to retval
325 $retval = "$retval$begin";
326 if (defined($variable{$var})) {
327 $retval = "$retval$variable{$var}";
328 } elsif (defined($remove_undef) && $remove_undef) {
329 # for if statements, any variable that is not defined,
330 # we simple convert to 0
331 $retval = "${retval}0";
333 # put back the origin piece.
334 $retval = "$retval\$\{$var\}";
338 $retval = "$retval$value";
340 # remove the space added in the beginning
347 my ($lvalue, $rvalue, $override, $overrides, $name) = @_;
349 if (defined($opt{$lvalue})) {
350 if (!$override || defined(${$overrides}{$lvalue})) {
353 $extra = "In the same override section!\n";
355 die "$name: $.: Option $lvalue defined more than once!\n$extra";
357 ${$overrides}{$lvalue} = $rvalue;
359 if ($rvalue =~ /^\s*$/) {
360 delete $opt{$lvalue};
362 $rvalue = process_variables($rvalue);
363 $opt{$lvalue} = $rvalue;
368 my ($lvalue, $rvalue) = @_;
370 if ($rvalue =~ /^\s*$/) {
371 delete $variable{$lvalue};
373 $rvalue = process_variables($rvalue);
374 $variable{$lvalue} = $rvalue;
378 sub process_compare {
379 my ($lval, $cmp, $rval) = @_;
390 return $lval eq $rval;
391 } elsif ($cmp eq "!=") {
392 return $lval ne $rval;
395 my $statement = "$lval $cmp $rval";
396 my $ret = eval $statement;
398 # $@ stores error of eval
409 return defined($variable{$2}) ||
414 sub process_expression {
415 my ($name, $val) = @_;
419 while ($val =~ s/\(([^\(]*?)\)/\&\&\&\&VAL\&\&\&\&/) {
422 if (process_expression($name, $express)) {
423 $val =~ s/\&\&\&\&VAL\&\&\&\&/ 1 /;
425 $val =~ s/\&\&\&\&VAL\&\&\&\&/ 0 /;
433 while ($val =~ s/^(.*?)($OR|$AND)//) {
437 if (process_expression($name, $express)) {
448 if ($val =~ /(.*)(==|\!=|>=|<=|>|<)(.*)/) {
449 my $ret = process_compare($1, $2, $3);
451 die "$name: $.: Unable to process comparison\n";
456 if ($val =~ /^\s*(NOT\s*)?DEFINED\s+(\S+)\s*$/) {
458 return !value_defined($2);
460 return value_defined($2);
464 if ($val =~ /^\s*0\s*$/) {
466 } elsif ($val =~ /^\s*\d+\s*$/) {
470 die ("$name: $.: Undefined content $val in if statement\n");
474 my ($name, $value) = @_;
476 # Convert variables and replace undefined ones with 0
477 my $val = process_variables($value, 1);
478 my $ret = process_expression $name, $val;
484 my ($config, $current_test_num) = @_;
487 open($in, $config) || die "can't read file $config";
490 $name =~ s,.*/(.*),$1,;
492 my $test_num = $$current_test_num;
495 my $num_tests_set = 0;
508 # ignore blank lines and comments
509 next if (/^\s*$/ || /\s*\#/);
511 if (/^\s*(TEST_START|DEFAULTS)\b(.*)/) {
521 if ($type eq "TEST_START") {
523 if ($num_tests_set) {
524 die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
527 $old_test_num = $test_num;
528 $old_repeat = $repeat;
530 $test_num += $repeat;
537 # If SKIP is anywhere in the line, the command will be skipped
538 if ($rest =~ s/\s+SKIP\b//) {
545 if ($rest =~ s/\sELSE\b//) {
547 die "$name: $.: ELSE found with out matching IF section\n$_";
558 if ($rest =~ s/\sIF\s+(.*)//) {
559 if (process_if($name, $1)) {
571 if ($type eq "TEST_START") {
572 if ($rest =~ s/\s+ITERATE\s+(\d+)//) {
574 $repeat_tests{"$test_num"} = $repeat;
576 } elsif ($rest =~ s/\sOVERRIDE\b//) {
579 # Clear previous overrides
584 if (!$skip && $rest !~ /^\s*$/) {
585 die "$name: $.: Gargbage found after $type\n$_";
588 if ($skip && $type eq "TEST_START") {
589 $test_num = $old_test_num;
590 $repeat = $old_repeat;
593 } elsif (/^\s*ELSE\b(.*)$/) {
595 die "$name: $.: ELSE found with out matching IF section\n$_";
604 if ($rest =~ /\sIF\s+(.*)/) {
605 # May be a ELSE IF section.
606 if (!process_if($name, $1)) {
615 if ($rest !~ /^\s*$/) {
616 die "$name: $.: Gargbage found after DEFAULTS\n$_";
619 } elsif (/^\s*INCLUDE\s+(\S+)/) {
624 die "$name: $.: INCLUDE can only be done in default sections\n$_";
627 my $file = process_variables($1);
629 if ($file !~ m,^/,) {
630 # check the path of the config file first
631 if ($config =~ m,(.*)/,) {
639 die "$name: $.: Can't read file $file\n$_";
642 if (__read_config($file, \$test_num)) {
646 } elsif (/^\s*([A-Z_\[\]\d]+)\s*=\s*(.*?)\s*$/) {
654 ($lvalue eq "NUM_TESTS" ||
655 $lvalue eq "LOG_FILE" ||
656 $lvalue eq "CLEAR_LOG")) {
657 die "$name: $.: $lvalue must be set in DEFAULTS section\n";
660 if ($lvalue eq "NUM_TESTS") {
662 die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
665 die "$name: $.: NUM_TESTS must be set in default section\n";
670 if ($default || $lvalue =~ /\[\d+\]$/) {
671 set_value($lvalue, $rvalue, $override, \%overrides, $name);
673 my $val = "$lvalue\[$test_num\]";
674 set_value($val, $rvalue, $override, \%overrides, $name);
677 $repeats{$val} = $repeat;
680 } elsif (/^\s*([A-Z_\[\]\d]+)\s*:=\s*(.*?)\s*$/) {
686 # process config variables.
687 # Config variables are only active while reading the
688 # config and can be defined anywhere. They also ignore
689 # TEST_START and DEFAULTS, but are skipped if they are in
690 # on of these sections that have SKIP defined.
691 # The save variable can be
692 # defined multiple times and the new one simply overrides
694 set_variable($lvalue, $rvalue);
697 die "$name: $.: Garbage found in config\n$_";
702 $test_num += $repeat - 1;
703 $opt{"NUM_TESTS"} = $test_num;
708 $$current_test_num = $test_num;
719 $test_case = __read_config $config, \$test_num;
721 # make sure we have all mandatory configs
724 # was a test specified?
726 print "No test case specified.\n";
727 print "What test case would you like to run?\n";
730 $default{"TEST_TYPE"} = $ans;
735 foreach my $default (keys %default) {
736 if (!defined($opt{$default})) {
737 $opt{$default} = $default{$default};
743 my ($option, $i) = @_;
745 # Add space to evaluate the character before $
746 $option = " $option";
749 while ($option =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) {
754 # Append beginning of line
755 $retval = "$retval$start";
757 # If the iteration option OPT[$i] exists, then use that.
758 # otherwise see if the default OPT (without [$i]) exists.
760 my $o = "$var\[$i\]";
762 if (defined($opt{$o})) {
764 $retval = "$retval$o";
765 } elsif (defined($opt{$var})) {
767 $retval = "$retval$o";
769 $retval = "$retval\$\{$var\}";
775 $retval = "$retval$option";
783 my ($option, $i) = @_;
787 # Since an option can evaluate to another option,
788 # keep iterating until we do not evaluate any more
791 while ($prev ne $option) {
792 # Check for recursive evaluations.
793 # 100 deep should be more than enough.
795 die "Over 100 evaluations accurred with $option\n" .
796 "Check for recursive variables\n";
799 $option = __eval_option($option, $i);
806 if (defined($opt{"LOG_FILE"})) {
807 open(OUT, ">> $opt{LOG_FILE}") or die "Can't write to $opt{LOG_FILE}";
814 if (defined($opt{"LOG_FILE"})) {
829 sub wait_for_monitor;
834 if (defined($time)) {
836 # flush out current monitor
837 # May contain the reboot success line
841 # try to reboot normally
842 if (run_command $reboot) {
843 if (defined($powercycle_after_reboot)) {
844 sleep $powercycle_after_reboot;
845 run_command "$power_cycle";
848 # nope? power cycle it.
849 run_command "$power_cycle";
852 if (defined($time)) {
853 wait_for_monitor($time, $reboot_success_line);
861 return $test_type eq "build" || $no_reboot ||
862 ($test_type eq "patchcheck" && $opt{"PATCHCHECK_TYPE[$i]"} eq "build") ||
863 ($test_type eq "bisect" && $opt{"BISECT_TYPE[$i]"} eq "build");
867 doprint "CRITICAL FAILURE... ", @_, "\n";
871 if ($reboot_on_error && !do_not_reboot) {
873 doprint "REBOOTING\n";
876 } elsif ($poweroff_on_error && defined($power_off)) {
877 doprint "POWERING OFF\n";
881 if (defined($opt{"LOG_FILE"})) {
882 print " See $opt{LOG_FILE} for more info.\n";
893 my $pid = open($fp, "$console|") or
894 dodie "Can't open console $console";
896 $flags = fcntl($fp, F_GETFL, 0) or
897 dodie "Can't get flags for the socket: $!";
898 $flags = fcntl($fp, F_SETFL, $flags | O_NONBLOCK) or
899 dodie "Can't set flags for the socket: $!";
907 doprint "kill child process $pid\n";
915 if ($monitor_cnt++) {
918 $monitor_fp = \*MONFD;
919 $monitor_pid = open_console $monitor_fp;
923 open(MONFD, "Stop perl from warning about single use of MONFD");
927 if (--$monitor_cnt) {
930 close_console($monitor_fp, $monitor_pid);
933 sub wait_for_monitor {
934 my ($time, $stop) = @_;
939 doprint "** Wait for monitor to settle down **\n";
941 # read the monitor and wait for the system to calm down
943 $line = wait_for_input($monitor_fp, $time);
944 last if (!defined($line));
948 if (defined($stop) && $full_line =~ /$stop/) {
949 doprint "wait for monitor detected $stop\n";
957 print "** Monitor flushed **\n";
962 if ($die_on_failure) {
970 # no need to reboot for just building.
971 if (!do_not_reboot) {
972 doprint "REBOOTING\n";
978 if (defined($test_name)) {
979 $name = " ($test_name)";
982 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
983 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
984 doprint "KTEST RESULT: TEST $i$name Failed: ", @_, "\n";
985 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
986 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
988 return 1 if (!defined($store_failures));
991 my $date = sprintf "%04d%02d%02d%02d%02d%02d",
992 1900+$t[5],$t[4],$t[3],$t[2],$t[1],$t[0];
994 my $type = $build_type;
995 if ($type =~ /useconfig/) {
999 my $dir = "$machine-$test_type-$type-fail-$date";
1000 my $faildir = "$store_failures/$dir";
1004 die "can't create $faildir";
1006 if (-f "$output_config") {
1007 cp "$output_config", "$faildir/config" or
1008 die "failed to copy .config";
1011 cp $buildlog, "$faildir/buildlog" or
1012 die "failed to move $buildlog";
1015 cp $dmesg, "$faildir/dmesg" or
1016 die "failed to move $dmesg";
1019 doprint "*** Saved info to $faildir ***\n";
1030 $command =~ s/\$SSH_USER/$ssh_user/g;
1031 $command =~ s/\$MACHINE/$machine/g;
1033 doprint("$command ... ");
1035 $pid = open(CMD, "$command 2>&1 |") or
1036 (fail "unable to exec $command" and return 0);
1038 if (defined($opt{"LOG_FILE"})) {
1039 open(LOG, ">>$opt{LOG_FILE}") or
1040 dodie "failed to write to log";
1044 if (defined($redirect)) {
1045 open (RD, ">$redirect") or
1046 dodie "failed to write to redirect $redirect";
1051 print LOG if ($dolog);
1052 print RD if ($dord);
1059 close(LOG) if ($dolog);
1060 close(RD) if ($dord);
1063 doprint "FAILED!\n";
1065 doprint "SUCCESS\n";
1073 my $cp_exec = $ssh_exec;
1075 $cp_exec =~ s/\$SSH_COMMAND/$cmd/g;
1076 return run_command "$cp_exec";
1080 my ($src, $dst) = @_;
1081 my $cp_scp = $scp_to_target;
1083 $cp_scp =~ s/\$SRC_FILE/$src/g;
1084 $cp_scp =~ s/\$DST_FILE/$dst/g;
1086 return run_command "$cp_scp";
1089 sub get_grub_index {
1091 if ($reboot_type ne "grub") {
1094 return if (defined($grub_number));
1096 doprint "Find grub menu ... ";
1099 my $ssh_grub = $ssh_exec;
1100 $ssh_grub =~ s,\$SSH_COMMAND,cat /boot/grub/menu.lst,g;
1102 open(IN, "$ssh_grub |")
1103 or die "unable to get menu.lst";
1108 if (/^\s*title\s+$grub_menu\s*$/) {
1112 } elsif (/^\s*title\s/) {
1118 die "Could not find '$grub_menu' in /boot/grub/menu on $machine"
1120 doprint "$grub_number\n";
1125 my ($fp, $time) = @_;
1131 if (!defined($time)) {
1136 vec($rin, fileno($fp), 1) = 1;
1137 $ready = select($rin, undef, undef, $time);
1141 # try to read one char at a time
1142 while (sysread $fp, $ch, 1) {
1144 last if ($ch eq "\n");
1147 if (!length($line)) {
1155 if ($reboot_type eq "grub") {
1156 run_ssh "'(echo \"savedefault --default=$grub_number --once\" | grub --batch)'";
1161 run_command "$reboot_script";
1167 doprint "git rev-list --max-count=1 $commit ... ";
1168 my $sha1 = `git rev-list --max-count=1 $commit`;
1175 dodie "Failed to get git $commit";
1188 my $skip_call_trace = 0;
1196 open(DMESG, "> $dmesg") or
1197 die "unable to write to $dmesg";
1203 my $monitor_start = time;
1205 my $version_found = 0;
1209 if ($bug && defined($stop_after_failure) &&
1210 $stop_after_failure >= 0) {
1211 my $time = $stop_after_failure - (time - $failure_start);
1212 $line = wait_for_input($monitor_fp, $time);
1213 if (!defined($line)) {
1214 doprint "bug timed out after $booted_timeout seconds\n";
1215 doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
1219 $line = wait_for_input($monitor_fp, $booted_timeout);
1220 if (!defined($line)) {
1221 my $s = $booted_timeout == 1 ? "" : "s";
1222 doprint "Successful boot found: break after $booted_timeout second$s\n";
1226 $line = wait_for_input($monitor_fp);
1227 if (!defined($line)) {
1228 my $s = $timeout == 1 ? "" : "s";
1229 doprint "Timed out after $timeout second$s\n";
1237 # we are not guaranteed to get a full line
1238 $full_line .= $line;
1240 if ($full_line =~ /$success_line/) {
1242 $success_start = time;
1245 if ($booted && defined($stop_after_success) &&
1246 $stop_after_success >= 0) {
1248 if ($now - $success_start >= $stop_after_success) {
1249 doprint "Test forced to stop after $stop_after_success seconds after success\n";
1254 if ($full_line =~ /\[ backtrace testing \]/) {
1255 $skip_call_trace = 1;
1258 if ($full_line =~ /call trace:/i) {
1259 if (!$bug && !$skip_call_trace) {
1261 $failure_start = time;
1265 if ($bug && defined($stop_after_failure) &&
1266 $stop_after_failure >= 0) {
1268 if ($now - $failure_start >= $stop_after_failure) {
1269 doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
1274 if ($full_line =~ /\[ end of backtrace testing \]/) {
1275 $skip_call_trace = 0;
1278 if ($full_line =~ /Kernel panic -/) {
1279 $failure_start = time;
1283 # Detect triple faults by testing the banner
1284 if ($full_line =~ /\bLinux version (\S+).*\n/) {
1285 if ($1 eq $version) {
1287 } elsif ($version_found && $detect_triplefault) {
1288 # We already booted into the kernel we are testing,
1289 # but now we booted into another kernel?
1290 # Consider this a triple fault.
1291 doprint "Aleady booted in Linux kernel $version, but now\n";
1292 doprint "we booted into Linux kernel $1.\n";
1293 doprint "Assuming that this is a triple fault.\n";
1294 doprint "To disable this: set DETECT_TRIPLE_FAULT to 0\n";
1299 if ($line =~ /\n/) {
1303 if ($stop_test_after > 0 && !$booted && !$bug) {
1304 if (time - $monitor_start > $stop_test_after) {
1305 doprint "STOP_TEST_AFTER ($stop_test_after seconds) timed out\n";
1314 return 0 if ($in_bisect);
1315 fail "failed - got a bug report" and return 0;
1319 return 0 if ($in_bisect);
1320 fail "failed - never got a boot prompt." and return 0;
1326 sub do_post_install {
1328 return if (!defined($post_install));
1330 my $cp_post_install = $post_install;
1331 $cp_post_install =~ s/\$KERNEL_VERSION/$version/g;
1332 run_command "$cp_post_install" or
1333 dodie "Failed to run post install";
1338 return if ($no_install);
1340 run_scp "$outputdir/$build_target", "$target_image" or
1341 dodie "failed to copy image";
1343 my $install_mods = 0;
1345 # should we process modules?
1347 open(IN, "$output_config") or dodie("Can't read config file");
1349 if (/CONFIG_MODULES(=y)?/) {
1350 $install_mods = 1 if (defined($1));
1356 if (!$install_mods) {
1358 doprint "No modules needed\n";
1362 run_command "$make INSTALL_MOD_PATH=$tmpdir modules_install" or
1363 dodie "Failed to install modules";
1365 my $modlib = "/lib/modules/$version";
1366 my $modtar = "ktest-mods.tar.bz2";
1368 run_ssh "rm -rf $modlib" or
1369 dodie "failed to remove old mods: $modlib";
1371 # would be nice if scp -r did not follow symbolic links
1372 run_command "cd $tmpdir && tar -cjf $modtar lib/modules/$version" or
1373 dodie "making tarball";
1375 run_scp "$tmpdir/$modtar", "/tmp" or
1376 dodie "failed to copy modules";
1378 unlink "$tmpdir/$modtar";
1380 run_ssh "'(cd / && tar xjf /tmp/$modtar)'" or
1381 dodie "failed to tar modules";
1383 run_ssh "rm -f /tmp/$modtar";
1389 # get the release name
1390 doprint "$make kernelrelease ... ";
1391 $version = `$make kernelrelease | tail -1`;
1393 doprint "$version\n";
1396 sub start_monitor_and_boot {
1397 # Make sure the stable kernel has finished booting
1410 sub check_buildlog {
1413 my @files = `git show $patch | diffstat -l`;
1415 open(IN, "git show $patch |") or
1416 dodie "failed to show $patch";
1418 if (m,^--- a/(.*),) {
1420 $files[$#files] = $1;
1425 open(IN, $buildlog) or dodie "Can't open $buildlog";
1427 if (/^\s*(.*?):.*(warning|error)/) {
1429 foreach my $file (@files) {
1430 my $fullpath = "$builddir/$file";
1431 if ($file eq $err || $fullpath eq $err) {
1432 fail "$file built with warnings" and return 0;
1442 sub apply_min_config {
1443 my $outconfig = "$output_config.new";
1445 # Read the config file and remove anything that
1446 # is in the force_config hash (from minconfig and others)
1447 # then add the force config back.
1449 doprint "Applying minimum configurations into $output_config.new\n";
1451 open (OUT, ">$outconfig") or
1452 dodie "Can't create $outconfig";
1454 if (-f $output_config) {
1455 open (IN, $output_config) or
1456 dodie "Failed to open $output_config";
1458 if (/^(# )?(CONFIG_[^\s=]*)/) {
1459 next if (defined($force_config{$2}));
1465 foreach my $config (keys %force_config) {
1466 print OUT "$force_config{$config}\n";
1470 run_command "mv $outconfig $output_config";
1473 sub make_oldconfig {
1475 my @force_list = keys %force_config;
1477 if ($#force_list >= 0) {
1481 if (!run_command "$make oldnoconfig") {
1482 # Perhaps oldnoconfig doesn't exist in this version of the kernel
1483 # try a yes '' | oldconfig
1484 doprint "oldnoconfig failed, trying yes '' | make oldconfig\n";
1485 run_command "yes '' | $make oldconfig" or
1486 dodie "failed make config oldconfig";
1490 # read a config file and use this to force new configs.
1491 sub load_force_config {
1494 open(IN, $config) or
1495 dodie "failed to read $config";
1498 if (/^(CONFIG[^\s=]*)(\s*=.*)/) {
1499 $force_config{$1} = $_;
1500 } elsif (/^# (CONFIG_\S*) is not set/) {
1501 $force_config{$1} = $_;
1512 # Failed builds should not reboot the target
1513 my $save_no_reboot = $no_reboot;
1516 if (defined($pre_build)) {
1517 my $ret = run_command $pre_build;
1518 if (!$ret && defined($pre_build_die) &&
1520 dodie "failed to pre_build\n";
1524 if ($type =~ /^useconfig:(.*)/) {
1525 run_command "cp $1 $output_config" or
1526 dodie "could not copy $1 to .config";
1528 $type = "oldconfig";
1531 # old config can ask questions
1532 if ($type eq "oldconfig") {
1533 $type = "oldnoconfig";
1535 # allow for empty configs
1536 run_command "touch $output_config";
1539 run_command "mv $output_config $outputdir/config_temp" or
1540 dodie "moving .config";
1542 run_command "$make mrproper" or dodie "make mrproper";
1544 run_command "mv $outputdir/config_temp $output_config" or
1545 dodie "moving config_temp";
1548 } elsif (!$noclean) {
1549 unlink "$output_config";
1550 run_command "$make mrproper" or
1551 dodie "make mrproper";
1554 # add something to distinguish this build
1555 open(OUT, "> $outputdir/localversion") or dodie("Can't make localversion file");
1556 print OUT "$localversion\n";
1559 if (defined($minconfig)) {
1560 load_force_config($minconfig);
1563 if ($type ne "oldnoconfig") {
1564 run_command "$make $type" or
1565 dodie "failed make config";
1567 # Run old config regardless, to enforce min configurations
1570 $redirect = "$buildlog";
1571 my $build_ret = run_command "$make $build_options";
1574 if (defined($post_build)) {
1575 my $ret = run_command $post_build;
1576 if (!$ret && defined($post_build_die) &&
1578 dodie "failed to post_build\n";
1583 # bisect may need this to pass
1585 $no_reboot = $save_no_reboot;
1588 fail "failed build" and return 0;
1591 $no_reboot = $save_no_reboot;
1597 if (!run_ssh "halt" or defined($power_off)) {
1598 if (defined($poweroff_after_halt)) {
1599 sleep $poweroff_after_halt;
1600 run_command "$power_off";
1604 run_command "$power_off";
1615 if (defined($test_name)) {
1616 $name = " ($test_name)";
1619 doprint "\n\n*******************************************\n";
1620 doprint "*******************************************\n";
1621 doprint "KTEST RESULT: TEST $i$name SUCCESS!!!! **\n";
1622 doprint "*******************************************\n";
1623 doprint "*******************************************\n";
1625 if ($i != $opt{"NUM_TESTS"} && !do_not_reboot) {
1626 doprint "Reboot and wait $sleep_time seconds\n";
1633 doprint "Pass or fail? [p/f]";
1636 if ($ans eq "p" || $ans eq "P") {
1638 } elsif ($ans eq "f" || $ans eq "F") {
1641 print "Please answer 'P' or 'F'\n";
1646 sub child_run_test {
1649 # child should have no power
1650 $reboot_on_error = 0;
1651 $poweroff_on_error = 0;
1652 $die_on_failure = 1;
1654 run_command $run_test or $failed = 1;
1660 sub child_finished {
1673 doprint "run test $run_test\n";
1677 $SIG{CHLD} = qw(child_finished);
1681 child_run_test if (!$child_pid);
1686 $line = wait_for_input($monitor_fp, 1);
1687 if (defined($line)) {
1689 # we are not guaranteed to get a full line
1690 $full_line .= $line;
1693 if ($full_line =~ /call trace:/i) {
1697 if ($full_line =~ /Kernel panic -/) {
1701 if ($line =~ /\n/) {
1705 } while (!$child_done && !$bug);
1708 my $failure_start = time;
1711 $line = wait_for_input($monitor_fp, 1);
1712 if (defined($line)) {
1716 if ($now - $failure_start >= $stop_after_failure) {
1719 } while (defined($line));
1721 doprint "Detected kernel crash!\n";
1722 # kill the child with extreme prejudice
1726 waitpid $child_pid, 0;
1729 if ($bug || $child_exit) {
1730 return 0 if $in_bisect;
1731 fail "test failed" and return 0;
1736 sub run_git_bisect {
1739 doprint "$command ... ";
1741 my $output = `$command 2>&1`;
1748 dodie "Failed to git bisect";
1751 doprint "SUCCESS\n";
1752 if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\))\s+\[([[:xdigit:]]+)\]/) {
1753 doprint "$1 [$2]\n";
1754 } elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) {
1756 doprint "Found bad commit... $1\n";
1759 # we already logged it, just print it now.
1767 doprint "Reboot and sleep $bisect_sleep_time seconds\n";
1768 reboot $bisect_sleep_time;
1771 # returns 1 on success, 0 on failure, -1 on skip
1772 sub run_bisect_test {
1773 my ($type, $buildtype) = @_;
1782 build $buildtype or $failed = 1;
1784 if ($type ne "build") {
1785 if ($failed && $bisect_skip) {
1789 dodie "Failed on build" if $failed;
1792 start_monitor_and_boot or $failed = 1;
1794 if ($type ne "boot") {
1795 if ($failed && $bisect_skip) {
1801 dodie "Failed on boot" if $failed;
1803 do_run_test or $failed = 1;
1814 # reboot the box to a kernel we can ssh to
1815 if ($type ne "build") {
1825 my $buildtype = "oldconfig";
1827 # We should have a minconfig to use?
1828 if (defined($minconfig)) {
1829 $buildtype = "useconfig:$minconfig";
1832 my $ret = run_bisect_test $type, $buildtype;
1834 if ($bisect_manual) {
1835 $ret = answer_bisect;
1838 # Are we looking for where it worked, not failed?
1839 if ($reverse_bisect) {
1845 } elsif ($ret == 0) {
1847 } elsif ($bisect_skip) {
1848 doprint "HIT A BAD COMMIT ... SKIPPING\n";
1858 die "BISECT_GOOD[$i] not defined\n" if (!defined($opt{"BISECT_GOOD[$i]"}));
1859 die "BISECT_BAD[$i] not defined\n" if (!defined($opt{"BISECT_BAD[$i]"}));
1860 die "BISECT_TYPE[$i] not defined\n" if (!defined($opt{"BISECT_TYPE[$i]"}));
1862 my $good = $opt{"BISECT_GOOD[$i]"};
1863 my $bad = $opt{"BISECT_BAD[$i]"};
1864 my $type = $opt{"BISECT_TYPE[$i]"};
1865 my $start = $opt{"BISECT_START[$i]"};
1866 my $replay = $opt{"BISECT_REPLAY[$i]"};
1867 my $start_files = $opt{"BISECT_FILES[$i]"};
1869 if (defined($start_files)) {
1870 $start_files = " -- " . $start_files;
1875 # convert to true sha1's
1876 $good = get_sha1($good);
1877 $bad = get_sha1($bad);
1879 if (defined($opt{"BISECT_REVERSE[$i]"}) &&
1880 $opt{"BISECT_REVERSE[$i]"} == 1) {
1881 doprint "Performing a reverse bisect (bad is good, good is bad!)\n";
1882 $reverse_bisect = 1;
1884 $reverse_bisect = 0;
1887 # Can't have a test without having a test to run
1888 if ($type eq "test" && !defined($run_test)) {
1892 my $check = $opt{"BISECT_CHECK[$i]"};
1893 if (defined($check) && $check ne "0") {
1896 my $head = get_sha1("HEAD");
1898 if ($check ne "good") {
1899 doprint "TESTING BISECT BAD [$bad]\n";
1900 run_command "git checkout $bad" or
1901 die "Failed to checkout $bad";
1903 $result = run_bisect $type;
1905 if ($result ne "bad") {
1906 fail "Tested BISECT_BAD [$bad] and it succeeded" and return 0;
1910 if ($check ne "bad") {
1911 doprint "TESTING BISECT GOOD [$good]\n";
1912 run_command "git checkout $good" or
1913 die "Failed to checkout $good";
1915 $result = run_bisect $type;
1917 if ($result ne "good") {
1918 fail "Tested BISECT_GOOD [$good] and it failed" and return 0;
1922 # checkout where we started
1923 run_command "git checkout $head" or
1924 die "Failed to checkout $head";
1927 run_command "git bisect start$start_files" or
1928 dodie "could not start bisect";
1930 run_command "git bisect good $good" or
1931 dodie "could not set bisect good to $good";
1933 run_git_bisect "git bisect bad $bad" or
1934 dodie "could not set bisect bad to $bad";
1936 if (defined($replay)) {
1937 run_command "git bisect replay $replay" or
1938 dodie "failed to run replay";
1941 if (defined($start)) {
1942 run_command "git checkout $start" or
1943 dodie "failed to checkout $start";
1948 $result = run_bisect $type;
1949 $test = run_git_bisect "git bisect $result";
1952 run_command "git bisect log" or
1953 dodie "could not capture git bisect log";
1955 run_command "git bisect reset" or
1956 dodie "could not reset git bisect";
1958 doprint "Bad commit was [$bisect_bad]\n";
1971 sub assign_configs {
1972 my ($hash, $config) = @_;
1975 or dodie "Failed to read $config";
1978 if (/^((CONFIG\S*)=.*)/) {
1986 sub process_config_ignore {
1989 assign_configs \%config_ignore, $config;
1992 sub read_current_config {
1993 my ($config_ref) = @_;
1995 %{$config_ref} = ();
1996 undef %{$config_ref};
1998 my @key = keys %{$config_ref};
2000 print "did not delete!\n";
2003 open (IN, "$output_config");
2006 if (/^(CONFIG\S+)=(.*)/) {
2007 ${$config_ref}{$1} = $2;
2013 sub get_dependencies {
2016 my $arr = $dependency{$config};
2017 if (!defined($arr)) {
2023 foreach my $dep (@{$arr}) {
2024 print "ADD DEP $dep\n";
2025 @deps = (@deps, get_dependencies $dep);
2034 open(OUT, ">$output_config") or dodie "Can not write to $output_config";
2036 foreach my $config (@configs) {
2037 print OUT "$config_set{$config}\n";
2038 my @deps = get_dependencies $config;
2039 foreach my $dep (@deps) {
2040 print OUT "$config_set{$dep}\n";
2044 foreach my $config (keys %config_ignore) {
2045 print OUT "$config_ignore{$config}\n";
2053 sub compare_configs {
2056 foreach my $item (keys %a) {
2057 if (!defined($b{$item})) {
2058 print "diff $item\n";
2066 print "diff2 $keys[0]\n";
2068 return -1 if ($#keys >= 0);
2073 sub run_config_bisect_test {
2076 return run_bisect_test $type, "oldconfig";
2079 sub process_passed {
2082 doprint "These configs had no failure: (Enabling them for further compiles)\n";
2083 # Passed! All these configs are part of a good compile.
2084 # Add them to the min options.
2085 foreach my $config (keys %configs) {
2086 if (defined($config_list{$config})) {
2087 doprint " removing $config\n";
2088 $config_ignore{$config} = $config_list{$config};
2089 delete $config_list{$config};
2092 doprint "config copied to $outputdir/config_good\n";
2093 run_command "cp -f $output_config $outputdir/config_good";
2096 sub process_failed {
2099 doprint "\n\n***************************************\n";
2100 doprint "Found bad config: $config\n";
2101 doprint "***************************************\n\n";
2104 sub run_config_bisect {
2106 my @start_list = keys %config_list;
2108 if ($#start_list < 0) {
2109 doprint "No more configs to test!!!\n";
2113 doprint "***** RUN TEST ***\n";
2114 my $type = $opt{"CONFIG_BISECT_TYPE[$iteration]"};
2118 my $count = $#start_list + 1;
2119 doprint " $count configs to test\n";
2121 my $half = int($#start_list / 2);
2124 my @tophalf = @start_list[0 .. $half];
2126 create_config @tophalf;
2127 read_current_config \%current_config;
2129 $count = $#tophalf + 1;
2130 doprint "Testing $count configs\n";
2132 # make sure we test something
2133 foreach my $config (@tophalf) {
2134 if (defined($current_config{$config})) {
2140 # try the other half
2141 doprint "Top half produced no set configs, trying bottom half\n";
2142 @tophalf = @start_list[$half + 1 .. $#start_list];
2143 create_config @tophalf;
2144 read_current_config \%current_config;
2145 foreach my $config (@tophalf) {
2146 if (defined($current_config{$config})) {
2152 doprint "Failed: Can't make new config with current configs\n";
2153 foreach my $config (@start_list) {
2154 doprint " CONFIG: $config\n";
2158 $count = $#tophalf + 1;
2159 doprint "Testing $count configs\n";
2162 $ret = run_config_bisect_test $type;
2163 if ($bisect_manual) {
2164 $ret = answer_bisect;
2167 process_passed %current_config;
2171 doprint "This config had a failure.\n";
2172 doprint "Removing these configs that were not set in this config:\n";
2173 doprint "config copied to $outputdir/config_bad\n";
2174 run_command "cp -f $output_config $outputdir/config_bad";
2176 # A config exists in this group that was bad.
2177 foreach my $config (keys %config_list) {
2178 if (!defined($current_config{$config})) {
2179 doprint " removing $config\n";
2180 delete $config_list{$config};
2184 @start_list = @tophalf;
2186 if ($#start_list == 0) {
2187 process_failed $start_list[0];
2191 # remove half the configs we are looking at and see if
2193 $half = int($#start_list / 2);
2194 } while ($#start_list > 0);
2196 # we found a single config, try it again unless we are running manually
2198 if ($bisect_manual) {
2199 process_failed $start_list[0];
2203 my @tophalf = @start_list[0 .. 0];
2205 $ret = run_config_bisect_test $type;
2207 process_passed %current_config;
2211 process_failed $start_list[0];
2218 my $start_config = $opt{"CONFIG_BISECT[$i]"};
2220 my $tmpconfig = "$tmpdir/use_config";
2222 if (defined($config_bisect_good)) {
2223 process_config_ignore $config_bisect_good;
2226 # Make the file with the bad config and the min config
2227 if (defined($minconfig)) {
2228 # read the min config for things to ignore
2229 run_command "cp $minconfig $tmpconfig" or
2230 dodie "failed to copy $minconfig to $tmpconfig";
2235 if (-f $tmpconfig) {
2236 load_force_config($tmpconfig);
2237 process_config_ignore $tmpconfig;
2240 # now process the start config
2241 run_command "cp $start_config $output_config" or
2242 dodie "failed to copy $start_config to $output_config";
2244 # read directly what we want to check
2246 open (IN, $output_config)
2247 or dodie "faied to open $output_config";
2250 if (/^((CONFIG\S*)=.*)/) {
2251 $config_check{$2} = $1;
2256 # Now run oldconfig with the minconfig
2259 # check to see what we lost (or gained)
2260 open (IN, $output_config)
2261 or dodie "Failed to read $start_config";
2263 my %removed_configs;
2267 if (/^((CONFIG\S*)=.*)/) {
2268 # save off all options
2269 $config_set{$2} = $1;
2270 if (defined($config_check{$2})) {
2271 if (defined($config_ignore{$2})) {
2272 $removed_configs{$2} = $1;
2274 $config_list{$2} = $1;
2276 } elsif (!defined($config_ignore{$2})) {
2277 $added_configs{$2} = $1;
2278 $config_list{$2} = $1;
2284 my @confs = keys %removed_configs;
2286 doprint "Configs overridden by default configs and removed from check:\n";
2287 foreach my $config (@confs) {
2288 doprint " $config\n";
2291 @confs = keys %added_configs;
2293 doprint "Configs appearing in make oldconfig and added:\n";
2294 foreach my $config (@confs) {
2295 doprint " $config\n";
2302 # Sometimes kconfig does weird things. We must make sure
2303 # that the config we autocreate has everything we need
2304 # to test, otherwise we may miss testing configs, or
2305 # may not be able to create a new config.
2306 # Here we create a config with everything set.
2307 create_config (keys %config_list);
2308 read_current_config \%config_test;
2309 foreach my $config (keys %config_list) {
2310 if (!defined($config_test{$config})) {
2313 doprint "Configs not produced by kconfig (will not be checked):\n";
2315 doprint " $config\n";
2316 delete $config_list{$config};
2321 $ret = run_config_bisect;
2324 return $ret if ($ret < 0);
2329 sub patchcheck_reboot {
2330 doprint "Reboot and sleep $patchcheck_sleep_time seconds\n";
2331 reboot $patchcheck_sleep_time;
2337 die "PATCHCHECK_START[$i] not defined\n"
2338 if (!defined($opt{"PATCHCHECK_START[$i]"}));
2339 die "PATCHCHECK_TYPE[$i] not defined\n"
2340 if (!defined($opt{"PATCHCHECK_TYPE[$i]"}));
2342 my $start = $opt{"PATCHCHECK_START[$i]"};
2345 if (defined($opt{"PATCHCHECK_END[$i]"})) {
2346 $end = $opt{"PATCHCHECK_END[$i]"};
2349 # Get the true sha1's since we can use things like HEAD~3
2350 $start = get_sha1($start);
2351 $end = get_sha1($end);
2353 my $type = $opt{"PATCHCHECK_TYPE[$i]"};
2355 # Can't have a test without having a test to run
2356 if ($type eq "test" && !defined($run_test)) {
2360 open (IN, "git log --pretty=oneline $end|") or
2361 dodie "could not get git list";
2367 $list[$#list+1] = $_;
2368 last if (/^$start/);
2372 if ($list[$#list] !~ /^$start/) {
2373 fail "SHA1 $start not found";
2376 # go backwards in the list
2377 @list = reverse @list;
2379 my $save_clean = $noclean;
2380 my %ignored_warnings;
2382 if (defined($ignore_warnings)) {
2383 foreach my $sha1 (split /\s+/, $ignore_warnings) {
2384 $ignored_warnings{$sha1} = 1;
2389 foreach my $item (@list) {
2391 $sha1 =~ s/^([[:xdigit:]]+).*/$1/;
2393 doprint "\nProcessing commit $item\n\n";
2395 run_command "git checkout $sha1" or
2396 die "Failed to checkout $sha1";
2398 # only clean on the first and last patch
2399 if ($item eq $list[0] ||
2400 $item eq $list[$#list]) {
2401 $noclean = $save_clean;
2406 if (defined($minconfig)) {
2407 build "useconfig:$minconfig" or return 0;
2409 # ?? no config to use?
2410 build "oldconfig" or return 0;
2414 if (!defined($ignored_warnings{$sha1})) {
2415 check_buildlog $sha1 or return 0;
2418 next if ($type eq "build");
2422 start_monitor_and_boot or $failed = 1;
2424 if (!$failed && $type ne "boot"){
2425 do_run_test or $failed = 1;
2428 return 0 if ($failed);
2448 # $config depends on $dep
2449 my ($config, $dep) = @_;
2451 if (defined($depends{$config})) {
2452 $depends{$config} .= " " . $dep;
2454 $depends{$config} = $dep;
2457 # record the number of configs depending on $dep
2458 if (defined $depcount{$dep}) {
2461 $depcount{$dep} = 1;
2465 # taken from streamline_config.pl
2477 if (! -f $kconfig) {
2478 doprint "file $kconfig does not exist, skipping\n";
2482 open(KIN, "$kconfig")
2483 or die "Can't open $kconfig";
2487 # Make sure that lines ending with \ continue
2489 $_ = $line . " " . $_;
2500 # collect any Kconfig sources
2501 if (/^source\s*"(.*)"/) {
2502 $kconfigs[$#kconfigs+1] = $1;
2506 if (/^\s*(menu)?config\s+(\S+)\s*$/) {
2510 for (my $i = 0; $i < $iflevel; $i++) {
2511 add_dep $config, $ifdeps[$i];
2514 # collect the depends for the config
2515 } elsif ($state eq "NEW" && /^\s*depends\s+on\s+(.*)$/) {
2517 add_dep $config, $1;
2519 # Get the configs that select this config
2520 } elsif ($state eq "NEW" && /^\s*select\s+(\S+)/) {
2522 # selected by depends on config
2523 add_dep $1, $config;
2525 # Check for if statements
2526 } elsif (/^if\s+(.*\S)\s*$/) {
2528 # remove beginning and ending non text
2529 $deps =~ s/^[^a-zA-Z0-9_]*//;
2530 $deps =~ s/[^a-zA-Z0-9_]*$//;
2532 my @deps = split /[^a-zA-Z0-9_]+/, $deps;
2534 $ifdeps[$iflevel++] = join ':', @deps;
2536 } elsif (/^endif/) {
2538 $iflevel-- if ($iflevel);
2541 } elsif (/^\s*help\s*$/) {
2547 # read in any configs that were found.
2548 foreach $kconfig (@kconfigs) {
2549 if (!defined($read_kconfigs{$kconfig})) {
2550 $read_kconfigs{$kconfig} = 1;
2551 read_kconfig("$builddir/$kconfig");
2557 # find out which arch this is by the kconfig file
2558 open (IN, $output_config)
2559 or dodie "Failed to read $output_config";
2562 if (m,Linux/(\S+)\s+\S+\s+Kernel Configuration,) {
2569 if (!defined($arch)) {
2570 doprint "Could not find arch from config file\n";
2571 doprint "no dependencies used\n";
2575 # arch is really the subarch, we need to know
2576 # what directory to look at.
2577 if ($arch eq "i386" || $arch eq "x86_64") {
2579 } elsif ($arch =~ /^tile/) {
2583 my $kconfig = "$builddir/arch/$arch/Kconfig";
2585 if (! -f $kconfig && $arch =~ /\d$/) {
2587 # some subarchs have numbers, truncate them
2589 $kconfig = "$builddir/arch/$arch/Kconfig";
2590 if (! -f $kconfig) {
2591 doprint "No idea what arch dir $orig is for\n";
2592 doprint "no dependencies used\n";
2597 read_kconfig($kconfig);
2600 sub read_config_list {
2604 or dodie "Failed to read $config";
2607 if (/^((CONFIG\S*)=.*)/) {
2608 if (!defined($config_ignore{$2})) {
2609 $config_list{$2} = $1;
2617 sub read_output_config {
2620 assign_configs \%config_ignore, $config;
2623 sub make_new_config {
2626 open (OUT, ">$output_config")
2627 or dodie "Failed to write $output_config";
2629 foreach my $config (@configs) {
2630 print OUT "$config\n";
2638 $config =~ s/CONFIG_//;
2646 my $kconfig = chomp_config $dep;
2648 $dep = $depends{"$kconfig"};
2650 # the dep string we have saves the dependencies as they
2651 # were found, including expressions like ! && ||. We
2652 # want to split this out into just an array of configs.
2654 my $valid = "A-Za-z_0-9";
2658 while ($dep =~ /[$valid]/) {
2660 if ($dep =~ /^[^$valid]*([$valid]+)/) {
2661 my $conf = "CONFIG_" . $1;
2663 $configs[$#configs + 1] = $conf;
2665 $dep =~ s/^[^$valid]*[$valid]+//;
2667 die "this should never happen";
2677 my %processed_configs;
2678 my %nochange_config;
2680 sub test_this_config {
2685 # if we already processed this config, skip it
2686 if (defined($processed_configs{$config})) {
2689 $processed_configs{$config} = 1;
2691 # if this config failed during this round, skip it
2692 if (defined($nochange_config{$config})) {
2696 my $kconfig = chomp_config $config;
2698 # Test dependencies first
2699 if (defined($depends{"$kconfig"})) {
2700 my @parents = get_depends $config;
2701 foreach my $parent (@parents) {
2702 # if the parent is in the min config, check it first
2703 next if (!defined($min_configs{$parent}));
2704 $found = test_this_config($parent);
2705 if (defined($found)) {
2711 # Remove this config from the list of configs
2712 # do a make oldnoconfig and then read the resulting
2713 # .config to make sure it is missing the config that
2715 my %configs = %min_configs;
2716 delete $configs{$config};
2717 make_new_config ((values %configs), (values %keep_configs));
2720 assign_configs \%configs, $output_config;
2722 return $config if (!defined($configs{$config}));
2724 doprint "disabling config $config did not change .config\n";
2726 $nochange_config{$config} = 1;
2731 sub make_min_config {
2734 if (!defined($output_minconfig)) {
2735 fail "OUTPUT_MIN_CONFIG not defined" and return;
2738 # If output_minconfig exists, and the start_minconfig
2739 # came from min_config, than ask if we should use
2741 if (-f $output_minconfig && !$start_minconfig_defined) {
2742 print "$output_minconfig exists\n";
2743 if (read_yn " Use it as minconfig?") {
2744 $start_minconfig = $output_minconfig;
2748 if (!defined($start_minconfig)) {
2749 fail "START_MIN_CONFIG or MIN_CONFIG not defined" and return;
2752 my $temp_config = "$tmpdir/temp_config";
2754 # First things first. We build an allnoconfig to find
2755 # out what the defaults are that we can't touch.
2756 # Some are selections, but we really can't handle selections.
2758 my $save_minconfig = $minconfig;
2761 run_command "$make allnoconfig" or return 0;
2765 process_config_ignore $output_config;
2767 undef %save_configs;
2770 if (defined($ignore_config)) {
2771 # make sure the file exists
2772 `touch $ignore_config`;
2773 assign_configs \%save_configs, $ignore_config;
2776 %keep_configs = %save_configs;
2778 doprint "Load initial configs from $start_minconfig\n";
2780 # Look at the current min configs, and save off all the
2781 # ones that were set via the allnoconfig
2782 assign_configs \%min_configs, $start_minconfig;
2784 my @config_keys = keys %min_configs;
2786 # All configs need a depcount
2787 foreach my $config (@config_keys) {
2788 my $kconfig = chomp_config $config;
2789 if (!defined $depcount{$kconfig}) {
2790 $depcount{$kconfig} = 0;
2794 # Remove anything that was set by the make allnoconfig
2795 # we shouldn't need them as they get set for us anyway.
2796 foreach my $config (@config_keys) {
2797 # Remove anything in the ignore_config
2798 if (defined($keep_configs{$config})) {
2799 my $file = $ignore_config;
2800 $file =~ s,.*/(.*?)$,$1,;
2801 doprint "$config set by $file ... ignored\n";
2802 delete $min_configs{$config};
2805 # But make sure the settings are the same. If a min config
2806 # sets a selection, we do not want to get rid of it if
2807 # it is not the same as what we have. Just move it into
2809 if (defined($config_ignore{$config})) {
2810 if ($config_ignore{$config} ne $min_configs{$config}) {
2811 doprint "$config is in allnoconfig as '$config_ignore{$config}'";
2812 doprint " but it is '$min_configs{$config}' in minconfig .. keeping\n";
2813 $keep_configs{$config} = $min_configs{$config};
2815 doprint "$config set by allnoconfig ... ignored\n";
2817 delete $min_configs{$config};
2829 # Now disable each config one by one and do a make oldconfig
2830 # till we find a config that changes our list.
2832 my @test_configs = keys %min_configs;
2834 # Sort keys by who is most dependent on
2835 @test_configs = sort { $depcount{chomp_config($b)} <=> $depcount{chomp_config($a)} }
2838 # Put configs that did not modify the config at the end.
2840 for (my $i = 0; $i < $#test_configs; $i++) {
2841 if (!defined($nochange_config{$test_configs[0]})) {
2845 # This config didn't change the .config last time.
2846 # Place it at the end
2847 my $config = shift @test_configs;
2848 push @test_configs, $config;
2851 # if every test config has failed to modify the .config file
2852 # in the past, then reset and start over.
2854 undef %nochange_config;
2857 undef %processed_configs;
2859 foreach my $config (@test_configs) {
2861 $found = test_this_config $config;
2863 last if (defined($found));
2865 # oh well, try another config
2868 if (!defined($found)) {
2869 # we could have failed due to the nochange_config hash
2870 # reset and try again
2872 undef %nochange_config;
2876 doprint "No more configs found that we can disable\n";
2884 doprint "Test with $config disabled\n";
2886 # set in_bisect to keep build and monitor from dieing
2891 start_monitor_and_boot or $failed = 1;
2897 doprint "$min_configs{$config} is needed to boot the box... keeping\n";
2898 # this config is needed, add it to the ignore list.
2899 $keep_configs{$config} = $min_configs{$config};
2900 $save_configs{$config} = $min_configs{$config};
2901 delete $min_configs{$config};
2903 # update new ignore configs
2904 if (defined($ignore_config)) {
2905 open (OUT, ">$temp_config")
2906 or die "Can't write to $temp_config";
2907 foreach my $config (keys %save_configs) {
2908 print OUT "$save_configs{$config}\n";
2911 run_command "mv $temp_config $ignore_config" or
2912 dodie "failed to copy update to $ignore_config";
2916 # We booted without this config, remove it from the minconfigs.
2917 doprint "$config is not needed, disabling\n";
2919 delete $min_configs{$config};
2921 # Also disable anything that is not enabled in this config
2923 assign_configs \%configs, $output_config;
2924 my @config_keys = keys %min_configs;
2925 foreach my $config (@config_keys) {
2926 if (!defined($configs{$config})) {
2927 doprint "$config is not set, disabling\n";
2928 delete $min_configs{$config};
2932 # Save off all the current mandidory configs
2933 open (OUT, ">$temp_config")
2934 or die "Can't write to $temp_config";
2935 foreach my $config (keys %keep_configs) {
2936 print OUT "$keep_configs{$config}\n";
2938 foreach my $config (keys %min_configs) {
2939 print OUT "$min_configs{$config}\n";
2943 run_command "mv $temp_config $output_minconfig" or
2944 dodie "failed to copy update to $output_minconfig";
2947 doprint "Reboot and wait $sleep_time seconds\n";
2955 $#ARGV < 1 or die "ktest.pl version: $VERSION\n usage: ktest.pl config-file\n";
2958 $ktest_config = $ARGV[0];
2959 if (! -f $ktest_config) {
2960 print "$ktest_config does not exist.\n";
2961 if (!read_yn "Create it?") {
2966 $ktest_config = "ktest.conf";
2969 if (! -f $ktest_config) {
2970 open(OUT, ">$ktest_config") or die "Can not create $ktest_config";
2972 # Generated by ktest.pl
2974 # Define each test with TEST_START
2975 # The config options below it will override the defaults
2983 read_config $ktest_config;
2985 if (defined($opt{"LOG_FILE"})) {
2986 $opt{"LOG_FILE"} = eval_option($opt{"LOG_FILE"}, -1);
2989 # Append any configs entered in manually to the config file.
2990 my @new_configs = keys %entered_configs;
2991 if ($#new_configs >= 0) {
2992 print "\nAppending entered in configs to $ktest_config\n";
2993 open(OUT, ">>$ktest_config") or die "Can not append to $ktest_config";
2994 foreach my $config (@new_configs) {
2995 print OUT "$config = $entered_configs{$config}\n";
2996 $opt{$config} = $entered_configs{$config};
3000 if ($opt{"CLEAR_LOG"} && defined($opt{"LOG_FILE"})) {
3001 unlink $opt{"LOG_FILE"};
3004 doprint "\n\nSTARTING AUTOMATED TESTS\n\n";
3006 for (my $i = 0, my $repeat = 1; $i <= $opt{"NUM_TESTS"}; $i += $repeat) {
3009 doprint "DEFAULT OPTIONS:\n";
3011 doprint "\nTEST $i OPTIONS";
3012 if (defined($repeat_tests{$i})) {
3013 $repeat = $repeat_tests{$i};
3014 doprint " ITERATE $repeat";
3019 foreach my $option (sort keys %opt) {
3021 if ($option =~ /\[(\d+)\]$/) {
3027 doprint "$option = $opt{$option}\n";
3031 sub __set_test_option {
3032 my ($name, $i) = @_;
3034 my $option = "$name\[$i\]";
3036 if (defined($opt{$option})) {
3037 return $opt{$option};
3040 foreach my $test (keys %repeat_tests) {
3042 $i < $test + $repeat_tests{$test}) {
3043 $option = "$name\[$test\]";
3044 if (defined($opt{$option})) {
3045 return $opt{$option};
3050 if (defined($opt{$name})) {
3057 sub set_test_option {
3058 my ($name, $i) = @_;
3060 my $option = __set_test_option($name, $i);
3061 return $option if (!defined($option));
3063 return eval_option($option, $i);
3066 # First we need to do is the builds
3067 for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
3069 # Do not reboot on failing test options
3074 my $makecmd = set_test_option("MAKE_CMD", $i);
3076 $machine = set_test_option("MACHINE", $i);
3077 $ssh_user = set_test_option("SSH_USER", $i);
3078 $tmpdir = set_test_option("TMP_DIR", $i);
3079 $outputdir = set_test_option("OUTPUT_DIR", $i);
3080 $builddir = set_test_option("BUILD_DIR", $i);
3081 $test_type = set_test_option("TEST_TYPE", $i);
3082 $build_type = set_test_option("BUILD_TYPE", $i);
3083 $build_options = set_test_option("BUILD_OPTIONS", $i);
3084 $pre_build = set_test_option("PRE_BUILD", $i);
3085 $post_build = set_test_option("POST_BUILD", $i);
3086 $pre_build_die = set_test_option("PRE_BUILD_DIE", $i);
3087 $post_build_die = set_test_option("POST_BUILD_DIE", $i);
3088 $power_cycle = set_test_option("POWER_CYCLE", $i);
3089 $reboot = set_test_option("REBOOT", $i);
3090 $noclean = set_test_option("BUILD_NOCLEAN", $i);
3091 $minconfig = set_test_option("MIN_CONFIG", $i);
3092 $output_minconfig = set_test_option("OUTPUT_MIN_CONFIG", $i);
3093 $start_minconfig = set_test_option("START_MIN_CONFIG", $i);
3094 $ignore_config = set_test_option("IGNORE_CONFIG", $i);
3095 $run_test = set_test_option("TEST", $i);
3096 $addconfig = set_test_option("ADD_CONFIG", $i);
3097 $reboot_type = set_test_option("REBOOT_TYPE", $i);
3098 $grub_menu = set_test_option("GRUB_MENU", $i);
3099 $post_install = set_test_option("POST_INSTALL", $i);
3100 $no_install = set_test_option("NO_INSTALL", $i);
3101 $reboot_script = set_test_option("REBOOT_SCRIPT", $i);
3102 $reboot_on_error = set_test_option("REBOOT_ON_ERROR", $i);
3103 $poweroff_on_error = set_test_option("POWEROFF_ON_ERROR", $i);
3104 $die_on_failure = set_test_option("DIE_ON_FAILURE", $i);
3105 $power_off = set_test_option("POWER_OFF", $i);
3106 $powercycle_after_reboot = set_test_option("POWERCYCLE_AFTER_REBOOT", $i);
3107 $poweroff_after_halt = set_test_option("POWEROFF_AFTER_HALT", $i);
3108 $sleep_time = set_test_option("SLEEP_TIME", $i);
3109 $bisect_sleep_time = set_test_option("BISECT_SLEEP_TIME", $i);
3110 $patchcheck_sleep_time = set_test_option("PATCHCHECK_SLEEP_TIME", $i);
3111 $ignore_warnings = set_test_option("IGNORE_WARNINGS", $i);
3112 $bisect_manual = set_test_option("BISECT_MANUAL", $i);
3113 $bisect_skip = set_test_option("BISECT_SKIP", $i);
3114 $config_bisect_good = set_test_option("CONFIG_BISECT_GOOD", $i);
3115 $store_failures = set_test_option("STORE_FAILURES", $i);
3116 $test_name = set_test_option("TEST_NAME", $i);
3117 $timeout = set_test_option("TIMEOUT", $i);
3118 $booted_timeout = set_test_option("BOOTED_TIMEOUT", $i);
3119 $console = set_test_option("CONSOLE", $i);
3120 $detect_triplefault = set_test_option("DETECT_TRIPLE_FAULT", $i);
3121 $success_line = set_test_option("SUCCESS_LINE", $i);
3122 $reboot_success_line = set_test_option("REBOOT_SUCCESS_LINE", $i);
3123 $stop_after_success = set_test_option("STOP_AFTER_SUCCESS", $i);
3124 $stop_after_failure = set_test_option("STOP_AFTER_FAILURE", $i);
3125 $stop_test_after = set_test_option("STOP_TEST_AFTER", $i);
3126 $build_target = set_test_option("BUILD_TARGET", $i);
3127 $ssh_exec = set_test_option("SSH_EXEC", $i);
3128 $scp_to_target = set_test_option("SCP_TO_TARGET", $i);
3129 $target_image = set_test_option("TARGET_IMAGE", $i);
3130 $localversion = set_test_option("LOCALVERSION", $i);
3132 $start_minconfig_defined = 1;
3134 if (!defined($start_minconfig)) {
3135 $start_minconfig_defined = 0;
3136 $start_minconfig = $minconfig;
3139 chdir $builddir || die "can't change directory to $builddir";
3141 foreach my $dir ($tmpdir, $outputdir) {
3144 die "can't create $dir";
3148 $ENV{"SSH_USER"} = $ssh_user;
3149 $ENV{"MACHINE"} = $machine;
3151 $target = "$ssh_user\@$machine";
3153 $buildlog = "$tmpdir/buildlog-$machine";
3154 $dmesg = "$tmpdir/dmesg-$machine";
3155 $make = "$makecmd O=$outputdir";
3156 $output_config = "$outputdir/.config";
3158 if ($reboot_type eq "grub") {
3159 dodie "GRUB_MENU not defined" if (!defined($grub_menu));
3160 } elsif (!defined($reboot_script)) {
3161 dodie "REBOOT_SCRIPT not defined"
3164 my $run_type = $build_type;
3165 if ($test_type eq "patchcheck") {
3166 $run_type = $opt{"PATCHCHECK_TYPE[$i]"};
3167 } elsif ($test_type eq "bisect") {
3168 $run_type = $opt{"BISECT_TYPE[$i]"};
3169 } elsif ($test_type eq "config_bisect") {
3170 $run_type = $opt{"CONFIG_BISECT_TYPE[$i]"};
3173 if ($test_type eq "make_min_config") {
3177 # mistake in config file?
3178 if (!defined($run_type)) {
3179 $run_type = "ERROR";
3183 $installme = " no_install" if ($no_install);
3186 doprint "RUNNING TEST $i of $opt{NUM_TESTS} with option $test_type $run_type$installme\n\n";
3191 if (defined($addconfig)) {
3192 my $min = $minconfig;
3193 if (!defined($minconfig)) {
3196 run_command "cat $addconfig $min > $tmpdir/add_config" or
3197 dodie "Failed to create temp config";
3198 $minconfig = "$tmpdir/add_config";
3201 my $checkout = $opt{"CHECKOUT[$i]"};
3202 if (defined($checkout)) {
3203 run_command "git checkout $checkout" or
3204 die "failed to checkout $checkout";
3210 if ($test_type eq "bisect") {
3213 } elsif ($test_type eq "config_bisect") {
3216 } elsif ($test_type eq "patchcheck") {
3219 } elsif ($test_type eq "make_min_config") {
3224 if ($build_type ne "nobuild") {
3225 build $build_type or next;
3228 if ($test_type eq "install") {
3235 if ($test_type ne "build") {
3237 start_monitor_and_boot or $failed = 1;
3239 if (!$failed && $test_type ne "boot" && defined($run_test)) {
3240 do_run_test or $failed = 1;
3249 if ($opt{"POWEROFF_ON_SUCCESS"}) {
3251 } elsif ($opt{"REBOOT_ON_SUCCESS"} && !do_not_reboot) {
3255 doprint "\n $successes of $opt{NUM_TESTS} tests were successful\n\n";