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