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