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