ktest: Print build,install,boot,test times at success and failure
[deliverable/linux.git] / tools / testing / ktest / ktest.pl
1 #!/usr/bin/perl -w
2 #
3 # Copyright 2010 - Steven Rostedt <srostedt@redhat.com>, Red Hat Inc.
4 # Licensed under the terms of the GNU GPL License version 2
5 #
6
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;
13
14 my $VERSION = "0.2";
15
16 $| = 1;
17
18 my %opt;
19 my %repeat_tests;
20 my %repeats;
21 my %evals;
22
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",
62
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",
70
71 "LOG_FILE" => undef,
72 "IGNORE_UNUSED" => 0,
73 );
74
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
183 my $bisect_good;
184 my $bisect_bad;
185 my $bisect_type;
186 my $bisect_start;
187 my $bisect_replay;
188 my $bisect_files;
189 my $bisect_reverse;
190 my $bisect_check;
191
192 my $config_bisect;
193 my $config_bisect_type;
194 my $config_bisect_check;
195
196 my $patchcheck_type;
197 my $patchcheck_start;
198 my $patchcheck_cherry;
199 my $patchcheck_end;
200
201 my $build_time;
202 my $install_time;
203 my $reboot_time;
204 my $test_time;
205
206 # set when a test is something other that just building or install
207 # which would require more options.
208 my $buildonly = 1;
209
210 # tell build not to worry about warnings, even when WARNINGS_FILE is set
211 my $warnings_ok = 0;
212
213 # set when creating a new config
214 my $newconfig = 0;
215
216 my %entered_configs;
217 my %config_help;
218 my %variable;
219
220 # force_config is the list of configs that we force enabled (or disabled)
221 # in a .config file. The MIN_CONFIG and ADD_CONFIG configs.
222 my %force_config;
223
224 # do not force reboots on config problems
225 my $no_reboot = 1;
226
227 # reboot on success
228 my $reboot_success = 0;
229
230 my %option_map = (
231 "MACHINE" => \$machine,
232 "SSH_USER" => \$ssh_user,
233 "TMP_DIR" => \$tmpdir,
234 "OUTPUT_DIR" => \$outputdir,
235 "BUILD_DIR" => \$builddir,
236 "TEST_TYPE" => \$test_type,
237 "PRE_KTEST" => \$pre_ktest,
238 "POST_KTEST" => \$post_ktest,
239 "PRE_TEST" => \$pre_test,
240 "POST_TEST" => \$post_test,
241 "BUILD_TYPE" => \$build_type,
242 "BUILD_OPTIONS" => \$build_options,
243 "PRE_BUILD" => \$pre_build,
244 "POST_BUILD" => \$post_build,
245 "PRE_BUILD_DIE" => \$pre_build_die,
246 "POST_BUILD_DIE" => \$post_build_die,
247 "POWER_CYCLE" => \$power_cycle,
248 "REBOOT" => \$reboot,
249 "BUILD_NOCLEAN" => \$noclean,
250 "MIN_CONFIG" => \$minconfig,
251 "OUTPUT_MIN_CONFIG" => \$output_minconfig,
252 "START_MIN_CONFIG" => \$start_minconfig,
253 "MIN_CONFIG_TYPE" => \$minconfig_type,
254 "USE_OUTPUT_MIN_CONFIG" => \$use_output_minconfig,
255 "WARNINGS_FILE" => \$warnings_file,
256 "IGNORE_CONFIG" => \$ignore_config,
257 "TEST" => \$run_test,
258 "ADD_CONFIG" => \$addconfig,
259 "REBOOT_TYPE" => \$reboot_type,
260 "GRUB_MENU" => \$grub_menu,
261 "GRUB_FILE" => \$grub_file,
262 "GRUB_REBOOT" => \$grub_reboot,
263 "SYSLINUX" => \$syslinux,
264 "SYSLINUX_PATH" => \$syslinux_path,
265 "SYSLINUX_LABEL" => \$syslinux_label,
266 "PRE_INSTALL" => \$pre_install,
267 "POST_INSTALL" => \$post_install,
268 "NO_INSTALL" => \$no_install,
269 "REBOOT_SCRIPT" => \$reboot_script,
270 "REBOOT_ON_ERROR" => \$reboot_on_error,
271 "SWITCH_TO_GOOD" => \$switch_to_good,
272 "SWITCH_TO_TEST" => \$switch_to_test,
273 "POWEROFF_ON_ERROR" => \$poweroff_on_error,
274 "REBOOT_ON_SUCCESS" => \$reboot_on_success,
275 "DIE_ON_FAILURE" => \$die_on_failure,
276 "POWER_OFF" => \$power_off,
277 "POWERCYCLE_AFTER_REBOOT" => \$powercycle_after_reboot,
278 "POWEROFF_AFTER_HALT" => \$poweroff_after_halt,
279 "MAX_MONITOR_WAIT" => \$max_monitor_wait,
280 "SLEEP_TIME" => \$sleep_time,
281 "BISECT_SLEEP_TIME" => \$bisect_sleep_time,
282 "PATCHCHECK_SLEEP_TIME" => \$patchcheck_sleep_time,
283 "IGNORE_WARNINGS" => \$ignore_warnings,
284 "IGNORE_ERRORS" => \$ignore_errors,
285 "BISECT_MANUAL" => \$bisect_manual,
286 "BISECT_SKIP" => \$bisect_skip,
287 "BISECT_TRIES" => \$bisect_tries,
288 "CONFIG_BISECT_GOOD" => \$config_bisect_good,
289 "BISECT_RET_GOOD" => \$bisect_ret_good,
290 "BISECT_RET_BAD" => \$bisect_ret_bad,
291 "BISECT_RET_SKIP" => \$bisect_ret_skip,
292 "BISECT_RET_ABORT" => \$bisect_ret_abort,
293 "BISECT_RET_DEFAULT" => \$bisect_ret_default,
294 "STORE_FAILURES" => \$store_failures,
295 "STORE_SUCCESSES" => \$store_successes,
296 "TEST_NAME" => \$test_name,
297 "TIMEOUT" => \$timeout,
298 "BOOTED_TIMEOUT" => \$booted_timeout,
299 "CONSOLE" => \$console,
300 "CLOSE_CONSOLE_SIGNAL" => \$close_console_signal,
301 "DETECT_TRIPLE_FAULT" => \$detect_triplefault,
302 "SUCCESS_LINE" => \$success_line,
303 "REBOOT_SUCCESS_LINE" => \$reboot_success_line,
304 "STOP_AFTER_SUCCESS" => \$stop_after_success,
305 "STOP_AFTER_FAILURE" => \$stop_after_failure,
306 "STOP_TEST_AFTER" => \$stop_test_after,
307 "BUILD_TARGET" => \$build_target,
308 "SSH_EXEC" => \$ssh_exec,
309 "SCP_TO_TARGET" => \$scp_to_target,
310 "SCP_TO_TARGET_INSTALL" => \$scp_to_target_install,
311 "CHECKOUT" => \$checkout,
312 "TARGET_IMAGE" => \$target_image,
313 "LOCALVERSION" => \$localversion,
314
315 "BISECT_GOOD" => \$bisect_good,
316 "BISECT_BAD" => \$bisect_bad,
317 "BISECT_TYPE" => \$bisect_type,
318 "BISECT_START" => \$bisect_start,
319 "BISECT_REPLAY" => \$bisect_replay,
320 "BISECT_FILES" => \$bisect_files,
321 "BISECT_REVERSE" => \$bisect_reverse,
322 "BISECT_CHECK" => \$bisect_check,
323
324 "CONFIG_BISECT" => \$config_bisect,
325 "CONFIG_BISECT_TYPE" => \$config_bisect_type,
326 "CONFIG_BISECT_CHECK" => \$config_bisect_check,
327
328 "PATCHCHECK_TYPE" => \$patchcheck_type,
329 "PATCHCHECK_START" => \$patchcheck_start,
330 "PATCHCHECK_CHERRY" => \$patchcheck_cherry,
331 "PATCHCHECK_END" => \$patchcheck_end,
332 );
333
334 # Options may be used by other options, record them.
335 my %used_options;
336
337 # default variables that can be used
338 chomp ($variable{"PWD"} = `pwd`);
339
340 $config_help{"MACHINE"} = << "EOF"
341 The machine hostname that you will test.
342 For build only tests, it is still needed to differentiate log files.
343 EOF
344 ;
345 $config_help{"SSH_USER"} = << "EOF"
346 The box is expected to have ssh on normal bootup, provide the user
347 (most likely root, since you need privileged operations)
348 EOF
349 ;
350 $config_help{"BUILD_DIR"} = << "EOF"
351 The directory that contains the Linux source code (full path).
352 You can use \${PWD} that will be the path where ktest.pl is run, or use
353 \${THIS_DIR} which is assigned \${PWD} but may be changed later.
354 EOF
355 ;
356 $config_help{"OUTPUT_DIR"} = << "EOF"
357 The directory that the objects will be built (full path).
358 (can not be same as BUILD_DIR)
359 You can use \${PWD} that will be the path where ktest.pl is run, or use
360 \${THIS_DIR} which is assigned \${PWD} but may be changed later.
361 EOF
362 ;
363 $config_help{"BUILD_TARGET"} = << "EOF"
364 The location of the compiled file to copy to the target.
365 (relative to OUTPUT_DIR)
366 EOF
367 ;
368 $config_help{"BUILD_OPTIONS"} = << "EOF"
369 Options to add to \"make\" when building.
370 i.e. -j20
371 EOF
372 ;
373 $config_help{"TARGET_IMAGE"} = << "EOF"
374 The place to put your image on the test machine.
375 EOF
376 ;
377 $config_help{"POWER_CYCLE"} = << "EOF"
378 A script or command to reboot the box.
379
380 Here is a digital loggers power switch example
381 POWER_CYCLE = wget --no-proxy -O /dev/null -q --auth-no-challenge 'http://admin:admin\@power/outlet?5=CCL'
382
383 Here is an example to reboot a virtual box on the current host
384 with the name "Guest".
385 POWER_CYCLE = virsh destroy Guest; sleep 5; virsh start Guest
386 EOF
387 ;
388 $config_help{"CONSOLE"} = << "EOF"
389 The script or command that reads the console
390
391 If you use ttywatch server, something like the following would work.
392 CONSOLE = nc -d localhost 3001
393
394 For a virtual machine with guest name "Guest".
395 CONSOLE = virsh console Guest
396 EOF
397 ;
398 $config_help{"LOCALVERSION"} = << "EOF"
399 Required version ending to differentiate the test
400 from other linux builds on the system.
401 EOF
402 ;
403 $config_help{"REBOOT_TYPE"} = << "EOF"
404 Way to reboot the box to the test kernel.
405 Only valid options so far are "grub", "grub2", "syslinux", and "script".
406
407 If you specify grub, it will assume grub version 1
408 and will search in /boot/grub/menu.lst for the title \$GRUB_MENU
409 and select that target to reboot to the kernel. If this is not
410 your setup, then specify "script" and have a command or script
411 specified in REBOOT_SCRIPT to boot to the target.
412
413 The entry in /boot/grub/menu.lst must be entered in manually.
414 The test will not modify that file.
415
416 If you specify grub2, then you also need to specify both \$GRUB_MENU
417 and \$GRUB_FILE.
418
419 If you specify syslinux, then you may use SYSLINUX to define the syslinux
420 command (defaults to extlinux), and SYSLINUX_PATH to specify the path to
421 the syslinux install (defaults to /boot/extlinux). But you have to specify
422 SYSLINUX_LABEL to define the label to boot to for the test kernel.
423 EOF
424 ;
425 $config_help{"GRUB_MENU"} = << "EOF"
426 The grub title name for the test kernel to boot
427 (Only mandatory if REBOOT_TYPE = grub or grub2)
428
429 Note, ktest.pl will not update the grub menu.lst, you need to
430 manually add an option for the test. ktest.pl will search
431 the grub menu.lst for this option to find what kernel to
432 reboot into.
433
434 For example, if in the /boot/grub/menu.lst the test kernel title has:
435 title Test Kernel
436 kernel vmlinuz-test
437 GRUB_MENU = Test Kernel
438
439 For grub2, a search of \$GRUB_FILE is performed for the lines
440 that begin with "menuentry". It will not detect submenus. The
441 menu must be a non-nested menu. Add the quotes used in the menu
442 to guarantee your selection, as the first menuentry with the content
443 of \$GRUB_MENU that is found will be used.
444 EOF
445 ;
446 $config_help{"GRUB_FILE"} = << "EOF"
447 If grub2 is used, the full path for the grub.cfg file is placed
448 here. Use something like /boot/grub2/grub.cfg to search.
449 EOF
450 ;
451 $config_help{"SYSLINUX_LABEL"} = << "EOF"
452 If syslinux is used, the label that boots the target kernel must
453 be specified with SYSLINUX_LABEL.
454 EOF
455 ;
456 $config_help{"REBOOT_SCRIPT"} = << "EOF"
457 A script to reboot the target into the test kernel
458 (Only mandatory if REBOOT_TYPE = script)
459 EOF
460 ;
461
462 sub _logit {
463 if (defined($opt{"LOG_FILE"})) {
464 open(OUT, ">> $opt{LOG_FILE}") or die "Can't write to $opt{LOG_FILE}";
465 print OUT @_;
466 close(OUT);
467 }
468 }
469
470 sub logit {
471 if (defined($opt{"LOG_FILE"})) {
472 _logit @_;
473 } else {
474 print @_;
475 }
476 }
477
478 sub doprint {
479 print @_;
480 _logit @_;
481 }
482
483 sub read_prompt {
484 my ($cancel, $prompt) = @_;
485
486 my $ans;
487
488 for (;;) {
489 if ($cancel) {
490 print "$prompt [y/n/C] ";
491 } else {
492 print "$prompt [Y/n] ";
493 }
494 $ans = <STDIN>;
495 chomp $ans;
496 if ($ans =~ /^\s*$/) {
497 if ($cancel) {
498 $ans = "c";
499 } else {
500 $ans = "y";
501 }
502 }
503 last if ($ans =~ /^y$/i || $ans =~ /^n$/i);
504 if ($cancel) {
505 last if ($ans =~ /^c$/i);
506 print "Please answer either 'y', 'n' or 'c'.\n";
507 } else {
508 print "Please answer either 'y' or 'n'.\n";
509 }
510 }
511 if ($ans =~ /^c/i) {
512 exit;
513 }
514 if ($ans !~ /^y$/i) {
515 return 0;
516 }
517 return 1;
518 }
519
520 sub read_yn {
521 my ($prompt) = @_;
522
523 return read_prompt 0, $prompt;
524 }
525
526 sub read_ync {
527 my ($prompt) = @_;
528
529 return read_prompt 1, $prompt;
530 }
531
532 sub get_mandatory_config {
533 my ($config) = @_;
534 my $ans;
535
536 return if (defined($opt{$config}));
537
538 if (defined($config_help{$config})) {
539 print "\n";
540 print $config_help{$config};
541 }
542
543 for (;;) {
544 print "$config = ";
545 if (defined($default{$config}) && length($default{$config})) {
546 print "\[$default{$config}\] ";
547 }
548 $ans = <STDIN>;
549 $ans =~ s/^\s*(.*\S)\s*$/$1/;
550 if ($ans =~ /^\s*$/) {
551 if ($default{$config}) {
552 $ans = $default{$config};
553 } else {
554 print "Your answer can not be blank\n";
555 next;
556 }
557 }
558 $entered_configs{$config} = ${ans};
559 last;
560 }
561 }
562
563 sub show_time {
564 my ($time) = @_;
565
566 my $hours = 0;
567 my $minutes = 0;
568
569 if ($time > 3600) {
570 $hours = int($time / 3600);
571 $time -= $hours * 3600;
572 }
573 if ($time > 60) {
574 $minutes = int($time / 60);
575 $time -= $minutes * 60;
576 }
577
578 if ($hours > 0) {
579 doprint "$hours hour";
580 doprint "s" if ($hours > 1);
581 doprint " ";
582 }
583
584 if ($minutes > 0) {
585 doprint "$minutes minute";
586 doprint "s" if ($minutes > 1);
587 doprint " ";
588 }
589
590 doprint "$time second";
591 doprint "s" if ($time != 1);
592 }
593
594 sub print_times {
595 doprint "\n";
596 if ($build_time) {
597 doprint "Build time: ";
598 show_time($build_time);
599 doprint "\n";
600 }
601 if ($install_time) {
602 doprint "Install time: ";
603 show_time($install_time);
604 doprint "\n";
605 }
606 if ($reboot_time) {
607 doprint "Reboot time: ";
608 show_time($reboot_time);
609 doprint "\n";
610 }
611 if ($test_time) {
612 doprint "Test time: ";
613 show_time($test_time);
614 doprint "\n";
615 }
616 # reset for iterations like bisect
617 $build_time = 0;
618 $install_time = 0;
619 $reboot_time = 0;
620 $test_time = 0;
621 }
622
623 sub get_mandatory_configs {
624 get_mandatory_config("MACHINE");
625 get_mandatory_config("BUILD_DIR");
626 get_mandatory_config("OUTPUT_DIR");
627
628 if ($newconfig) {
629 get_mandatory_config("BUILD_OPTIONS");
630 }
631
632 # options required for other than just building a kernel
633 if (!$buildonly) {
634 get_mandatory_config("POWER_CYCLE");
635 get_mandatory_config("CONSOLE");
636 }
637
638 # options required for install and more
639 if ($buildonly != 1) {
640 get_mandatory_config("SSH_USER");
641 get_mandatory_config("BUILD_TARGET");
642 get_mandatory_config("TARGET_IMAGE");
643 }
644
645 get_mandatory_config("LOCALVERSION");
646
647 return if ($buildonly);
648
649 my $rtype = $opt{"REBOOT_TYPE"};
650
651 if (!defined($rtype)) {
652 if (!defined($opt{"GRUB_MENU"})) {
653 get_mandatory_config("REBOOT_TYPE");
654 $rtype = $entered_configs{"REBOOT_TYPE"};
655 } else {
656 $rtype = "grub";
657 }
658 }
659
660 if ($rtype eq "grub") {
661 get_mandatory_config("GRUB_MENU");
662 }
663
664 if ($rtype eq "grub2") {
665 get_mandatory_config("GRUB_MENU");
666 get_mandatory_config("GRUB_FILE");
667 }
668
669 if ($rtype eq "syslinux") {
670 get_mandatory_config("SYSLINUX_LABEL");
671 }
672 }
673
674 sub process_variables {
675 my ($value, $remove_undef) = @_;
676 my $retval = "";
677
678 # We want to check for '\', and it is just easier
679 # to check the previous characet of '$' and not need
680 # to worry if '$' is the first character. By adding
681 # a space to $value, we can just check [^\\]\$ and
682 # it will still work.
683 $value = " $value";
684
685 while ($value =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) {
686 my $begin = $1;
687 my $var = $2;
688 my $end = $3;
689 # append beginning of value to retval
690 $retval = "$retval$begin";
691 if (defined($variable{$var})) {
692 $retval = "$retval$variable{$var}";
693 } elsif (defined($remove_undef) && $remove_undef) {
694 # for if statements, any variable that is not defined,
695 # we simple convert to 0
696 $retval = "${retval}0";
697 } else {
698 # put back the origin piece.
699 $retval = "$retval\$\{$var\}";
700 # This could be an option that is used later, save
701 # it so we don't warn if this option is not one of
702 # ktests options.
703 $used_options{$var} = 1;
704 }
705 $value = $end;
706 }
707 $retval = "$retval$value";
708
709 # remove the space added in the beginning
710 $retval =~ s/ //;
711
712 return "$retval"
713 }
714
715 sub set_value {
716 my ($lvalue, $rvalue, $override, $overrides, $name) = @_;
717
718 my $prvalue = process_variables($rvalue);
719
720 if ($buildonly && $lvalue =~ /^TEST_TYPE(\[.*\])?$/ && $prvalue ne "build") {
721 # Note if a test is something other than build, then we
722 # will need other manditory options.
723 if ($prvalue ne "install") {
724 # for bisect, we need to check BISECT_TYPE
725 if ($prvalue ne "bisect") {
726 $buildonly = 0;
727 }
728 } else {
729 # install still limits some manditory options.
730 $buildonly = 2;
731 }
732 }
733
734 if ($buildonly && $lvalue =~ /^BISECT_TYPE(\[.*\])?$/ && $prvalue ne "build") {
735 if ($prvalue ne "install") {
736 $buildonly = 0;
737 } else {
738 # install still limits some manditory options.
739 $buildonly = 2;
740 }
741 }
742
743 if (defined($opt{$lvalue})) {
744 if (!$override || defined(${$overrides}{$lvalue})) {
745 my $extra = "";
746 if ($override) {
747 $extra = "In the same override section!\n";
748 }
749 die "$name: $.: Option $lvalue defined more than once!\n$extra";
750 }
751 ${$overrides}{$lvalue} = $prvalue;
752 }
753
754 $opt{$lvalue} = $prvalue;
755 }
756
757 sub set_eval {
758 my ($lvalue, $rvalue, $name) = @_;
759
760 my $prvalue = process_variables($rvalue);
761 my $arr;
762
763 if (defined($evals{$lvalue})) {
764 $arr = $evals{$lvalue};
765 } else {
766 $arr = [];
767 $evals{$lvalue} = $arr;
768 }
769
770 push @{$arr}, $rvalue;
771 }
772
773 sub set_variable {
774 my ($lvalue, $rvalue) = @_;
775
776 if ($rvalue =~ /^\s*$/) {
777 delete $variable{$lvalue};
778 } else {
779 $rvalue = process_variables($rvalue);
780 $variable{$lvalue} = $rvalue;
781 }
782 }
783
784 sub process_compare {
785 my ($lval, $cmp, $rval) = @_;
786
787 # remove whitespace
788
789 $lval =~ s/^\s*//;
790 $lval =~ s/\s*$//;
791
792 $rval =~ s/^\s*//;
793 $rval =~ s/\s*$//;
794
795 if ($cmp eq "==") {
796 return $lval eq $rval;
797 } elsif ($cmp eq "!=") {
798 return $lval ne $rval;
799 } elsif ($cmp eq "=~") {
800 return $lval =~ m/$rval/;
801 } elsif ($cmp eq "!~") {
802 return $lval !~ m/$rval/;
803 }
804
805 my $statement = "$lval $cmp $rval";
806 my $ret = eval $statement;
807
808 # $@ stores error of eval
809 if ($@) {
810 return -1;
811 }
812
813 return $ret;
814 }
815
816 sub value_defined {
817 my ($val) = @_;
818
819 return defined($variable{$2}) ||
820 defined($opt{$2});
821 }
822
823 my $d = 0;
824 sub process_expression {
825 my ($name, $val) = @_;
826
827 my $c = $d++;
828
829 while ($val =~ s/\(([^\(]*?)\)/\&\&\&\&VAL\&\&\&\&/) {
830 my $express = $1;
831
832 if (process_expression($name, $express)) {
833 $val =~ s/\&\&\&\&VAL\&\&\&\&/ 1 /;
834 } else {
835 $val =~ s/\&\&\&\&VAL\&\&\&\&/ 0 /;
836 }
837 }
838
839 $d--;
840 my $OR = "\\|\\|";
841 my $AND = "\\&\\&";
842
843 while ($val =~ s/^(.*?)($OR|$AND)//) {
844 my $express = $1;
845 my $op = $2;
846
847 if (process_expression($name, $express)) {
848 if ($op eq "||") {
849 return 1;
850 }
851 } else {
852 if ($op eq "&&") {
853 return 0;
854 }
855 }
856 }
857
858 if ($val =~ /(.*)(==|\!=|>=|<=|>|<|=~|\!~)(.*)/) {
859 my $ret = process_compare($1, $2, $3);
860 if ($ret < 0) {
861 die "$name: $.: Unable to process comparison\n";
862 }
863 return $ret;
864 }
865
866 if ($val =~ /^\s*(NOT\s*)?DEFINED\s+(\S+)\s*$/) {
867 if (defined $1) {
868 return !value_defined($2);
869 } else {
870 return value_defined($2);
871 }
872 }
873
874 if ($val =~ /^\s*0\s*$/) {
875 return 0;
876 } elsif ($val =~ /^\s*\d+\s*$/) {
877 return 1;
878 }
879
880 die ("$name: $.: Undefined content $val in if statement\n");
881 }
882
883 sub process_if {
884 my ($name, $value) = @_;
885
886 # Convert variables and replace undefined ones with 0
887 my $val = process_variables($value, 1);
888 my $ret = process_expression $name, $val;
889
890 return $ret;
891 }
892
893 sub __read_config {
894 my ($config, $current_test_num) = @_;
895
896 my $in;
897 open($in, $config) || die "can't read file $config";
898
899 my $name = $config;
900 $name =~ s,.*/(.*),$1,;
901
902 my $test_num = $$current_test_num;
903 my $default = 1;
904 my $repeat = 1;
905 my $num_tests_set = 0;
906 my $skip = 0;
907 my $rest;
908 my $line;
909 my $test_case = 0;
910 my $if = 0;
911 my $if_set = 0;
912 my $override = 0;
913
914 my %overrides;
915
916 while (<$in>) {
917
918 # ignore blank lines and comments
919 next if (/^\s*$/ || /\s*\#/);
920
921 if (/^\s*(TEST_START|DEFAULTS)\b(.*)/) {
922
923 my $type = $1;
924 $rest = $2;
925 $line = $2;
926
927 my $old_test_num;
928 my $old_repeat;
929 $override = 0;
930
931 if ($type eq "TEST_START") {
932
933 if ($num_tests_set) {
934 die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
935 }
936
937 $old_test_num = $test_num;
938 $old_repeat = $repeat;
939
940 $test_num += $repeat;
941 $default = 0;
942 $repeat = 1;
943 } else {
944 $default = 1;
945 }
946
947 # If SKIP is anywhere in the line, the command will be skipped
948 if ($rest =~ s/\s+SKIP\b//) {
949 $skip = 1;
950 } else {
951 $test_case = 1;
952 $skip = 0;
953 }
954
955 if ($rest =~ s/\sELSE\b//) {
956 if (!$if) {
957 die "$name: $.: ELSE found with out matching IF section\n$_";
958 }
959 $if = 0;
960
961 if ($if_set) {
962 $skip = 1;
963 } else {
964 $skip = 0;
965 }
966 }
967
968 if ($rest =~ s/\sIF\s+(.*)//) {
969 if (process_if($name, $1)) {
970 $if_set = 1;
971 } else {
972 $skip = 1;
973 }
974 $if = 1;
975 } else {
976 $if = 0;
977 $if_set = 0;
978 }
979
980 if (!$skip) {
981 if ($type eq "TEST_START") {
982 if ($rest =~ s/\s+ITERATE\s+(\d+)//) {
983 $repeat = $1;
984 $repeat_tests{"$test_num"} = $repeat;
985 }
986 } elsif ($rest =~ s/\sOVERRIDE\b//) {
987 # DEFAULT only
988 $override = 1;
989 # Clear previous overrides
990 %overrides = ();
991 }
992 }
993
994 if (!$skip && $rest !~ /^\s*$/) {
995 die "$name: $.: Gargbage found after $type\n$_";
996 }
997
998 if ($skip && $type eq "TEST_START") {
999 $test_num = $old_test_num;
1000 $repeat = $old_repeat;
1001 }
1002
1003 } elsif (/^\s*ELSE\b(.*)$/) {
1004 if (!$if) {
1005 die "$name: $.: ELSE found with out matching IF section\n$_";
1006 }
1007 $rest = $1;
1008 if ($if_set) {
1009 $skip = 1;
1010 $rest = "";
1011 } else {
1012 $skip = 0;
1013
1014 if ($rest =~ /\sIF\s+(.*)/) {
1015 # May be a ELSE IF section.
1016 if (process_if($name, $1)) {
1017 $if_set = 1;
1018 } else {
1019 $skip = 1;
1020 }
1021 $rest = "";
1022 } else {
1023 $if = 0;
1024 }
1025 }
1026
1027 if ($rest !~ /^\s*$/) {
1028 die "$name: $.: Gargbage found after DEFAULTS\n$_";
1029 }
1030
1031 } elsif (/^\s*INCLUDE\s+(\S+)/) {
1032
1033 next if ($skip);
1034
1035 if (!$default) {
1036 die "$name: $.: INCLUDE can only be done in default sections\n$_";
1037 }
1038
1039 my $file = process_variables($1);
1040
1041 if ($file !~ m,^/,) {
1042 # check the path of the config file first
1043 if ($config =~ m,(.*)/,) {
1044 if (-f "$1/$file") {
1045 $file = "$1/$file";
1046 }
1047 }
1048 }
1049
1050 if ( ! -r $file ) {
1051 die "$name: $.: Can't read file $file\n$_";
1052 }
1053
1054 if (__read_config($file, \$test_num)) {
1055 $test_case = 1;
1056 }
1057
1058 } elsif (/^\s*([A-Z_\[\]\d]+)\s*=~\s*(.*?)\s*$/) {
1059
1060 next if ($skip);
1061
1062 my $lvalue = $1;
1063 my $rvalue = $2;
1064
1065 if ($default || $lvalue =~ /\[\d+\]$/) {
1066 set_eval($lvalue, $rvalue, $name);
1067 } else {
1068 my $val = "$lvalue\[$test_num\]";
1069 set_eval($val, $rvalue, $name);
1070 }
1071
1072 } elsif (/^\s*([A-Z_\[\]\d]+)\s*=\s*(.*?)\s*$/) {
1073
1074 next if ($skip);
1075
1076 my $lvalue = $1;
1077 my $rvalue = $2;
1078
1079 if (!$default &&
1080 ($lvalue eq "NUM_TESTS" ||
1081 $lvalue eq "LOG_FILE" ||
1082 $lvalue eq "CLEAR_LOG")) {
1083 die "$name: $.: $lvalue must be set in DEFAULTS section\n";
1084 }
1085
1086 if ($lvalue eq "NUM_TESTS") {
1087 if ($test_num) {
1088 die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
1089 }
1090 if (!$default) {
1091 die "$name: $.: NUM_TESTS must be set in default section\n";
1092 }
1093 $num_tests_set = 1;
1094 }
1095
1096 if ($default || $lvalue =~ /\[\d+\]$/) {
1097 set_value($lvalue, $rvalue, $override, \%overrides, $name);
1098 } else {
1099 my $val = "$lvalue\[$test_num\]";
1100 set_value($val, $rvalue, $override, \%overrides, $name);
1101
1102 if ($repeat > 1) {
1103 $repeats{$val} = $repeat;
1104 }
1105 }
1106 } elsif (/^\s*([A-Z_\[\]\d]+)\s*:=\s*(.*?)\s*$/) {
1107 next if ($skip);
1108
1109 my $lvalue = $1;
1110 my $rvalue = $2;
1111
1112 # process config variables.
1113 # Config variables are only active while reading the
1114 # config and can be defined anywhere. They also ignore
1115 # TEST_START and DEFAULTS, but are skipped if they are in
1116 # on of these sections that have SKIP defined.
1117 # The save variable can be
1118 # defined multiple times and the new one simply overrides
1119 # the prevous one.
1120 set_variable($lvalue, $rvalue);
1121
1122 } else {
1123 die "$name: $.: Garbage found in config\n$_";
1124 }
1125 }
1126
1127 if ($test_num) {
1128 $test_num += $repeat - 1;
1129 $opt{"NUM_TESTS"} = $test_num;
1130 }
1131
1132 close($in);
1133
1134 $$current_test_num = $test_num;
1135
1136 return $test_case;
1137 }
1138
1139 sub get_test_case {
1140 print "What test case would you like to run?\n";
1141 print " (build, install or boot)\n";
1142 print " Other tests are available but require editing the config file\n";
1143 my $ans = <STDIN>;
1144 chomp $ans;
1145 $default{"TEST_TYPE"} = $ans;
1146 }
1147
1148 sub read_config {
1149 my ($config) = @_;
1150
1151 my $test_case;
1152 my $test_num = 0;
1153
1154 $test_case = __read_config $config, \$test_num;
1155
1156 # make sure we have all mandatory configs
1157 get_mandatory_configs;
1158
1159 # was a test specified?
1160 if (!$test_case) {
1161 print "No test case specified.\n";
1162 get_test_case;
1163 }
1164
1165 # set any defaults
1166
1167 foreach my $default (keys %default) {
1168 if (!defined($opt{$default})) {
1169 $opt{$default} = $default{$default};
1170 }
1171 }
1172
1173 if ($opt{"IGNORE_UNUSED"} == 1) {
1174 return;
1175 }
1176
1177 my %not_used;
1178
1179 # check if there are any stragglers (typos?)
1180 foreach my $option (keys %opt) {
1181 my $op = $option;
1182 # remove per test labels.
1183 $op =~ s/\[.*\]//;
1184 if (!exists($option_map{$op}) &&
1185 !exists($default{$op}) &&
1186 !exists($used_options{$op})) {
1187 $not_used{$op} = 1;
1188 }
1189 }
1190
1191 if (%not_used) {
1192 my $s = "s are";
1193 $s = " is" if (keys %not_used == 1);
1194 print "The following option$s not used; could be a typo:\n";
1195 foreach my $option (keys %not_used) {
1196 print "$option\n";
1197 }
1198 print "Set IGRNORE_UNUSED = 1 to have ktest ignore unused variables\n";
1199 if (!read_yn "Do you want to continue?") {
1200 exit -1;
1201 }
1202 }
1203 }
1204
1205 sub __eval_option {
1206 my ($name, $option, $i) = @_;
1207
1208 # Add space to evaluate the character before $
1209 $option = " $option";
1210 my $retval = "";
1211 my $repeated = 0;
1212 my $parent = 0;
1213
1214 foreach my $test (keys %repeat_tests) {
1215 if ($i >= $test &&
1216 $i < $test + $repeat_tests{$test}) {
1217
1218 $repeated = 1;
1219 $parent = $test;
1220 last;
1221 }
1222 }
1223
1224 while ($option =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) {
1225 my $start = $1;
1226 my $var = $2;
1227 my $end = $3;
1228
1229 # Append beginning of line
1230 $retval = "$retval$start";
1231
1232 # If the iteration option OPT[$i] exists, then use that.
1233 # otherwise see if the default OPT (without [$i]) exists.
1234
1235 my $o = "$var\[$i\]";
1236 my $parento = "$var\[$parent\]";
1237
1238 # If a variable contains itself, use the default var
1239 if (($var eq $name) && defined($opt{$var})) {
1240 $o = $opt{$var};
1241 $retval = "$retval$o";
1242 } elsif (defined($opt{$o})) {
1243 $o = $opt{$o};
1244 $retval = "$retval$o";
1245 } elsif ($repeated && defined($opt{$parento})) {
1246 $o = $opt{$parento};
1247 $retval = "$retval$o";
1248 } elsif (defined($opt{$var})) {
1249 $o = $opt{$var};
1250 $retval = "$retval$o";
1251 } elsif ($var eq "KERNEL_VERSION" && defined($make)) {
1252 # special option KERNEL_VERSION uses kernel version
1253 get_version();
1254 $retval = "$retval$version";
1255 } else {
1256 $retval = "$retval\$\{$var\}";
1257 }
1258
1259 $option = $end;
1260 }
1261
1262 $retval = "$retval$option";
1263
1264 $retval =~ s/^ //;
1265
1266 return $retval;
1267 }
1268
1269 sub process_evals {
1270 my ($name, $option, $i) = @_;
1271
1272 my $option_name = "$name\[$i\]";
1273 my $ev;
1274
1275 my $old_option = $option;
1276
1277 if (defined($evals{$option_name})) {
1278 $ev = $evals{$option_name};
1279 } elsif (defined($evals{$name})) {
1280 $ev = $evals{$name};
1281 } else {
1282 return $option;
1283 }
1284
1285 for my $e (@{$ev}) {
1286 eval "\$option =~ $e";
1287 }
1288
1289 if ($option ne $old_option) {
1290 doprint("$name changed from '$old_option' to '$option'\n");
1291 }
1292
1293 return $option;
1294 }
1295
1296 sub eval_option {
1297 my ($name, $option, $i) = @_;
1298
1299 my $prev = "";
1300
1301 # Since an option can evaluate to another option,
1302 # keep iterating until we do not evaluate any more
1303 # options.
1304 my $r = 0;
1305 while ($prev ne $option) {
1306 # Check for recursive evaluations.
1307 # 100 deep should be more than enough.
1308 if ($r++ > 100) {
1309 die "Over 100 evaluations accurred with $option\n" .
1310 "Check for recursive variables\n";
1311 }
1312 $prev = $option;
1313 $option = __eval_option($name, $option, $i);
1314 }
1315
1316 $option = process_evals($name, $option, $i);
1317
1318 return $option;
1319 }
1320
1321 sub run_command;
1322 sub start_monitor;
1323 sub end_monitor;
1324 sub wait_for_monitor;
1325
1326 sub reboot {
1327 my ($time) = @_;
1328
1329 # Make sure everything has been written to disk
1330 run_ssh("sync");
1331
1332 if (defined($time)) {
1333 start_monitor;
1334 # flush out current monitor
1335 # May contain the reboot success line
1336 wait_for_monitor 1;
1337 }
1338
1339 # try to reboot normally
1340 if (run_command $reboot) {
1341 if (defined($powercycle_after_reboot)) {
1342 sleep $powercycle_after_reboot;
1343 run_command "$power_cycle";
1344 }
1345 } else {
1346 # nope? power cycle it.
1347 run_command "$power_cycle";
1348 }
1349
1350 if (defined($time)) {
1351
1352 # We only want to get to the new kernel, don't fail
1353 # if we stumble over a call trace.
1354 my $save_ignore_errors = $ignore_errors;
1355 $ignore_errors = 1;
1356
1357 # Look for the good kernel to boot
1358 if (wait_for_monitor($time, "Linux version")) {
1359 # reboot got stuck?
1360 doprint "Reboot did not finish. Forcing power cycle\n";
1361 run_command "$power_cycle";
1362 }
1363
1364 $ignore_errors = $save_ignore_errors;
1365
1366 # Still need to wait for the reboot to finish
1367 wait_for_monitor($time, $reboot_success_line);
1368
1369 end_monitor;
1370 }
1371 }
1372
1373 sub reboot_to_good {
1374 my ($time) = @_;
1375
1376 if (defined($switch_to_good)) {
1377 run_command $switch_to_good;
1378 }
1379
1380 reboot $time;
1381 }
1382
1383 sub do_not_reboot {
1384 my $i = $iteration;
1385
1386 return $test_type eq "build" || $no_reboot ||
1387 ($test_type eq "patchcheck" && $opt{"PATCHCHECK_TYPE[$i]"} eq "build") ||
1388 ($test_type eq "bisect" && $opt{"BISECT_TYPE[$i]"} eq "build");
1389 }
1390
1391 sub dodie {
1392 doprint "CRITICAL FAILURE... ", @_, "\n";
1393
1394 my $i = $iteration;
1395
1396 if ($reboot_on_error && !do_not_reboot) {
1397
1398 doprint "REBOOTING\n";
1399 reboot_to_good;
1400
1401 } elsif ($poweroff_on_error && defined($power_off)) {
1402 doprint "POWERING OFF\n";
1403 `$power_off`;
1404 }
1405
1406 if (defined($opt{"LOG_FILE"})) {
1407 print " See $opt{LOG_FILE} for more info.\n";
1408 }
1409
1410 die @_, "\n";
1411 }
1412
1413 sub create_pty {
1414 my ($ptm, $pts) = @_;
1415 my $tmp;
1416 my $TIOCSPTLCK = 0x40045431;
1417 my $TIOCGPTN = 0x80045430;
1418
1419 sysopen($ptm, "/dev/ptmx", O_RDWR | O_NONBLOCK) or
1420 dodie "Cant open /dev/ptmx";
1421
1422 # unlockpt()
1423 $tmp = pack("i", 0);
1424 ioctl($ptm, $TIOCSPTLCK, $tmp) or
1425 dodie "ioctl TIOCSPTLCK for /dev/ptmx failed";
1426
1427 # ptsname()
1428 ioctl($ptm, $TIOCGPTN, $tmp) or
1429 dodie "ioctl TIOCGPTN for /dev/ptmx failed";
1430 $tmp = unpack("i", $tmp);
1431
1432 sysopen($pts, "/dev/pts/$tmp", O_RDWR | O_NONBLOCK) or
1433 dodie "Can't open /dev/pts/$tmp";
1434 }
1435
1436 sub exec_console {
1437 my ($ptm, $pts) = @_;
1438
1439 close($ptm);
1440
1441 close(\*STDIN);
1442 close(\*STDOUT);
1443 close(\*STDERR);
1444
1445 open(\*STDIN, '<&', $pts);
1446 open(\*STDOUT, '>&', $pts);
1447 open(\*STDERR, '>&', $pts);
1448
1449 close($pts);
1450
1451 exec $console or
1452 dodie "Can't open console $console";
1453 }
1454
1455 sub open_console {
1456 my ($ptm) = @_;
1457 my $pts = \*PTSFD;
1458 my $pid;
1459
1460 # save terminal settings
1461 $stty_orig = `stty -g`;
1462
1463 # place terminal in cbreak mode so that stdin can be read one character at
1464 # a time without having to wait for a newline
1465 system("stty -icanon -echo -icrnl");
1466
1467 create_pty($ptm, $pts);
1468
1469 $pid = fork;
1470
1471 if (!$pid) {
1472 # child
1473 exec_console($ptm, $pts)
1474 }
1475
1476 # parent
1477 close($pts);
1478
1479 return $pid;
1480
1481 open(PTSFD, "Stop perl from warning about single use of PTSFD");
1482 }
1483
1484 sub close_console {
1485 my ($fp, $pid) = @_;
1486
1487 doprint "kill child process $pid\n";
1488 kill $close_console_signal, $pid;
1489
1490 print "closing!\n";
1491 close($fp);
1492
1493 # restore terminal settings
1494 system("stty $stty_orig");
1495 }
1496
1497 sub start_monitor {
1498 if ($monitor_cnt++) {
1499 return;
1500 }
1501 $monitor_fp = \*MONFD;
1502 $monitor_pid = open_console $monitor_fp;
1503
1504 return;
1505
1506 open(MONFD, "Stop perl from warning about single use of MONFD");
1507 }
1508
1509 sub end_monitor {
1510 return if (!defined $console);
1511 if (--$monitor_cnt) {
1512 return;
1513 }
1514 close_console($monitor_fp, $monitor_pid);
1515 }
1516
1517 sub wait_for_monitor {
1518 my ($time, $stop) = @_;
1519 my $full_line = "";
1520 my $line;
1521 my $booted = 0;
1522 my $start_time = time;
1523 my $skip_call_trace = 0;
1524 my $bug = 0;
1525 my $bug_ignored = 0;
1526 my $now;
1527
1528 doprint "** Wait for monitor to settle down **\n";
1529
1530 # read the monitor and wait for the system to calm down
1531 while (!$booted) {
1532 $line = wait_for_input($monitor_fp, $time);
1533 last if (!defined($line));
1534 print "$line";
1535 $full_line .= $line;
1536
1537 if (defined($stop) && $full_line =~ /$stop/) {
1538 doprint "wait for monitor detected $stop\n";
1539 $booted = 1;
1540 }
1541
1542 if ($full_line =~ /\[ backtrace testing \]/) {
1543 $skip_call_trace = 1;
1544 }
1545
1546 if ($full_line =~ /call trace:/i) {
1547 if (!$bug && !$skip_call_trace) {
1548 if ($ignore_errors) {
1549 $bug_ignored = 1;
1550 } else {
1551 $bug = 1;
1552 }
1553 }
1554 }
1555
1556 if ($full_line =~ /\[ end of backtrace testing \]/) {
1557 $skip_call_trace = 0;
1558 }
1559
1560 if ($full_line =~ /Kernel panic -/) {
1561 $bug = 1;
1562 }
1563
1564 if ($line =~ /\n/) {
1565 $full_line = "";
1566 }
1567 $now = time;
1568 if ($now - $start_time >= $max_monitor_wait) {
1569 doprint "Exiting monitor flush due to hitting MAX_MONITOR_WAIT\n";
1570 return 1;
1571 }
1572 }
1573 print "** Monitor flushed **\n";
1574
1575 # if stop is defined but wasn't hit, return error
1576 # used by reboot (which wants to see a reboot)
1577 if (defined($stop) && !$booted) {
1578 $bug = 1;
1579 }
1580 return $bug;
1581 }
1582
1583 sub save_logs {
1584 my ($result, $basedir) = @_;
1585 my @t = localtime;
1586 my $date = sprintf "%04d%02d%02d%02d%02d%02d",
1587 1900+$t[5],$t[4],$t[3],$t[2],$t[1],$t[0];
1588
1589 my $type = $build_type;
1590 if ($type =~ /useconfig/) {
1591 $type = "useconfig";
1592 }
1593
1594 my $dir = "$machine-$test_type-$type-$result-$date";
1595
1596 $dir = "$basedir/$dir";
1597
1598 if (!-d $dir) {
1599 mkpath($dir) or
1600 die "can't create $dir";
1601 }
1602
1603 my %files = (
1604 "config" => $output_config,
1605 "buildlog" => $buildlog,
1606 "dmesg" => $dmesg,
1607 "testlog" => $testlog,
1608 );
1609
1610 while (my ($name, $source) = each(%files)) {
1611 if (-f "$source") {
1612 cp "$source", "$dir/$name" or
1613 die "failed to copy $source";
1614 }
1615 }
1616
1617 doprint "*** Saved info to $dir ***\n";
1618 }
1619
1620 sub fail {
1621
1622 if (defined($post_test)) {
1623 run_command $post_test;
1624 }
1625
1626 if ($die_on_failure) {
1627 dodie @_;
1628 }
1629
1630 doprint "FAILED\n";
1631
1632 my $i = $iteration;
1633
1634 # no need to reboot for just building.
1635 if (!do_not_reboot) {
1636 doprint "REBOOTING\n";
1637 reboot_to_good $sleep_time;
1638 }
1639
1640 my $name = "";
1641
1642 if (defined($test_name)) {
1643 $name = " ($test_name)";
1644 }
1645
1646 print_times;
1647
1648 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
1649 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
1650 doprint "KTEST RESULT: TEST $i$name Failed: ", @_, "\n";
1651 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
1652 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
1653
1654 if (defined($store_failures)) {
1655 save_logs "fail", $store_failures;
1656 }
1657
1658 return 1;
1659 }
1660
1661 sub run_command {
1662 my ($command, $redirect) = @_;
1663 my $start_time;
1664 my $end_time;
1665 my $dolog = 0;
1666 my $dord = 0;
1667 my $pid;
1668
1669 $start_time = time;
1670
1671 $command =~ s/\$SSH_USER/$ssh_user/g;
1672 $command =~ s/\$MACHINE/$machine/g;
1673
1674 doprint("$command ... ");
1675
1676 $pid = open(CMD, "$command 2>&1 |") or
1677 (fail "unable to exec $command" and return 0);
1678
1679 if (defined($opt{"LOG_FILE"})) {
1680 open(LOG, ">>$opt{LOG_FILE}") or
1681 dodie "failed to write to log";
1682 $dolog = 1;
1683 }
1684
1685 if (defined($redirect)) {
1686 open (RD, ">$redirect") or
1687 dodie "failed to write to redirect $redirect";
1688 $dord = 1;
1689 }
1690
1691 while (<CMD>) {
1692 print LOG if ($dolog);
1693 print RD if ($dord);
1694 }
1695
1696 waitpid($pid, 0);
1697 my $failed = $?;
1698
1699 close(CMD);
1700 close(LOG) if ($dolog);
1701 close(RD) if ($dord);
1702
1703 $end_time = time;
1704 my $delta = $end_time - $start_time;
1705
1706 if ($delta == 1) {
1707 doprint "[1 second] ";
1708 } else {
1709 doprint "[$delta seconds] ";
1710 }
1711
1712 if ($failed) {
1713 doprint "FAILED!\n";
1714 } else {
1715 doprint "SUCCESS\n";
1716 }
1717
1718 return !$failed;
1719 }
1720
1721 sub run_ssh {
1722 my ($cmd) = @_;
1723 my $cp_exec = $ssh_exec;
1724
1725 $cp_exec =~ s/\$SSH_COMMAND/$cmd/g;
1726 return run_command "$cp_exec";
1727 }
1728
1729 sub run_scp {
1730 my ($src, $dst, $cp_scp) = @_;
1731
1732 $cp_scp =~ s/\$SRC_FILE/$src/g;
1733 $cp_scp =~ s/\$DST_FILE/$dst/g;
1734
1735 return run_command "$cp_scp";
1736 }
1737
1738 sub run_scp_install {
1739 my ($src, $dst) = @_;
1740
1741 my $cp_scp = $scp_to_target_install;
1742
1743 return run_scp($src, $dst, $cp_scp);
1744 }
1745
1746 sub run_scp_mod {
1747 my ($src, $dst) = @_;
1748
1749 my $cp_scp = $scp_to_target;
1750
1751 return run_scp($src, $dst, $cp_scp);
1752 }
1753
1754 sub get_grub2_index {
1755
1756 return if (defined($grub_number) && defined($last_grub_menu) &&
1757 $last_grub_menu eq $grub_menu && defined($last_machine) &&
1758 $last_machine eq $machine);
1759
1760 doprint "Find grub2 menu ... ";
1761 $grub_number = -1;
1762
1763 my $ssh_grub = $ssh_exec;
1764 $ssh_grub =~ s,\$SSH_COMMAND,cat $grub_file,g;
1765
1766 open(IN, "$ssh_grub |")
1767 or die "unable to get $grub_file";
1768
1769 my $found = 0;
1770
1771 while (<IN>) {
1772 if (/^menuentry.*$grub_menu/) {
1773 $grub_number++;
1774 $found = 1;
1775 last;
1776 } elsif (/^menuentry\s/) {
1777 $grub_number++;
1778 }
1779 }
1780 close(IN);
1781
1782 die "Could not find '$grub_menu' in $grub_file on $machine"
1783 if (!$found);
1784 doprint "$grub_number\n";
1785 $last_grub_menu = $grub_menu;
1786 $last_machine = $machine;
1787 }
1788
1789 sub get_grub_index {
1790
1791 if ($reboot_type eq "grub2") {
1792 get_grub2_index;
1793 return;
1794 }
1795
1796 if ($reboot_type ne "grub") {
1797 return;
1798 }
1799 return if (defined($grub_number) && defined($last_grub_menu) &&
1800 $last_grub_menu eq $grub_menu && defined($last_machine) &&
1801 $last_machine eq $machine);
1802
1803 doprint "Find grub menu ... ";
1804 $grub_number = -1;
1805
1806 my $ssh_grub = $ssh_exec;
1807 $ssh_grub =~ s,\$SSH_COMMAND,cat /boot/grub/menu.lst,g;
1808
1809 open(IN, "$ssh_grub |")
1810 or die "unable to get menu.lst";
1811
1812 my $found = 0;
1813
1814 while (<IN>) {
1815 if (/^\s*title\s+$grub_menu\s*$/) {
1816 $grub_number++;
1817 $found = 1;
1818 last;
1819 } elsif (/^\s*title\s/) {
1820 $grub_number++;
1821 }
1822 }
1823 close(IN);
1824
1825 die "Could not find '$grub_menu' in /boot/grub/menu on $machine"
1826 if (!$found);
1827 doprint "$grub_number\n";
1828 $last_grub_menu = $grub_menu;
1829 $last_machine = $machine;
1830 }
1831
1832 sub wait_for_input
1833 {
1834 my ($fp, $time) = @_;
1835 my $rin;
1836 my $rout;
1837 my $nr;
1838 my $buf;
1839 my $line;
1840 my $ch;
1841
1842 if (!defined($time)) {
1843 $time = $timeout;
1844 }
1845
1846 $rin = '';
1847 vec($rin, fileno($fp), 1) = 1;
1848 vec($rin, fileno(\*STDIN), 1) = 1;
1849
1850 while (1) {
1851 $nr = select($rout=$rin, undef, undef, $time);
1852
1853 if ($nr <= 0) {
1854 return undef;
1855 }
1856
1857 # copy data from stdin to the console
1858 if (vec($rout, fileno(\*STDIN), 1) == 1) {
1859 sysread(\*STDIN, $buf, 1000);
1860 syswrite($fp, $buf, 1000);
1861 next;
1862 }
1863
1864 $line = "";
1865
1866 # try to read one char at a time
1867 while (sysread $fp, $ch, 1) {
1868 $line .= $ch;
1869 last if ($ch eq "\n");
1870 }
1871
1872 if (!length($line)) {
1873 return undef;
1874 }
1875
1876 return $line;
1877 }
1878 }
1879
1880 sub reboot_to {
1881 if (defined($switch_to_test)) {
1882 run_command $switch_to_test;
1883 }
1884
1885 if ($reboot_type eq "grub") {
1886 run_ssh "'(echo \"savedefault --default=$grub_number --once\" | grub --batch)'";
1887 } elsif ($reboot_type eq "grub2") {
1888 run_ssh "$grub_reboot $grub_number";
1889 } elsif ($reboot_type eq "syslinux") {
1890 run_ssh "$syslinux --once \\\"$syslinux_label\\\" $syslinux_path";
1891 } elsif (defined $reboot_script) {
1892 run_command "$reboot_script";
1893 }
1894 reboot;
1895 }
1896
1897 sub get_sha1 {
1898 my ($commit) = @_;
1899
1900 doprint "git rev-list --max-count=1 $commit ... ";
1901 my $sha1 = `git rev-list --max-count=1 $commit`;
1902 my $ret = $?;
1903
1904 logit $sha1;
1905
1906 if ($ret) {
1907 doprint "FAILED\n";
1908 dodie "Failed to get git $commit";
1909 }
1910
1911 print "SUCCESS\n";
1912
1913 chomp $sha1;
1914
1915 return $sha1;
1916 }
1917
1918 sub monitor {
1919 my $booted = 0;
1920 my $bug = 0;
1921 my $bug_ignored = 0;
1922 my $skip_call_trace = 0;
1923 my $loops;
1924
1925 my $start_time = time;
1926
1927 wait_for_monitor 5;
1928
1929 my $line;
1930 my $full_line = "";
1931
1932 open(DMESG, "> $dmesg") or
1933 die "unable to write to $dmesg";
1934
1935 reboot_to;
1936
1937 my $success_start;
1938 my $failure_start;
1939 my $monitor_start = time;
1940 my $done = 0;
1941 my $version_found = 0;
1942
1943 while (!$done) {
1944
1945 if ($bug && defined($stop_after_failure) &&
1946 $stop_after_failure >= 0) {
1947 my $time = $stop_after_failure - (time - $failure_start);
1948 $line = wait_for_input($monitor_fp, $time);
1949 if (!defined($line)) {
1950 doprint "bug timed out after $booted_timeout seconds\n";
1951 doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
1952 last;
1953 }
1954 } elsif ($booted) {
1955 $line = wait_for_input($monitor_fp, $booted_timeout);
1956 if (!defined($line)) {
1957 my $s = $booted_timeout == 1 ? "" : "s";
1958 doprint "Successful boot found: break after $booted_timeout second$s\n";
1959 last;
1960 }
1961 } else {
1962 $line = wait_for_input($monitor_fp);
1963 if (!defined($line)) {
1964 my $s = $timeout == 1 ? "" : "s";
1965 doprint "Timed out after $timeout second$s\n";
1966 last;
1967 }
1968 }
1969
1970 doprint $line;
1971 print DMESG $line;
1972
1973 # we are not guaranteed to get a full line
1974 $full_line .= $line;
1975
1976 if ($full_line =~ /$success_line/) {
1977 $booted = 1;
1978 $success_start = time;
1979 }
1980
1981 if ($booted && defined($stop_after_success) &&
1982 $stop_after_success >= 0) {
1983 my $now = time;
1984 if ($now - $success_start >= $stop_after_success) {
1985 doprint "Test forced to stop after $stop_after_success seconds after success\n";
1986 last;
1987 }
1988 }
1989
1990 if ($full_line =~ /\[ backtrace testing \]/) {
1991 $skip_call_trace = 1;
1992 }
1993
1994 if ($full_line =~ /call trace:/i) {
1995 if (!$bug && !$skip_call_trace) {
1996 if ($ignore_errors) {
1997 $bug_ignored = 1;
1998 } else {
1999 $bug = 1;
2000 $failure_start = time;
2001 }
2002 }
2003 }
2004
2005 if ($bug && defined($stop_after_failure) &&
2006 $stop_after_failure >= 0) {
2007 my $now = time;
2008 if ($now - $failure_start >= $stop_after_failure) {
2009 doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
2010 last;
2011 }
2012 }
2013
2014 if ($full_line =~ /\[ end of backtrace testing \]/) {
2015 $skip_call_trace = 0;
2016 }
2017
2018 if ($full_line =~ /Kernel panic -/) {
2019 $failure_start = time;
2020 $bug = 1;
2021 }
2022
2023 # Detect triple faults by testing the banner
2024 if ($full_line =~ /\bLinux version (\S+).*\n/) {
2025 if ($1 eq $version) {
2026 $version_found = 1;
2027 } elsif ($version_found && $detect_triplefault) {
2028 # We already booted into the kernel we are testing,
2029 # but now we booted into another kernel?
2030 # Consider this a triple fault.
2031 doprint "Already booted in Linux kernel $version, but now\n";
2032 doprint "we booted into Linux kernel $1.\n";
2033 doprint "Assuming that this is a triple fault.\n";
2034 doprint "To disable this: set DETECT_TRIPLE_FAULT to 0\n";
2035 last;
2036 }
2037 }
2038
2039 if ($line =~ /\n/) {
2040 $full_line = "";
2041 }
2042
2043 if ($stop_test_after > 0 && !$booted && !$bug) {
2044 if (time - $monitor_start > $stop_test_after) {
2045 doprint "STOP_TEST_AFTER ($stop_test_after seconds) timed out\n";
2046 $done = 1;
2047 }
2048 }
2049 }
2050
2051 my $end_time = time;
2052 $reboot_time = $end_time - $start_time;
2053
2054 close(DMESG);
2055
2056 if ($bug) {
2057 return 0 if ($in_bisect);
2058 fail "failed - got a bug report" and return 0;
2059 }
2060
2061 if (!$booted) {
2062 return 0 if ($in_bisect);
2063 fail "failed - never got a boot prompt." and return 0;
2064 }
2065
2066 if ($bug_ignored) {
2067 doprint "WARNING: Call Trace detected but ignored due to IGNORE_ERRORS=1\n";
2068 }
2069
2070 return 1;
2071 }
2072
2073 sub eval_kernel_version {
2074 my ($option) = @_;
2075
2076 $option =~ s/\$KERNEL_VERSION/$version/g;
2077
2078 return $option;
2079 }
2080
2081 sub do_post_install {
2082
2083 return if (!defined($post_install));
2084
2085 my $cp_post_install = eval_kernel_version $post_install;
2086 run_command "$cp_post_install" or
2087 dodie "Failed to run post install";
2088 }
2089
2090 # Sometimes the reboot fails, and will hang. We try to ssh to the box
2091 # and if we fail, we force another reboot, that should powercycle it.
2092 sub test_booted {
2093 if (!run_ssh "echo testing connection") {
2094 reboot $sleep_time;
2095 }
2096 }
2097
2098 sub install {
2099
2100 return if ($no_install);
2101
2102 my $start_time = time;
2103
2104 if (defined($pre_install)) {
2105 my $cp_pre_install = eval_kernel_version $pre_install;
2106 run_command "$cp_pre_install" or
2107 dodie "Failed to run pre install";
2108 }
2109
2110 my $cp_target = eval_kernel_version $target_image;
2111
2112 test_booted;
2113
2114 run_scp_install "$outputdir/$build_target", "$cp_target" or
2115 dodie "failed to copy image";
2116
2117 my $install_mods = 0;
2118
2119 # should we process modules?
2120 $install_mods = 0;
2121 open(IN, "$output_config") or dodie("Can't read config file");
2122 while (<IN>) {
2123 if (/CONFIG_MODULES(=y)?/) {
2124 if (defined($1)) {
2125 $install_mods = 1;
2126 last;
2127 }
2128 }
2129 }
2130 close(IN);
2131
2132 if (!$install_mods) {
2133 do_post_install;
2134 doprint "No modules needed\n";
2135 my $end_time = time;
2136 $install_time = $end_time - $start_time;
2137 return;
2138 }
2139
2140 run_command "$make INSTALL_MOD_STRIP=1 INSTALL_MOD_PATH=$tmpdir modules_install" or
2141 dodie "Failed to install modules";
2142
2143 my $modlib = "/lib/modules/$version";
2144 my $modtar = "ktest-mods.tar.bz2";
2145
2146 run_ssh "rm -rf $modlib" or
2147 dodie "failed to remove old mods: $modlib";
2148
2149 # would be nice if scp -r did not follow symbolic links
2150 run_command "cd $tmpdir && tar -cjf $modtar lib/modules/$version" or
2151 dodie "making tarball";
2152
2153 run_scp_mod "$tmpdir/$modtar", "/tmp" or
2154 dodie "failed to copy modules";
2155
2156 unlink "$tmpdir/$modtar";
2157
2158 run_ssh "'(cd / && tar xjf /tmp/$modtar)'" or
2159 dodie "failed to tar modules";
2160
2161 run_ssh "rm -f /tmp/$modtar";
2162
2163 do_post_install;
2164
2165 my $end_time = time;
2166 $install_time = $end_time - $start_time;
2167 }
2168
2169 sub get_version {
2170 # get the release name
2171 return if ($have_version);
2172 doprint "$make kernelrelease ... ";
2173 $version = `$make -s kernelrelease | tail -1`;
2174 chomp($version);
2175 doprint "$version\n";
2176 $have_version = 1;
2177 }
2178
2179 sub start_monitor_and_install {
2180 # Make sure the stable kernel has finished booting
2181
2182 # Install bisects, don't need console
2183 if (defined $console) {
2184 start_monitor;
2185 wait_for_monitor 5;
2186 end_monitor;
2187 }
2188
2189 get_grub_index;
2190 get_version;
2191 install;
2192
2193 start_monitor if (defined $console);
2194 return monitor;
2195 }
2196
2197 my $check_build_re = ".*:.*(warning|error|Error):.*";
2198 my $utf8_quote = "\\x{e2}\\x{80}(\\x{98}|\\x{99})";
2199
2200 sub process_warning_line {
2201 my ($line) = @_;
2202
2203 chomp $line;
2204
2205 # for distcc heterogeneous systems, some compilers
2206 # do things differently causing warning lines
2207 # to be slightly different. This makes an attempt
2208 # to fixe those issues.
2209
2210 # chop off the index into the line
2211 # using distcc, some compilers give different indexes
2212 # depending on white space
2213 $line =~ s/^(\s*\S+:\d+:)\d+/$1/;
2214
2215 # Some compilers use UTF-8 extended for quotes and some don't.
2216 $line =~ s/$utf8_quote/'/g;
2217
2218 return $line;
2219 }
2220
2221 # Read buildlog and check against warnings file for any
2222 # new warnings.
2223 #
2224 # Returns 1 if OK
2225 # 0 otherwise
2226 sub check_buildlog {
2227 return 1 if (!defined $warnings_file);
2228
2229 my %warnings_list;
2230
2231 # Failed builds should not reboot the target
2232 my $save_no_reboot = $no_reboot;
2233 $no_reboot = 1;
2234
2235 if (-f $warnings_file) {
2236 open(IN, $warnings_file) or
2237 dodie "Error opening $warnings_file";
2238
2239 while (<IN>) {
2240 if (/$check_build_re/) {
2241 my $warning = process_warning_line $_;
2242
2243 $warnings_list{$warning} = 1;
2244 }
2245 }
2246 close(IN);
2247 }
2248
2249 # If warnings file didn't exist, and WARNINGS_FILE exist,
2250 # then we fail on any warning!
2251
2252 open(IN, $buildlog) or dodie "Can't open $buildlog";
2253 while (<IN>) {
2254 if (/$check_build_re/) {
2255 my $warning = process_warning_line $_;
2256
2257 if (!defined $warnings_list{$warning}) {
2258 fail "New warning found (not in $warnings_file)\n$_\n";
2259 $no_reboot = $save_no_reboot;
2260 return 0;
2261 }
2262 }
2263 }
2264 $no_reboot = $save_no_reboot;
2265 close(IN);
2266 }
2267
2268 sub check_patch_buildlog {
2269 my ($patch) = @_;
2270
2271 my @files = `git show $patch | diffstat -l`;
2272
2273 foreach my $file (@files) {
2274 chomp $file;
2275 }
2276
2277 open(IN, "git show $patch |") or
2278 dodie "failed to show $patch";
2279 while (<IN>) {
2280 if (m,^--- a/(.*),) {
2281 chomp $1;
2282 $files[$#files] = $1;
2283 }
2284 }
2285 close(IN);
2286
2287 open(IN, $buildlog) or dodie "Can't open $buildlog";
2288 while (<IN>) {
2289 if (/^\s*(.*?):.*(warning|error)/) {
2290 my $err = $1;
2291 foreach my $file (@files) {
2292 my $fullpath = "$builddir/$file";
2293 if ($file eq $err || $fullpath eq $err) {
2294 fail "$file built with warnings" and return 0;
2295 }
2296 }
2297 }
2298 }
2299 close(IN);
2300
2301 return 1;
2302 }
2303
2304 sub apply_min_config {
2305 my $outconfig = "$output_config.new";
2306
2307 # Read the config file and remove anything that
2308 # is in the force_config hash (from minconfig and others)
2309 # then add the force config back.
2310
2311 doprint "Applying minimum configurations into $output_config.new\n";
2312
2313 open (OUT, ">$outconfig") or
2314 dodie "Can't create $outconfig";
2315
2316 if (-f $output_config) {
2317 open (IN, $output_config) or
2318 dodie "Failed to open $output_config";
2319 while (<IN>) {
2320 if (/^(# )?(CONFIG_[^\s=]*)/) {
2321 next if (defined($force_config{$2}));
2322 }
2323 print OUT;
2324 }
2325 close IN;
2326 }
2327 foreach my $config (keys %force_config) {
2328 print OUT "$force_config{$config}\n";
2329 }
2330 close OUT;
2331
2332 run_command "mv $outconfig $output_config";
2333 }
2334
2335 sub make_oldconfig {
2336
2337 my @force_list = keys %force_config;
2338
2339 if ($#force_list >= 0) {
2340 apply_min_config;
2341 }
2342
2343 if (!run_command "$make olddefconfig") {
2344 # Perhaps olddefconfig doesn't exist in this version of the kernel
2345 # try oldnoconfig
2346 doprint "olddefconfig failed, trying make oldnoconfig\n";
2347 if (!run_command "$make oldnoconfig") {
2348 doprint "oldnoconfig failed, trying yes '' | make oldconfig\n";
2349 # try a yes '' | oldconfig
2350 run_command "yes '' | $make oldconfig" or
2351 dodie "failed make config oldconfig";
2352 }
2353 }
2354 }
2355
2356 # read a config file and use this to force new configs.
2357 sub load_force_config {
2358 my ($config) = @_;
2359
2360 doprint "Loading force configs from $config\n";
2361 open(IN, $config) or
2362 dodie "failed to read $config";
2363 while (<IN>) {
2364 chomp;
2365 if (/^(CONFIG[^\s=]*)(\s*=.*)/) {
2366 $force_config{$1} = $_;
2367 } elsif (/^# (CONFIG_\S*) is not set/) {
2368 $force_config{$1} = $_;
2369 }
2370 }
2371 close IN;
2372 }
2373
2374 sub build {
2375 my ($type) = @_;
2376
2377 unlink $buildlog;
2378
2379 my $start_time = time;
2380
2381 # Failed builds should not reboot the target
2382 my $save_no_reboot = $no_reboot;
2383 $no_reboot = 1;
2384
2385 # Calculate a new version from here.
2386 $have_version = 0;
2387
2388 if (defined($pre_build)) {
2389 my $ret = run_command $pre_build;
2390 if (!$ret && defined($pre_build_die) &&
2391 $pre_build_die) {
2392 dodie "failed to pre_build\n";
2393 }
2394 }
2395
2396 if ($type =~ /^useconfig:(.*)/) {
2397 run_command "cp $1 $output_config" or
2398 dodie "could not copy $1 to .config";
2399
2400 $type = "oldconfig";
2401 }
2402
2403 # old config can ask questions
2404 if ($type eq "oldconfig") {
2405 $type = "olddefconfig";
2406
2407 # allow for empty configs
2408 run_command "touch $output_config";
2409
2410 if (!$noclean) {
2411 run_command "mv $output_config $outputdir/config_temp" or
2412 dodie "moving .config";
2413
2414 run_command "$make mrproper" or dodie "make mrproper";
2415
2416 run_command "mv $outputdir/config_temp $output_config" or
2417 dodie "moving config_temp";
2418 }
2419
2420 } elsif (!$noclean) {
2421 unlink "$output_config";
2422 run_command "$make mrproper" or
2423 dodie "make mrproper";
2424 }
2425
2426 # add something to distinguish this build
2427 open(OUT, "> $outputdir/localversion") or dodie("Can't make localversion file");
2428 print OUT "$localversion\n";
2429 close(OUT);
2430
2431 if (defined($minconfig)) {
2432 load_force_config($minconfig);
2433 }
2434
2435 if ($type ne "olddefconfig") {
2436 run_command "$make $type" or
2437 dodie "failed make config";
2438 }
2439 # Run old config regardless, to enforce min configurations
2440 make_oldconfig;
2441
2442 my $build_ret = run_command "$make $build_options", $buildlog;
2443
2444 if (defined($post_build)) {
2445 # Because a post build may change the kernel version
2446 # do it now.
2447 get_version;
2448 my $ret = run_command $post_build;
2449 if (!$ret && defined($post_build_die) &&
2450 $post_build_die) {
2451 dodie "failed to post_build\n";
2452 }
2453 }
2454
2455 if (!$build_ret) {
2456 # bisect may need this to pass
2457 if ($in_bisect) {
2458 $no_reboot = $save_no_reboot;
2459 return 0;
2460 }
2461 fail "failed build" and return 0;
2462 }
2463
2464 $no_reboot = $save_no_reboot;
2465
2466 my $end_time = time;
2467 $build_time = $end_time - $start_time;
2468
2469 return 1;
2470 }
2471
2472 sub halt {
2473 if (!run_ssh "halt" or defined($power_off)) {
2474 if (defined($poweroff_after_halt)) {
2475 sleep $poweroff_after_halt;
2476 run_command "$power_off";
2477 }
2478 } else {
2479 # nope? the zap it!
2480 run_command "$power_off";
2481 }
2482 }
2483
2484 sub success {
2485 my ($i) = @_;
2486
2487 if (defined($post_test)) {
2488 run_command $post_test;
2489 }
2490
2491 $successes++;
2492
2493 my $name = "";
2494
2495 if (defined($test_name)) {
2496 $name = " ($test_name)";
2497 }
2498
2499 print_times;
2500
2501 doprint "\n\n*******************************************\n";
2502 doprint "*******************************************\n";
2503 doprint "KTEST RESULT: TEST $i$name SUCCESS!!!! **\n";
2504 doprint "*******************************************\n";
2505 doprint "*******************************************\n";
2506
2507 if (defined($store_successes)) {
2508 save_logs "success", $store_successes;
2509 }
2510
2511 if ($i != $opt{"NUM_TESTS"} && !do_not_reboot) {
2512 doprint "Reboot and wait $sleep_time seconds\n";
2513 reboot_to_good $sleep_time;
2514 }
2515 }
2516
2517 sub answer_bisect {
2518 for (;;) {
2519 doprint "Pass, fail, or skip? [p/f/s]";
2520 my $ans = <STDIN>;
2521 chomp $ans;
2522 if ($ans eq "p" || $ans eq "P") {
2523 return 1;
2524 } elsif ($ans eq "f" || $ans eq "F") {
2525 return 0;
2526 } elsif ($ans eq "s" || $ans eq "S") {
2527 return -1;
2528 } else {
2529 print "Please answer 'p', 'f', or 's'\n";
2530 }
2531 }
2532 }
2533
2534 sub child_run_test {
2535 my $failed = 0;
2536
2537 # child should have no power
2538 $reboot_on_error = 0;
2539 $poweroff_on_error = 0;
2540 $die_on_failure = 1;
2541
2542 run_command $run_test, $testlog or $failed = 1;
2543
2544 exit $failed;
2545 }
2546
2547 my $child_done;
2548
2549 sub child_finished {
2550 $child_done = 1;
2551 }
2552
2553 sub do_run_test {
2554 my $child_pid;
2555 my $child_exit;
2556 my $line;
2557 my $full_line;
2558 my $bug = 0;
2559 my $bug_ignored = 0;
2560
2561 my $start_time = time;
2562
2563 wait_for_monitor 1;
2564
2565 doprint "run test $run_test\n";
2566
2567 $child_done = 0;
2568
2569 $SIG{CHLD} = qw(child_finished);
2570
2571 $child_pid = fork;
2572
2573 child_run_test if (!$child_pid);
2574
2575 $full_line = "";
2576
2577 do {
2578 $line = wait_for_input($monitor_fp, 1);
2579 if (defined($line)) {
2580
2581 # we are not guaranteed to get a full line
2582 $full_line .= $line;
2583 doprint $line;
2584
2585 if ($full_line =~ /call trace:/i) {
2586 if ($ignore_errors) {
2587 $bug_ignored = 1;
2588 } else {
2589 $bug = 1;
2590 }
2591 }
2592
2593 if ($full_line =~ /Kernel panic -/) {
2594 $bug = 1;
2595 }
2596
2597 if ($line =~ /\n/) {
2598 $full_line = "";
2599 }
2600 }
2601 } while (!$child_done && !$bug);
2602
2603 if (!$bug && $bug_ignored) {
2604 doprint "WARNING: Call Trace detected but ignored due to IGNORE_ERRORS=1\n";
2605 }
2606
2607 if ($bug) {
2608 my $failure_start = time;
2609 my $now;
2610 do {
2611 $line = wait_for_input($monitor_fp, 1);
2612 if (defined($line)) {
2613 doprint $line;
2614 }
2615 $now = time;
2616 if ($now - $failure_start >= $stop_after_failure) {
2617 last;
2618 }
2619 } while (defined($line));
2620
2621 doprint "Detected kernel crash!\n";
2622 # kill the child with extreme prejudice
2623 kill 9, $child_pid;
2624 }
2625
2626 waitpid $child_pid, 0;
2627 $child_exit = $?;
2628
2629 my $end_time = time;
2630 $test_time = $end_time - $start_time;
2631
2632 if (!$bug && $in_bisect) {
2633 if (defined($bisect_ret_good)) {
2634 if ($child_exit == $bisect_ret_good) {
2635 return 1;
2636 }
2637 }
2638 if (defined($bisect_ret_skip)) {
2639 if ($child_exit == $bisect_ret_skip) {
2640 return -1;
2641 }
2642 }
2643 if (defined($bisect_ret_abort)) {
2644 if ($child_exit == $bisect_ret_abort) {
2645 fail "test abort" and return -2;
2646 }
2647 }
2648 if (defined($bisect_ret_bad)) {
2649 if ($child_exit == $bisect_ret_skip) {
2650 return 0;
2651 }
2652 }
2653 if (defined($bisect_ret_default)) {
2654 if ($bisect_ret_default eq "good") {
2655 return 1;
2656 } elsif ($bisect_ret_default eq "bad") {
2657 return 0;
2658 } elsif ($bisect_ret_default eq "skip") {
2659 return -1;
2660 } elsif ($bisect_ret_default eq "abort") {
2661 return -2;
2662 } else {
2663 fail "unknown default action: $bisect_ret_default"
2664 and return -2;
2665 }
2666 }
2667 }
2668
2669 if ($bug || $child_exit) {
2670 return 0 if $in_bisect;
2671 fail "test failed" and return 0;
2672 }
2673 return 1;
2674 }
2675
2676 sub run_git_bisect {
2677 my ($command) = @_;
2678
2679 doprint "$command ... ";
2680
2681 my $output = `$command 2>&1`;
2682 my $ret = $?;
2683
2684 logit $output;
2685
2686 if ($ret) {
2687 doprint "FAILED\n";
2688 dodie "Failed to git bisect";
2689 }
2690
2691 doprint "SUCCESS\n";
2692 if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\))\s+\[([[:xdigit:]]+)\]/) {
2693 doprint "$1 [$2]\n";
2694 } elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) {
2695 $bisect_bad_commit = $1;
2696 doprint "Found bad commit... $1\n";
2697 return 0;
2698 } else {
2699 # we already logged it, just print it now.
2700 print $output;
2701 }
2702
2703 return 1;
2704 }
2705
2706 sub bisect_reboot {
2707 doprint "Reboot and sleep $bisect_sleep_time seconds\n";
2708 reboot_to_good $bisect_sleep_time;
2709 }
2710
2711 # returns 1 on success, 0 on failure, -1 on skip
2712 sub run_bisect_test {
2713 my ($type, $buildtype) = @_;
2714
2715 my $failed = 0;
2716 my $result;
2717 my $output;
2718 my $ret;
2719
2720 $in_bisect = 1;
2721
2722 build $buildtype or $failed = 1;
2723
2724 if ($type ne "build") {
2725 if ($failed && $bisect_skip) {
2726 $in_bisect = 0;
2727 return -1;
2728 }
2729 dodie "Failed on build" if $failed;
2730
2731 # Now boot the box
2732 start_monitor_and_install or $failed = 1;
2733
2734 if ($type ne "boot") {
2735 if ($failed && $bisect_skip) {
2736 end_monitor;
2737 bisect_reboot;
2738 $in_bisect = 0;
2739 return -1;
2740 }
2741 dodie "Failed on boot" if $failed;
2742
2743 do_run_test or $failed = 1;
2744 }
2745 end_monitor;
2746 }
2747
2748 if ($failed) {
2749 $result = 0;
2750 } else {
2751 $result = 1;
2752 }
2753
2754 # reboot the box to a kernel we can ssh to
2755 if ($type ne "build") {
2756 bisect_reboot;
2757 }
2758 $in_bisect = 0;
2759
2760 return $result;
2761 }
2762
2763 sub run_bisect {
2764 my ($type) = @_;
2765 my $buildtype = "oldconfig";
2766
2767 # We should have a minconfig to use?
2768 if (defined($minconfig)) {
2769 $buildtype = "useconfig:$minconfig";
2770 }
2771
2772 # If the user sets bisect_tries to less than 1, then no tries
2773 # is a success.
2774 my $ret = 1;
2775
2776 # Still let the user manually decide that though.
2777 if ($bisect_tries < 1 && $bisect_manual) {
2778 $ret = answer_bisect;
2779 }
2780
2781 for (my $i = 0; $i < $bisect_tries; $i++) {
2782 if ($bisect_tries > 1) {
2783 my $t = $i + 1;
2784 doprint("Running bisect trial $t of $bisect_tries:\n");
2785 }
2786 $ret = run_bisect_test $type, $buildtype;
2787
2788 if ($bisect_manual) {
2789 $ret = answer_bisect;
2790 }
2791
2792 last if (!$ret);
2793 }
2794
2795 # Are we looking for where it worked, not failed?
2796 if ($reverse_bisect && $ret >= 0) {
2797 $ret = !$ret;
2798 }
2799
2800 if ($ret > 0) {
2801 return "good";
2802 } elsif ($ret == 0) {
2803 return "bad";
2804 } elsif ($bisect_skip) {
2805 doprint "HIT A BAD COMMIT ... SKIPPING\n";
2806 return "skip";
2807 }
2808 }
2809
2810 sub update_bisect_replay {
2811 my $tmp_log = "$tmpdir/ktest_bisect_log";
2812 run_command "git bisect log > $tmp_log" or
2813 die "can't create bisect log";
2814 return $tmp_log;
2815 }
2816
2817 sub bisect {
2818 my ($i) = @_;
2819
2820 my $result;
2821
2822 die "BISECT_GOOD[$i] not defined\n" if (!defined($bisect_good));
2823 die "BISECT_BAD[$i] not defined\n" if (!defined($bisect_bad));
2824 die "BISECT_TYPE[$i] not defined\n" if (!defined($bisect_type));
2825
2826 my $good = $bisect_good;
2827 my $bad = $bisect_bad;
2828 my $type = $bisect_type;
2829 my $start = $bisect_start;
2830 my $replay = $bisect_replay;
2831 my $start_files = $bisect_files;
2832
2833 if (defined($start_files)) {
2834 $start_files = " -- " . $start_files;
2835 } else {
2836 $start_files = "";
2837 }
2838
2839 # convert to true sha1's
2840 $good = get_sha1($good);
2841 $bad = get_sha1($bad);
2842
2843 if (defined($bisect_reverse) && $bisect_reverse == 1) {
2844 doprint "Performing a reverse bisect (bad is good, good is bad!)\n";
2845 $reverse_bisect = 1;
2846 } else {
2847 $reverse_bisect = 0;
2848 }
2849
2850 # Can't have a test without having a test to run
2851 if ($type eq "test" && !defined($run_test)) {
2852 $type = "boot";
2853 }
2854
2855 # Check if a bisect was running
2856 my $bisect_start_file = "$builddir/.git/BISECT_START";
2857
2858 my $check = $bisect_check;
2859 my $do_check = defined($check) && $check ne "0";
2860
2861 if ( -f $bisect_start_file ) {
2862 print "Bisect in progress found\n";
2863 if ($do_check) {
2864 print " If you say yes, then no checks of good or bad will be done\n";
2865 }
2866 if (defined($replay)) {
2867 print "** BISECT_REPLAY is defined in config file **";
2868 print " Ignore config option and perform new git bisect log?\n";
2869 if (read_ync " (yes, no, or cancel) ") {
2870 $replay = update_bisect_replay;
2871 $do_check = 0;
2872 }
2873 } elsif (read_yn "read git log and continue?") {
2874 $replay = update_bisect_replay;
2875 $do_check = 0;
2876 }
2877 }
2878
2879 if ($do_check) {
2880
2881 # get current HEAD
2882 my $head = get_sha1("HEAD");
2883
2884 if ($check ne "good") {
2885 doprint "TESTING BISECT BAD [$bad]\n";
2886 run_command "git checkout $bad" or
2887 die "Failed to checkout $bad";
2888
2889 $result = run_bisect $type;
2890
2891 if ($result ne "bad") {
2892 fail "Tested BISECT_BAD [$bad] and it succeeded" and return 0;
2893 }
2894 }
2895
2896 if ($check ne "bad") {
2897 doprint "TESTING BISECT GOOD [$good]\n";
2898 run_command "git checkout $good" or
2899 die "Failed to checkout $good";
2900
2901 $result = run_bisect $type;
2902
2903 if ($result ne "good") {
2904 fail "Tested BISECT_GOOD [$good] and it failed" and return 0;
2905 }
2906 }
2907
2908 # checkout where we started
2909 run_command "git checkout $head" or
2910 die "Failed to checkout $head";
2911 }
2912
2913 run_command "git bisect start$start_files" or
2914 dodie "could not start bisect";
2915
2916 if (defined($replay)) {
2917 run_command "git bisect replay $replay" or
2918 dodie "failed to run replay";
2919 } else {
2920
2921 run_command "git bisect good $good" or
2922 dodie "could not set bisect good to $good";
2923
2924 run_git_bisect "git bisect bad $bad" or
2925 dodie "could not set bisect bad to $bad";
2926
2927 }
2928
2929 if (defined($start)) {
2930 run_command "git checkout $start" or
2931 dodie "failed to checkout $start";
2932 }
2933
2934 my $test;
2935 do {
2936 $result = run_bisect $type;
2937 $test = run_git_bisect "git bisect $result";
2938 print_times;
2939 } while ($test);
2940
2941 run_command "git bisect log" or
2942 dodie "could not capture git bisect log";
2943
2944 run_command "git bisect reset" or
2945 dodie "could not reset git bisect";
2946
2947 doprint "Bad commit was [$bisect_bad_commit]\n";
2948
2949 success $i;
2950 }
2951
2952 # config_ignore holds the configs that were set (or unset) for
2953 # a good config and we will ignore these configs for the rest
2954 # of a config bisect. These configs stay as they were.
2955 my %config_ignore;
2956
2957 # config_set holds what all configs were set as.
2958 my %config_set;
2959
2960 # config_off holds the set of configs that the bad config had disabled.
2961 # We need to record them and set them in the .config when running
2962 # olddefconfig, because olddefconfig keeps the defaults.
2963 my %config_off;
2964
2965 # config_off_tmp holds a set of configs to turn off for now
2966 my @config_off_tmp;
2967
2968 # config_list is the set of configs that are being tested
2969 my %config_list;
2970 my %null_config;
2971
2972 my %dependency;
2973
2974 sub assign_configs {
2975 my ($hash, $config) = @_;
2976
2977 doprint "Reading configs from $config\n";
2978
2979 open (IN, $config)
2980 or dodie "Failed to read $config";
2981
2982 while (<IN>) {
2983 chomp;
2984 if (/^((CONFIG\S*)=.*)/) {
2985 ${$hash}{$2} = $1;
2986 } elsif (/^(# (CONFIG\S*) is not set)/) {
2987 ${$hash}{$2} = $1;
2988 }
2989 }
2990
2991 close(IN);
2992 }
2993
2994 sub process_config_ignore {
2995 my ($config) = @_;
2996
2997 assign_configs \%config_ignore, $config;
2998 }
2999
3000 sub get_dependencies {
3001 my ($config) = @_;
3002
3003 my $arr = $dependency{$config};
3004 if (!defined($arr)) {
3005 return ();
3006 }
3007
3008 my @deps = @{$arr};
3009
3010 foreach my $dep (@{$arr}) {
3011 print "ADD DEP $dep\n";
3012 @deps = (@deps, get_dependencies $dep);
3013 }
3014
3015 return @deps;
3016 }
3017
3018 sub save_config {
3019 my ($pc, $file) = @_;
3020
3021 my %configs = %{$pc};
3022
3023 doprint "Saving configs into $file\n";
3024
3025 open(OUT, ">$file") or dodie "Can not write to $file";
3026
3027 foreach my $config (keys %configs) {
3028 print OUT "$configs{$config}\n";
3029 }
3030 close(OUT);
3031 }
3032
3033 sub create_config {
3034 my ($name, $pc) = @_;
3035
3036 doprint "Creating old config from $name configs\n";
3037
3038 save_config $pc, $output_config;
3039
3040 make_oldconfig;
3041 }
3042
3043 # compare two config hashes, and return configs with different vals.
3044 # It returns B's config values, but you can use A to see what A was.
3045 sub diff_config_vals {
3046 my ($pa, $pb) = @_;
3047
3048 # crappy Perl way to pass in hashes.
3049 my %a = %{$pa};
3050 my %b = %{$pb};
3051
3052 my %ret;
3053
3054 foreach my $item (keys %a) {
3055 if (defined($b{$item}) && $b{$item} ne $a{$item}) {
3056 $ret{$item} = $b{$item};
3057 }
3058 }
3059
3060 return %ret;
3061 }
3062
3063 # compare two config hashes and return the configs in B but not A
3064 sub diff_configs {
3065 my ($pa, $pb) = @_;
3066
3067 my %ret;
3068
3069 # crappy Perl way to pass in hashes.
3070 my %a = %{$pa};
3071 my %b = %{$pb};
3072
3073 foreach my $item (keys %b) {
3074 if (!defined($a{$item})) {
3075 $ret{$item} = $b{$item};
3076 }
3077 }
3078
3079 return %ret;
3080 }
3081
3082 # return if two configs are equal or not
3083 # 0 is equal +1 b has something a does not
3084 # +1 if a and b have a different item.
3085 # -1 if a has something b does not
3086 sub compare_configs {
3087 my ($pa, $pb) = @_;
3088
3089 my %ret;
3090
3091 # crappy Perl way to pass in hashes.
3092 my %a = %{$pa};
3093 my %b = %{$pb};
3094
3095 foreach my $item (keys %b) {
3096 if (!defined($a{$item})) {
3097 return 1;
3098 }
3099 if ($a{$item} ne $b{$item}) {
3100 return 1;
3101 }
3102 }
3103
3104 foreach my $item (keys %a) {
3105 if (!defined($b{$item})) {
3106 return -1;
3107 }
3108 }
3109
3110 return 0;
3111 }
3112
3113 sub run_config_bisect_test {
3114 my ($type) = @_;
3115
3116 my $ret = run_bisect_test $type, "oldconfig";
3117
3118 if ($bisect_manual) {
3119 $ret = answer_bisect;
3120 }
3121
3122 return $ret;
3123 }
3124
3125 sub process_failed {
3126 my ($config) = @_;
3127
3128 doprint "\n\n***************************************\n";
3129 doprint "Found bad config: $config\n";
3130 doprint "***************************************\n\n";
3131 }
3132
3133 # used for config bisecting
3134 my $good_config;
3135 my $bad_config;
3136
3137 sub process_new_config {
3138 my ($tc, $nc, $gc, $bc) = @_;
3139
3140 my %tmp_config = %{$tc};
3141 my %good_configs = %{$gc};
3142 my %bad_configs = %{$bc};
3143
3144 my %new_configs;
3145
3146 my $runtest = 1;
3147 my $ret;
3148
3149 create_config "tmp_configs", \%tmp_config;
3150 assign_configs \%new_configs, $output_config;
3151
3152 $ret = compare_configs \%new_configs, \%bad_configs;
3153 if (!$ret) {
3154 doprint "New config equals bad config, try next test\n";
3155 $runtest = 0;
3156 }
3157
3158 if ($runtest) {
3159 $ret = compare_configs \%new_configs, \%good_configs;
3160 if (!$ret) {
3161 doprint "New config equals good config, try next test\n";
3162 $runtest = 0;
3163 }
3164 }
3165
3166 %{$nc} = %new_configs;
3167
3168 return $runtest;
3169 }
3170
3171 sub run_config_bisect {
3172 my ($pgood, $pbad) = @_;
3173
3174 my $type = $config_bisect_type;
3175
3176 my %good_configs = %{$pgood};
3177 my %bad_configs = %{$pbad};
3178
3179 my %diff_configs = diff_config_vals \%good_configs, \%bad_configs;
3180 my %b_configs = diff_configs \%good_configs, \%bad_configs;
3181 my %g_configs = diff_configs \%bad_configs, \%good_configs;
3182
3183 my @diff_arr = keys %diff_configs;
3184 my $len_diff = $#diff_arr + 1;
3185
3186 my @b_arr = keys %b_configs;
3187 my $len_b = $#b_arr + 1;
3188
3189 my @g_arr = keys %g_configs;
3190 my $len_g = $#g_arr + 1;
3191
3192 my $runtest = 1;
3193 my %new_configs;
3194 my $ret;
3195
3196 # First, lets get it down to a single subset.
3197 # Is the problem with a difference in values?
3198 # Is the problem with a missing config?
3199 # Is the problem with a config that breaks things?
3200
3201 # Enable all of one set and see if we get a new bad
3202 # or good config.
3203
3204 # first set the good config to the bad values.
3205
3206 doprint "d=$len_diff g=$len_g b=$len_b\n";
3207
3208 # first lets enable things in bad config that are enabled in good config
3209
3210 if ($len_diff > 0) {
3211 if ($len_b > 0 || $len_g > 0) {
3212 my %tmp_config = %bad_configs;
3213
3214 doprint "Set tmp config to be bad config with good config values\n";
3215 foreach my $item (@diff_arr) {
3216 $tmp_config{$item} = $good_configs{$item};
3217 }
3218
3219 $runtest = process_new_config \%tmp_config, \%new_configs,
3220 \%good_configs, \%bad_configs;
3221 }
3222 }
3223
3224 if (!$runtest && $len_diff > 0) {
3225
3226 if ($len_diff == 1) {
3227 process_failed $diff_arr[0];
3228 return 1;
3229 }
3230 my %tmp_config = %bad_configs;
3231
3232 my $half = int($#diff_arr / 2);
3233 my @tophalf = @diff_arr[0 .. $half];
3234
3235 doprint "Settings bisect with top half:\n";
3236 doprint "Set tmp config to be bad config with some good config values\n";
3237 foreach my $item (@tophalf) {
3238 $tmp_config{$item} = $good_configs{$item};
3239 }
3240
3241 $runtest = process_new_config \%tmp_config, \%new_configs,
3242 \%good_configs, \%bad_configs;
3243
3244 if (!$runtest) {
3245 my %tmp_config = %bad_configs;
3246
3247 doprint "Try bottom half\n";
3248
3249 my @bottomhalf = @diff_arr[$half+1 .. $#diff_arr];
3250
3251 foreach my $item (@bottomhalf) {
3252 $tmp_config{$item} = $good_configs{$item};
3253 }
3254
3255 $runtest = process_new_config \%tmp_config, \%new_configs,
3256 \%good_configs, \%bad_configs;
3257 }
3258 }
3259
3260 if ($runtest) {
3261 $ret = run_config_bisect_test $type;
3262 if ($ret) {
3263 doprint "NEW GOOD CONFIG\n";
3264 %good_configs = %new_configs;
3265 run_command "mv $good_config ${good_config}.last";
3266 save_config \%good_configs, $good_config;
3267 %{$pgood} = %good_configs;
3268 } else {
3269 doprint "NEW BAD CONFIG\n";
3270 %bad_configs = %new_configs;
3271 run_command "mv $bad_config ${bad_config}.last";
3272 save_config \%bad_configs, $bad_config;
3273 %{$pbad} = %bad_configs;
3274 }
3275 return 0;
3276 }
3277
3278 fail "Hmm, need to do a mix match?\n";
3279 return -1;
3280 }
3281
3282 sub config_bisect {
3283 my ($i) = @_;
3284
3285 my $type = $config_bisect_type;
3286 my $ret;
3287
3288 $bad_config = $config_bisect;
3289
3290 if (defined($config_bisect_good)) {
3291 $good_config = $config_bisect_good;
3292 } elsif (defined($minconfig)) {
3293 $good_config = $minconfig;
3294 } else {
3295 doprint "No config specified, checking if defconfig works";
3296 $ret = run_bisect_test $type, "defconfig";
3297 if (!$ret) {
3298 fail "Have no good config to compare with, please set CONFIG_BISECT_GOOD";
3299 return 1;
3300 }
3301 $good_config = $output_config;
3302 }
3303
3304 # we don't want min configs to cause issues here.
3305 doprint "Disabling 'MIN_CONFIG' for this test\n";
3306 undef $minconfig;
3307
3308 my %good_configs;
3309 my %bad_configs;
3310 my %tmp_configs;
3311
3312 doprint "Run good configs through make oldconfig\n";
3313 assign_configs \%tmp_configs, $good_config;
3314 create_config "$good_config", \%tmp_configs;
3315 assign_configs \%good_configs, $output_config;
3316
3317 doprint "Run bad configs through make oldconfig\n";
3318 assign_configs \%tmp_configs, $bad_config;
3319 create_config "$bad_config", \%tmp_configs;
3320 assign_configs \%bad_configs, $output_config;
3321
3322 $good_config = "$tmpdir/good_config";
3323 $bad_config = "$tmpdir/bad_config";
3324
3325 save_config \%good_configs, $good_config;
3326 save_config \%bad_configs, $bad_config;
3327
3328
3329 if (defined($config_bisect_check) && $config_bisect_check ne "0") {
3330 if ($config_bisect_check ne "good") {
3331 doprint "Testing bad config\n";
3332
3333 $ret = run_bisect_test $type, "useconfig:$bad_config";
3334 if ($ret) {
3335 fail "Bad config succeeded when expected to fail!";
3336 return 0;
3337 }
3338 }
3339 if ($config_bisect_check ne "bad") {
3340 doprint "Testing good config\n";
3341
3342 $ret = run_bisect_test $type, "useconfig:$good_config";
3343 if (!$ret) {
3344 fail "Good config failed when expected to succeed!";
3345 return 0;
3346 }
3347 }
3348 }
3349
3350 do {
3351 $ret = run_config_bisect \%good_configs, \%bad_configs;
3352 print_times;
3353 } while (!$ret);
3354
3355 return $ret if ($ret < 0);
3356
3357 success $i;
3358 }
3359
3360 sub patchcheck_reboot {
3361 doprint "Reboot and sleep $patchcheck_sleep_time seconds\n";
3362 reboot_to_good $patchcheck_sleep_time;
3363 }
3364
3365 sub patchcheck {
3366 my ($i) = @_;
3367
3368 die "PATCHCHECK_START[$i] not defined\n"
3369 if (!defined($patchcheck_start));
3370 die "PATCHCHECK_TYPE[$i] not defined\n"
3371 if (!defined($patchcheck_type));
3372
3373 my $start = $patchcheck_start;
3374
3375 my $cherry = $patchcheck_cherry;
3376 if (!defined($cherry)) {
3377 $cherry = 0;
3378 }
3379
3380 my $end = "HEAD";
3381 if (defined($patchcheck_end)) {
3382 $end = $patchcheck_end;
3383 } elsif ($cherry) {
3384 die "PATCHCHECK_END must be defined with PATCHCHECK_CHERRY\n";
3385 }
3386
3387 # Get the true sha1's since we can use things like HEAD~3
3388 $start = get_sha1($start);
3389 $end = get_sha1($end);
3390
3391 my $type = $patchcheck_type;
3392
3393 # Can't have a test without having a test to run
3394 if ($type eq "test" && !defined($run_test)) {
3395 $type = "boot";
3396 }
3397
3398 if ($cherry) {
3399 open (IN, "git cherry -v $start $end|") or
3400 dodie "could not get git list";
3401 } else {
3402 open (IN, "git log --pretty=oneline $end|") or
3403 dodie "could not get git list";
3404 }
3405
3406 my @list;
3407
3408 while (<IN>) {
3409 chomp;
3410 # git cherry adds a '+' we want to remove
3411 s/^\+ //;
3412 $list[$#list+1] = $_;
3413 last if (/^$start/);
3414 }
3415 close(IN);
3416
3417 if (!$cherry) {
3418 if ($list[$#list] !~ /^$start/) {
3419 fail "SHA1 $start not found";
3420 }
3421
3422 # go backwards in the list
3423 @list = reverse @list;
3424 }
3425
3426 doprint("Going to test the following commits:\n");
3427 foreach my $l (@list) {
3428 doprint "$l\n";
3429 }
3430
3431 my $save_clean = $noclean;
3432 my %ignored_warnings;
3433
3434 if (defined($ignore_warnings)) {
3435 foreach my $sha1 (split /\s+/, $ignore_warnings) {
3436 $ignored_warnings{$sha1} = 1;
3437 }
3438 }
3439
3440 $in_patchcheck = 1;
3441 foreach my $item (@list) {
3442 my $sha1 = $item;
3443 $sha1 =~ s/^([[:xdigit:]]+).*/$1/;
3444
3445 doprint "\nProcessing commit $item\n\n";
3446
3447 run_command "git checkout $sha1" or
3448 die "Failed to checkout $sha1";
3449
3450 # only clean on the first and last patch
3451 if ($item eq $list[0] ||
3452 $item eq $list[$#list]) {
3453 $noclean = $save_clean;
3454 } else {
3455 $noclean = 1;
3456 }
3457
3458 if (defined($minconfig)) {
3459 build "useconfig:$minconfig" or return 0;
3460 } else {
3461 # ?? no config to use?
3462 build "oldconfig" or return 0;
3463 }
3464
3465 # No need to do per patch checking if warnings file exists
3466 if (!defined($warnings_file) && !defined($ignored_warnings{$sha1})) {
3467 check_patch_buildlog $sha1 or return 0;
3468 }
3469
3470 check_buildlog or return 0;
3471
3472 next if ($type eq "build");
3473
3474 my $failed = 0;
3475
3476 start_monitor_and_install or $failed = 1;
3477
3478 if (!$failed && $type ne "boot"){
3479 do_run_test or $failed = 1;
3480 }
3481 end_monitor;
3482 if ($failed) {
3483 print_times;
3484 return 0;
3485 }
3486 patchcheck_reboot;
3487 print_times;
3488 }
3489 $in_patchcheck = 0;
3490 success $i;
3491
3492 return 1;
3493 }
3494
3495 my %depends;
3496 my %depcount;
3497 my $iflevel = 0;
3498 my @ifdeps;
3499
3500 # prevent recursion
3501 my %read_kconfigs;
3502
3503 sub add_dep {
3504 # $config depends on $dep
3505 my ($config, $dep) = @_;
3506
3507 if (defined($depends{$config})) {
3508 $depends{$config} .= " " . $dep;
3509 } else {
3510 $depends{$config} = $dep;
3511 }
3512
3513 # record the number of configs depending on $dep
3514 if (defined $depcount{$dep}) {
3515 $depcount{$dep}++;
3516 } else {
3517 $depcount{$dep} = 1;
3518 }
3519 }
3520
3521 # taken from streamline_config.pl
3522 sub read_kconfig {
3523 my ($kconfig) = @_;
3524
3525 my $state = "NONE";
3526 my $config;
3527 my @kconfigs;
3528
3529 my $cont = 0;
3530 my $line;
3531
3532
3533 if (! -f $kconfig) {
3534 doprint "file $kconfig does not exist, skipping\n";
3535 return;
3536 }
3537
3538 open(KIN, "$kconfig")
3539 or die "Can't open $kconfig";
3540 while (<KIN>) {
3541 chomp;
3542
3543 # Make sure that lines ending with \ continue
3544 if ($cont) {
3545 $_ = $line . " " . $_;
3546 }
3547
3548 if (s/\\$//) {
3549 $cont = 1;
3550 $line = $_;
3551 next;
3552 }
3553
3554 $cont = 0;
3555
3556 # collect any Kconfig sources
3557 if (/^source\s*"(.*)"/) {
3558 $kconfigs[$#kconfigs+1] = $1;
3559 }
3560
3561 # configs found
3562 if (/^\s*(menu)?config\s+(\S+)\s*$/) {
3563 $state = "NEW";
3564 $config = $2;
3565
3566 for (my $i = 0; $i < $iflevel; $i++) {
3567 add_dep $config, $ifdeps[$i];
3568 }
3569
3570 # collect the depends for the config
3571 } elsif ($state eq "NEW" && /^\s*depends\s+on\s+(.*)$/) {
3572
3573 add_dep $config, $1;
3574
3575 # Get the configs that select this config
3576 } elsif ($state eq "NEW" && /^\s*select\s+(\S+)/) {
3577
3578 # selected by depends on config
3579 add_dep $1, $config;
3580
3581 # Check for if statements
3582 } elsif (/^if\s+(.*\S)\s*$/) {
3583 my $deps = $1;
3584 # remove beginning and ending non text
3585 $deps =~ s/^[^a-zA-Z0-9_]*//;
3586 $deps =~ s/[^a-zA-Z0-9_]*$//;
3587
3588 my @deps = split /[^a-zA-Z0-9_]+/, $deps;
3589
3590 $ifdeps[$iflevel++] = join ':', @deps;
3591
3592 } elsif (/^endif/) {
3593
3594 $iflevel-- if ($iflevel);
3595
3596 # stop on "help"
3597 } elsif (/^\s*help\s*$/) {
3598 $state = "NONE";
3599 }
3600 }
3601 close(KIN);
3602
3603 # read in any configs that were found.
3604 foreach $kconfig (@kconfigs) {
3605 if (!defined($read_kconfigs{$kconfig})) {
3606 $read_kconfigs{$kconfig} = 1;
3607 read_kconfig("$builddir/$kconfig");
3608 }
3609 }
3610 }
3611
3612 sub read_depends {
3613 # find out which arch this is by the kconfig file
3614 open (IN, $output_config)
3615 or dodie "Failed to read $output_config";
3616 my $arch;
3617 while (<IN>) {
3618 if (m,Linux/(\S+)\s+\S+\s+Kernel Configuration,) {
3619 $arch = $1;
3620 last;
3621 }
3622 }
3623 close IN;
3624
3625 if (!defined($arch)) {
3626 doprint "Could not find arch from config file\n";
3627 doprint "no dependencies used\n";
3628 return;
3629 }
3630
3631 # arch is really the subarch, we need to know
3632 # what directory to look at.
3633 if ($arch eq "i386" || $arch eq "x86_64") {
3634 $arch = "x86";
3635 } elsif ($arch =~ /^tile/) {
3636 $arch = "tile";
3637 }
3638
3639 my $kconfig = "$builddir/arch/$arch/Kconfig";
3640
3641 if (! -f $kconfig && $arch =~ /\d$/) {
3642 my $orig = $arch;
3643 # some subarchs have numbers, truncate them
3644 $arch =~ s/\d*$//;
3645 $kconfig = "$builddir/arch/$arch/Kconfig";
3646 if (! -f $kconfig) {
3647 doprint "No idea what arch dir $orig is for\n";
3648 doprint "no dependencies used\n";
3649 return;
3650 }
3651 }
3652
3653 read_kconfig($kconfig);
3654 }
3655
3656 sub make_new_config {
3657 my @configs = @_;
3658
3659 open (OUT, ">$output_config")
3660 or dodie "Failed to write $output_config";
3661
3662 foreach my $config (@configs) {
3663 print OUT "$config\n";
3664 }
3665 close OUT;
3666 }
3667
3668 sub chomp_config {
3669 my ($config) = @_;
3670
3671 $config =~ s/CONFIG_//;
3672
3673 return $config;
3674 }
3675
3676 sub get_depends {
3677 my ($dep) = @_;
3678
3679 my $kconfig = chomp_config $dep;
3680
3681 $dep = $depends{"$kconfig"};
3682
3683 # the dep string we have saves the dependencies as they
3684 # were found, including expressions like ! && ||. We
3685 # want to split this out into just an array of configs.
3686
3687 my $valid = "A-Za-z_0-9";
3688
3689 my @configs;
3690
3691 while ($dep =~ /[$valid]/) {
3692
3693 if ($dep =~ /^[^$valid]*([$valid]+)/) {
3694 my $conf = "CONFIG_" . $1;
3695
3696 $configs[$#configs + 1] = $conf;
3697
3698 $dep =~ s/^[^$valid]*[$valid]+//;
3699 } else {
3700 die "this should never happen";
3701 }
3702 }
3703
3704 return @configs;
3705 }
3706
3707 my %min_configs;
3708 my %keep_configs;
3709 my %save_configs;
3710 my %processed_configs;
3711 my %nochange_config;
3712
3713 sub test_this_config {
3714 my ($config) = @_;
3715
3716 my $found;
3717
3718 # if we already processed this config, skip it
3719 if (defined($processed_configs{$config})) {
3720 return undef;
3721 }
3722 $processed_configs{$config} = 1;
3723
3724 # if this config failed during this round, skip it
3725 if (defined($nochange_config{$config})) {
3726 return undef;
3727 }
3728
3729 my $kconfig = chomp_config $config;
3730
3731 # Test dependencies first
3732 if (defined($depends{"$kconfig"})) {
3733 my @parents = get_depends $config;
3734 foreach my $parent (@parents) {
3735 # if the parent is in the min config, check it first
3736 next if (!defined($min_configs{$parent}));
3737 $found = test_this_config($parent);
3738 if (defined($found)) {
3739 return $found;
3740 }
3741 }
3742 }
3743
3744 # Remove this config from the list of configs
3745 # do a make olddefconfig and then read the resulting
3746 # .config to make sure it is missing the config that
3747 # we had before
3748 my %configs = %min_configs;
3749 delete $configs{$config};
3750 make_new_config ((values %configs), (values %keep_configs));
3751 make_oldconfig;
3752 undef %configs;
3753 assign_configs \%configs, $output_config;
3754
3755 if (!defined($configs{$config}) || $configs{$config} =~ /^#/) {
3756 return $config;
3757 }
3758
3759 doprint "disabling config $config did not change .config\n";
3760
3761 $nochange_config{$config} = 1;
3762
3763 return undef;
3764 }
3765
3766 sub make_min_config {
3767 my ($i) = @_;
3768
3769 my $type = $minconfig_type;
3770 if ($type ne "boot" && $type ne "test") {
3771 fail "Invalid MIN_CONFIG_TYPE '$minconfig_type'\n" .
3772 " make_min_config works only with 'boot' and 'test'\n" and return;
3773 }
3774
3775 if (!defined($output_minconfig)) {
3776 fail "OUTPUT_MIN_CONFIG not defined" and return;
3777 }
3778
3779 # If output_minconfig exists, and the start_minconfig
3780 # came from min_config, than ask if we should use
3781 # that instead.
3782 if (-f $output_minconfig && !$start_minconfig_defined) {
3783 print "$output_minconfig exists\n";
3784 if (!defined($use_output_minconfig)) {
3785 if (read_yn " Use it as minconfig?") {
3786 $start_minconfig = $output_minconfig;
3787 }
3788 } elsif ($use_output_minconfig > 0) {
3789 doprint "Using $output_minconfig as MIN_CONFIG\n";
3790 $start_minconfig = $output_minconfig;
3791 } else {
3792 doprint "Set to still use MIN_CONFIG as starting point\n";
3793 }
3794 }
3795
3796 if (!defined($start_minconfig)) {
3797 fail "START_MIN_CONFIG or MIN_CONFIG not defined" and return;
3798 }
3799
3800 my $temp_config = "$tmpdir/temp_config";
3801
3802 # First things first. We build an allnoconfig to find
3803 # out what the defaults are that we can't touch.
3804 # Some are selections, but we really can't handle selections.
3805
3806 my $save_minconfig = $minconfig;
3807 undef $minconfig;
3808
3809 run_command "$make allnoconfig" or return 0;
3810
3811 read_depends;
3812
3813 process_config_ignore $output_config;
3814
3815 undef %save_configs;
3816 undef %min_configs;
3817
3818 if (defined($ignore_config)) {
3819 # make sure the file exists
3820 `touch $ignore_config`;
3821 assign_configs \%save_configs, $ignore_config;
3822 }
3823
3824 %keep_configs = %save_configs;
3825
3826 doprint "Load initial configs from $start_minconfig\n";
3827
3828 # Look at the current min configs, and save off all the
3829 # ones that were set via the allnoconfig
3830 assign_configs \%min_configs, $start_minconfig;
3831
3832 my @config_keys = keys %min_configs;
3833
3834 # All configs need a depcount
3835 foreach my $config (@config_keys) {
3836 my $kconfig = chomp_config $config;
3837 if (!defined $depcount{$kconfig}) {
3838 $depcount{$kconfig} = 0;
3839 }
3840 }
3841
3842 # Remove anything that was set by the make allnoconfig
3843 # we shouldn't need them as they get set for us anyway.
3844 foreach my $config (@config_keys) {
3845 # Remove anything in the ignore_config
3846 if (defined($keep_configs{$config})) {
3847 my $file = $ignore_config;
3848 $file =~ s,.*/(.*?)$,$1,;
3849 doprint "$config set by $file ... ignored\n";
3850 delete $min_configs{$config};
3851 next;
3852 }
3853 # But make sure the settings are the same. If a min config
3854 # sets a selection, we do not want to get rid of it if
3855 # it is not the same as what we have. Just move it into
3856 # the keep configs.
3857 if (defined($config_ignore{$config})) {
3858 if ($config_ignore{$config} ne $min_configs{$config}) {
3859 doprint "$config is in allnoconfig as '$config_ignore{$config}'";
3860 doprint " but it is '$min_configs{$config}' in minconfig .. keeping\n";
3861 $keep_configs{$config} = $min_configs{$config};
3862 } else {
3863 doprint "$config set by allnoconfig ... ignored\n";
3864 }
3865 delete $min_configs{$config};
3866 }
3867 }
3868
3869 my $done = 0;
3870 my $take_two = 0;
3871
3872 while (!$done) {
3873
3874 my $config;
3875 my $found;
3876
3877 # Now disable each config one by one and do a make oldconfig
3878 # till we find a config that changes our list.
3879
3880 my @test_configs = keys %min_configs;
3881
3882 # Sort keys by who is most dependent on
3883 @test_configs = sort { $depcount{chomp_config($b)} <=> $depcount{chomp_config($a)} }
3884 @test_configs ;
3885
3886 # Put configs that did not modify the config at the end.
3887 my $reset = 1;
3888 for (my $i = 0; $i < $#test_configs; $i++) {
3889 if (!defined($nochange_config{$test_configs[0]})) {
3890 $reset = 0;
3891 last;
3892 }
3893 # This config didn't change the .config last time.
3894 # Place it at the end
3895 my $config = shift @test_configs;
3896 push @test_configs, $config;
3897 }
3898
3899 # if every test config has failed to modify the .config file
3900 # in the past, then reset and start over.
3901 if ($reset) {
3902 undef %nochange_config;
3903 }
3904
3905 undef %processed_configs;
3906
3907 foreach my $config (@test_configs) {
3908
3909 $found = test_this_config $config;
3910
3911 last if (defined($found));
3912
3913 # oh well, try another config
3914 }
3915
3916 if (!defined($found)) {
3917 # we could have failed due to the nochange_config hash
3918 # reset and try again
3919 if (!$take_two) {
3920 undef %nochange_config;
3921 $take_two = 1;
3922 next;
3923 }
3924 doprint "No more configs found that we can disable\n";
3925 $done = 1;
3926 last;
3927 }
3928 $take_two = 0;
3929
3930 $config = $found;
3931
3932 doprint "Test with $config disabled\n";
3933
3934 # set in_bisect to keep build and monitor from dieing
3935 $in_bisect = 1;
3936
3937 my $failed = 0;
3938 build "oldconfig" or $failed = 1;
3939 if (!$failed) {
3940 start_monitor_and_install or $failed = 1;
3941
3942 if ($type eq "test" && !$failed) {
3943 do_run_test or $failed = 1;
3944 }
3945
3946 end_monitor;
3947 }
3948
3949 $in_bisect = 0;
3950
3951 if ($failed) {
3952 doprint "$min_configs{$config} is needed to boot the box... keeping\n";
3953 # this config is needed, add it to the ignore list.
3954 $keep_configs{$config} = $min_configs{$config};
3955 $save_configs{$config} = $min_configs{$config};
3956 delete $min_configs{$config};
3957
3958 # update new ignore configs
3959 if (defined($ignore_config)) {
3960 open (OUT, ">$temp_config")
3961 or die "Can't write to $temp_config";
3962 foreach my $config (keys %save_configs) {
3963 print OUT "$save_configs{$config}\n";
3964 }
3965 close OUT;
3966 run_command "mv $temp_config $ignore_config" or
3967 dodie "failed to copy update to $ignore_config";
3968 }
3969
3970 } else {
3971 # We booted without this config, remove it from the minconfigs.
3972 doprint "$config is not needed, disabling\n";
3973
3974 delete $min_configs{$config};
3975
3976 # Also disable anything that is not enabled in this config
3977 my %configs;
3978 assign_configs \%configs, $output_config;
3979 my @config_keys = keys %min_configs;
3980 foreach my $config (@config_keys) {
3981 if (!defined($configs{$config})) {
3982 doprint "$config is not set, disabling\n";
3983 delete $min_configs{$config};
3984 }
3985 }
3986
3987 # Save off all the current mandidory configs
3988 open (OUT, ">$temp_config")
3989 or die "Can't write to $temp_config";
3990 foreach my $config (keys %keep_configs) {
3991 print OUT "$keep_configs{$config}\n";
3992 }
3993 foreach my $config (keys %min_configs) {
3994 print OUT "$min_configs{$config}\n";
3995 }
3996 close OUT;
3997
3998 run_command "mv $temp_config $output_minconfig" or
3999 dodie "failed to copy update to $output_minconfig";
4000 }
4001
4002 doprint "Reboot and wait $sleep_time seconds\n";
4003 reboot_to_good $sleep_time;
4004 }
4005
4006 success $i;
4007 return 1;
4008 }
4009
4010 sub make_warnings_file {
4011 my ($i) = @_;
4012
4013 if (!defined($warnings_file)) {
4014 dodie "Must define WARNINGS_FILE for make_warnings_file test";
4015 }
4016
4017 if ($build_type eq "nobuild") {
4018 dodie "BUILD_TYPE can not be 'nobuild' for make_warnings_file test";
4019 }
4020
4021 build $build_type or dodie "Failed to build";
4022
4023 open(OUT, ">$warnings_file") or dodie "Can't create $warnings_file";
4024
4025 open(IN, $buildlog) or dodie "Can't open $buildlog";
4026 while (<IN>) {
4027
4028 # Some compilers use UTF-8 extended for quotes
4029 # for distcc heterogeneous systems, this causes issues
4030 s/$utf8_quote/'/g;
4031
4032 if (/$check_build_re/) {
4033 print OUT;
4034 }
4035 }
4036 close(IN);
4037
4038 close(OUT);
4039
4040 success $i;
4041 }
4042
4043 $#ARGV < 1 or die "ktest.pl version: $VERSION\n usage: ktest.pl [config-file]\n";
4044
4045 if ($#ARGV == 0) {
4046 $ktest_config = $ARGV[0];
4047 if (! -f $ktest_config) {
4048 print "$ktest_config does not exist.\n";
4049 if (!read_yn "Create it?") {
4050 exit 0;
4051 }
4052 }
4053 }
4054
4055 if (! -f $ktest_config) {
4056 $newconfig = 1;
4057 get_test_case;
4058 open(OUT, ">$ktest_config") or die "Can not create $ktest_config";
4059 print OUT << "EOF"
4060 # Generated by ktest.pl
4061 #
4062
4063 # PWD is a ktest.pl variable that will result in the process working
4064 # directory that ktest.pl is executed in.
4065
4066 # THIS_DIR is automatically assigned the PWD of the path that generated
4067 # the config file. It is best to use this variable when assigning other
4068 # directory paths within this directory. This allows you to easily
4069 # move the test cases to other locations or to other machines.
4070 #
4071 THIS_DIR := $variable{"PWD"}
4072
4073 # Define each test with TEST_START
4074 # The config options below it will override the defaults
4075 TEST_START
4076 TEST_TYPE = $default{"TEST_TYPE"}
4077
4078 DEFAULTS
4079 EOF
4080 ;
4081 close(OUT);
4082 }
4083 read_config $ktest_config;
4084
4085 if (defined($opt{"LOG_FILE"})) {
4086 $opt{"LOG_FILE"} = eval_option("LOG_FILE", $opt{"LOG_FILE"}, -1);
4087 }
4088
4089 # Append any configs entered in manually to the config file.
4090 my @new_configs = keys %entered_configs;
4091 if ($#new_configs >= 0) {
4092 print "\nAppending entered in configs to $ktest_config\n";
4093 open(OUT, ">>$ktest_config") or die "Can not append to $ktest_config";
4094 foreach my $config (@new_configs) {
4095 print OUT "$config = $entered_configs{$config}\n";
4096 $opt{$config} = process_variables($entered_configs{$config});
4097 }
4098 }
4099
4100 if ($opt{"CLEAR_LOG"} && defined($opt{"LOG_FILE"})) {
4101 unlink $opt{"LOG_FILE"};
4102 }
4103
4104 doprint "\n\nSTARTING AUTOMATED TESTS\n\n";
4105
4106 for (my $i = 0, my $repeat = 1; $i <= $opt{"NUM_TESTS"}; $i += $repeat) {
4107
4108 if (!$i) {
4109 doprint "DEFAULT OPTIONS:\n";
4110 } else {
4111 doprint "\nTEST $i OPTIONS";
4112 if (defined($repeat_tests{$i})) {
4113 $repeat = $repeat_tests{$i};
4114 doprint " ITERATE $repeat";
4115 }
4116 doprint "\n";
4117 }
4118
4119 foreach my $option (sort keys %opt) {
4120
4121 if ($option =~ /\[(\d+)\]$/) {
4122 next if ($i != $1);
4123 } else {
4124 next if ($i);
4125 }
4126
4127 doprint "$option = $opt{$option}\n";
4128 }
4129 }
4130
4131 sub option_defined {
4132 my ($option) = @_;
4133
4134 if (defined($opt{$option}) && $opt{$option} !~ /^\s*$/) {
4135 return 1;
4136 }
4137
4138 return 0;
4139 }
4140
4141 sub __set_test_option {
4142 my ($name, $i) = @_;
4143
4144 my $option = "$name\[$i\]";
4145
4146 if (option_defined($option)) {
4147 return $opt{$option};
4148 }
4149
4150 foreach my $test (keys %repeat_tests) {
4151 if ($i >= $test &&
4152 $i < $test + $repeat_tests{$test}) {
4153 $option = "$name\[$test\]";
4154 if (option_defined($option)) {
4155 return $opt{$option};
4156 }
4157 }
4158 }
4159
4160 if (option_defined($name)) {
4161 return $opt{$name};
4162 }
4163
4164 return undef;
4165 }
4166
4167 sub set_test_option {
4168 my ($name, $i) = @_;
4169
4170 my $option = __set_test_option($name, $i);
4171 return $option if (!defined($option));
4172
4173 return eval_option($name, $option, $i);
4174 }
4175
4176 # First we need to do is the builds
4177 for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
4178
4179 # Do not reboot on failing test options
4180 $no_reboot = 1;
4181 $reboot_success = 0;
4182
4183 $have_version = 0;
4184
4185 $iteration = $i;
4186
4187 $build_time = 0;
4188 $install_time = 0;
4189 $reboot_time = 0;
4190 $test_time = 0;
4191
4192 undef %force_config;
4193
4194 my $makecmd = set_test_option("MAKE_CMD", $i);
4195
4196 $outputdir = set_test_option("OUTPUT_DIR", $i);
4197 $builddir = set_test_option("BUILD_DIR", $i);
4198
4199 chdir $builddir || die "can't change directory to $builddir";
4200
4201 if (!-d $outputdir) {
4202 mkpath($outputdir) or
4203 die "can't create $outputdir";
4204 }
4205
4206 $make = "$makecmd O=$outputdir";
4207
4208 # Load all the options into their mapped variable names
4209 foreach my $opt (keys %option_map) {
4210 ${$option_map{$opt}} = set_test_option($opt, $i);
4211 }
4212
4213 $start_minconfig_defined = 1;
4214
4215 # The first test may override the PRE_KTEST option
4216 if (defined($pre_ktest) && $i == 1) {
4217 doprint "\n";
4218 run_command $pre_ktest;
4219 }
4220
4221 # Any test can override the POST_KTEST option
4222 # The last test takes precedence.
4223 if (defined($post_ktest)) {
4224 $final_post_ktest = $post_ktest;
4225 }
4226
4227 if (!defined($start_minconfig)) {
4228 $start_minconfig_defined = 0;
4229 $start_minconfig = $minconfig;
4230 }
4231
4232 if (!-d $tmpdir) {
4233 mkpath($tmpdir) or
4234 die "can't create $tmpdir";
4235 }
4236
4237 $ENV{"SSH_USER"} = $ssh_user;
4238 $ENV{"MACHINE"} = $machine;
4239
4240 $buildlog = "$tmpdir/buildlog-$machine";
4241 $testlog = "$tmpdir/testlog-$machine";
4242 $dmesg = "$tmpdir/dmesg-$machine";
4243 $output_config = "$outputdir/.config";
4244
4245 if (!$buildonly) {
4246 $target = "$ssh_user\@$machine";
4247 if ($reboot_type eq "grub") {
4248 dodie "GRUB_MENU not defined" if (!defined($grub_menu));
4249 } elsif ($reboot_type eq "grub2") {
4250 dodie "GRUB_MENU not defined" if (!defined($grub_menu));
4251 dodie "GRUB_FILE not defined" if (!defined($grub_file));
4252 } elsif ($reboot_type eq "syslinux") {
4253 dodie "SYSLINUX_LABEL not defined" if (!defined($syslinux_label));
4254 }
4255 }
4256
4257 my $run_type = $build_type;
4258 if ($test_type eq "patchcheck") {
4259 $run_type = $patchcheck_type;
4260 } elsif ($test_type eq "bisect") {
4261 $run_type = $bisect_type;
4262 } elsif ($test_type eq "config_bisect") {
4263 $run_type = $config_bisect_type;
4264 } elsif ($test_type eq "make_min_config") {
4265 $run_type = "";
4266 } elsif ($test_type eq "make_warnings_file") {
4267 $run_type = "";
4268 }
4269
4270 # mistake in config file?
4271 if (!defined($run_type)) {
4272 $run_type = "ERROR";
4273 }
4274
4275 my $installme = "";
4276 $installme = " no_install" if ($no_install);
4277
4278 my $name = "";
4279
4280 if (defined($test_name)) {
4281 $name = " ($test_name)";
4282 }
4283
4284 doprint "\n\n";
4285 doprint "RUNNING TEST $i of $opt{NUM_TESTS}$name with option $test_type $run_type$installme\n\n";
4286
4287 if (defined($pre_test)) {
4288 run_command $pre_test;
4289 }
4290
4291 unlink $dmesg;
4292 unlink $buildlog;
4293 unlink $testlog;
4294
4295 if (defined($addconfig)) {
4296 my $min = $minconfig;
4297 if (!defined($minconfig)) {
4298 $min = "";
4299 }
4300 run_command "cat $addconfig $min > $tmpdir/add_config" or
4301 dodie "Failed to create temp config";
4302 $minconfig = "$tmpdir/add_config";
4303 }
4304
4305 if (defined($checkout)) {
4306 run_command "git checkout $checkout" or
4307 die "failed to checkout $checkout";
4308 }
4309
4310 $no_reboot = 0;
4311
4312 # A test may opt to not reboot the box
4313 if ($reboot_on_success) {
4314 $reboot_success = 1;
4315 }
4316
4317 if ($test_type eq "bisect") {
4318 bisect $i;
4319 next;
4320 } elsif ($test_type eq "config_bisect") {
4321 config_bisect $i;
4322 next;
4323 } elsif ($test_type eq "patchcheck") {
4324 patchcheck $i;
4325 next;
4326 } elsif ($test_type eq "make_min_config") {
4327 make_min_config $i;
4328 next;
4329 } elsif ($test_type eq "make_warnings_file") {
4330 $no_reboot = 1;
4331 make_warnings_file $i;
4332 next;
4333 }
4334
4335 if ($build_type ne "nobuild") {
4336 build $build_type or next;
4337 check_buildlog or next;
4338 }
4339
4340 if ($test_type eq "install") {
4341 get_version;
4342 install;
4343 success $i;
4344 next;
4345 }
4346
4347 if ($test_type ne "build") {
4348 my $failed = 0;
4349 start_monitor_and_install or $failed = 1;
4350
4351 if (!$failed && $test_type ne "boot" && defined($run_test)) {
4352 do_run_test or $failed = 1;
4353 }
4354 end_monitor;
4355 if ($failed) {
4356 print_times;
4357 next;
4358 }
4359 }
4360
4361 print_times;
4362
4363 success $i;
4364 }
4365
4366 if (defined($final_post_ktest)) {
4367 run_command $final_post_ktest;
4368 }
4369
4370 if ($opt{"POWEROFF_ON_SUCCESS"}) {
4371 halt;
4372 } elsif ($opt{"REBOOT_ON_SUCCESS"} && !do_not_reboot && $reboot_success) {
4373 reboot_to_good;
4374 } elsif (defined($switch_to_good)) {
4375 # still need to get to the good kernel
4376 run_command $switch_to_good;
4377 }
4378
4379
4380 doprint "\n $successes of $opt{NUM_TESTS} tests were successful\n\n";
4381
4382 exit 0;
This page took 0.153699 seconds and 5 git commands to generate.