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