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