x86/mm: Remove preempt_disable/enable() from __native_flush_tlb()
[linux/fpc-iii.git] / tools / testing / ktest / ktest.pl
blob0c8b61f8398edace8b4d7be42e50b8638679520d
1 #!/usr/bin/perl -w
3 # Copyright 2010 - Steven Rostedt <srostedt@redhat.com>, Red Hat Inc.
4 # Licensed under the terms of the GNU GPL License version 2
7 use strict;
8 use IPC::Open2;
9 use Fcntl qw(F_GETFL F_SETFL O_NONBLOCK);
10 use File::Path qw(mkpath);
11 use File::Copy qw(cp);
12 use FileHandle;
14 my $VERSION = "0.2";
16 $| = 1;
18 my %opt;
19 my %repeat_tests;
20 my %repeats;
21 my %evals;
23 #default opts
24 my %default = (
25 "NUM_TESTS" => 1,
26 "TEST_TYPE" => "build",
27 "BUILD_TYPE" => "randconfig",
28 "MAKE_CMD" => "make",
29 "CLOSE_CONSOLE_SIGNAL" => "INT",
30 "TIMEOUT" => 120,
31 "TMP_DIR" => "/tmp/ktest/\${MACHINE}",
32 "SLEEP_TIME" => 60, # sleep time between tests
33 "BUILD_NOCLEAN" => 0,
34 "REBOOT_ON_ERROR" => 0,
35 "POWEROFF_ON_ERROR" => 0,
36 "REBOOT_ON_SUCCESS" => 1,
37 "POWEROFF_ON_SUCCESS" => 0,
38 "BUILD_OPTIONS" => "",
39 "BISECT_SLEEP_TIME" => 60, # sleep time between bisects
40 "PATCHCHECK_SLEEP_TIME" => 60, # sleep time between patch checks
41 "CLEAR_LOG" => 0,
42 "BISECT_MANUAL" => 0,
43 "BISECT_SKIP" => 1,
44 "BISECT_TRIES" => 1,
45 "MIN_CONFIG_TYPE" => "boot",
46 "SUCCESS_LINE" => "login:",
47 "DETECT_TRIPLE_FAULT" => 1,
48 "NO_INSTALL" => 0,
49 "BOOTED_TIMEOUT" => 1,
50 "DIE_ON_FAILURE" => 1,
51 "SSH_EXEC" => "ssh \$SSH_USER\@\$MACHINE \$SSH_COMMAND",
52 "SCP_TO_TARGET" => "scp \$SRC_FILE \$SSH_USER\@\$MACHINE:\$DST_FILE",
53 "SCP_TO_TARGET_INSTALL" => "\${SCP_TO_TARGET}",
54 "REBOOT" => "ssh \$SSH_USER\@\$MACHINE reboot",
55 "STOP_AFTER_SUCCESS" => 10,
56 "STOP_AFTER_FAILURE" => 60,
57 "STOP_TEST_AFTER" => 600,
58 "MAX_MONITOR_WAIT" => 1800,
59 "GRUB_REBOOT" => "grub2-reboot",
60 "SYSLINUX" => "extlinux",
61 "SYSLINUX_PATH" => "/boot/extlinux",
63 # required, and we will ask users if they don't have them but we keep the default
64 # value something that is common.
65 "REBOOT_TYPE" => "grub",
66 "LOCALVERSION" => "-test",
67 "SSH_USER" => "root",
68 "BUILD_TARGET" => "arch/x86/boot/bzImage",
69 "TARGET_IMAGE" => "/boot/vmlinuz-test",
71 "LOG_FILE" => undef,
72 "IGNORE_UNUSED" => 0,
75 my $ktest_config = "ktest.conf";
76 my $version;
77 my $have_version = 0;
78 my $machine;
79 my $last_machine;
80 my $ssh_user;
81 my $tmpdir;
82 my $builddir;
83 my $outputdir;
84 my $output_config;
85 my $test_type;
86 my $build_type;
87 my $build_options;
88 my $final_post_ktest;
89 my $pre_ktest;
90 my $post_ktest;
91 my $pre_test;
92 my $post_test;
93 my $pre_build;
94 my $post_build;
95 my $pre_build_die;
96 my $post_build_die;
97 my $reboot_type;
98 my $reboot_script;
99 my $power_cycle;
100 my $reboot;
101 my $reboot_on_error;
102 my $switch_to_good;
103 my $switch_to_test;
104 my $poweroff_on_error;
105 my $reboot_on_success;
106 my $die_on_failure;
107 my $powercycle_after_reboot;
108 my $poweroff_after_halt;
109 my $max_monitor_wait;
110 my $ssh_exec;
111 my $scp_to_target;
112 my $scp_to_target_install;
113 my $power_off;
114 my $grub_menu;
115 my $last_grub_menu;
116 my $grub_file;
117 my $grub_number;
118 my $grub_reboot;
119 my $syslinux;
120 my $syslinux_path;
121 my $syslinux_label;
122 my $target;
123 my $make;
124 my $pre_install;
125 my $post_install;
126 my $no_install;
127 my $noclean;
128 my $minconfig;
129 my $start_minconfig;
130 my $start_minconfig_defined;
131 my $output_minconfig;
132 my $minconfig_type;
133 my $use_output_minconfig;
134 my $warnings_file;
135 my $ignore_config;
136 my $ignore_errors;
137 my $addconfig;
138 my $in_bisect = 0;
139 my $bisect_bad_commit = "";
140 my $reverse_bisect;
141 my $bisect_manual;
142 my $bisect_skip;
143 my $bisect_tries;
144 my $config_bisect_good;
145 my $bisect_ret_good;
146 my $bisect_ret_bad;
147 my $bisect_ret_skip;
148 my $bisect_ret_abort;
149 my $bisect_ret_default;
150 my $in_patchcheck = 0;
151 my $run_test;
152 my $buildlog;
153 my $testlog;
154 my $dmesg;
155 my $monitor_fp;
156 my $monitor_pid;
157 my $monitor_cnt = 0;
158 my $sleep_time;
159 my $bisect_sleep_time;
160 my $patchcheck_sleep_time;
161 my $ignore_warnings;
162 my $store_failures;
163 my $store_successes;
164 my $test_name;
165 my $timeout;
166 my $booted_timeout;
167 my $detect_triplefault;
168 my $console;
169 my $close_console_signal;
170 my $reboot_success_line;
171 my $success_line;
172 my $stop_after_success;
173 my $stop_after_failure;
174 my $stop_test_after;
175 my $build_target;
176 my $target_image;
177 my $checkout;
178 my $localversion;
179 my $iteration = 0;
180 my $successes = 0;
181 my $stty_orig;
182 my $run_command_status = 0;
184 my $bisect_good;
185 my $bisect_bad;
186 my $bisect_type;
187 my $bisect_start;
188 my $bisect_replay;
189 my $bisect_files;
190 my $bisect_reverse;
191 my $bisect_check;
193 my $config_bisect;
194 my $config_bisect_type;
195 my $config_bisect_check;
197 my $patchcheck_type;
198 my $patchcheck_start;
199 my $patchcheck_cherry;
200 my $patchcheck_end;
202 my $build_time;
203 my $install_time;
204 my $reboot_time;
205 my $test_time;
207 # set when a test is something other that just building or install
208 # which would require more options.
209 my $buildonly = 1;
211 # tell build not to worry about warnings, even when WARNINGS_FILE is set
212 my $warnings_ok = 0;
214 # set when creating a new config
215 my $newconfig = 0;
217 my %entered_configs;
218 my %config_help;
219 my %variable;
221 # force_config is the list of configs that we force enabled (or disabled)
222 # in a .config file. The MIN_CONFIG and ADD_CONFIG configs.
223 my %force_config;
225 # do not force reboots on config problems
226 my $no_reboot = 1;
228 # reboot on success
229 my $reboot_success = 0;
231 my %option_map = (
232 "MACHINE" => \$machine,
233 "SSH_USER" => \$ssh_user,
234 "TMP_DIR" => \$tmpdir,
235 "OUTPUT_DIR" => \$outputdir,
236 "BUILD_DIR" => \$builddir,
237 "TEST_TYPE" => \$test_type,
238 "PRE_KTEST" => \$pre_ktest,
239 "POST_KTEST" => \$post_ktest,
240 "PRE_TEST" => \$pre_test,
241 "POST_TEST" => \$post_test,
242 "BUILD_TYPE" => \$build_type,
243 "BUILD_OPTIONS" => \$build_options,
244 "PRE_BUILD" => \$pre_build,
245 "POST_BUILD" => \$post_build,
246 "PRE_BUILD_DIE" => \$pre_build_die,
247 "POST_BUILD_DIE" => \$post_build_die,
248 "POWER_CYCLE" => \$power_cycle,
249 "REBOOT" => \$reboot,
250 "BUILD_NOCLEAN" => \$noclean,
251 "MIN_CONFIG" => \$minconfig,
252 "OUTPUT_MIN_CONFIG" => \$output_minconfig,
253 "START_MIN_CONFIG" => \$start_minconfig,
254 "MIN_CONFIG_TYPE" => \$minconfig_type,
255 "USE_OUTPUT_MIN_CONFIG" => \$use_output_minconfig,
256 "WARNINGS_FILE" => \$warnings_file,
257 "IGNORE_CONFIG" => \$ignore_config,
258 "TEST" => \$run_test,
259 "ADD_CONFIG" => \$addconfig,
260 "REBOOT_TYPE" => \$reboot_type,
261 "GRUB_MENU" => \$grub_menu,
262 "GRUB_FILE" => \$grub_file,
263 "GRUB_REBOOT" => \$grub_reboot,
264 "SYSLINUX" => \$syslinux,
265 "SYSLINUX_PATH" => \$syslinux_path,
266 "SYSLINUX_LABEL" => \$syslinux_label,
267 "PRE_INSTALL" => \$pre_install,
268 "POST_INSTALL" => \$post_install,
269 "NO_INSTALL" => \$no_install,
270 "REBOOT_SCRIPT" => \$reboot_script,
271 "REBOOT_ON_ERROR" => \$reboot_on_error,
272 "SWITCH_TO_GOOD" => \$switch_to_good,
273 "SWITCH_TO_TEST" => \$switch_to_test,
274 "POWEROFF_ON_ERROR" => \$poweroff_on_error,
275 "REBOOT_ON_SUCCESS" => \$reboot_on_success,
276 "DIE_ON_FAILURE" => \$die_on_failure,
277 "POWER_OFF" => \$power_off,
278 "POWERCYCLE_AFTER_REBOOT" => \$powercycle_after_reboot,
279 "POWEROFF_AFTER_HALT" => \$poweroff_after_halt,
280 "MAX_MONITOR_WAIT" => \$max_monitor_wait,
281 "SLEEP_TIME" => \$sleep_time,
282 "BISECT_SLEEP_TIME" => \$bisect_sleep_time,
283 "PATCHCHECK_SLEEP_TIME" => \$patchcheck_sleep_time,
284 "IGNORE_WARNINGS" => \$ignore_warnings,
285 "IGNORE_ERRORS" => \$ignore_errors,
286 "BISECT_MANUAL" => \$bisect_manual,
287 "BISECT_SKIP" => \$bisect_skip,
288 "BISECT_TRIES" => \$bisect_tries,
289 "CONFIG_BISECT_GOOD" => \$config_bisect_good,
290 "BISECT_RET_GOOD" => \$bisect_ret_good,
291 "BISECT_RET_BAD" => \$bisect_ret_bad,
292 "BISECT_RET_SKIP" => \$bisect_ret_skip,
293 "BISECT_RET_ABORT" => \$bisect_ret_abort,
294 "BISECT_RET_DEFAULT" => \$bisect_ret_default,
295 "STORE_FAILURES" => \$store_failures,
296 "STORE_SUCCESSES" => \$store_successes,
297 "TEST_NAME" => \$test_name,
298 "TIMEOUT" => \$timeout,
299 "BOOTED_TIMEOUT" => \$booted_timeout,
300 "CONSOLE" => \$console,
301 "CLOSE_CONSOLE_SIGNAL" => \$close_console_signal,
302 "DETECT_TRIPLE_FAULT" => \$detect_triplefault,
303 "SUCCESS_LINE" => \$success_line,
304 "REBOOT_SUCCESS_LINE" => \$reboot_success_line,
305 "STOP_AFTER_SUCCESS" => \$stop_after_success,
306 "STOP_AFTER_FAILURE" => \$stop_after_failure,
307 "STOP_TEST_AFTER" => \$stop_test_after,
308 "BUILD_TARGET" => \$build_target,
309 "SSH_EXEC" => \$ssh_exec,
310 "SCP_TO_TARGET" => \$scp_to_target,
311 "SCP_TO_TARGET_INSTALL" => \$scp_to_target_install,
312 "CHECKOUT" => \$checkout,
313 "TARGET_IMAGE" => \$target_image,
314 "LOCALVERSION" => \$localversion,
316 "BISECT_GOOD" => \$bisect_good,
317 "BISECT_BAD" => \$bisect_bad,
318 "BISECT_TYPE" => \$bisect_type,
319 "BISECT_START" => \$bisect_start,
320 "BISECT_REPLAY" => \$bisect_replay,
321 "BISECT_FILES" => \$bisect_files,
322 "BISECT_REVERSE" => \$bisect_reverse,
323 "BISECT_CHECK" => \$bisect_check,
325 "CONFIG_BISECT" => \$config_bisect,
326 "CONFIG_BISECT_TYPE" => \$config_bisect_type,
327 "CONFIG_BISECT_CHECK" => \$config_bisect_check,
329 "PATCHCHECK_TYPE" => \$patchcheck_type,
330 "PATCHCHECK_START" => \$patchcheck_start,
331 "PATCHCHECK_CHERRY" => \$patchcheck_cherry,
332 "PATCHCHECK_END" => \$patchcheck_end,
335 # Options may be used by other options, record them.
336 my %used_options;
338 # default variables that can be used
339 chomp ($variable{"PWD"} = `pwd`);
341 $config_help{"MACHINE"} = << "EOF"
342 The machine hostname that you will test.
343 For build only tests, it is still needed to differentiate log files.
346 $config_help{"SSH_USER"} = << "EOF"
347 The box is expected to have ssh on normal bootup, provide the user
348 (most likely root, since you need privileged operations)
351 $config_help{"BUILD_DIR"} = << "EOF"
352 The directory that contains the Linux source code (full path).
353 You can use \${PWD} that will be the path where ktest.pl is run, or use
354 \${THIS_DIR} which is assigned \${PWD} but may be changed later.
357 $config_help{"OUTPUT_DIR"} = << "EOF"
358 The directory that the objects will be built (full path).
359 (can not be same as BUILD_DIR)
360 You can use \${PWD} that will be the path where ktest.pl is run, or use
361 \${THIS_DIR} which is assigned \${PWD} but may be changed later.
364 $config_help{"BUILD_TARGET"} = << "EOF"
365 The location of the compiled file to copy to the target.
366 (relative to OUTPUT_DIR)
369 $config_help{"BUILD_OPTIONS"} = << "EOF"
370 Options to add to \"make\" when building.
371 i.e. -j20
374 $config_help{"TARGET_IMAGE"} = << "EOF"
375 The place to put your image on the test machine.
378 $config_help{"POWER_CYCLE"} = << "EOF"
379 A script or command to reboot the box.
381 Here is a digital loggers power switch example
382 POWER_CYCLE = wget --no-proxy -O /dev/null -q --auth-no-challenge 'http://admin:admin\@power/outlet?5=CCL'
384 Here is an example to reboot a virtual box on the current host
385 with the name "Guest".
386 POWER_CYCLE = virsh destroy Guest; sleep 5; virsh start Guest
389 $config_help{"CONSOLE"} = << "EOF"
390 The script or command that reads the console
392 If you use ttywatch server, something like the following would work.
393 CONSOLE = nc -d localhost 3001
395 For a virtual machine with guest name "Guest".
396 CONSOLE = virsh console Guest
399 $config_help{"LOCALVERSION"} = << "EOF"
400 Required version ending to differentiate the test
401 from other linux builds on the system.
404 $config_help{"REBOOT_TYPE"} = << "EOF"
405 Way to reboot the box to the test kernel.
406 Only valid options so far are "grub", "grub2", "syslinux", and "script".
408 If you specify grub, it will assume grub version 1
409 and will search in /boot/grub/menu.lst for the title \$GRUB_MENU
410 and select that target to reboot to the kernel. If this is not
411 your setup, then specify "script" and have a command or script
412 specified in REBOOT_SCRIPT to boot to the target.
414 The entry in /boot/grub/menu.lst must be entered in manually.
415 The test will not modify that file.
417 If you specify grub2, then you also need to specify both \$GRUB_MENU
418 and \$GRUB_FILE.
420 If you specify syslinux, then you may use SYSLINUX to define the syslinux
421 command (defaults to extlinux), and SYSLINUX_PATH to specify the path to
422 the syslinux install (defaults to /boot/extlinux). But you have to specify
423 SYSLINUX_LABEL to define the label to boot to for the test kernel.
426 $config_help{"GRUB_MENU"} = << "EOF"
427 The grub title name for the test kernel to boot
428 (Only mandatory if REBOOT_TYPE = grub or grub2)
430 Note, ktest.pl will not update the grub menu.lst, you need to
431 manually add an option for the test. ktest.pl will search
432 the grub menu.lst for this option to find what kernel to
433 reboot into.
435 For example, if in the /boot/grub/menu.lst the test kernel title has:
436 title Test Kernel
437 kernel vmlinuz-test
438 GRUB_MENU = Test Kernel
440 For grub2, a search of \$GRUB_FILE is performed for the lines
441 that begin with "menuentry". It will not detect submenus. The
442 menu must be a non-nested menu. Add the quotes used in the menu
443 to guarantee your selection, as the first menuentry with the content
444 of \$GRUB_MENU that is found will be used.
447 $config_help{"GRUB_FILE"} = << "EOF"
448 If grub2 is used, the full path for the grub.cfg file is placed
449 here. Use something like /boot/grub2/grub.cfg to search.
452 $config_help{"SYSLINUX_LABEL"} = << "EOF"
453 If syslinux is used, the label that boots the target kernel must
454 be specified with SYSLINUX_LABEL.
457 $config_help{"REBOOT_SCRIPT"} = << "EOF"
458 A script to reboot the target into the test kernel
459 (Only mandatory if REBOOT_TYPE = script)
463 sub _logit {
464 if (defined($opt{"LOG_FILE"})) {
465 open(OUT, ">> $opt{LOG_FILE}") or die "Can't write to $opt{LOG_FILE}";
466 print OUT @_;
467 close(OUT);
471 sub logit {
472 if (defined($opt{"LOG_FILE"})) {
473 _logit @_;
474 } else {
475 print @_;
479 sub doprint {
480 print @_;
481 _logit @_;
484 sub read_prompt {
485 my ($cancel, $prompt) = @_;
487 my $ans;
489 for (;;) {
490 if ($cancel) {
491 print "$prompt [y/n/C] ";
492 } else {
493 print "$prompt [Y/n] ";
495 $ans = <STDIN>;
496 chomp $ans;
497 if ($ans =~ /^\s*$/) {
498 if ($cancel) {
499 $ans = "c";
500 } else {
501 $ans = "y";
504 last if ($ans =~ /^y$/i || $ans =~ /^n$/i);
505 if ($cancel) {
506 last if ($ans =~ /^c$/i);
507 print "Please answer either 'y', 'n' or 'c'.\n";
508 } else {
509 print "Please answer either 'y' or 'n'.\n";
512 if ($ans =~ /^c/i) {
513 exit;
515 if ($ans !~ /^y$/i) {
516 return 0;
518 return 1;
521 sub read_yn {
522 my ($prompt) = @_;
524 return read_prompt 0, $prompt;
527 sub read_ync {
528 my ($prompt) = @_;
530 return read_prompt 1, $prompt;
533 sub get_mandatory_config {
534 my ($config) = @_;
535 my $ans;
537 return if (defined($opt{$config}));
539 if (defined($config_help{$config})) {
540 print "\n";
541 print $config_help{$config};
544 for (;;) {
545 print "$config = ";
546 if (defined($default{$config}) && length($default{$config})) {
547 print "\[$default{$config}\] ";
549 $ans = <STDIN>;
550 $ans =~ s/^\s*(.*\S)\s*$/$1/;
551 if ($ans =~ /^\s*$/) {
552 if ($default{$config}) {
553 $ans = $default{$config};
554 } else {
555 print "Your answer can not be blank\n";
556 next;
559 $entered_configs{$config} = ${ans};
560 last;
564 sub show_time {
565 my ($time) = @_;
567 my $hours = 0;
568 my $minutes = 0;
570 if ($time > 3600) {
571 $hours = int($time / 3600);
572 $time -= $hours * 3600;
574 if ($time > 60) {
575 $minutes = int($time / 60);
576 $time -= $minutes * 60;
579 if ($hours > 0) {
580 doprint "$hours hour";
581 doprint "s" if ($hours > 1);
582 doprint " ";
585 if ($minutes > 0) {
586 doprint "$minutes minute";
587 doprint "s" if ($minutes > 1);
588 doprint " ";
591 doprint "$time second";
592 doprint "s" if ($time != 1);
595 sub print_times {
596 doprint "\n";
597 if ($build_time) {
598 doprint "Build time: ";
599 show_time($build_time);
600 doprint "\n";
602 if ($install_time) {
603 doprint "Install time: ";
604 show_time($install_time);
605 doprint "\n";
607 if ($reboot_time) {
608 doprint "Reboot time: ";
609 show_time($reboot_time);
610 doprint "\n";
612 if ($test_time) {
613 doprint "Test time: ";
614 show_time($test_time);
615 doprint "\n";
617 # reset for iterations like bisect
618 $build_time = 0;
619 $install_time = 0;
620 $reboot_time = 0;
621 $test_time = 0;
624 sub get_mandatory_configs {
625 get_mandatory_config("MACHINE");
626 get_mandatory_config("BUILD_DIR");
627 get_mandatory_config("OUTPUT_DIR");
629 if ($newconfig) {
630 get_mandatory_config("BUILD_OPTIONS");
633 # options required for other than just building a kernel
634 if (!$buildonly) {
635 get_mandatory_config("POWER_CYCLE");
636 get_mandatory_config("CONSOLE");
639 # options required for install and more
640 if ($buildonly != 1) {
641 get_mandatory_config("SSH_USER");
642 get_mandatory_config("BUILD_TARGET");
643 get_mandatory_config("TARGET_IMAGE");
646 get_mandatory_config("LOCALVERSION");
648 return if ($buildonly);
650 my $rtype = $opt{"REBOOT_TYPE"};
652 if (!defined($rtype)) {
653 if (!defined($opt{"GRUB_MENU"})) {
654 get_mandatory_config("REBOOT_TYPE");
655 $rtype = $entered_configs{"REBOOT_TYPE"};
656 } else {
657 $rtype = "grub";
661 if ($rtype eq "grub") {
662 get_mandatory_config("GRUB_MENU");
665 if ($rtype eq "grub2") {
666 get_mandatory_config("GRUB_MENU");
667 get_mandatory_config("GRUB_FILE");
670 if ($rtype eq "syslinux") {
671 get_mandatory_config("SYSLINUX_LABEL");
675 sub process_variables {
676 my ($value, $remove_undef) = @_;
677 my $retval = "";
679 # We want to check for '\', and it is just easier
680 # to check the previous characet of '$' and not need
681 # to worry if '$' is the first character. By adding
682 # a space to $value, we can just check [^\\]\$ and
683 # it will still work.
684 $value = " $value";
686 while ($value =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) {
687 my $begin = $1;
688 my $var = $2;
689 my $end = $3;
690 # append beginning of value to retval
691 $retval = "$retval$begin";
692 if (defined($variable{$var})) {
693 $retval = "$retval$variable{$var}";
694 } elsif (defined($remove_undef) && $remove_undef) {
695 # for if statements, any variable that is not defined,
696 # we simple convert to 0
697 $retval = "${retval}0";
698 } else {
699 # put back the origin piece.
700 $retval = "$retval\$\{$var\}";
701 # This could be an option that is used later, save
702 # it so we don't warn if this option is not one of
703 # ktests options.
704 $used_options{$var} = 1;
706 $value = $end;
708 $retval = "$retval$value";
710 # remove the space added in the beginning
711 $retval =~ s/ //;
713 return "$retval"
716 sub set_value {
717 my ($lvalue, $rvalue, $override, $overrides, $name) = @_;
719 my $prvalue = process_variables($rvalue);
721 if ($buildonly && $lvalue =~ /^TEST_TYPE(\[.*\])?$/ && $prvalue ne "build") {
722 # Note if a test is something other than build, then we
723 # will need other mandatory options.
724 if ($prvalue ne "install") {
725 # for bisect, we need to check BISECT_TYPE
726 if ($prvalue ne "bisect") {
727 $buildonly = 0;
729 } else {
730 # install still limits some mandatory options.
731 $buildonly = 2;
735 if ($buildonly && $lvalue =~ /^BISECT_TYPE(\[.*\])?$/ && $prvalue ne "build") {
736 if ($prvalue ne "install") {
737 $buildonly = 0;
738 } else {
739 # install still limits some mandatory options.
740 $buildonly = 2;
744 if (defined($opt{$lvalue})) {
745 if (!$override || defined(${$overrides}{$lvalue})) {
746 my $extra = "";
747 if ($override) {
748 $extra = "In the same override section!\n";
750 die "$name: $.: Option $lvalue defined more than once!\n$extra";
752 ${$overrides}{$lvalue} = $prvalue;
755 $opt{$lvalue} = $prvalue;
758 sub set_eval {
759 my ($lvalue, $rvalue, $name) = @_;
761 my $prvalue = process_variables($rvalue);
762 my $arr;
764 if (defined($evals{$lvalue})) {
765 $arr = $evals{$lvalue};
766 } else {
767 $arr = [];
768 $evals{$lvalue} = $arr;
771 push @{$arr}, $rvalue;
774 sub set_variable {
775 my ($lvalue, $rvalue) = @_;
777 if ($rvalue =~ /^\s*$/) {
778 delete $variable{$lvalue};
779 } else {
780 $rvalue = process_variables($rvalue);
781 $variable{$lvalue} = $rvalue;
785 sub process_compare {
786 my ($lval, $cmp, $rval) = @_;
788 # remove whitespace
790 $lval =~ s/^\s*//;
791 $lval =~ s/\s*$//;
793 $rval =~ s/^\s*//;
794 $rval =~ s/\s*$//;
796 if ($cmp eq "==") {
797 return $lval eq $rval;
798 } elsif ($cmp eq "!=") {
799 return $lval ne $rval;
800 } elsif ($cmp eq "=~") {
801 return $lval =~ m/$rval/;
802 } elsif ($cmp eq "!~") {
803 return $lval !~ m/$rval/;
806 my $statement = "$lval $cmp $rval";
807 my $ret = eval $statement;
809 # $@ stores error of eval
810 if ($@) {
811 return -1;
814 return $ret;
817 sub value_defined {
818 my ($val) = @_;
820 return defined($variable{$2}) ||
821 defined($opt{$2});
824 my $d = 0;
825 sub process_expression {
826 my ($name, $val) = @_;
828 my $c = $d++;
830 while ($val =~ s/\(([^\(]*?)\)/\&\&\&\&VAL\&\&\&\&/) {
831 my $express = $1;
833 if (process_expression($name, $express)) {
834 $val =~ s/\&\&\&\&VAL\&\&\&\&/ 1 /;
835 } else {
836 $val =~ s/\&\&\&\&VAL\&\&\&\&/ 0 /;
840 $d--;
841 my $OR = "\\|\\|";
842 my $AND = "\\&\\&";
844 while ($val =~ s/^(.*?)($OR|$AND)//) {
845 my $express = $1;
846 my $op = $2;
848 if (process_expression($name, $express)) {
849 if ($op eq "||") {
850 return 1;
852 } else {
853 if ($op eq "&&") {
854 return 0;
859 if ($val =~ /(.*)(==|\!=|>=|<=|>|<|=~|\!~)(.*)/) {
860 my $ret = process_compare($1, $2, $3);
861 if ($ret < 0) {
862 die "$name: $.: Unable to process comparison\n";
864 return $ret;
867 if ($val =~ /^\s*(NOT\s*)?DEFINED\s+(\S+)\s*$/) {
868 if (defined $1) {
869 return !value_defined($2);
870 } else {
871 return value_defined($2);
875 if ($val =~ /^\s*0\s*$/) {
876 return 0;
877 } elsif ($val =~ /^\s*\d+\s*$/) {
878 return 1;
881 die ("$name: $.: Undefined content $val in if statement\n");
884 sub process_if {
885 my ($name, $value) = @_;
887 # Convert variables and replace undefined ones with 0
888 my $val = process_variables($value, 1);
889 my $ret = process_expression $name, $val;
891 return $ret;
894 sub __read_config {
895 my ($config, $current_test_num) = @_;
897 my $in;
898 open($in, $config) || die "can't read file $config";
900 my $name = $config;
901 $name =~ s,.*/(.*),$1,;
903 my $test_num = $$current_test_num;
904 my $default = 1;
905 my $repeat = 1;
906 my $num_tests_set = 0;
907 my $skip = 0;
908 my $rest;
909 my $line;
910 my $test_case = 0;
911 my $if = 0;
912 my $if_set = 0;
913 my $override = 0;
915 my %overrides;
917 while (<$in>) {
919 # ignore blank lines and comments
920 next if (/^\s*$/ || /\s*\#/);
922 if (/^\s*(TEST_START|DEFAULTS)\b(.*)/) {
924 my $type = $1;
925 $rest = $2;
926 $line = $2;
928 my $old_test_num;
929 my $old_repeat;
930 $override = 0;
932 if ($type eq "TEST_START") {
934 if ($num_tests_set) {
935 die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
938 $old_test_num = $test_num;
939 $old_repeat = $repeat;
941 $test_num += $repeat;
942 $default = 0;
943 $repeat = 1;
944 } else {
945 $default = 1;
948 # If SKIP is anywhere in the line, the command will be skipped
949 if ($rest =~ s/\s+SKIP\b//) {
950 $skip = 1;
951 } else {
952 $test_case = 1;
953 $skip = 0;
956 if ($rest =~ s/\sELSE\b//) {
957 if (!$if) {
958 die "$name: $.: ELSE found with out matching IF section\n$_";
960 $if = 0;
962 if ($if_set) {
963 $skip = 1;
964 } else {
965 $skip = 0;
969 if ($rest =~ s/\sIF\s+(.*)//) {
970 if (process_if($name, $1)) {
971 $if_set = 1;
972 } else {
973 $skip = 1;
975 $if = 1;
976 } else {
977 $if = 0;
978 $if_set = 0;
981 if (!$skip) {
982 if ($type eq "TEST_START") {
983 if ($rest =~ s/\s+ITERATE\s+(\d+)//) {
984 $repeat = $1;
985 $repeat_tests{"$test_num"} = $repeat;
987 } elsif ($rest =~ s/\sOVERRIDE\b//) {
988 # DEFAULT only
989 $override = 1;
990 # Clear previous overrides
991 %overrides = ();
995 if (!$skip && $rest !~ /^\s*$/) {
996 die "$name: $.: Gargbage found after $type\n$_";
999 if ($skip && $type eq "TEST_START") {
1000 $test_num = $old_test_num;
1001 $repeat = $old_repeat;
1004 } elsif (/^\s*ELSE\b(.*)$/) {
1005 if (!$if) {
1006 die "$name: $.: ELSE found with out matching IF section\n$_";
1008 $rest = $1;
1009 if ($if_set) {
1010 $skip = 1;
1011 $rest = "";
1012 } else {
1013 $skip = 0;
1015 if ($rest =~ /\sIF\s+(.*)/) {
1016 # May be a ELSE IF section.
1017 if (process_if($name, $1)) {
1018 $if_set = 1;
1019 } else {
1020 $skip = 1;
1022 $rest = "";
1023 } else {
1024 $if = 0;
1028 if ($rest !~ /^\s*$/) {
1029 die "$name: $.: Gargbage found after DEFAULTS\n$_";
1032 } elsif (/^\s*INCLUDE\s+(\S+)/) {
1034 next if ($skip);
1036 if (!$default) {
1037 die "$name: $.: INCLUDE can only be done in default sections\n$_";
1040 my $file = process_variables($1);
1042 if ($file !~ m,^/,) {
1043 # check the path of the config file first
1044 if ($config =~ m,(.*)/,) {
1045 if (-f "$1/$file") {
1046 $file = "$1/$file";
1051 if ( ! -r $file ) {
1052 die "$name: $.: Can't read file $file\n$_";
1055 if (__read_config($file, \$test_num)) {
1056 $test_case = 1;
1059 } elsif (/^\s*([A-Z_\[\]\d]+)\s*=~\s*(.*?)\s*$/) {
1061 next if ($skip);
1063 my $lvalue = $1;
1064 my $rvalue = $2;
1066 if ($default || $lvalue =~ /\[\d+\]$/) {
1067 set_eval($lvalue, $rvalue, $name);
1068 } else {
1069 my $val = "$lvalue\[$test_num\]";
1070 set_eval($val, $rvalue, $name);
1073 } elsif (/^\s*([A-Z_\[\]\d]+)\s*=\s*(.*?)\s*$/) {
1075 next if ($skip);
1077 my $lvalue = $1;
1078 my $rvalue = $2;
1080 if (!$default &&
1081 ($lvalue eq "NUM_TESTS" ||
1082 $lvalue eq "LOG_FILE" ||
1083 $lvalue eq "CLEAR_LOG")) {
1084 die "$name: $.: $lvalue must be set in DEFAULTS section\n";
1087 if ($lvalue eq "NUM_TESTS") {
1088 if ($test_num) {
1089 die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
1091 if (!$default) {
1092 die "$name: $.: NUM_TESTS must be set in default section\n";
1094 $num_tests_set = 1;
1097 if ($default || $lvalue =~ /\[\d+\]$/) {
1098 set_value($lvalue, $rvalue, $override, \%overrides, $name);
1099 } else {
1100 my $val = "$lvalue\[$test_num\]";
1101 set_value($val, $rvalue, $override, \%overrides, $name);
1103 if ($repeat > 1) {
1104 $repeats{$val} = $repeat;
1107 } elsif (/^\s*([A-Z_\[\]\d]+)\s*:=\s*(.*?)\s*$/) {
1108 next if ($skip);
1110 my $lvalue = $1;
1111 my $rvalue = $2;
1113 # process config variables.
1114 # Config variables are only active while reading the
1115 # config and can be defined anywhere. They also ignore
1116 # TEST_START and DEFAULTS, but are skipped if they are in
1117 # on of these sections that have SKIP defined.
1118 # The save variable can be
1119 # defined multiple times and the new one simply overrides
1120 # the prevous one.
1121 set_variable($lvalue, $rvalue);
1123 } else {
1124 die "$name: $.: Garbage found in config\n$_";
1128 if ($test_num) {
1129 $test_num += $repeat - 1;
1130 $opt{"NUM_TESTS"} = $test_num;
1133 close($in);
1135 $$current_test_num = $test_num;
1137 return $test_case;
1140 sub get_test_case {
1141 print "What test case would you like to run?\n";
1142 print " (build, install or boot)\n";
1143 print " Other tests are available but require editing the config file\n";
1144 my $ans = <STDIN>;
1145 chomp $ans;
1146 $default{"TEST_TYPE"} = $ans;
1149 sub read_config {
1150 my ($config) = @_;
1152 my $test_case;
1153 my $test_num = 0;
1155 $test_case = __read_config $config, \$test_num;
1157 # make sure we have all mandatory configs
1158 get_mandatory_configs;
1160 # was a test specified?
1161 if (!$test_case) {
1162 print "No test case specified.\n";
1163 get_test_case;
1166 # set any defaults
1168 foreach my $default (keys %default) {
1169 if (!defined($opt{$default})) {
1170 $opt{$default} = $default{$default};
1174 if ($opt{"IGNORE_UNUSED"} == 1) {
1175 return;
1178 my %not_used;
1180 # check if there are any stragglers (typos?)
1181 foreach my $option (keys %opt) {
1182 my $op = $option;
1183 # remove per test labels.
1184 $op =~ s/\[.*\]//;
1185 if (!exists($option_map{$op}) &&
1186 !exists($default{$op}) &&
1187 !exists($used_options{$op})) {
1188 $not_used{$op} = 1;
1192 if (%not_used) {
1193 my $s = "s are";
1194 $s = " is" if (keys %not_used == 1);
1195 print "The following option$s not used; could be a typo:\n";
1196 foreach my $option (keys %not_used) {
1197 print "$option\n";
1199 print "Set IGRNORE_UNUSED = 1 to have ktest ignore unused variables\n";
1200 if (!read_yn "Do you want to continue?") {
1201 exit -1;
1206 sub __eval_option {
1207 my ($name, $option, $i) = @_;
1209 # Add space to evaluate the character before $
1210 $option = " $option";
1211 my $retval = "";
1212 my $repeated = 0;
1213 my $parent = 0;
1215 foreach my $test (keys %repeat_tests) {
1216 if ($i >= $test &&
1217 $i < $test + $repeat_tests{$test}) {
1219 $repeated = 1;
1220 $parent = $test;
1221 last;
1225 while ($option =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) {
1226 my $start = $1;
1227 my $var = $2;
1228 my $end = $3;
1230 # Append beginning of line
1231 $retval = "$retval$start";
1233 # If the iteration option OPT[$i] exists, then use that.
1234 # otherwise see if the default OPT (without [$i]) exists.
1236 my $o = "$var\[$i\]";
1237 my $parento = "$var\[$parent\]";
1239 # If a variable contains itself, use the default var
1240 if (($var eq $name) && defined($opt{$var})) {
1241 $o = $opt{$var};
1242 $retval = "$retval$o";
1243 } elsif (defined($opt{$o})) {
1244 $o = $opt{$o};
1245 $retval = "$retval$o";
1246 } elsif ($repeated && defined($opt{$parento})) {
1247 $o = $opt{$parento};
1248 $retval = "$retval$o";
1249 } elsif (defined($opt{$var})) {
1250 $o = $opt{$var};
1251 $retval = "$retval$o";
1252 } elsif ($var eq "KERNEL_VERSION" && defined($make)) {
1253 # special option KERNEL_VERSION uses kernel version
1254 get_version();
1255 $retval = "$retval$version";
1256 } else {
1257 $retval = "$retval\$\{$var\}";
1260 $option = $end;
1263 $retval = "$retval$option";
1265 $retval =~ s/^ //;
1267 return $retval;
1270 sub process_evals {
1271 my ($name, $option, $i) = @_;
1273 my $option_name = "$name\[$i\]";
1274 my $ev;
1276 my $old_option = $option;
1278 if (defined($evals{$option_name})) {
1279 $ev = $evals{$option_name};
1280 } elsif (defined($evals{$name})) {
1281 $ev = $evals{$name};
1282 } else {
1283 return $option;
1286 for my $e (@{$ev}) {
1287 eval "\$option =~ $e";
1290 if ($option ne $old_option) {
1291 doprint("$name changed from '$old_option' to '$option'\n");
1294 return $option;
1297 sub eval_option {
1298 my ($name, $option, $i) = @_;
1300 my $prev = "";
1302 # Since an option can evaluate to another option,
1303 # keep iterating until we do not evaluate any more
1304 # options.
1305 my $r = 0;
1306 while ($prev ne $option) {
1307 # Check for recursive evaluations.
1308 # 100 deep should be more than enough.
1309 if ($r++ > 100) {
1310 die "Over 100 evaluations accurred with $option\n" .
1311 "Check for recursive variables\n";
1313 $prev = $option;
1314 $option = __eval_option($name, $option, $i);
1317 $option = process_evals($name, $option, $i);
1319 return $option;
1322 sub run_command;
1323 sub start_monitor;
1324 sub end_monitor;
1325 sub wait_for_monitor;
1327 sub reboot {
1328 my ($time) = @_;
1329 my $powercycle = 0;
1331 # test if the machine can be connected to within 5 seconds
1332 my $stat = run_ssh("echo check machine status", 5);
1333 if (!$stat) {
1334 doprint("power cycle\n");
1335 $powercycle = 1;
1338 if ($powercycle) {
1339 run_command "$power_cycle";
1341 start_monitor;
1342 # flush out current monitor
1343 # May contain the reboot success line
1344 wait_for_monitor 1;
1346 } else {
1347 # Make sure everything has been written to disk
1348 run_ssh("sync");
1350 if (defined($time)) {
1351 start_monitor;
1352 # flush out current monitor
1353 # May contain the reboot success line
1354 wait_for_monitor 1;
1357 # try to reboot normally
1358 if (run_command $reboot) {
1359 if (defined($powercycle_after_reboot)) {
1360 sleep $powercycle_after_reboot;
1361 run_command "$power_cycle";
1363 } else {
1364 # nope? power cycle it.
1365 run_command "$power_cycle";
1369 if (defined($time)) {
1371 # We only want to get to the new kernel, don't fail
1372 # if we stumble over a call trace.
1373 my $save_ignore_errors = $ignore_errors;
1374 $ignore_errors = 1;
1376 # Look for the good kernel to boot
1377 if (wait_for_monitor($time, "Linux version")) {
1378 # reboot got stuck?
1379 doprint "Reboot did not finish. Forcing power cycle\n";
1380 run_command "$power_cycle";
1383 $ignore_errors = $save_ignore_errors;
1385 # Still need to wait for the reboot to finish
1386 wait_for_monitor($time, $reboot_success_line);
1388 end_monitor;
1392 sub reboot_to_good {
1393 my ($time) = @_;
1395 if (defined($switch_to_good)) {
1396 run_command $switch_to_good;
1399 reboot $time;
1402 sub do_not_reboot {
1403 my $i = $iteration;
1405 return $test_type eq "build" || $no_reboot ||
1406 ($test_type eq "patchcheck" && $opt{"PATCHCHECK_TYPE[$i]"} eq "build") ||
1407 ($test_type eq "bisect" && $opt{"BISECT_TYPE[$i]"} eq "build");
1410 sub dodie {
1411 doprint "CRITICAL FAILURE... ", @_, "\n";
1413 my $i = $iteration;
1415 if ($reboot_on_error && !do_not_reboot) {
1417 doprint "REBOOTING\n";
1418 reboot_to_good;
1420 } elsif ($poweroff_on_error && defined($power_off)) {
1421 doprint "POWERING OFF\n";
1422 `$power_off`;
1425 if (defined($opt{"LOG_FILE"})) {
1426 print " See $opt{LOG_FILE} for more info.\n";
1429 if ($monitor_cnt) {
1430 # restore terminal settings
1431 system("stty $stty_orig");
1434 if (defined($post_test)) {
1435 run_command $post_test;
1438 die @_, "\n";
1441 sub create_pty {
1442 my ($ptm, $pts) = @_;
1443 my $tmp;
1444 my $TIOCSPTLCK = 0x40045431;
1445 my $TIOCGPTN = 0x80045430;
1447 sysopen($ptm, "/dev/ptmx", O_RDWR | O_NONBLOCK) or
1448 dodie "Cant open /dev/ptmx";
1450 # unlockpt()
1451 $tmp = pack("i", 0);
1452 ioctl($ptm, $TIOCSPTLCK, $tmp) or
1453 dodie "ioctl TIOCSPTLCK for /dev/ptmx failed";
1455 # ptsname()
1456 ioctl($ptm, $TIOCGPTN, $tmp) or
1457 dodie "ioctl TIOCGPTN for /dev/ptmx failed";
1458 $tmp = unpack("i", $tmp);
1460 sysopen($pts, "/dev/pts/$tmp", O_RDWR | O_NONBLOCK) or
1461 dodie "Can't open /dev/pts/$tmp";
1464 sub exec_console {
1465 my ($ptm, $pts) = @_;
1467 close($ptm);
1469 close(\*STDIN);
1470 close(\*STDOUT);
1471 close(\*STDERR);
1473 open(\*STDIN, '<&', $pts);
1474 open(\*STDOUT, '>&', $pts);
1475 open(\*STDERR, '>&', $pts);
1477 close($pts);
1479 exec $console or
1480 die "Can't open console $console";
1483 sub open_console {
1484 my ($ptm) = @_;
1485 my $pts = \*PTSFD;
1486 my $pid;
1488 # save terminal settings
1489 $stty_orig = `stty -g`;
1491 # place terminal in cbreak mode so that stdin can be read one character at
1492 # a time without having to wait for a newline
1493 system("stty -icanon -echo -icrnl");
1495 create_pty($ptm, $pts);
1497 $pid = fork;
1499 if (!$pid) {
1500 # child
1501 exec_console($ptm, $pts)
1504 # parent
1505 close($pts);
1507 return $pid;
1509 open(PTSFD, "Stop perl from warning about single use of PTSFD");
1512 sub close_console {
1513 my ($fp, $pid) = @_;
1515 doprint "kill child process $pid\n";
1516 kill $close_console_signal, $pid;
1518 print "closing!\n";
1519 close($fp);
1521 # restore terminal settings
1522 system("stty $stty_orig");
1525 sub start_monitor {
1526 if ($monitor_cnt++) {
1527 return;
1529 $monitor_fp = \*MONFD;
1530 $monitor_pid = open_console $monitor_fp;
1532 return;
1534 open(MONFD, "Stop perl from warning about single use of MONFD");
1537 sub end_monitor {
1538 return if (!defined $console);
1539 if (--$monitor_cnt) {
1540 return;
1542 close_console($monitor_fp, $monitor_pid);
1545 sub wait_for_monitor {
1546 my ($time, $stop) = @_;
1547 my $full_line = "";
1548 my $line;
1549 my $booted = 0;
1550 my $start_time = time;
1551 my $skip_call_trace = 0;
1552 my $bug = 0;
1553 my $bug_ignored = 0;
1554 my $now;
1556 doprint "** Wait for monitor to settle down **\n";
1558 # read the monitor and wait for the system to calm down
1559 while (!$booted) {
1560 $line = wait_for_input($monitor_fp, $time);
1561 last if (!defined($line));
1562 print "$line";
1563 $full_line .= $line;
1565 if (defined($stop) && $full_line =~ /$stop/) {
1566 doprint "wait for monitor detected $stop\n";
1567 $booted = 1;
1570 if ($full_line =~ /\[ backtrace testing \]/) {
1571 $skip_call_trace = 1;
1574 if ($full_line =~ /call trace:/i) {
1575 if (!$bug && !$skip_call_trace) {
1576 if ($ignore_errors) {
1577 $bug_ignored = 1;
1578 } else {
1579 $bug = 1;
1584 if ($full_line =~ /\[ end of backtrace testing \]/) {
1585 $skip_call_trace = 0;
1588 if ($full_line =~ /Kernel panic -/) {
1589 $bug = 1;
1592 if ($line =~ /\n/) {
1593 $full_line = "";
1595 $now = time;
1596 if ($now - $start_time >= $max_monitor_wait) {
1597 doprint "Exiting monitor flush due to hitting MAX_MONITOR_WAIT\n";
1598 return 1;
1601 print "** Monitor flushed **\n";
1603 # if stop is defined but wasn't hit, return error
1604 # used by reboot (which wants to see a reboot)
1605 if (defined($stop) && !$booted) {
1606 $bug = 1;
1608 return $bug;
1611 sub save_logs {
1612 my ($result, $basedir) = @_;
1613 my @t = localtime;
1614 my $date = sprintf "%04d%02d%02d%02d%02d%02d",
1615 1900+$t[5],$t[4],$t[3],$t[2],$t[1],$t[0];
1617 my $type = $build_type;
1618 if ($type =~ /useconfig/) {
1619 $type = "useconfig";
1622 my $dir = "$machine-$test_type-$type-$result-$date";
1624 $dir = "$basedir/$dir";
1626 if (!-d $dir) {
1627 mkpath($dir) or
1628 die "can't create $dir";
1631 my %files = (
1632 "config" => $output_config,
1633 "buildlog" => $buildlog,
1634 "dmesg" => $dmesg,
1635 "testlog" => $testlog,
1638 while (my ($name, $source) = each(%files)) {
1639 if (-f "$source") {
1640 cp "$source", "$dir/$name" or
1641 die "failed to copy $source";
1645 doprint "*** Saved info to $dir ***\n";
1648 sub fail {
1650 if ($die_on_failure) {
1651 dodie @_;
1654 doprint "FAILED\n";
1656 my $i = $iteration;
1658 # no need to reboot for just building.
1659 if (!do_not_reboot) {
1660 doprint "REBOOTING\n";
1661 reboot_to_good $sleep_time;
1664 my $name = "";
1666 if (defined($test_name)) {
1667 $name = " ($test_name)";
1670 print_times;
1672 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
1673 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
1674 doprint "KTEST RESULT: TEST $i$name Failed: ", @_, "\n";
1675 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
1676 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
1678 if (defined($store_failures)) {
1679 save_logs "fail", $store_failures;
1682 if (defined($post_test)) {
1683 run_command $post_test;
1686 return 1;
1689 sub run_command {
1690 my ($command, $redirect, $timeout) = @_;
1691 my $start_time;
1692 my $end_time;
1693 my $dolog = 0;
1694 my $dord = 0;
1695 my $pid;
1697 $command =~ s/\$SSH_USER/$ssh_user/g;
1698 $command =~ s/\$MACHINE/$machine/g;
1700 doprint("$command ... ");
1701 $start_time = time;
1703 $pid = open(CMD, "$command 2>&1 |") or
1704 (fail "unable to exec $command" and return 0);
1706 if (defined($opt{"LOG_FILE"})) {
1707 open(LOG, ">>$opt{LOG_FILE}") or
1708 dodie "failed to write to log";
1709 $dolog = 1;
1712 if (defined($redirect)) {
1713 open (RD, ">$redirect") or
1714 dodie "failed to write to redirect $redirect";
1715 $dord = 1;
1718 my $hit_timeout = 0;
1720 while (1) {
1721 my $fp = \*CMD;
1722 if (defined($timeout)) {
1723 doprint "timeout = $timeout\n";
1725 my $line = wait_for_input($fp, $timeout);
1726 if (!defined($line)) {
1727 my $now = time;
1728 if (defined($timeout) && (($now - $start_time) >= $timeout)) {
1729 doprint "Hit timeout of $timeout, killing process\n";
1730 $hit_timeout = 1;
1731 kill 9, $pid;
1733 last;
1735 print LOG $line if ($dolog);
1736 print RD $line if ($dord);
1739 waitpid($pid, 0);
1740 # shift 8 for real exit status
1741 $run_command_status = $? >> 8;
1743 close(CMD);
1744 close(LOG) if ($dolog);
1745 close(RD) if ($dord);
1747 $end_time = time;
1748 my $delta = $end_time - $start_time;
1750 if ($delta == 1) {
1751 doprint "[1 second] ";
1752 } else {
1753 doprint "[$delta seconds] ";
1756 if ($hit_timeout) {
1757 $run_command_status = 1;
1760 if ($run_command_status) {
1761 doprint "FAILED!\n";
1762 } else {
1763 doprint "SUCCESS\n";
1766 return !$run_command_status;
1769 sub run_ssh {
1770 my ($cmd, $timeout) = @_;
1771 my $cp_exec = $ssh_exec;
1773 $cp_exec =~ s/\$SSH_COMMAND/$cmd/g;
1774 return run_command "$cp_exec", undef , $timeout;
1777 sub run_scp {
1778 my ($src, $dst, $cp_scp) = @_;
1780 $cp_scp =~ s/\$SRC_FILE/$src/g;
1781 $cp_scp =~ s/\$DST_FILE/$dst/g;
1783 return run_command "$cp_scp";
1786 sub run_scp_install {
1787 my ($src, $dst) = @_;
1789 my $cp_scp = $scp_to_target_install;
1791 return run_scp($src, $dst, $cp_scp);
1794 sub run_scp_mod {
1795 my ($src, $dst) = @_;
1797 my $cp_scp = $scp_to_target;
1799 return run_scp($src, $dst, $cp_scp);
1802 sub get_grub2_index {
1804 return if (defined($grub_number) && defined($last_grub_menu) &&
1805 $last_grub_menu eq $grub_menu && defined($last_machine) &&
1806 $last_machine eq $machine);
1808 doprint "Find grub2 menu ... ";
1809 $grub_number = -1;
1811 my $ssh_grub = $ssh_exec;
1812 $ssh_grub =~ s,\$SSH_COMMAND,cat $grub_file,g;
1814 open(IN, "$ssh_grub |")
1815 or die "unable to get $grub_file";
1817 my $found = 0;
1819 while (<IN>) {
1820 if (/^menuentry.*$grub_menu/) {
1821 $grub_number++;
1822 $found = 1;
1823 last;
1824 } elsif (/^menuentry\s/) {
1825 $grub_number++;
1828 close(IN);
1830 die "Could not find '$grub_menu' in $grub_file on $machine"
1831 if (!$found);
1832 doprint "$grub_number\n";
1833 $last_grub_menu = $grub_menu;
1834 $last_machine = $machine;
1837 sub get_grub_index {
1839 if ($reboot_type eq "grub2") {
1840 get_grub2_index;
1841 return;
1844 if ($reboot_type ne "grub") {
1845 return;
1847 return if (defined($grub_number) && defined($last_grub_menu) &&
1848 $last_grub_menu eq $grub_menu && defined($last_machine) &&
1849 $last_machine eq $machine);
1851 doprint "Find grub menu ... ";
1852 $grub_number = -1;
1854 my $ssh_grub = $ssh_exec;
1855 $ssh_grub =~ s,\$SSH_COMMAND,cat /boot/grub/menu.lst,g;
1857 open(IN, "$ssh_grub |")
1858 or die "unable to get menu.lst";
1860 my $found = 0;
1862 while (<IN>) {
1863 if (/^\s*title\s+$grub_menu\s*$/) {
1864 $grub_number++;
1865 $found = 1;
1866 last;
1867 } elsif (/^\s*title\s/) {
1868 $grub_number++;
1871 close(IN);
1873 die "Could not find '$grub_menu' in /boot/grub/menu on $machine"
1874 if (!$found);
1875 doprint "$grub_number\n";
1876 $last_grub_menu = $grub_menu;
1877 $last_machine = $machine;
1880 sub wait_for_input
1882 my ($fp, $time) = @_;
1883 my $start_time;
1884 my $rin;
1885 my $rout;
1886 my $nr;
1887 my $buf;
1888 my $line;
1889 my $ch;
1891 if (!defined($time)) {
1892 $time = $timeout;
1895 $rin = '';
1896 vec($rin, fileno($fp), 1) = 1;
1897 vec($rin, fileno(\*STDIN), 1) = 1;
1899 $start_time = time;
1901 while (1) {
1902 $nr = select($rout=$rin, undef, undef, $time);
1904 last if ($nr <= 0);
1906 # copy data from stdin to the console
1907 if (vec($rout, fileno(\*STDIN), 1) == 1) {
1908 $nr = sysread(\*STDIN, $buf, 1000);
1909 syswrite($fp, $buf, $nr) if ($nr > 0);
1912 # The timeout is based on time waiting for the fp data
1913 if (vec($rout, fileno($fp), 1) != 1) {
1914 last if (defined($time) && (time - $start_time > $time));
1915 next;
1918 $line = "";
1920 # try to read one char at a time
1921 while (sysread $fp, $ch, 1) {
1922 $line .= $ch;
1923 last if ($ch eq "\n");
1926 last if (!length($line));
1928 return $line;
1930 return undef;
1933 sub reboot_to {
1934 if (defined($switch_to_test)) {
1935 run_command $switch_to_test;
1938 if ($reboot_type eq "grub") {
1939 run_ssh "'(echo \"savedefault --default=$grub_number --once\" | grub --batch)'";
1940 } elsif ($reboot_type eq "grub2") {
1941 run_ssh "$grub_reboot $grub_number";
1942 } elsif ($reboot_type eq "syslinux") {
1943 run_ssh "$syslinux --once \\\"$syslinux_label\\\" $syslinux_path";
1944 } elsif (defined $reboot_script) {
1945 run_command "$reboot_script";
1947 reboot;
1950 sub get_sha1 {
1951 my ($commit) = @_;
1953 doprint "git rev-list --max-count=1 $commit ... ";
1954 my $sha1 = `git rev-list --max-count=1 $commit`;
1955 my $ret = $?;
1957 logit $sha1;
1959 if ($ret) {
1960 doprint "FAILED\n";
1961 dodie "Failed to get git $commit";
1964 print "SUCCESS\n";
1966 chomp $sha1;
1968 return $sha1;
1971 sub monitor {
1972 my $booted = 0;
1973 my $bug = 0;
1974 my $bug_ignored = 0;
1975 my $skip_call_trace = 0;
1976 my $loops;
1978 my $start_time = time;
1980 wait_for_monitor 5;
1982 my $line;
1983 my $full_line = "";
1985 open(DMESG, "> $dmesg") or
1986 die "unable to write to $dmesg";
1988 reboot_to;
1990 my $success_start;
1991 my $failure_start;
1992 my $monitor_start = time;
1993 my $done = 0;
1994 my $version_found = 0;
1996 while (!$done) {
1998 if ($bug && defined($stop_after_failure) &&
1999 $stop_after_failure >= 0) {
2000 my $time = $stop_after_failure - (time - $failure_start);
2001 $line = wait_for_input($monitor_fp, $time);
2002 if (!defined($line)) {
2003 doprint "bug timed out after $booted_timeout seconds\n";
2004 doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
2005 last;
2007 } elsif ($booted) {
2008 $line = wait_for_input($monitor_fp, $booted_timeout);
2009 if (!defined($line)) {
2010 my $s = $booted_timeout == 1 ? "" : "s";
2011 doprint "Successful boot found: break after $booted_timeout second$s\n";
2012 last;
2014 } else {
2015 $line = wait_for_input($monitor_fp);
2016 if (!defined($line)) {
2017 my $s = $timeout == 1 ? "" : "s";
2018 doprint "Timed out after $timeout second$s\n";
2019 last;
2023 doprint $line;
2024 print DMESG $line;
2026 # we are not guaranteed to get a full line
2027 $full_line .= $line;
2029 if ($full_line =~ /$success_line/) {
2030 $booted = 1;
2031 $success_start = time;
2034 if ($booted && defined($stop_after_success) &&
2035 $stop_after_success >= 0) {
2036 my $now = time;
2037 if ($now - $success_start >= $stop_after_success) {
2038 doprint "Test forced to stop after $stop_after_success seconds after success\n";
2039 last;
2043 if ($full_line =~ /\[ backtrace testing \]/) {
2044 $skip_call_trace = 1;
2047 if ($full_line =~ /call trace:/i) {
2048 if (!$bug && !$skip_call_trace) {
2049 if ($ignore_errors) {
2050 $bug_ignored = 1;
2051 } else {
2052 $bug = 1;
2053 $failure_start = time;
2058 if ($bug && defined($stop_after_failure) &&
2059 $stop_after_failure >= 0) {
2060 my $now = time;
2061 if ($now - $failure_start >= $stop_after_failure) {
2062 doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
2063 last;
2067 if ($full_line =~ /\[ end of backtrace testing \]/) {
2068 $skip_call_trace = 0;
2071 if ($full_line =~ /Kernel panic -/) {
2072 $failure_start = time;
2073 $bug = 1;
2076 # Detect triple faults by testing the banner
2077 if ($full_line =~ /\bLinux version (\S+).*\n/) {
2078 if ($1 eq $version) {
2079 $version_found = 1;
2080 } elsif ($version_found && $detect_triplefault) {
2081 # We already booted into the kernel we are testing,
2082 # but now we booted into another kernel?
2083 # Consider this a triple fault.
2084 doprint "Already booted in Linux kernel $version, but now\n";
2085 doprint "we booted into Linux kernel $1.\n";
2086 doprint "Assuming that this is a triple fault.\n";
2087 doprint "To disable this: set DETECT_TRIPLE_FAULT to 0\n";
2088 last;
2092 if ($line =~ /\n/) {
2093 $full_line = "";
2096 if ($stop_test_after > 0 && !$booted && !$bug) {
2097 if (time - $monitor_start > $stop_test_after) {
2098 doprint "STOP_TEST_AFTER ($stop_test_after seconds) timed out\n";
2099 $done = 1;
2104 my $end_time = time;
2105 $reboot_time = $end_time - $start_time;
2107 close(DMESG);
2109 if ($bug) {
2110 return 0 if ($in_bisect);
2111 fail "failed - got a bug report" and return 0;
2114 if (!$booted) {
2115 return 0 if ($in_bisect);
2116 fail "failed - never got a boot prompt." and return 0;
2119 if ($bug_ignored) {
2120 doprint "WARNING: Call Trace detected but ignored due to IGNORE_ERRORS=1\n";
2123 return 1;
2126 sub eval_kernel_version {
2127 my ($option) = @_;
2129 $option =~ s/\$KERNEL_VERSION/$version/g;
2131 return $option;
2134 sub do_post_install {
2136 return if (!defined($post_install));
2138 my $cp_post_install = eval_kernel_version $post_install;
2139 run_command "$cp_post_install" or
2140 dodie "Failed to run post install";
2143 # Sometimes the reboot fails, and will hang. We try to ssh to the box
2144 # and if we fail, we force another reboot, that should powercycle it.
2145 sub test_booted {
2146 if (!run_ssh "echo testing connection") {
2147 reboot $sleep_time;
2151 sub install {
2153 return if ($no_install);
2155 my $start_time = time;
2157 if (defined($pre_install)) {
2158 my $cp_pre_install = eval_kernel_version $pre_install;
2159 run_command "$cp_pre_install" or
2160 dodie "Failed to run pre install";
2163 my $cp_target = eval_kernel_version $target_image;
2165 test_booted;
2167 run_scp_install "$outputdir/$build_target", "$cp_target" or
2168 dodie "failed to copy image";
2170 my $install_mods = 0;
2172 # should we process modules?
2173 $install_mods = 0;
2174 open(IN, "$output_config") or dodie("Can't read config file");
2175 while (<IN>) {
2176 if (/CONFIG_MODULES(=y)?/) {
2177 if (defined($1)) {
2178 $install_mods = 1;
2179 last;
2183 close(IN);
2185 if (!$install_mods) {
2186 do_post_install;
2187 doprint "No modules needed\n";
2188 my $end_time = time;
2189 $install_time = $end_time - $start_time;
2190 return;
2193 run_command "$make INSTALL_MOD_STRIP=1 INSTALL_MOD_PATH=$tmpdir modules_install" or
2194 dodie "Failed to install modules";
2196 my $modlib = "/lib/modules/$version";
2197 my $modtar = "ktest-mods.tar.bz2";
2199 run_ssh "rm -rf $modlib" or
2200 dodie "failed to remove old mods: $modlib";
2202 # would be nice if scp -r did not follow symbolic links
2203 run_command "cd $tmpdir && tar -cjf $modtar lib/modules/$version" or
2204 dodie "making tarball";
2206 run_scp_mod "$tmpdir/$modtar", "/tmp" or
2207 dodie "failed to copy modules";
2209 unlink "$tmpdir/$modtar";
2211 run_ssh "'(cd / && tar xjf /tmp/$modtar)'" or
2212 dodie "failed to tar modules";
2214 run_ssh "rm -f /tmp/$modtar";
2216 do_post_install;
2218 my $end_time = time;
2219 $install_time = $end_time - $start_time;
2222 sub get_version {
2223 # get the release name
2224 return if ($have_version);
2225 doprint "$make kernelrelease ... ";
2226 $version = `$make -s kernelrelease | tail -1`;
2227 chomp($version);
2228 doprint "$version\n";
2229 $have_version = 1;
2232 sub start_monitor_and_install {
2233 # Make sure the stable kernel has finished booting
2235 # Install bisects, don't need console
2236 if (defined $console) {
2237 start_monitor;
2238 wait_for_monitor 5;
2239 end_monitor;
2242 get_grub_index;
2243 get_version;
2244 install;
2246 start_monitor if (defined $console);
2247 return monitor;
2250 my $check_build_re = ".*:.*(warning|error|Error):.*";
2251 my $utf8_quote = "\\x{e2}\\x{80}(\\x{98}|\\x{99})";
2253 sub process_warning_line {
2254 my ($line) = @_;
2256 chomp $line;
2258 # for distcc heterogeneous systems, some compilers
2259 # do things differently causing warning lines
2260 # to be slightly different. This makes an attempt
2261 # to fixe those issues.
2263 # chop off the index into the line
2264 # using distcc, some compilers give different indexes
2265 # depending on white space
2266 $line =~ s/^(\s*\S+:\d+:)\d+/$1/;
2268 # Some compilers use UTF-8 extended for quotes and some don't.
2269 $line =~ s/$utf8_quote/'/g;
2271 return $line;
2274 # Read buildlog and check against warnings file for any
2275 # new warnings.
2277 # Returns 1 if OK
2278 # 0 otherwise
2279 sub check_buildlog {
2280 return 1 if (!defined $warnings_file);
2282 my %warnings_list;
2284 # Failed builds should not reboot the target
2285 my $save_no_reboot = $no_reboot;
2286 $no_reboot = 1;
2288 if (-f $warnings_file) {
2289 open(IN, $warnings_file) or
2290 dodie "Error opening $warnings_file";
2292 while (<IN>) {
2293 if (/$check_build_re/) {
2294 my $warning = process_warning_line $_;
2296 $warnings_list{$warning} = 1;
2299 close(IN);
2302 # If warnings file didn't exist, and WARNINGS_FILE exist,
2303 # then we fail on any warning!
2305 open(IN, $buildlog) or dodie "Can't open $buildlog";
2306 while (<IN>) {
2307 if (/$check_build_re/) {
2308 my $warning = process_warning_line $_;
2310 if (!defined $warnings_list{$warning}) {
2311 fail "New warning found (not in $warnings_file)\n$_\n";
2312 $no_reboot = $save_no_reboot;
2313 return 0;
2317 $no_reboot = $save_no_reboot;
2318 close(IN);
2321 sub check_patch_buildlog {
2322 my ($patch) = @_;
2324 my @files = `git show $patch | diffstat -l`;
2326 foreach my $file (@files) {
2327 chomp $file;
2330 open(IN, "git show $patch |") or
2331 dodie "failed to show $patch";
2332 while (<IN>) {
2333 if (m,^--- a/(.*),) {
2334 chomp $1;
2335 $files[$#files] = $1;
2338 close(IN);
2340 open(IN, $buildlog) or dodie "Can't open $buildlog";
2341 while (<IN>) {
2342 if (/^\s*(.*?):.*(warning|error)/) {
2343 my $err = $1;
2344 foreach my $file (@files) {
2345 my $fullpath = "$builddir/$file";
2346 if ($file eq $err || $fullpath eq $err) {
2347 fail "$file built with warnings" and return 0;
2352 close(IN);
2354 return 1;
2357 sub apply_min_config {
2358 my $outconfig = "$output_config.new";
2360 # Read the config file and remove anything that
2361 # is in the force_config hash (from minconfig and others)
2362 # then add the force config back.
2364 doprint "Applying minimum configurations into $output_config.new\n";
2366 open (OUT, ">$outconfig") or
2367 dodie "Can't create $outconfig";
2369 if (-f $output_config) {
2370 open (IN, $output_config) or
2371 dodie "Failed to open $output_config";
2372 while (<IN>) {
2373 if (/^(# )?(CONFIG_[^\s=]*)/) {
2374 next if (defined($force_config{$2}));
2376 print OUT;
2378 close IN;
2380 foreach my $config (keys %force_config) {
2381 print OUT "$force_config{$config}\n";
2383 close OUT;
2385 run_command "mv $outconfig $output_config";
2388 sub make_oldconfig {
2390 my @force_list = keys %force_config;
2392 if ($#force_list >= 0) {
2393 apply_min_config;
2396 if (!run_command "$make olddefconfig") {
2397 # Perhaps olddefconfig doesn't exist in this version of the kernel
2398 # try oldnoconfig
2399 doprint "olddefconfig failed, trying make oldnoconfig\n";
2400 if (!run_command "$make oldnoconfig") {
2401 doprint "oldnoconfig failed, trying yes '' | make oldconfig\n";
2402 # try a yes '' | oldconfig
2403 run_command "yes '' | $make oldconfig" or
2404 dodie "failed make config oldconfig";
2409 # read a config file and use this to force new configs.
2410 sub load_force_config {
2411 my ($config) = @_;
2413 doprint "Loading force configs from $config\n";
2414 open(IN, $config) or
2415 dodie "failed to read $config";
2416 while (<IN>) {
2417 chomp;
2418 if (/^(CONFIG[^\s=]*)(\s*=.*)/) {
2419 $force_config{$1} = $_;
2420 } elsif (/^# (CONFIG_\S*) is not set/) {
2421 $force_config{$1} = $_;
2424 close IN;
2427 sub build {
2428 my ($type) = @_;
2430 unlink $buildlog;
2432 my $start_time = time;
2434 # Failed builds should not reboot the target
2435 my $save_no_reboot = $no_reboot;
2436 $no_reboot = 1;
2438 # Calculate a new version from here.
2439 $have_version = 0;
2441 if (defined($pre_build)) {
2442 my $ret = run_command $pre_build;
2443 if (!$ret && defined($pre_build_die) &&
2444 $pre_build_die) {
2445 dodie "failed to pre_build\n";
2449 if ($type =~ /^useconfig:(.*)/) {
2450 run_command "cp $1 $output_config" or
2451 dodie "could not copy $1 to .config";
2453 $type = "oldconfig";
2456 # old config can ask questions
2457 if ($type eq "oldconfig") {
2458 $type = "olddefconfig";
2460 # allow for empty configs
2461 run_command "touch $output_config";
2463 if (!$noclean) {
2464 run_command "mv $output_config $outputdir/config_temp" or
2465 dodie "moving .config";
2467 run_command "$make mrproper" or dodie "make mrproper";
2469 run_command "mv $outputdir/config_temp $output_config" or
2470 dodie "moving config_temp";
2473 } elsif (!$noclean) {
2474 unlink "$output_config";
2475 run_command "$make mrproper" or
2476 dodie "make mrproper";
2479 # add something to distinguish this build
2480 open(OUT, "> $outputdir/localversion") or dodie("Can't make localversion file");
2481 print OUT "$localversion\n";
2482 close(OUT);
2484 if (defined($minconfig)) {
2485 load_force_config($minconfig);
2488 if ($type ne "olddefconfig") {
2489 run_command "$make $type" or
2490 dodie "failed make config";
2492 # Run old config regardless, to enforce min configurations
2493 make_oldconfig;
2495 my $build_ret = run_command "$make $build_options", $buildlog;
2497 if (defined($post_build)) {
2498 # Because a post build may change the kernel version
2499 # do it now.
2500 get_version;
2501 my $ret = run_command $post_build;
2502 if (!$ret && defined($post_build_die) &&
2503 $post_build_die) {
2504 dodie "failed to post_build\n";
2508 if (!$build_ret) {
2509 # bisect may need this to pass
2510 if ($in_bisect) {
2511 $no_reboot = $save_no_reboot;
2512 return 0;
2514 fail "failed build" and return 0;
2517 $no_reboot = $save_no_reboot;
2519 my $end_time = time;
2520 $build_time = $end_time - $start_time;
2522 return 1;
2525 sub halt {
2526 if (!run_ssh "halt" or defined($power_off)) {
2527 if (defined($poweroff_after_halt)) {
2528 sleep $poweroff_after_halt;
2529 run_command "$power_off";
2531 } else {
2532 # nope? the zap it!
2533 run_command "$power_off";
2537 sub success {
2538 my ($i) = @_;
2540 $successes++;
2542 my $name = "";
2544 if (defined($test_name)) {
2545 $name = " ($test_name)";
2548 print_times;
2550 doprint "\n\n*******************************************\n";
2551 doprint "*******************************************\n";
2552 doprint "KTEST RESULT: TEST $i$name SUCCESS!!!! **\n";
2553 doprint "*******************************************\n";
2554 doprint "*******************************************\n";
2556 if (defined($store_successes)) {
2557 save_logs "success", $store_successes;
2560 if ($i != $opt{"NUM_TESTS"} && !do_not_reboot) {
2561 doprint "Reboot and wait $sleep_time seconds\n";
2562 reboot_to_good $sleep_time;
2565 if (defined($post_test)) {
2566 run_command $post_test;
2570 sub answer_bisect {
2571 for (;;) {
2572 doprint "Pass, fail, or skip? [p/f/s]";
2573 my $ans = <STDIN>;
2574 chomp $ans;
2575 if ($ans eq "p" || $ans eq "P") {
2576 return 1;
2577 } elsif ($ans eq "f" || $ans eq "F") {
2578 return 0;
2579 } elsif ($ans eq "s" || $ans eq "S") {
2580 return -1;
2581 } else {
2582 print "Please answer 'p', 'f', or 's'\n";
2587 sub child_run_test {
2589 # child should have no power
2590 $reboot_on_error = 0;
2591 $poweroff_on_error = 0;
2592 $die_on_failure = 1;
2594 run_command $run_test, $testlog;
2596 exit $run_command_status;
2599 my $child_done;
2601 sub child_finished {
2602 $child_done = 1;
2605 sub do_run_test {
2606 my $child_pid;
2607 my $child_exit;
2608 my $line;
2609 my $full_line;
2610 my $bug = 0;
2611 my $bug_ignored = 0;
2613 my $start_time = time;
2615 wait_for_monitor 1;
2617 doprint "run test $run_test\n";
2619 $child_done = 0;
2621 $SIG{CHLD} = qw(child_finished);
2623 $child_pid = fork;
2625 child_run_test if (!$child_pid);
2627 $full_line = "";
2629 do {
2630 $line = wait_for_input($monitor_fp, 1);
2631 if (defined($line)) {
2633 # we are not guaranteed to get a full line
2634 $full_line .= $line;
2635 doprint $line;
2637 if ($full_line =~ /call trace:/i) {
2638 if ($ignore_errors) {
2639 $bug_ignored = 1;
2640 } else {
2641 $bug = 1;
2645 if ($full_line =~ /Kernel panic -/) {
2646 $bug = 1;
2649 if ($line =~ /\n/) {
2650 $full_line = "";
2653 } while (!$child_done && !$bug);
2655 if (!$bug && $bug_ignored) {
2656 doprint "WARNING: Call Trace detected but ignored due to IGNORE_ERRORS=1\n";
2659 if ($bug) {
2660 my $failure_start = time;
2661 my $now;
2662 do {
2663 $line = wait_for_input($monitor_fp, 1);
2664 if (defined($line)) {
2665 doprint $line;
2667 $now = time;
2668 if ($now - $failure_start >= $stop_after_failure) {
2669 last;
2671 } while (defined($line));
2673 doprint "Detected kernel crash!\n";
2674 # kill the child with extreme prejudice
2675 kill 9, $child_pid;
2678 waitpid $child_pid, 0;
2679 $child_exit = $? >> 8;
2681 my $end_time = time;
2682 $test_time = $end_time - $start_time;
2684 if (!$bug && $in_bisect) {
2685 if (defined($bisect_ret_good)) {
2686 if ($child_exit == $bisect_ret_good) {
2687 return 1;
2690 if (defined($bisect_ret_skip)) {
2691 if ($child_exit == $bisect_ret_skip) {
2692 return -1;
2695 if (defined($bisect_ret_abort)) {
2696 if ($child_exit == $bisect_ret_abort) {
2697 fail "test abort" and return -2;
2700 if (defined($bisect_ret_bad)) {
2701 if ($child_exit == $bisect_ret_skip) {
2702 return 0;
2705 if (defined($bisect_ret_default)) {
2706 if ($bisect_ret_default eq "good") {
2707 return 1;
2708 } elsif ($bisect_ret_default eq "bad") {
2709 return 0;
2710 } elsif ($bisect_ret_default eq "skip") {
2711 return -1;
2712 } elsif ($bisect_ret_default eq "abort") {
2713 return -2;
2714 } else {
2715 fail "unknown default action: $bisect_ret_default"
2716 and return -2;
2721 if ($bug || $child_exit) {
2722 return 0 if $in_bisect;
2723 fail "test failed" and return 0;
2725 return 1;
2728 sub run_git_bisect {
2729 my ($command) = @_;
2731 doprint "$command ... ";
2733 my $output = `$command 2>&1`;
2734 my $ret = $?;
2736 logit $output;
2738 if ($ret) {
2739 doprint "FAILED\n";
2740 dodie "Failed to git bisect";
2743 doprint "SUCCESS\n";
2744 if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\))\s+\[([[:xdigit:]]+)\]/) {
2745 doprint "$1 [$2]\n";
2746 } elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) {
2747 $bisect_bad_commit = $1;
2748 doprint "Found bad commit... $1\n";
2749 return 0;
2750 } else {
2751 # we already logged it, just print it now.
2752 print $output;
2755 return 1;
2758 sub bisect_reboot {
2759 doprint "Reboot and sleep $bisect_sleep_time seconds\n";
2760 reboot_to_good $bisect_sleep_time;
2763 # returns 1 on success, 0 on failure, -1 on skip
2764 sub run_bisect_test {
2765 my ($type, $buildtype) = @_;
2767 my $failed = 0;
2768 my $result;
2769 my $output;
2770 my $ret;
2772 $in_bisect = 1;
2774 build $buildtype or $failed = 1;
2776 if ($type ne "build") {
2777 if ($failed && $bisect_skip) {
2778 $in_bisect = 0;
2779 return -1;
2781 dodie "Failed on build" if $failed;
2783 # Now boot the box
2784 start_monitor_and_install or $failed = 1;
2786 if ($type ne "boot") {
2787 if ($failed && $bisect_skip) {
2788 end_monitor;
2789 bisect_reboot;
2790 $in_bisect = 0;
2791 return -1;
2793 dodie "Failed on boot" if $failed;
2795 do_run_test or $failed = 1;
2797 end_monitor;
2800 if ($failed) {
2801 $result = 0;
2802 } else {
2803 $result = 1;
2806 # reboot the box to a kernel we can ssh to
2807 if ($type ne "build") {
2808 bisect_reboot;
2810 $in_bisect = 0;
2812 return $result;
2815 sub run_bisect {
2816 my ($type) = @_;
2817 my $buildtype = "oldconfig";
2819 # We should have a minconfig to use?
2820 if (defined($minconfig)) {
2821 $buildtype = "useconfig:$minconfig";
2824 # If the user sets bisect_tries to less than 1, then no tries
2825 # is a success.
2826 my $ret = 1;
2828 # Still let the user manually decide that though.
2829 if ($bisect_tries < 1 && $bisect_manual) {
2830 $ret = answer_bisect;
2833 for (my $i = 0; $i < $bisect_tries; $i++) {
2834 if ($bisect_tries > 1) {
2835 my $t = $i + 1;
2836 doprint("Running bisect trial $t of $bisect_tries:\n");
2838 $ret = run_bisect_test $type, $buildtype;
2840 if ($bisect_manual) {
2841 $ret = answer_bisect;
2844 last if (!$ret);
2847 # Are we looking for where it worked, not failed?
2848 if ($reverse_bisect && $ret >= 0) {
2849 $ret = !$ret;
2852 if ($ret > 0) {
2853 return "good";
2854 } elsif ($ret == 0) {
2855 return "bad";
2856 } elsif ($bisect_skip) {
2857 doprint "HIT A BAD COMMIT ... SKIPPING\n";
2858 return "skip";
2862 sub update_bisect_replay {
2863 my $tmp_log = "$tmpdir/ktest_bisect_log";
2864 run_command "git bisect log > $tmp_log" or
2865 die "can't create bisect log";
2866 return $tmp_log;
2869 sub bisect {
2870 my ($i) = @_;
2872 my $result;
2874 die "BISECT_GOOD[$i] not defined\n" if (!defined($bisect_good));
2875 die "BISECT_BAD[$i] not defined\n" if (!defined($bisect_bad));
2876 die "BISECT_TYPE[$i] not defined\n" if (!defined($bisect_type));
2878 my $good = $bisect_good;
2879 my $bad = $bisect_bad;
2880 my $type = $bisect_type;
2881 my $start = $bisect_start;
2882 my $replay = $bisect_replay;
2883 my $start_files = $bisect_files;
2885 if (defined($start_files)) {
2886 $start_files = " -- " . $start_files;
2887 } else {
2888 $start_files = "";
2891 # convert to true sha1's
2892 $good = get_sha1($good);
2893 $bad = get_sha1($bad);
2895 if (defined($bisect_reverse) && $bisect_reverse == 1) {
2896 doprint "Performing a reverse bisect (bad is good, good is bad!)\n";
2897 $reverse_bisect = 1;
2898 } else {
2899 $reverse_bisect = 0;
2902 # Can't have a test without having a test to run
2903 if ($type eq "test" && !defined($run_test)) {
2904 $type = "boot";
2907 # Check if a bisect was running
2908 my $bisect_start_file = "$builddir/.git/BISECT_START";
2910 my $check = $bisect_check;
2911 my $do_check = defined($check) && $check ne "0";
2913 if ( -f $bisect_start_file ) {
2914 print "Bisect in progress found\n";
2915 if ($do_check) {
2916 print " If you say yes, then no checks of good or bad will be done\n";
2918 if (defined($replay)) {
2919 print "** BISECT_REPLAY is defined in config file **";
2920 print " Ignore config option and perform new git bisect log?\n";
2921 if (read_ync " (yes, no, or cancel) ") {
2922 $replay = update_bisect_replay;
2923 $do_check = 0;
2925 } elsif (read_yn "read git log and continue?") {
2926 $replay = update_bisect_replay;
2927 $do_check = 0;
2931 if ($do_check) {
2933 # get current HEAD
2934 my $head = get_sha1("HEAD");
2936 if ($check ne "good") {
2937 doprint "TESTING BISECT BAD [$bad]\n";
2938 run_command "git checkout $bad" or
2939 die "Failed to checkout $bad";
2941 $result = run_bisect $type;
2943 if ($result ne "bad") {
2944 fail "Tested BISECT_BAD [$bad] and it succeeded" and return 0;
2948 if ($check ne "bad") {
2949 doprint "TESTING BISECT GOOD [$good]\n";
2950 run_command "git checkout $good" or
2951 die "Failed to checkout $good";
2953 $result = run_bisect $type;
2955 if ($result ne "good") {
2956 fail "Tested BISECT_GOOD [$good] and it failed" and return 0;
2960 # checkout where we started
2961 run_command "git checkout $head" or
2962 die "Failed to checkout $head";
2965 run_command "git bisect start$start_files" or
2966 dodie "could not start bisect";
2968 if (defined($replay)) {
2969 run_command "git bisect replay $replay" or
2970 dodie "failed to run replay";
2971 } else {
2973 run_command "git bisect good $good" or
2974 dodie "could not set bisect good to $good";
2976 run_git_bisect "git bisect bad $bad" or
2977 dodie "could not set bisect bad to $bad";
2981 if (defined($start)) {
2982 run_command "git checkout $start" or
2983 dodie "failed to checkout $start";
2986 my $test;
2987 do {
2988 $result = run_bisect $type;
2989 $test = run_git_bisect "git bisect $result";
2990 print_times;
2991 } while ($test);
2993 run_command "git bisect log" or
2994 dodie "could not capture git bisect log";
2996 run_command "git bisect reset" or
2997 dodie "could not reset git bisect";
2999 doprint "Bad commit was [$bisect_bad_commit]\n";
3001 success $i;
3004 # config_ignore holds the configs that were set (or unset) for
3005 # a good config and we will ignore these configs for the rest
3006 # of a config bisect. These configs stay as they were.
3007 my %config_ignore;
3009 # config_set holds what all configs were set as.
3010 my %config_set;
3012 # config_off holds the set of configs that the bad config had disabled.
3013 # We need to record them and set them in the .config when running
3014 # olddefconfig, because olddefconfig keeps the defaults.
3015 my %config_off;
3017 # config_off_tmp holds a set of configs to turn off for now
3018 my @config_off_tmp;
3020 # config_list is the set of configs that are being tested
3021 my %config_list;
3022 my %null_config;
3024 my %dependency;
3026 sub assign_configs {
3027 my ($hash, $config) = @_;
3029 doprint "Reading configs from $config\n";
3031 open (IN, $config)
3032 or dodie "Failed to read $config";
3034 while (<IN>) {
3035 chomp;
3036 if (/^((CONFIG\S*)=.*)/) {
3037 ${$hash}{$2} = $1;
3038 } elsif (/^(# (CONFIG\S*) is not set)/) {
3039 ${$hash}{$2} = $1;
3043 close(IN);
3046 sub process_config_ignore {
3047 my ($config) = @_;
3049 assign_configs \%config_ignore, $config;
3052 sub get_dependencies {
3053 my ($config) = @_;
3055 my $arr = $dependency{$config};
3056 if (!defined($arr)) {
3057 return ();
3060 my @deps = @{$arr};
3062 foreach my $dep (@{$arr}) {
3063 print "ADD DEP $dep\n";
3064 @deps = (@deps, get_dependencies $dep);
3067 return @deps;
3070 sub save_config {
3071 my ($pc, $file) = @_;
3073 my %configs = %{$pc};
3075 doprint "Saving configs into $file\n";
3077 open(OUT, ">$file") or dodie "Can not write to $file";
3079 foreach my $config (keys %configs) {
3080 print OUT "$configs{$config}\n";
3082 close(OUT);
3085 sub create_config {
3086 my ($name, $pc) = @_;
3088 doprint "Creating old config from $name configs\n";
3090 save_config $pc, $output_config;
3092 make_oldconfig;
3095 # compare two config hashes, and return configs with different vals.
3096 # It returns B's config values, but you can use A to see what A was.
3097 sub diff_config_vals {
3098 my ($pa, $pb) = @_;
3100 # crappy Perl way to pass in hashes.
3101 my %a = %{$pa};
3102 my %b = %{$pb};
3104 my %ret;
3106 foreach my $item (keys %a) {
3107 if (defined($b{$item}) && $b{$item} ne $a{$item}) {
3108 $ret{$item} = $b{$item};
3112 return %ret;
3115 # compare two config hashes and return the configs in B but not A
3116 sub diff_configs {
3117 my ($pa, $pb) = @_;
3119 my %ret;
3121 # crappy Perl way to pass in hashes.
3122 my %a = %{$pa};
3123 my %b = %{$pb};
3125 foreach my $item (keys %b) {
3126 if (!defined($a{$item})) {
3127 $ret{$item} = $b{$item};
3131 return %ret;
3134 # return if two configs are equal or not
3135 # 0 is equal +1 b has something a does not
3136 # +1 if a and b have a different item.
3137 # -1 if a has something b does not
3138 sub compare_configs {
3139 my ($pa, $pb) = @_;
3141 my %ret;
3143 # crappy Perl way to pass in hashes.
3144 my %a = %{$pa};
3145 my %b = %{$pb};
3147 foreach my $item (keys %b) {
3148 if (!defined($a{$item})) {
3149 return 1;
3151 if ($a{$item} ne $b{$item}) {
3152 return 1;
3156 foreach my $item (keys %a) {
3157 if (!defined($b{$item})) {
3158 return -1;
3162 return 0;
3165 sub run_config_bisect_test {
3166 my ($type) = @_;
3168 my $ret = run_bisect_test $type, "oldconfig";
3170 if ($bisect_manual) {
3171 $ret = answer_bisect;
3174 return $ret;
3177 sub process_failed {
3178 my ($config) = @_;
3180 doprint "\n\n***************************************\n";
3181 doprint "Found bad config: $config\n";
3182 doprint "***************************************\n\n";
3185 # used for config bisecting
3186 my $good_config;
3187 my $bad_config;
3189 sub process_new_config {
3190 my ($tc, $nc, $gc, $bc) = @_;
3192 my %tmp_config = %{$tc};
3193 my %good_configs = %{$gc};
3194 my %bad_configs = %{$bc};
3196 my %new_configs;
3198 my $runtest = 1;
3199 my $ret;
3201 create_config "tmp_configs", \%tmp_config;
3202 assign_configs \%new_configs, $output_config;
3204 $ret = compare_configs \%new_configs, \%bad_configs;
3205 if (!$ret) {
3206 doprint "New config equals bad config, try next test\n";
3207 $runtest = 0;
3210 if ($runtest) {
3211 $ret = compare_configs \%new_configs, \%good_configs;
3212 if (!$ret) {
3213 doprint "New config equals good config, try next test\n";
3214 $runtest = 0;
3218 %{$nc} = %new_configs;
3220 return $runtest;
3223 sub run_config_bisect {
3224 my ($pgood, $pbad) = @_;
3226 my $type = $config_bisect_type;
3228 my %good_configs = %{$pgood};
3229 my %bad_configs = %{$pbad};
3231 my %diff_configs = diff_config_vals \%good_configs, \%bad_configs;
3232 my %b_configs = diff_configs \%good_configs, \%bad_configs;
3233 my %g_configs = diff_configs \%bad_configs, \%good_configs;
3235 my @diff_arr = keys %diff_configs;
3236 my $len_diff = $#diff_arr + 1;
3238 my @b_arr = keys %b_configs;
3239 my $len_b = $#b_arr + 1;
3241 my @g_arr = keys %g_configs;
3242 my $len_g = $#g_arr + 1;
3244 my $runtest = 1;
3245 my %new_configs;
3246 my $ret;
3248 # First, lets get it down to a single subset.
3249 # Is the problem with a difference in values?
3250 # Is the problem with a missing config?
3251 # Is the problem with a config that breaks things?
3253 # Enable all of one set and see if we get a new bad
3254 # or good config.
3256 # first set the good config to the bad values.
3258 doprint "d=$len_diff g=$len_g b=$len_b\n";
3260 # first lets enable things in bad config that are enabled in good config
3262 if ($len_diff > 0) {
3263 if ($len_b > 0 || $len_g > 0) {
3264 my %tmp_config = %bad_configs;
3266 doprint "Set tmp config to be bad config with good config values\n";
3267 foreach my $item (@diff_arr) {
3268 $tmp_config{$item} = $good_configs{$item};
3271 $runtest = process_new_config \%tmp_config, \%new_configs,
3272 \%good_configs, \%bad_configs;
3276 if (!$runtest && $len_diff > 0) {
3278 if ($len_diff == 1) {
3279 process_failed $diff_arr[0];
3280 return 1;
3282 my %tmp_config = %bad_configs;
3284 my $half = int($#diff_arr / 2);
3285 my @tophalf = @diff_arr[0 .. $half];
3287 doprint "Settings bisect with top half:\n";
3288 doprint "Set tmp config to be bad config with some good config values\n";
3289 foreach my $item (@tophalf) {
3290 $tmp_config{$item} = $good_configs{$item};
3293 $runtest = process_new_config \%tmp_config, \%new_configs,
3294 \%good_configs, \%bad_configs;
3296 if (!$runtest) {
3297 my %tmp_config = %bad_configs;
3299 doprint "Try bottom half\n";
3301 my @bottomhalf = @diff_arr[$half+1 .. $#diff_arr];
3303 foreach my $item (@bottomhalf) {
3304 $tmp_config{$item} = $good_configs{$item};
3307 $runtest = process_new_config \%tmp_config, \%new_configs,
3308 \%good_configs, \%bad_configs;
3312 if ($runtest) {
3313 $ret = run_config_bisect_test $type;
3314 if ($ret) {
3315 doprint "NEW GOOD CONFIG\n";
3316 %good_configs = %new_configs;
3317 run_command "mv $good_config ${good_config}.last";
3318 save_config \%good_configs, $good_config;
3319 %{$pgood} = %good_configs;
3320 } else {
3321 doprint "NEW BAD CONFIG\n";
3322 %bad_configs = %new_configs;
3323 run_command "mv $bad_config ${bad_config}.last";
3324 save_config \%bad_configs, $bad_config;
3325 %{$pbad} = %bad_configs;
3327 return 0;
3330 fail "Hmm, need to do a mix match?\n";
3331 return -1;
3334 sub config_bisect {
3335 my ($i) = @_;
3337 my $type = $config_bisect_type;
3338 my $ret;
3340 $bad_config = $config_bisect;
3342 if (defined($config_bisect_good)) {
3343 $good_config = $config_bisect_good;
3344 } elsif (defined($minconfig)) {
3345 $good_config = $minconfig;
3346 } else {
3347 doprint "No config specified, checking if defconfig works";
3348 $ret = run_bisect_test $type, "defconfig";
3349 if (!$ret) {
3350 fail "Have no good config to compare with, please set CONFIG_BISECT_GOOD";
3351 return 1;
3353 $good_config = $output_config;
3356 # we don't want min configs to cause issues here.
3357 doprint "Disabling 'MIN_CONFIG' for this test\n";
3358 undef $minconfig;
3360 my %good_configs;
3361 my %bad_configs;
3362 my %tmp_configs;
3364 doprint "Run good configs through make oldconfig\n";
3365 assign_configs \%tmp_configs, $good_config;
3366 create_config "$good_config", \%tmp_configs;
3367 assign_configs \%good_configs, $output_config;
3369 doprint "Run bad configs through make oldconfig\n";
3370 assign_configs \%tmp_configs, $bad_config;
3371 create_config "$bad_config", \%tmp_configs;
3372 assign_configs \%bad_configs, $output_config;
3374 $good_config = "$tmpdir/good_config";
3375 $bad_config = "$tmpdir/bad_config";
3377 save_config \%good_configs, $good_config;
3378 save_config \%bad_configs, $bad_config;
3380 if (defined($config_bisect_check) && $config_bisect_check ne "0") {
3381 if ($config_bisect_check ne "good") {
3382 doprint "Testing bad config\n";
3384 $ret = run_bisect_test $type, "useconfig:$bad_config";
3385 if ($ret) {
3386 fail "Bad config succeeded when expected to fail!";
3387 return 0;
3390 if ($config_bisect_check ne "bad") {
3391 doprint "Testing good config\n";
3393 $ret = run_bisect_test $type, "useconfig:$good_config";
3394 if (!$ret) {
3395 fail "Good config failed when expected to succeed!";
3396 return 0;
3401 do {
3402 $ret = run_config_bisect \%good_configs, \%bad_configs;
3403 print_times;
3404 } while (!$ret);
3406 return $ret if ($ret < 0);
3408 success $i;
3411 sub patchcheck_reboot {
3412 doprint "Reboot and sleep $patchcheck_sleep_time seconds\n";
3413 reboot_to_good $patchcheck_sleep_time;
3416 sub patchcheck {
3417 my ($i) = @_;
3419 die "PATCHCHECK_START[$i] not defined\n"
3420 if (!defined($patchcheck_start));
3421 die "PATCHCHECK_TYPE[$i] not defined\n"
3422 if (!defined($patchcheck_type));
3424 my $start = $patchcheck_start;
3426 my $cherry = $patchcheck_cherry;
3427 if (!defined($cherry)) {
3428 $cherry = 0;
3431 my $end = "HEAD";
3432 if (defined($patchcheck_end)) {
3433 $end = $patchcheck_end;
3434 } elsif ($cherry) {
3435 die "PATCHCHECK_END must be defined with PATCHCHECK_CHERRY\n";
3438 # Get the true sha1's since we can use things like HEAD~3
3439 $start = get_sha1($start);
3440 $end = get_sha1($end);
3442 my $type = $patchcheck_type;
3444 # Can't have a test without having a test to run
3445 if ($type eq "test" && !defined($run_test)) {
3446 $type = "boot";
3449 if ($cherry) {
3450 open (IN, "git cherry -v $start $end|") or
3451 dodie "could not get git list";
3452 } else {
3453 open (IN, "git log --pretty=oneline $end|") or
3454 dodie "could not get git list";
3457 my @list;
3459 while (<IN>) {
3460 chomp;
3461 # git cherry adds a '+' we want to remove
3462 s/^\+ //;
3463 $list[$#list+1] = $_;
3464 last if (/^$start/);
3466 close(IN);
3468 if (!$cherry) {
3469 if ($list[$#list] !~ /^$start/) {
3470 fail "SHA1 $start not found";
3473 # go backwards in the list
3474 @list = reverse @list;
3477 doprint("Going to test the following commits:\n");
3478 foreach my $l (@list) {
3479 doprint "$l\n";
3482 my $save_clean = $noclean;
3483 my %ignored_warnings;
3485 if (defined($ignore_warnings)) {
3486 foreach my $sha1 (split /\s+/, $ignore_warnings) {
3487 $ignored_warnings{$sha1} = 1;
3491 $in_patchcheck = 1;
3492 foreach my $item (@list) {
3493 my $sha1 = $item;
3494 $sha1 =~ s/^([[:xdigit:]]+).*/$1/;
3496 doprint "\nProcessing commit \"$item\"\n\n";
3498 run_command "git checkout $sha1" or
3499 die "Failed to checkout $sha1";
3501 # only clean on the first and last patch
3502 if ($item eq $list[0] ||
3503 $item eq $list[$#list]) {
3504 $noclean = $save_clean;
3505 } else {
3506 $noclean = 1;
3509 if (defined($minconfig)) {
3510 build "useconfig:$minconfig" or return 0;
3511 } else {
3512 # ?? no config to use?
3513 build "oldconfig" or return 0;
3516 # No need to do per patch checking if warnings file exists
3517 if (!defined($warnings_file) && !defined($ignored_warnings{$sha1})) {
3518 check_patch_buildlog $sha1 or return 0;
3521 check_buildlog or return 0;
3523 next if ($type eq "build");
3525 my $failed = 0;
3527 start_monitor_and_install or $failed = 1;
3529 if (!$failed && $type ne "boot"){
3530 do_run_test or $failed = 1;
3532 end_monitor;
3533 if ($failed) {
3534 print_times;
3535 return 0;
3537 patchcheck_reboot;
3538 print_times;
3540 $in_patchcheck = 0;
3541 success $i;
3543 return 1;
3546 my %depends;
3547 my %depcount;
3548 my $iflevel = 0;
3549 my @ifdeps;
3551 # prevent recursion
3552 my %read_kconfigs;
3554 sub add_dep {
3555 # $config depends on $dep
3556 my ($config, $dep) = @_;
3558 if (defined($depends{$config})) {
3559 $depends{$config} .= " " . $dep;
3560 } else {
3561 $depends{$config} = $dep;
3564 # record the number of configs depending on $dep
3565 if (defined $depcount{$dep}) {
3566 $depcount{$dep}++;
3567 } else {
3568 $depcount{$dep} = 1;
3572 # taken from streamline_config.pl
3573 sub read_kconfig {
3574 my ($kconfig) = @_;
3576 my $state = "NONE";
3577 my $config;
3578 my @kconfigs;
3580 my $cont = 0;
3581 my $line;
3584 if (! -f $kconfig) {
3585 doprint "file $kconfig does not exist, skipping\n";
3586 return;
3589 open(KIN, "$kconfig")
3590 or die "Can't open $kconfig";
3591 while (<KIN>) {
3592 chomp;
3594 # Make sure that lines ending with \ continue
3595 if ($cont) {
3596 $_ = $line . " " . $_;
3599 if (s/\\$//) {
3600 $cont = 1;
3601 $line = $_;
3602 next;
3605 $cont = 0;
3607 # collect any Kconfig sources
3608 if (/^source\s*"(.*)"/) {
3609 $kconfigs[$#kconfigs+1] = $1;
3612 # configs found
3613 if (/^\s*(menu)?config\s+(\S+)\s*$/) {
3614 $state = "NEW";
3615 $config = $2;
3617 for (my $i = 0; $i < $iflevel; $i++) {
3618 add_dep $config, $ifdeps[$i];
3621 # collect the depends for the config
3622 } elsif ($state eq "NEW" && /^\s*depends\s+on\s+(.*)$/) {
3624 add_dep $config, $1;
3626 # Get the configs that select this config
3627 } elsif ($state eq "NEW" && /^\s*select\s+(\S+)/) {
3629 # selected by depends on config
3630 add_dep $1, $config;
3632 # Check for if statements
3633 } elsif (/^if\s+(.*\S)\s*$/) {
3634 my $deps = $1;
3635 # remove beginning and ending non text
3636 $deps =~ s/^[^a-zA-Z0-9_]*//;
3637 $deps =~ s/[^a-zA-Z0-9_]*$//;
3639 my @deps = split /[^a-zA-Z0-9_]+/, $deps;
3641 $ifdeps[$iflevel++] = join ':', @deps;
3643 } elsif (/^endif/) {
3645 $iflevel-- if ($iflevel);
3647 # stop on "help"
3648 } elsif (/^\s*help\s*$/) {
3649 $state = "NONE";
3652 close(KIN);
3654 # read in any configs that were found.
3655 foreach $kconfig (@kconfigs) {
3656 if (!defined($read_kconfigs{$kconfig})) {
3657 $read_kconfigs{$kconfig} = 1;
3658 read_kconfig("$builddir/$kconfig");
3663 sub read_depends {
3664 # find out which arch this is by the kconfig file
3665 open (IN, $output_config)
3666 or dodie "Failed to read $output_config";
3667 my $arch;
3668 while (<IN>) {
3669 if (m,Linux/(\S+)\s+\S+\s+Kernel Configuration,) {
3670 $arch = $1;
3671 last;
3674 close IN;
3676 if (!defined($arch)) {
3677 doprint "Could not find arch from config file\n";
3678 doprint "no dependencies used\n";
3679 return;
3682 # arch is really the subarch, we need to know
3683 # what directory to look at.
3684 if ($arch eq "i386" || $arch eq "x86_64") {
3685 $arch = "x86";
3686 } elsif ($arch =~ /^tile/) {
3687 $arch = "tile";
3690 my $kconfig = "$builddir/arch/$arch/Kconfig";
3692 if (! -f $kconfig && $arch =~ /\d$/) {
3693 my $orig = $arch;
3694 # some subarchs have numbers, truncate them
3695 $arch =~ s/\d*$//;
3696 $kconfig = "$builddir/arch/$arch/Kconfig";
3697 if (! -f $kconfig) {
3698 doprint "No idea what arch dir $orig is for\n";
3699 doprint "no dependencies used\n";
3700 return;
3704 read_kconfig($kconfig);
3707 sub make_new_config {
3708 my @configs = @_;
3710 open (OUT, ">$output_config")
3711 or dodie "Failed to write $output_config";
3713 foreach my $config (@configs) {
3714 print OUT "$config\n";
3716 close OUT;
3719 sub chomp_config {
3720 my ($config) = @_;
3722 $config =~ s/CONFIG_//;
3724 return $config;
3727 sub get_depends {
3728 my ($dep) = @_;
3730 my $kconfig = chomp_config $dep;
3732 $dep = $depends{"$kconfig"};
3734 # the dep string we have saves the dependencies as they
3735 # were found, including expressions like ! && ||. We
3736 # want to split this out into just an array of configs.
3738 my $valid = "A-Za-z_0-9";
3740 my @configs;
3742 while ($dep =~ /[$valid]/) {
3744 if ($dep =~ /^[^$valid]*([$valid]+)/) {
3745 my $conf = "CONFIG_" . $1;
3747 $configs[$#configs + 1] = $conf;
3749 $dep =~ s/^[^$valid]*[$valid]+//;
3750 } else {
3751 die "this should never happen";
3755 return @configs;
3758 my %min_configs;
3759 my %keep_configs;
3760 my %save_configs;
3761 my %processed_configs;
3762 my %nochange_config;
3764 sub test_this_config {
3765 my ($config) = @_;
3767 my $found;
3769 # if we already processed this config, skip it
3770 if (defined($processed_configs{$config})) {
3771 return undef;
3773 $processed_configs{$config} = 1;
3775 # if this config failed during this round, skip it
3776 if (defined($nochange_config{$config})) {
3777 return undef;
3780 my $kconfig = chomp_config $config;
3782 # Test dependencies first
3783 if (defined($depends{"$kconfig"})) {
3784 my @parents = get_depends $config;
3785 foreach my $parent (@parents) {
3786 # if the parent is in the min config, check it first
3787 next if (!defined($min_configs{$parent}));
3788 $found = test_this_config($parent);
3789 if (defined($found)) {
3790 return $found;
3795 # Remove this config from the list of configs
3796 # do a make olddefconfig and then read the resulting
3797 # .config to make sure it is missing the config that
3798 # we had before
3799 my %configs = %min_configs;
3800 delete $configs{$config};
3801 make_new_config ((values %configs), (values %keep_configs));
3802 make_oldconfig;
3803 undef %configs;
3804 assign_configs \%configs, $output_config;
3806 if (!defined($configs{$config}) || $configs{$config} =~ /^#/) {
3807 return $config;
3810 doprint "disabling config $config did not change .config\n";
3812 $nochange_config{$config} = 1;
3814 return undef;
3817 sub make_min_config {
3818 my ($i) = @_;
3820 my $type = $minconfig_type;
3821 if ($type ne "boot" && $type ne "test") {
3822 fail "Invalid MIN_CONFIG_TYPE '$minconfig_type'\n" .
3823 " make_min_config works only with 'boot' and 'test'\n" and return;
3826 if (!defined($output_minconfig)) {
3827 fail "OUTPUT_MIN_CONFIG not defined" and return;
3830 # If output_minconfig exists, and the start_minconfig
3831 # came from min_config, than ask if we should use
3832 # that instead.
3833 if (-f $output_minconfig && !$start_minconfig_defined) {
3834 print "$output_minconfig exists\n";
3835 if (!defined($use_output_minconfig)) {
3836 if (read_yn " Use it as minconfig?") {
3837 $start_minconfig = $output_minconfig;
3839 } elsif ($use_output_minconfig > 0) {
3840 doprint "Using $output_minconfig as MIN_CONFIG\n";
3841 $start_minconfig = $output_minconfig;
3842 } else {
3843 doprint "Set to still use MIN_CONFIG as starting point\n";
3847 if (!defined($start_minconfig)) {
3848 fail "START_MIN_CONFIG or MIN_CONFIG not defined" and return;
3851 my $temp_config = "$tmpdir/temp_config";
3853 # First things first. We build an allnoconfig to find
3854 # out what the defaults are that we can't touch.
3855 # Some are selections, but we really can't handle selections.
3857 my $save_minconfig = $minconfig;
3858 undef $minconfig;
3860 run_command "$make allnoconfig" or return 0;
3862 read_depends;
3864 process_config_ignore $output_config;
3866 undef %save_configs;
3867 undef %min_configs;
3869 if (defined($ignore_config)) {
3870 # make sure the file exists
3871 `touch $ignore_config`;
3872 assign_configs \%save_configs, $ignore_config;
3875 %keep_configs = %save_configs;
3877 doprint "Load initial configs from $start_minconfig\n";
3879 # Look at the current min configs, and save off all the
3880 # ones that were set via the allnoconfig
3881 assign_configs \%min_configs, $start_minconfig;
3883 my @config_keys = keys %min_configs;
3885 # All configs need a depcount
3886 foreach my $config (@config_keys) {
3887 my $kconfig = chomp_config $config;
3888 if (!defined $depcount{$kconfig}) {
3889 $depcount{$kconfig} = 0;
3893 # Remove anything that was set by the make allnoconfig
3894 # we shouldn't need them as they get set for us anyway.
3895 foreach my $config (@config_keys) {
3896 # Remove anything in the ignore_config
3897 if (defined($keep_configs{$config})) {
3898 my $file = $ignore_config;
3899 $file =~ s,.*/(.*?)$,$1,;
3900 doprint "$config set by $file ... ignored\n";
3901 delete $min_configs{$config};
3902 next;
3904 # But make sure the settings are the same. If a min config
3905 # sets a selection, we do not want to get rid of it if
3906 # it is not the same as what we have. Just move it into
3907 # the keep configs.
3908 if (defined($config_ignore{$config})) {
3909 if ($config_ignore{$config} ne $min_configs{$config}) {
3910 doprint "$config is in allnoconfig as '$config_ignore{$config}'";
3911 doprint " but it is '$min_configs{$config}' in minconfig .. keeping\n";
3912 $keep_configs{$config} = $min_configs{$config};
3913 } else {
3914 doprint "$config set by allnoconfig ... ignored\n";
3916 delete $min_configs{$config};
3920 my $done = 0;
3921 my $take_two = 0;
3923 while (!$done) {
3925 my $config;
3926 my $found;
3928 # Now disable each config one by one and do a make oldconfig
3929 # till we find a config that changes our list.
3931 my @test_configs = keys %min_configs;
3933 # Sort keys by who is most dependent on
3934 @test_configs = sort { $depcount{chomp_config($b)} <=> $depcount{chomp_config($a)} }
3935 @test_configs ;
3937 # Put configs that did not modify the config at the end.
3938 my $reset = 1;
3939 for (my $i = 0; $i < $#test_configs; $i++) {
3940 if (!defined($nochange_config{$test_configs[0]})) {
3941 $reset = 0;
3942 last;
3944 # This config didn't change the .config last time.
3945 # Place it at the end
3946 my $config = shift @test_configs;
3947 push @test_configs, $config;
3950 # if every test config has failed to modify the .config file
3951 # in the past, then reset and start over.
3952 if ($reset) {
3953 undef %nochange_config;
3956 undef %processed_configs;
3958 foreach my $config (@test_configs) {
3960 $found = test_this_config $config;
3962 last if (defined($found));
3964 # oh well, try another config
3967 if (!defined($found)) {
3968 # we could have failed due to the nochange_config hash
3969 # reset and try again
3970 if (!$take_two) {
3971 undef %nochange_config;
3972 $take_two = 1;
3973 next;
3975 doprint "No more configs found that we can disable\n";
3976 $done = 1;
3977 last;
3979 $take_two = 0;
3981 $config = $found;
3983 doprint "Test with $config disabled\n";
3985 # set in_bisect to keep build and monitor from dieing
3986 $in_bisect = 1;
3988 my $failed = 0;
3989 build "oldconfig" or $failed = 1;
3990 if (!$failed) {
3991 start_monitor_and_install or $failed = 1;
3993 if ($type eq "test" && !$failed) {
3994 do_run_test or $failed = 1;
3997 end_monitor;
4000 $in_bisect = 0;
4002 if ($failed) {
4003 doprint "$min_configs{$config} is needed to boot the box... keeping\n";
4004 # this config is needed, add it to the ignore list.
4005 $keep_configs{$config} = $min_configs{$config};
4006 $save_configs{$config} = $min_configs{$config};
4007 delete $min_configs{$config};
4009 # update new ignore configs
4010 if (defined($ignore_config)) {
4011 open (OUT, ">$temp_config")
4012 or die "Can't write to $temp_config";
4013 foreach my $config (keys %save_configs) {
4014 print OUT "$save_configs{$config}\n";
4016 close OUT;
4017 run_command "mv $temp_config $ignore_config" or
4018 dodie "failed to copy update to $ignore_config";
4021 } else {
4022 # We booted without this config, remove it from the minconfigs.
4023 doprint "$config is not needed, disabling\n";
4025 delete $min_configs{$config};
4027 # Also disable anything that is not enabled in this config
4028 my %configs;
4029 assign_configs \%configs, $output_config;
4030 my @config_keys = keys %min_configs;
4031 foreach my $config (@config_keys) {
4032 if (!defined($configs{$config})) {
4033 doprint "$config is not set, disabling\n";
4034 delete $min_configs{$config};
4038 # Save off all the current mandatory configs
4039 open (OUT, ">$temp_config")
4040 or die "Can't write to $temp_config";
4041 foreach my $config (keys %keep_configs) {
4042 print OUT "$keep_configs{$config}\n";
4044 foreach my $config (keys %min_configs) {
4045 print OUT "$min_configs{$config}\n";
4047 close OUT;
4049 run_command "mv $temp_config $output_minconfig" or
4050 dodie "failed to copy update to $output_minconfig";
4053 doprint "Reboot and wait $sleep_time seconds\n";
4054 reboot_to_good $sleep_time;
4057 success $i;
4058 return 1;
4061 sub make_warnings_file {
4062 my ($i) = @_;
4064 if (!defined($warnings_file)) {
4065 dodie "Must define WARNINGS_FILE for make_warnings_file test";
4068 if ($build_type eq "nobuild") {
4069 dodie "BUILD_TYPE can not be 'nobuild' for make_warnings_file test";
4072 build $build_type or dodie "Failed to build";
4074 open(OUT, ">$warnings_file") or dodie "Can't create $warnings_file";
4076 open(IN, $buildlog) or dodie "Can't open $buildlog";
4077 while (<IN>) {
4079 # Some compilers use UTF-8 extended for quotes
4080 # for distcc heterogeneous systems, this causes issues
4081 s/$utf8_quote/'/g;
4083 if (/$check_build_re/) {
4084 print OUT;
4087 close(IN);
4089 close(OUT);
4091 success $i;
4094 $#ARGV < 1 or die "ktest.pl version: $VERSION\n usage: ktest.pl [config-file]\n";
4096 if ($#ARGV == 0) {
4097 $ktest_config = $ARGV[0];
4098 if (! -f $ktest_config) {
4099 print "$ktest_config does not exist.\n";
4100 if (!read_yn "Create it?") {
4101 exit 0;
4106 if (! -f $ktest_config) {
4107 $newconfig = 1;
4108 get_test_case;
4109 open(OUT, ">$ktest_config") or die "Can not create $ktest_config";
4110 print OUT << "EOF"
4111 # Generated by ktest.pl
4114 # PWD is a ktest.pl variable that will result in the process working
4115 # directory that ktest.pl is executed in.
4117 # THIS_DIR is automatically assigned the PWD of the path that generated
4118 # the config file. It is best to use this variable when assigning other
4119 # directory paths within this directory. This allows you to easily
4120 # move the test cases to other locations or to other machines.
4122 THIS_DIR := $variable{"PWD"}
4124 # Define each test with TEST_START
4125 # The config options below it will override the defaults
4126 TEST_START
4127 TEST_TYPE = $default{"TEST_TYPE"}
4129 DEFAULTS
4132 close(OUT);
4134 read_config $ktest_config;
4136 if (defined($opt{"LOG_FILE"})) {
4137 $opt{"LOG_FILE"} = eval_option("LOG_FILE", $opt{"LOG_FILE"}, -1);
4140 # Append any configs entered in manually to the config file.
4141 my @new_configs = keys %entered_configs;
4142 if ($#new_configs >= 0) {
4143 print "\nAppending entered in configs to $ktest_config\n";
4144 open(OUT, ">>$ktest_config") or die "Can not append to $ktest_config";
4145 foreach my $config (@new_configs) {
4146 print OUT "$config = $entered_configs{$config}\n";
4147 $opt{$config} = process_variables($entered_configs{$config});
4151 if ($opt{"CLEAR_LOG"} && defined($opt{"LOG_FILE"})) {
4152 unlink $opt{"LOG_FILE"};
4155 doprint "\n\nSTARTING AUTOMATED TESTS\n\n";
4157 for (my $i = 0, my $repeat = 1; $i <= $opt{"NUM_TESTS"}; $i += $repeat) {
4159 if (!$i) {
4160 doprint "DEFAULT OPTIONS:\n";
4161 } else {
4162 doprint "\nTEST $i OPTIONS";
4163 if (defined($repeat_tests{$i})) {
4164 $repeat = $repeat_tests{$i};
4165 doprint " ITERATE $repeat";
4167 doprint "\n";
4170 foreach my $option (sort keys %opt) {
4172 if ($option =~ /\[(\d+)\]$/) {
4173 next if ($i != $1);
4174 } else {
4175 next if ($i);
4178 doprint "$option = $opt{$option}\n";
4182 sub option_defined {
4183 my ($option) = @_;
4185 if (defined($opt{$option}) && $opt{$option} !~ /^\s*$/) {
4186 return 1;
4189 return 0;
4192 sub __set_test_option {
4193 my ($name, $i) = @_;
4195 my $option = "$name\[$i\]";
4197 if (option_defined($option)) {
4198 return $opt{$option};
4201 foreach my $test (keys %repeat_tests) {
4202 if ($i >= $test &&
4203 $i < $test + $repeat_tests{$test}) {
4204 $option = "$name\[$test\]";
4205 if (option_defined($option)) {
4206 return $opt{$option};
4211 if (option_defined($name)) {
4212 return $opt{$name};
4215 return undef;
4218 sub set_test_option {
4219 my ($name, $i) = @_;
4221 my $option = __set_test_option($name, $i);
4222 return $option if (!defined($option));
4224 return eval_option($name, $option, $i);
4227 # First we need to do is the builds
4228 for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
4230 # Do not reboot on failing test options
4231 $no_reboot = 1;
4232 $reboot_success = 0;
4234 $have_version = 0;
4236 $iteration = $i;
4238 $build_time = 0;
4239 $install_time = 0;
4240 $reboot_time = 0;
4241 $test_time = 0;
4243 undef %force_config;
4245 my $makecmd = set_test_option("MAKE_CMD", $i);
4247 $outputdir = set_test_option("OUTPUT_DIR", $i);
4248 $builddir = set_test_option("BUILD_DIR", $i);
4250 chdir $builddir || die "can't change directory to $builddir";
4252 if (!-d $outputdir) {
4253 mkpath($outputdir) or
4254 die "can't create $outputdir";
4257 $make = "$makecmd O=$outputdir";
4259 # Load all the options into their mapped variable names
4260 foreach my $opt (keys %option_map) {
4261 ${$option_map{$opt}} = set_test_option($opt, $i);
4264 $start_minconfig_defined = 1;
4266 # The first test may override the PRE_KTEST option
4267 if (defined($pre_ktest) && $i == 1) {
4268 doprint "\n";
4269 run_command $pre_ktest;
4272 # Any test can override the POST_KTEST option
4273 # The last test takes precedence.
4274 if (defined($post_ktest)) {
4275 $final_post_ktest = $post_ktest;
4278 if (!defined($start_minconfig)) {
4279 $start_minconfig_defined = 0;
4280 $start_minconfig = $minconfig;
4283 if (!-d $tmpdir) {
4284 mkpath($tmpdir) or
4285 die "can't create $tmpdir";
4288 $ENV{"SSH_USER"} = $ssh_user;
4289 $ENV{"MACHINE"} = $machine;
4291 $buildlog = "$tmpdir/buildlog-$machine";
4292 $testlog = "$tmpdir/testlog-$machine";
4293 $dmesg = "$tmpdir/dmesg-$machine";
4294 $output_config = "$outputdir/.config";
4296 if (!$buildonly) {
4297 $target = "$ssh_user\@$machine";
4298 if ($reboot_type eq "grub") {
4299 dodie "GRUB_MENU not defined" if (!defined($grub_menu));
4300 } elsif ($reboot_type eq "grub2") {
4301 dodie "GRUB_MENU not defined" if (!defined($grub_menu));
4302 dodie "GRUB_FILE not defined" if (!defined($grub_file));
4303 } elsif ($reboot_type eq "syslinux") {
4304 dodie "SYSLINUX_LABEL not defined" if (!defined($syslinux_label));
4308 my $run_type = $build_type;
4309 if ($test_type eq "patchcheck") {
4310 $run_type = $patchcheck_type;
4311 } elsif ($test_type eq "bisect") {
4312 $run_type = $bisect_type;
4313 } elsif ($test_type eq "config_bisect") {
4314 $run_type = $config_bisect_type;
4315 } elsif ($test_type eq "make_min_config") {
4316 $run_type = "";
4317 } elsif ($test_type eq "make_warnings_file") {
4318 $run_type = "";
4321 # mistake in config file?
4322 if (!defined($run_type)) {
4323 $run_type = "ERROR";
4326 my $installme = "";
4327 $installme = " no_install" if ($no_install);
4329 my $name = "";
4331 if (defined($test_name)) {
4332 $name = " ($test_name)";
4335 doprint "\n\n";
4336 doprint "RUNNING TEST $i of $opt{NUM_TESTS}$name with option $test_type $run_type$installme\n\n";
4338 if (defined($pre_test)) {
4339 run_command $pre_test;
4342 unlink $dmesg;
4343 unlink $buildlog;
4344 unlink $testlog;
4346 if (defined($addconfig)) {
4347 my $min = $minconfig;
4348 if (!defined($minconfig)) {
4349 $min = "";
4351 run_command "cat $addconfig $min > $tmpdir/add_config" or
4352 dodie "Failed to create temp config";
4353 $minconfig = "$tmpdir/add_config";
4356 if (defined($checkout)) {
4357 run_command "git checkout $checkout" or
4358 die "failed to checkout $checkout";
4361 $no_reboot = 0;
4363 # A test may opt to not reboot the box
4364 if ($reboot_on_success) {
4365 $reboot_success = 1;
4368 if ($test_type eq "bisect") {
4369 bisect $i;
4370 next;
4371 } elsif ($test_type eq "config_bisect") {
4372 config_bisect $i;
4373 next;
4374 } elsif ($test_type eq "patchcheck") {
4375 patchcheck $i;
4376 next;
4377 } elsif ($test_type eq "make_min_config") {
4378 make_min_config $i;
4379 next;
4380 } elsif ($test_type eq "make_warnings_file") {
4381 $no_reboot = 1;
4382 make_warnings_file $i;
4383 next;
4386 if ($build_type ne "nobuild") {
4387 build $build_type or next;
4388 check_buildlog or next;
4391 if ($test_type eq "install") {
4392 get_version;
4393 install;
4394 success $i;
4395 next;
4398 if ($test_type ne "build") {
4399 my $failed = 0;
4400 start_monitor_and_install or $failed = 1;
4402 if (!$failed && $test_type ne "boot" && defined($run_test)) {
4403 do_run_test or $failed = 1;
4405 end_monitor;
4406 if ($failed) {
4407 print_times;
4408 next;
4412 print_times;
4414 success $i;
4417 if (defined($final_post_ktest)) {
4418 run_command $final_post_ktest;
4421 if ($opt{"POWEROFF_ON_SUCCESS"}) {
4422 halt;
4423 } elsif ($opt{"REBOOT_ON_SUCCESS"} && !do_not_reboot && $reboot_success) {
4424 reboot_to_good;
4425 } elsif (defined($switch_to_good)) {
4426 # still need to get to the good kernel
4427 run_command $switch_to_good;
4431 doprint "\n $successes of $opt{NUM_TESTS} tests were successful\n\n";
4433 exit 0;