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