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