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