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