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