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