xref: /openbmc/linux/tools/testing/ktest/ktest.pl (revision 9064af5206c26ce0d47621fef216b0c43d65d693)
12545eb61SSteven Rostedt#!/usr/bin/perl -w
2d6ce2a0bSSteven Rostedt#
3cce1dac8SUwe Kleine-König# Copyright 2010 - Steven Rostedt <srostedt@redhat.com>, Red Hat Inc.
4d6ce2a0bSSteven Rostedt# Licensed under the terms of the GNU GPL License version 2
5d6ce2a0bSSteven Rostedt#
62545eb61SSteven Rostedt
72545eb61SSteven Rostedtuse strict;
82545eb61SSteven Rostedtuse IPC::Open2;
92545eb61SSteven Rostedtuse Fcntl qw(F_GETFL F_SETFL O_NONBLOCK);
107faafbd6SSteven Rostedtuse File::Path qw(mkpath);
117faafbd6SSteven Rostedtuse File::Copy qw(cp);
122545eb61SSteven Rostedtuse FileHandle;
132545eb61SSteven Rostedt
14e48c5293SSteven Rostedtmy $VERSION = "0.2";
15e48c5293SSteven Rostedt
162545eb61SSteven Rostedt$| = 1;
172545eb61SSteven Rostedt
182545eb61SSteven Rostedtmy %opt;
19a57419b3SSteven Rostedtmy %repeat_tests;
20a57419b3SSteven Rostedtmy %repeats;
21a75fececSSteven Rostedtmy %default;
222545eb61SSteven Rostedt
232545eb61SSteven Rostedt#default opts
24a57419b3SSteven Rostedt$default{"NUM_TESTS"}		= 1;
25a75fececSSteven Rostedt$default{"REBOOT_TYPE"}		= "grub";
26a75fececSSteven Rostedt$default{"TEST_TYPE"}		= "test";
27a75fececSSteven Rostedt$default{"BUILD_TYPE"}		= "randconfig";
28a75fececSSteven Rostedt$default{"MAKE_CMD"}		= "make";
29a75fececSSteven Rostedt$default{"TIMEOUT"}		= 120;
30a57419b3SSteven Rostedt$default{"TMP_DIR"}		= "/tmp/ktest";
31a75fececSSteven Rostedt$default{"SLEEP_TIME"}		= 60;	# sleep time between tests
32a75fececSSteven Rostedt$default{"BUILD_NOCLEAN"}	= 0;
33a75fececSSteven Rostedt$default{"REBOOT_ON_ERROR"}	= 0;
34a75fececSSteven Rostedt$default{"POWEROFF_ON_ERROR"}	= 0;
35a75fececSSteven Rostedt$default{"REBOOT_ON_SUCCESS"}	= 1;
36a75fececSSteven Rostedt$default{"POWEROFF_ON_SUCCESS"}	= 0;
37a75fececSSteven Rostedt$default{"BUILD_OPTIONS"}	= "";
38a75fececSSteven Rostedt$default{"BISECT_SLEEP_TIME"}	= 60;   # sleep time between bisects
3927d934b2SSteven Rostedt$default{"PATCHCHECK_SLEEP_TIME"} = 60; # sleep time between patch checks
40a75fececSSteven Rostedt$default{"CLEAR_LOG"}		= 0;
41c960bb9fSSteven Rostedt$default{"BISECT_MANUAL"}	= 0;
42c23dca7cSSteven Rostedt$default{"BISECT_SKIP"}		= 1;
43a75fececSSteven Rostedt$default{"SUCCESS_LINE"}	= "login:";
44f1a5b962SSteven Rostedt$default{"DETECT_TRIPLE_FAULT"} = 1;
45a75fececSSteven Rostedt$default{"BOOTED_TIMEOUT"}	= 1;
46a75fececSSteven Rostedt$default{"DIE_ON_FAILURE"}	= 1;
47e48c5293SSteven Rostedt$default{"SSH_EXEC"}		= "ssh \$SSH_USER\@\$MACHINE \$SSH_COMMAND";
48e48c5293SSteven Rostedt$default{"SCP_TO_TARGET"}	= "scp \$SRC_FILE \$SSH_USER\@\$MACHINE:\$DST_FILE";
49e48c5293SSteven Rostedt$default{"REBOOT"}		= "ssh \$SSH_USER\@\$MACHINE reboot";
501c8a617aSSteven Rostedt$default{"STOP_AFTER_SUCCESS"}	= 10;
511c8a617aSSteven Rostedt$default{"STOP_AFTER_FAILURE"}	= 60;
522d01b26aSSteven Rostedt$default{"STOP_TEST_AFTER"}	= 600;
538d1491baSSteven Rostedt$default{"LOCALVERSION"}	= "-test";
542545eb61SSteven Rostedt
558d1491baSSteven Rostedtmy $ktest_config;
562545eb61SSteven Rostedtmy $version;
57a75fececSSteven Rostedtmy $machine;
58e48c5293SSteven Rostedtmy $ssh_user;
59a75fececSSteven Rostedtmy $tmpdir;
60a75fececSSteven Rostedtmy $builddir;
61a75fececSSteven Rostedtmy $outputdir;
6251ad1dd1SSteven Rostedtmy $output_config;
63a75fececSSteven Rostedtmy $test_type;
647faafbd6SSteven Rostedtmy $build_type;
65a75fececSSteven Rostedtmy $build_options;
66a75fececSSteven Rostedtmy $reboot_type;
67a75fececSSteven Rostedtmy $reboot_script;
68a75fececSSteven Rostedtmy $power_cycle;
69e48c5293SSteven Rostedtmy $reboot;
70a75fececSSteven Rostedtmy $reboot_on_error;
71a75fececSSteven Rostedtmy $poweroff_on_error;
72a75fececSSteven Rostedtmy $die_on_failure;
73576f627cSSteven Rostedtmy $powercycle_after_reboot;
74576f627cSSteven Rostedtmy $poweroff_after_halt;
75e48c5293SSteven Rostedtmy $ssh_exec;
76e48c5293SSteven Rostedtmy $scp_to_target;
77a75fececSSteven Rostedtmy $power_off;
78a75fececSSteven Rostedtmy $grub_menu;
792545eb61SSteven Rostedtmy $grub_number;
802545eb61SSteven Rostedtmy $target;
812545eb61SSteven Rostedtmy $make;
828b37ca8cSSteven Rostedtmy $post_install;
835c42fc5bSSteven Rostedtmy $noclean;
845f9b6cedSSteven Rostedtmy $minconfig;
852b7d9b21SSteven Rostedtmy $addconfig;
865f9b6cedSSteven Rostedtmy $in_bisect = 0;
875f9b6cedSSteven Rostedtmy $bisect_bad = "";
88d6ce2a0bSSteven Rostedtmy $reverse_bisect;
89c960bb9fSSteven Rostedtmy $bisect_manual;
90c23dca7cSSteven Rostedtmy $bisect_skip;
9130f75da5SSteven Rostedtmy $config_bisect_good;
926c5ee0beSSteven Rostedtmy $in_patchcheck = 0;
935a391fbfSSteven Rostedtmy $run_test;
946c5ee0beSSteven Rostedtmy $redirect;
957faafbd6SSteven Rostedtmy $buildlog;
967faafbd6SSteven Rostedtmy $dmesg;
977faafbd6SSteven Rostedtmy $monitor_fp;
987faafbd6SSteven Rostedtmy $monitor_pid;
997faafbd6SSteven Rostedtmy $monitor_cnt = 0;
100a75fececSSteven Rostedtmy $sleep_time;
101a75fececSSteven Rostedtmy $bisect_sleep_time;
10227d934b2SSteven Rostedtmy $patchcheck_sleep_time;
103a75fececSSteven Rostedtmy $store_failures;
104*9064af52SSteven Rostedtmy $test_name;
105a75fececSSteven Rostedtmy $timeout;
106a75fececSSteven Rostedtmy $booted_timeout;
107f1a5b962SSteven Rostedtmy $detect_triplefault;
108a75fececSSteven Rostedtmy $console;
109a75fececSSteven Rostedtmy $success_line;
1101c8a617aSSteven Rostedtmy $stop_after_success;
1111c8a617aSSteven Rostedtmy $stop_after_failure;
1122d01b26aSSteven Rostedtmy $stop_test_after;
113a75fececSSteven Rostedtmy $build_target;
114a75fececSSteven Rostedtmy $target_image;
115a75fececSSteven Rostedtmy $localversion;
116576f627cSSteven Rostedtmy $iteration = 0;
117e48c5293SSteven Rostedtmy $successes = 0;
1182545eb61SSteven Rostedt
1198d1491baSSteven Rostedtmy %entered_configs;
1208d1491baSSteven Rostedtmy %config_help;
12177d942ceSSteven Rostedtmy %variable;
1228d1491baSSteven Rostedt
1238d1491baSSteven Rostedt$config_help{"MACHINE"} = << "EOF"
1248d1491baSSteven Rostedt The machine hostname that you will test.
1258d1491baSSteven RostedtEOF
1268d1491baSSteven Rostedt    ;
1278d1491baSSteven Rostedt$config_help{"SSH_USER"} = << "EOF"
1288d1491baSSteven Rostedt The box is expected to have ssh on normal bootup, provide the user
1298d1491baSSteven Rostedt  (most likely root, since you need privileged operations)
1308d1491baSSteven RostedtEOF
1318d1491baSSteven Rostedt    ;
1328d1491baSSteven Rostedt$config_help{"BUILD_DIR"} = << "EOF"
1338d1491baSSteven Rostedt The directory that contains the Linux source code (full path).
1348d1491baSSteven RostedtEOF
1358d1491baSSteven Rostedt    ;
1368d1491baSSteven Rostedt$config_help{"OUTPUT_DIR"} = << "EOF"
1378d1491baSSteven Rostedt The directory that the objects will be built (full path).
1388d1491baSSteven Rostedt (can not be same as BUILD_DIR)
1398d1491baSSteven RostedtEOF
1408d1491baSSteven Rostedt    ;
1418d1491baSSteven Rostedt$config_help{"BUILD_TARGET"} = << "EOF"
1428d1491baSSteven Rostedt The location of the compiled file to copy to the target.
1438d1491baSSteven Rostedt (relative to OUTPUT_DIR)
1448d1491baSSteven RostedtEOF
1458d1491baSSteven Rostedt    ;
1468d1491baSSteven Rostedt$config_help{"TARGET_IMAGE"} = << "EOF"
1478d1491baSSteven Rostedt The place to put your image on the test machine.
1488d1491baSSteven RostedtEOF
1498d1491baSSteven Rostedt    ;
1508d1491baSSteven Rostedt$config_help{"POWER_CYCLE"} = << "EOF"
1518d1491baSSteven Rostedt A script or command to reboot the box.
1528d1491baSSteven Rostedt
1538d1491baSSteven Rostedt Here is a digital loggers power switch example
1548d1491baSSteven Rostedt POWER_CYCLE = wget --no-proxy -O /dev/null -q  --auth-no-challenge 'http://admin:admin\@power/outlet?5=CCL'
1558d1491baSSteven Rostedt
1568d1491baSSteven Rostedt Here is an example to reboot a virtual box on the current host
1578d1491baSSteven Rostedt with the name "Guest".
1588d1491baSSteven Rostedt POWER_CYCLE = virsh destroy Guest; sleep 5; virsh start Guest
1598d1491baSSteven RostedtEOF
1608d1491baSSteven Rostedt    ;
1618d1491baSSteven Rostedt$config_help{"CONSOLE"} = << "EOF"
1628d1491baSSteven Rostedt The script or command that reads the console
1638d1491baSSteven Rostedt
1648d1491baSSteven Rostedt  If you use ttywatch server, something like the following would work.
1658d1491baSSteven RostedtCONSOLE = nc -d localhost 3001
1668d1491baSSteven Rostedt
1678d1491baSSteven Rostedt For a virtual machine with guest name "Guest".
1688d1491baSSteven RostedtCONSOLE =  virsh console Guest
1698d1491baSSteven RostedtEOF
1708d1491baSSteven Rostedt    ;
1718d1491baSSteven Rostedt$config_help{"LOCALVERSION"} = << "EOF"
1728d1491baSSteven Rostedt Required version ending to differentiate the test
1738d1491baSSteven Rostedt from other linux builds on the system.
1748d1491baSSteven RostedtEOF
1758d1491baSSteven Rostedt    ;
1768d1491baSSteven Rostedt$config_help{"REBOOT_TYPE"} = << "EOF"
1778d1491baSSteven Rostedt Way to reboot the box to the test kernel.
1788d1491baSSteven Rostedt Only valid options so far are "grub" and "script".
1798d1491baSSteven Rostedt
1808d1491baSSteven Rostedt If you specify grub, it will assume grub version 1
1818d1491baSSteven Rostedt and will search in /boot/grub/menu.lst for the title \$GRUB_MENU
1828d1491baSSteven Rostedt and select that target to reboot to the kernel. If this is not
1838d1491baSSteven Rostedt your setup, then specify "script" and have a command or script
1848d1491baSSteven Rostedt specified in REBOOT_SCRIPT to boot to the target.
1858d1491baSSteven Rostedt
1868d1491baSSteven Rostedt The entry in /boot/grub/menu.lst must be entered in manually.
1878d1491baSSteven Rostedt The test will not modify that file.
1888d1491baSSteven RostedtEOF
1898d1491baSSteven Rostedt    ;
1908d1491baSSteven Rostedt$config_help{"GRUB_MENU"} = << "EOF"
1918d1491baSSteven Rostedt The grub title name for the test kernel to boot
1928d1491baSSteven Rostedt (Only mandatory if REBOOT_TYPE = grub)
1938d1491baSSteven Rostedt
1948d1491baSSteven Rostedt Note, ktest.pl will not update the grub menu.lst, you need to
1958d1491baSSteven Rostedt manually add an option for the test. ktest.pl will search
1968d1491baSSteven Rostedt the grub menu.lst for this option to find what kernel to
1978d1491baSSteven Rostedt reboot into.
1988d1491baSSteven Rostedt
1998d1491baSSteven Rostedt For example, if in the /boot/grub/menu.lst the test kernel title has:
2008d1491baSSteven Rostedt title Test Kernel
2018d1491baSSteven Rostedt kernel vmlinuz-test
2028d1491baSSteven Rostedt GRUB_MENU = Test Kernel
2038d1491baSSteven RostedtEOF
2048d1491baSSteven Rostedt    ;
2058d1491baSSteven Rostedt$config_help{"REBOOT_SCRIPT"} = << "EOF"
2068d1491baSSteven Rostedt A script to reboot the target into the test kernel
2078d1491baSSteven Rostedt (Only mandatory if REBOOT_TYPE = script)
2088d1491baSSteven RostedtEOF
2098d1491baSSteven Rostedt    ;
2108d1491baSSteven Rostedt
2118d1491baSSteven Rostedt
2128d1491baSSteven Rostedtsub get_ktest_config {
2138d1491baSSteven Rostedt    my ($config) = @_;
2148d1491baSSteven Rostedt
2158d1491baSSteven Rostedt    return if (defined($opt{$config}));
2168d1491baSSteven Rostedt
2178d1491baSSteven Rostedt    if (defined($config_help{$config})) {
2188d1491baSSteven Rostedt	print "\n";
2198d1491baSSteven Rostedt	print $config_help{$config};
2208d1491baSSteven Rostedt    }
2218d1491baSSteven Rostedt
2228d1491baSSteven Rostedt    for (;;) {
2238d1491baSSteven Rostedt	print "$config = ";
2248d1491baSSteven Rostedt	if (defined($default{$config})) {
2258d1491baSSteven Rostedt	    print "\[$default{$config}\] ";
2268d1491baSSteven Rostedt	}
2278d1491baSSteven Rostedt	$entered_configs{$config} = <STDIN>;
2288d1491baSSteven Rostedt	$entered_configs{$config} =~ s/^\s*(.*\S)\s*$/$1/;
2298d1491baSSteven Rostedt	if ($entered_configs{$config} =~ /^\s*$/) {
2308d1491baSSteven Rostedt	    if ($default{$config}) {
2318d1491baSSteven Rostedt		$entered_configs{$config} = $default{$config};
2328d1491baSSteven Rostedt	    } else {
2338d1491baSSteven Rostedt		print "Your answer can not be blank\n";
2348d1491baSSteven Rostedt		next;
2358d1491baSSteven Rostedt	    }
2368d1491baSSteven Rostedt	}
2378d1491baSSteven Rostedt	last;
2388d1491baSSteven Rostedt    }
2398d1491baSSteven Rostedt}
2408d1491baSSteven Rostedt
2418d1491baSSteven Rostedtsub get_ktest_configs {
2428d1491baSSteven Rostedt    get_ktest_config("MACHINE");
2438d1491baSSteven Rostedt    get_ktest_config("SSH_USER");
2448d1491baSSteven Rostedt    get_ktest_config("BUILD_DIR");
2458d1491baSSteven Rostedt    get_ktest_config("OUTPUT_DIR");
2468d1491baSSteven Rostedt    get_ktest_config("BUILD_TARGET");
2478d1491baSSteven Rostedt    get_ktest_config("TARGET_IMAGE");
2488d1491baSSteven Rostedt    get_ktest_config("POWER_CYCLE");
2498d1491baSSteven Rostedt    get_ktest_config("CONSOLE");
2508d1491baSSteven Rostedt    get_ktest_config("LOCALVERSION");
2518d1491baSSteven Rostedt
2528d1491baSSteven Rostedt    my $rtype = $opt{"REBOOT_TYPE"};
2538d1491baSSteven Rostedt
2548d1491baSSteven Rostedt    if (!defined($rtype)) {
2558d1491baSSteven Rostedt	if (!defined($opt{"GRUB_MENU"})) {
2568d1491baSSteven Rostedt	    get_ktest_config("REBOOT_TYPE");
2578d1491baSSteven Rostedt	    $rtype = $entered_configs{"REBOOT_TYPE"};
2588d1491baSSteven Rostedt	} else {
2598d1491baSSteven Rostedt	    $rtype = "grub";
2608d1491baSSteven Rostedt	}
2618d1491baSSteven Rostedt    }
2628d1491baSSteven Rostedt
2638d1491baSSteven Rostedt    if ($rtype eq "grub") {
2648d1491baSSteven Rostedt	get_ktest_config("GRUB_MENU");
2658d1491baSSteven Rostedt    } else {
2668d1491baSSteven Rostedt	get_ktest_config("REBOOT_SCRIPT");
2678d1491baSSteven Rostedt    }
2688d1491baSSteven Rostedt}
2698d1491baSSteven Rostedt
27077d942ceSSteven Rostedtsub process_variables {
27177d942ceSSteven Rostedt    my ($value) = @_;
27277d942ceSSteven Rostedt    my $retval = "";
27377d942ceSSteven Rostedt
27477d942ceSSteven Rostedt    # We want to check for '\', and it is just easier
27577d942ceSSteven Rostedt    # to check the previous characet of '$' and not need
27677d942ceSSteven Rostedt    # to worry if '$' is the first character. By adding
27777d942ceSSteven Rostedt    # a space to $value, we can just check [^\\]\$ and
27877d942ceSSteven Rostedt    # it will still work.
27977d942ceSSteven Rostedt    $value = " $value";
28077d942ceSSteven Rostedt
28177d942ceSSteven Rostedt    while ($value =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) {
28277d942ceSSteven Rostedt	my $begin = $1;
28377d942ceSSteven Rostedt	my $var = $2;
28477d942ceSSteven Rostedt	my $end = $3;
28577d942ceSSteven Rostedt	# append beginning of value to retval
28677d942ceSSteven Rostedt	$retval = "$retval$begin";
28777d942ceSSteven Rostedt	if (defined($variable{$var})) {
28877d942ceSSteven Rostedt	    $retval = "$retval$variable{$var}";
28977d942ceSSteven Rostedt	} else {
29077d942ceSSteven Rostedt	    # put back the origin piece.
29177d942ceSSteven Rostedt	    $retval = "$retval\$\{$var\}";
29277d942ceSSteven Rostedt	}
29377d942ceSSteven Rostedt	$value = $end;
29477d942ceSSteven Rostedt    }
29577d942ceSSteven Rostedt    $retval = "$retval$value";
29677d942ceSSteven Rostedt
29777d942ceSSteven Rostedt    # remove the space added in the beginning
29877d942ceSSteven Rostedt    $retval =~ s/ //;
29977d942ceSSteven Rostedt
30077d942ceSSteven Rostedt    return "$retval"
30177d942ceSSteven Rostedt}
30277d942ceSSteven Rostedt
303a57419b3SSteven Rostedtsub set_value {
304a57419b3SSteven Rostedt    my ($lvalue, $rvalue) = @_;
3052545eb61SSteven Rostedt
306a75fececSSteven Rostedt    if (defined($opt{$lvalue})) {
307a75fececSSteven Rostedt	die "Error: Option $lvalue defined more than once!\n";
308a75fececSSteven Rostedt    }
30921a9679fSSteven Rostedt    if ($rvalue =~ /^\s*$/) {
31021a9679fSSteven Rostedt	delete $opt{$lvalue};
31121a9679fSSteven Rostedt    } else {
31277d942ceSSteven Rostedt	$rvalue = process_variables($rvalue);
31321a9679fSSteven Rostedt	$opt{$lvalue} = $rvalue;
31421a9679fSSteven Rostedt    }
3152545eb61SSteven Rostedt}
316a57419b3SSteven Rostedt
31777d942ceSSteven Rostedtsub set_variable {
31877d942ceSSteven Rostedt    my ($lvalue, $rvalue) = @_;
31977d942ceSSteven Rostedt
32077d942ceSSteven Rostedt    if ($rvalue =~ /^\s*$/) {
32177d942ceSSteven Rostedt	delete $variable{$lvalue};
32277d942ceSSteven Rostedt    } else {
32377d942ceSSteven Rostedt	$rvalue = process_variables($rvalue);
32477d942ceSSteven Rostedt	$variable{$lvalue} = $rvalue;
32577d942ceSSteven Rostedt    }
32677d942ceSSteven Rostedt}
32777d942ceSSteven Rostedt
328a57419b3SSteven Rostedtsub read_config {
329a57419b3SSteven Rostedt    my ($config) = @_;
330a57419b3SSteven Rostedt
331a57419b3SSteven Rostedt    open(IN, $config) || die "can't read file $config";
332a57419b3SSteven Rostedt
333a57419b3SSteven Rostedt    my $name = $config;
334a57419b3SSteven Rostedt    $name =~ s,.*/(.*),$1,;
335a57419b3SSteven Rostedt
336a57419b3SSteven Rostedt    my $test_num = 0;
337a57419b3SSteven Rostedt    my $default = 1;
338a57419b3SSteven Rostedt    my $repeat = 1;
339a57419b3SSteven Rostedt    my $num_tests_set = 0;
340a57419b3SSteven Rostedt    my $skip = 0;
341a57419b3SSteven Rostedt    my $rest;
342a57419b3SSteven Rostedt
343a57419b3SSteven Rostedt    while (<IN>) {
344a57419b3SSteven Rostedt
345a57419b3SSteven Rostedt	# ignore blank lines and comments
346a57419b3SSteven Rostedt	next if (/^\s*$/ || /\s*\#/);
347a57419b3SSteven Rostedt
348a57419b3SSteven Rostedt	if (/^\s*TEST_START(.*)/) {
349a57419b3SSteven Rostedt
350a57419b3SSteven Rostedt	    $rest = $1;
351a57419b3SSteven Rostedt
352a57419b3SSteven Rostedt	    if ($num_tests_set) {
353a57419b3SSteven Rostedt		die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
354a57419b3SSteven Rostedt	    }
355a57419b3SSteven Rostedt
356a57419b3SSteven Rostedt	    my $old_test_num = $test_num;
357e48c5293SSteven Rostedt	    my $old_repeat = $repeat;
358a57419b3SSteven Rostedt
359a57419b3SSteven Rostedt	    $test_num += $repeat;
360a57419b3SSteven Rostedt	    $default = 0;
361a57419b3SSteven Rostedt	    $repeat = 1;
362a57419b3SSteven Rostedt
363a57419b3SSteven Rostedt	    if ($rest =~ /\s+SKIP(.*)/) {
364a57419b3SSteven Rostedt		$rest = $1;
365a57419b3SSteven Rostedt		$skip = 1;
366a57419b3SSteven Rostedt	    } else {
367a57419b3SSteven Rostedt		$skip = 0;
368a57419b3SSteven Rostedt	    }
369a57419b3SSteven Rostedt
370a57419b3SSteven Rostedt	    if ($rest =~ /\s+ITERATE\s+(\d+)(.*)$/) {
371a57419b3SSteven Rostedt		$repeat = $1;
372a57419b3SSteven Rostedt		$rest = $2;
373a57419b3SSteven Rostedt		$repeat_tests{"$test_num"} = $repeat;
374a57419b3SSteven Rostedt	    }
375a57419b3SSteven Rostedt
376a57419b3SSteven Rostedt	    if ($rest =~ /\s+SKIP(.*)/) {
377a57419b3SSteven Rostedt		$rest = $1;
378a57419b3SSteven Rostedt		$skip = 1;
379a57419b3SSteven Rostedt	    }
380a57419b3SSteven Rostedt
381a57419b3SSteven Rostedt	    if ($rest !~ /^\s*$/) {
382a57419b3SSteven Rostedt		die "$name: $.: Gargbage found after TEST_START\n$_";
383a57419b3SSteven Rostedt	    }
384a57419b3SSteven Rostedt
385a57419b3SSteven Rostedt	    if ($skip) {
386a57419b3SSteven Rostedt		$test_num = $old_test_num;
387e48c5293SSteven Rostedt		$repeat = $old_repeat;
388a57419b3SSteven Rostedt	    }
389a57419b3SSteven Rostedt
390a57419b3SSteven Rostedt	} elsif (/^\s*DEFAULTS(.*)$/) {
391a57419b3SSteven Rostedt	    $default = 1;
392a57419b3SSteven Rostedt
393a57419b3SSteven Rostedt	    $rest = $1;
394a57419b3SSteven Rostedt
395a57419b3SSteven Rostedt	    if ($rest =~ /\s+SKIP(.*)/) {
396a57419b3SSteven Rostedt		$rest = $1;
397a57419b3SSteven Rostedt		$skip = 1;
398a57419b3SSteven Rostedt	    } else {
399a57419b3SSteven Rostedt		$skip = 0;
400a57419b3SSteven Rostedt	    }
401a57419b3SSteven Rostedt
402a57419b3SSteven Rostedt	    if ($rest !~ /^\s*$/) {
403a57419b3SSteven Rostedt		die "$name: $.: Gargbage found after DEFAULTS\n$_";
404a57419b3SSteven Rostedt	    }
405a57419b3SSteven Rostedt
406a57419b3SSteven Rostedt	} elsif (/^\s*([A-Z_\[\]\d]+)\s*=\s*(.*?)\s*$/) {
407a57419b3SSteven Rostedt
408a57419b3SSteven Rostedt	    next if ($skip);
409a57419b3SSteven Rostedt
410a57419b3SSteven Rostedt	    my $lvalue = $1;
411a57419b3SSteven Rostedt	    my $rvalue = $2;
412a57419b3SSteven Rostedt
413a57419b3SSteven Rostedt	    if (!$default &&
414a57419b3SSteven Rostedt		($lvalue eq "NUM_TESTS" ||
415a57419b3SSteven Rostedt		 $lvalue eq "LOG_FILE" ||
416a57419b3SSteven Rostedt		 $lvalue eq "CLEAR_LOG")) {
417a57419b3SSteven Rostedt		die "$name: $.: $lvalue must be set in DEFAULTS section\n";
418a57419b3SSteven Rostedt	    }
419a57419b3SSteven Rostedt
420a57419b3SSteven Rostedt	    if ($lvalue eq "NUM_TESTS") {
421a57419b3SSteven Rostedt		if ($test_num) {
422a57419b3SSteven Rostedt		    die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
423a57419b3SSteven Rostedt		}
424a57419b3SSteven Rostedt		if (!$default) {
425a57419b3SSteven Rostedt		    die "$name: $.: NUM_TESTS must be set in default section\n";
426a57419b3SSteven Rostedt		}
427a57419b3SSteven Rostedt		$num_tests_set = 1;
428a57419b3SSteven Rostedt	    }
429a57419b3SSteven Rostedt
430a57419b3SSteven Rostedt	    if ($default || $lvalue =~ /\[\d+\]$/) {
431a57419b3SSteven Rostedt		set_value($lvalue, $rvalue);
432a57419b3SSteven Rostedt	    } else {
433a57419b3SSteven Rostedt		my $val = "$lvalue\[$test_num\]";
434a57419b3SSteven Rostedt		set_value($val, $rvalue);
435a57419b3SSteven Rostedt
436a57419b3SSteven Rostedt		if ($repeat > 1) {
437a57419b3SSteven Rostedt		    $repeats{$val} = $repeat;
438a57419b3SSteven Rostedt		}
439a57419b3SSteven Rostedt	    }
44077d942ceSSteven Rostedt	} elsif (/^\s*([A-Z_\[\]\d]+)\s*:=\s*(.*?)\s*$/) {
44177d942ceSSteven Rostedt	    next if ($skip);
44277d942ceSSteven Rostedt
44377d942ceSSteven Rostedt	    my $lvalue = $1;
44477d942ceSSteven Rostedt	    my $rvalue = $2;
44577d942ceSSteven Rostedt
44677d942ceSSteven Rostedt	    # process config variables.
44777d942ceSSteven Rostedt	    # Config variables are only active while reading the
44877d942ceSSteven Rostedt	    # config and can be defined anywhere. They also ignore
44977d942ceSSteven Rostedt	    # TEST_START and DEFAULTS, but are skipped if they are in
45077d942ceSSteven Rostedt	    # on of these sections that have SKIP defined.
45177d942ceSSteven Rostedt	    # The save variable can be
45277d942ceSSteven Rostedt	    # defined multiple times and the new one simply overrides
45377d942ceSSteven Rostedt	    # the prevous one.
45477d942ceSSteven Rostedt	    set_variable($lvalue, $rvalue);
45577d942ceSSteven Rostedt
456a57419b3SSteven Rostedt	} else {
457a57419b3SSteven Rostedt	    die "$name: $.: Garbage found in config\n$_";
458a57419b3SSteven Rostedt	}
4592545eb61SSteven Rostedt    }
4602545eb61SSteven Rostedt
4612545eb61SSteven Rostedt    close(IN);
462a75fececSSteven Rostedt
463a57419b3SSteven Rostedt    if ($test_num) {
464a57419b3SSteven Rostedt	$test_num += $repeat - 1;
465a57419b3SSteven Rostedt	$opt{"NUM_TESTS"} = $test_num;
466a57419b3SSteven Rostedt    }
467a57419b3SSteven Rostedt
4688d1491baSSteven Rostedt    # make sure we have all mandatory configs
4698d1491baSSteven Rostedt    get_ktest_configs;
4708d1491baSSteven Rostedt
471a75fececSSteven Rostedt    # set any defaults
472a75fececSSteven Rostedt
473a75fececSSteven Rostedt    foreach my $default (keys %default) {
474a75fececSSteven Rostedt	if (!defined($opt{$default})) {
475a75fececSSteven Rostedt	    $opt{$default} = $default{$default};
476a75fececSSteven Rostedt	}
477a75fececSSteven Rostedt    }
4782545eb61SSteven Rostedt}
4792545eb61SSteven Rostedt
480d1e2f22aSSteven Rostedtsub _logit {
4812545eb61SSteven Rostedt    if (defined($opt{"LOG_FILE"})) {
4822545eb61SSteven Rostedt	open(OUT, ">> $opt{LOG_FILE}") or die "Can't write to $opt{LOG_FILE}";
4832545eb61SSteven Rostedt	print OUT @_;
4842545eb61SSteven Rostedt	close(OUT);
4852545eb61SSteven Rostedt    }
4862545eb61SSteven Rostedt}
4872545eb61SSteven Rostedt
488d1e2f22aSSteven Rostedtsub logit {
489d1e2f22aSSteven Rostedt    if (defined($opt{"LOG_FILE"})) {
490d1e2f22aSSteven Rostedt	_logit @_;
491d1e2f22aSSteven Rostedt    } else {
492d1e2f22aSSteven Rostedt	print @_;
493d1e2f22aSSteven Rostedt    }
494d1e2f22aSSteven Rostedt}
495d1e2f22aSSteven Rostedt
4965f9b6cedSSteven Rostedtsub doprint {
4975f9b6cedSSteven Rostedt    print @_;
498d1e2f22aSSteven Rostedt    _logit @_;
4995f9b6cedSSteven Rostedt}
5005f9b6cedSSteven Rostedt
5017faafbd6SSteven Rostedtsub run_command;
5027faafbd6SSteven Rostedt
5037faafbd6SSteven Rostedtsub reboot {
5047faafbd6SSteven Rostedt    # try to reboot normally
505e48c5293SSteven Rostedt    if (run_command $reboot) {
506576f627cSSteven Rostedt	if (defined($powercycle_after_reboot)) {
507576f627cSSteven Rostedt	    sleep $powercycle_after_reboot;
508576f627cSSteven Rostedt	    run_command "$power_cycle";
509576f627cSSteven Rostedt	}
510576f627cSSteven Rostedt    } else {
5117faafbd6SSteven Rostedt	# nope? power cycle it.
512a75fececSSteven Rostedt	run_command "$power_cycle";
5137faafbd6SSteven Rostedt    }
5147faafbd6SSteven Rostedt}
5157faafbd6SSteven Rostedt
516576f627cSSteven Rostedtsub do_not_reboot {
517576f627cSSteven Rostedt    my $i = $iteration;
518576f627cSSteven Rostedt
519576f627cSSteven Rostedt    return $test_type eq "build" ||
520576f627cSSteven Rostedt	($test_type eq "patchcheck" && $opt{"PATCHCHECK_TYPE[$i]"} eq "build") ||
521576f627cSSteven Rostedt	($test_type eq "bisect" && $opt{"BISECT_TYPE[$i]"} eq "build");
522576f627cSSteven Rostedt}
523576f627cSSteven Rostedt
5245c42fc5bSSteven Rostedtsub dodie {
5255a391fbfSSteven Rostedt    doprint "CRITICAL FAILURE... ", @_, "\n";
5265c42fc5bSSteven Rostedt
527576f627cSSteven Rostedt    my $i = $iteration;
528576f627cSSteven Rostedt
529576f627cSSteven Rostedt    if ($reboot_on_error && !do_not_reboot) {
530576f627cSSteven Rostedt
53175c3fda7SSteven Rostedt	doprint "REBOOTING\n";
5327faafbd6SSteven Rostedt	reboot;
53375c3fda7SSteven Rostedt
534a75fececSSteven Rostedt    } elsif ($poweroff_on_error && defined($power_off)) {
5355c42fc5bSSteven Rostedt	doprint "POWERING OFF\n";
536a75fececSSteven Rostedt	`$power_off`;
5375c42fc5bSSteven Rostedt    }
53875c3fda7SSteven Rostedt
539f80802cbSSteven Rostedt    if (defined($opt{"LOG_FILE"})) {
540f80802cbSSteven Rostedt	print " See $opt{LOG_FILE} for more info.\n";
541f80802cbSSteven Rostedt    }
542f80802cbSSteven Rostedt
543576f627cSSteven Rostedt    die @_, "\n";
5445c42fc5bSSteven Rostedt}
5455c42fc5bSSteven Rostedt
5467faafbd6SSteven Rostedtsub open_console {
5477faafbd6SSteven Rostedt    my ($fp) = @_;
5487faafbd6SSteven Rostedt
5497faafbd6SSteven Rostedt    my $flags;
5507faafbd6SSteven Rostedt
551a75fececSSteven Rostedt    my $pid = open($fp, "$console|") or
552a75fececSSteven Rostedt	dodie "Can't open console $console";
5537faafbd6SSteven Rostedt
5547faafbd6SSteven Rostedt    $flags = fcntl($fp, F_GETFL, 0) or
555576f627cSSteven Rostedt	dodie "Can't get flags for the socket: $!";
5567faafbd6SSteven Rostedt    $flags = fcntl($fp, F_SETFL, $flags | O_NONBLOCK) or
557576f627cSSteven Rostedt	dodie "Can't set flags for the socket: $!";
5587faafbd6SSteven Rostedt
5597faafbd6SSteven Rostedt    return $pid;
5607faafbd6SSteven Rostedt}
5617faafbd6SSteven Rostedt
5627faafbd6SSteven Rostedtsub close_console {
5637faafbd6SSteven Rostedt    my ($fp, $pid) = @_;
5647faafbd6SSteven Rostedt
5657faafbd6SSteven Rostedt    doprint "kill child process $pid\n";
5667faafbd6SSteven Rostedt    kill 2, $pid;
5677faafbd6SSteven Rostedt
5687faafbd6SSteven Rostedt    print "closing!\n";
5697faafbd6SSteven Rostedt    close($fp);
5707faafbd6SSteven Rostedt}
5717faafbd6SSteven Rostedt
5727faafbd6SSteven Rostedtsub start_monitor {
5737faafbd6SSteven Rostedt    if ($monitor_cnt++) {
5747faafbd6SSteven Rostedt	return;
5757faafbd6SSteven Rostedt    }
5767faafbd6SSteven Rostedt    $monitor_fp = \*MONFD;
5777faafbd6SSteven Rostedt    $monitor_pid = open_console $monitor_fp;
578a75fececSSteven Rostedt
579a75fececSSteven Rostedt    return;
580a75fececSSteven Rostedt
581a75fececSSteven Rostedt    open(MONFD, "Stop perl from warning about single use of MONFD");
5827faafbd6SSteven Rostedt}
5837faafbd6SSteven Rostedt
5847faafbd6SSteven Rostedtsub end_monitor {
5857faafbd6SSteven Rostedt    if (--$monitor_cnt) {
5867faafbd6SSteven Rostedt	return;
5877faafbd6SSteven Rostedt    }
5887faafbd6SSteven Rostedt    close_console($monitor_fp, $monitor_pid);
5897faafbd6SSteven Rostedt}
5907faafbd6SSteven Rostedt
5917faafbd6SSteven Rostedtsub wait_for_monitor {
5927faafbd6SSteven Rostedt    my ($time) = @_;
5937faafbd6SSteven Rostedt    my $line;
5947faafbd6SSteven Rostedt
595a75fececSSteven Rostedt    doprint "** Wait for monitor to settle down **\n";
5967faafbd6SSteven Rostedt
5977faafbd6SSteven Rostedt    # read the monitor and wait for the system to calm down
5987faafbd6SSteven Rostedt    do {
5997faafbd6SSteven Rostedt	$line = wait_for_input($monitor_fp, $time);
600a75fececSSteven Rostedt	print "$line" if (defined($line));
6017faafbd6SSteven Rostedt    } while (defined($line));
602a75fececSSteven Rostedt    print "** Monitor flushed **\n";
6037faafbd6SSteven Rostedt}
6047faafbd6SSteven Rostedt
6052b7d9b21SSteven Rostedtsub fail {
6062b7d9b21SSteven Rostedt
607a75fececSSteven Rostedt	if ($die_on_failure) {
6082b7d9b21SSteven Rostedt		dodie @_;
6092b7d9b21SSteven Rostedt	}
6102b7d9b21SSteven Rostedt
611a75fececSSteven Rostedt	doprint "FAILED\n";
6127faafbd6SSteven Rostedt
613576f627cSSteven Rostedt	my $i = $iteration;
614576f627cSSteven Rostedt
615a75fececSSteven Rostedt	# no need to reboot for just building.
616576f627cSSteven Rostedt	if (!do_not_reboot) {
6177faafbd6SSteven Rostedt	    doprint "REBOOTING\n";
6187faafbd6SSteven Rostedt	    reboot;
6197faafbd6SSteven Rostedt	    start_monitor;
620a75fececSSteven Rostedt	    wait_for_monitor $sleep_time;
6217faafbd6SSteven Rostedt	    end_monitor;
622a75fececSSteven Rostedt	}
6237faafbd6SSteven Rostedt
624*9064af52SSteven Rostedt	my $name = "";
625*9064af52SSteven Rostedt
626*9064af52SSteven Rostedt	if (defined($test_name)) {
627*9064af52SSteven Rostedt	    $name = " ($test_name)";
628*9064af52SSteven Rostedt	}
629*9064af52SSteven Rostedt
630576f627cSSteven Rostedt	doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
631576f627cSSteven Rostedt	doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
632*9064af52SSteven Rostedt	doprint "KTEST RESULT: TEST $i$name Failed: ", @_, "\n";
633576f627cSSteven Rostedt	doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
634576f627cSSteven Rostedt	doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
635a75fececSSteven Rostedt
636a75fececSSteven Rostedt	return 1 if (!defined($store_failures));
6377faafbd6SSteven Rostedt
6387faafbd6SSteven Rostedt	my @t = localtime;
6397faafbd6SSteven Rostedt	my $date = sprintf "%04d%02d%02d%02d%02d%02d",
6407faafbd6SSteven Rostedt		1900+$t[5],$t[4],$t[3],$t[2],$t[1],$t[0];
6417faafbd6SSteven Rostedt
642cccae1a6SSteven Rostedt	my $type = $build_type;
643cccae1a6SSteven Rostedt	if ($type =~ /useconfig/) {
644cccae1a6SSteven Rostedt	    $type = "useconfig";
645cccae1a6SSteven Rostedt	}
646cccae1a6SSteven Rostedt
647cccae1a6SSteven Rostedt	my $dir = "$machine-$test_type-$type-fail-$date";
648a75fececSSteven Rostedt	my $faildir = "$store_failures/$dir";
6497faafbd6SSteven Rostedt
6507faafbd6SSteven Rostedt	if (!-d $faildir) {
6517faafbd6SSteven Rostedt	    mkpath($faildir) or
652a75fececSSteven Rostedt		die "can't create $faildir";
6537faafbd6SSteven Rostedt	}
65451ad1dd1SSteven Rostedt	if (-f "$output_config") {
65551ad1dd1SSteven Rostedt	    cp "$output_config", "$faildir/config" or
6567faafbd6SSteven Rostedt		die "failed to copy .config";
6577faafbd6SSteven Rostedt	}
6587faafbd6SSteven Rostedt	if (-f $buildlog) {
6597faafbd6SSteven Rostedt	    cp $buildlog, "$faildir/buildlog" or
6607faafbd6SSteven Rostedt		die "failed to move $buildlog";
6617faafbd6SSteven Rostedt	}
6627faafbd6SSteven Rostedt	if (-f $dmesg) {
6637faafbd6SSteven Rostedt	    cp $dmesg, "$faildir/dmesg" or
6647faafbd6SSteven Rostedt		die "failed to move $dmesg";
6657faafbd6SSteven Rostedt	}
6667faafbd6SSteven Rostedt
6677faafbd6SSteven Rostedt	doprint "*** Saved info to $faildir ***\n";
6687faafbd6SSteven Rostedt
6692b7d9b21SSteven Rostedt	return 1;
6702b7d9b21SSteven Rostedt}
6712b7d9b21SSteven Rostedt
6722545eb61SSteven Rostedtsub run_command {
6732545eb61SSteven Rostedt    my ($command) = @_;
674d6ce2a0bSSteven Rostedt    my $dolog = 0;
675d6ce2a0bSSteven Rostedt    my $dord = 0;
676d6ce2a0bSSteven Rostedt    my $pid;
677d6ce2a0bSSteven Rostedt
678e48c5293SSteven Rostedt    $command =~ s/\$SSH_USER/$ssh_user/g;
679e48c5293SSteven Rostedt    $command =~ s/\$MACHINE/$machine/g;
680e48c5293SSteven Rostedt
681d6ce2a0bSSteven Rostedt    doprint("$command ... ");
682d6ce2a0bSSteven Rostedt
683d6ce2a0bSSteven Rostedt    $pid = open(CMD, "$command 2>&1 |") or
6842b7d9b21SSteven Rostedt	(fail "unable to exec $command" and return 0);
6852545eb61SSteven Rostedt
6862545eb61SSteven Rostedt    if (defined($opt{"LOG_FILE"})) {
687d6ce2a0bSSteven Rostedt	open(LOG, ">>$opt{LOG_FILE}") or
688d6ce2a0bSSteven Rostedt	    dodie "failed to write to log";
689d6ce2a0bSSteven Rostedt	$dolog = 1;
6906c5ee0beSSteven Rostedt    }
6916c5ee0beSSteven Rostedt
6926c5ee0beSSteven Rostedt    if (defined($redirect)) {
693d6ce2a0bSSteven Rostedt	open (RD, ">$redirect") or
694d6ce2a0bSSteven Rostedt	    dodie "failed to write to redirect $redirect";
695d6ce2a0bSSteven Rostedt	$dord = 1;
6962545eb61SSteven Rostedt    }
6972545eb61SSteven Rostedt
698d6ce2a0bSSteven Rostedt    while (<CMD>) {
699d6ce2a0bSSteven Rostedt	print LOG if ($dolog);
700d6ce2a0bSSteven Rostedt	print RD  if ($dord);
701d6ce2a0bSSteven Rostedt    }
7022545eb61SSteven Rostedt
703d6ce2a0bSSteven Rostedt    waitpid($pid, 0);
7042545eb61SSteven Rostedt    my $failed = $?;
7052545eb61SSteven Rostedt
706d6ce2a0bSSteven Rostedt    close(CMD);
707d6ce2a0bSSteven Rostedt    close(LOG) if ($dolog);
708d6ce2a0bSSteven Rostedt    close(RD)  if ($dord);
709d6ce2a0bSSteven Rostedt
7102545eb61SSteven Rostedt    if ($failed) {
7112545eb61SSteven Rostedt	doprint "FAILED!\n";
7122545eb61SSteven Rostedt    } else {
7132545eb61SSteven Rostedt	doprint "SUCCESS\n";
7142545eb61SSteven Rostedt    }
7152545eb61SSteven Rostedt
7165f9b6cedSSteven Rostedt    return !$failed;
7175f9b6cedSSteven Rostedt}
7185f9b6cedSSteven Rostedt
719e48c5293SSteven Rostedtsub run_ssh {
720e48c5293SSteven Rostedt    my ($cmd) = @_;
721e48c5293SSteven Rostedt    my $cp_exec = $ssh_exec;
722e48c5293SSteven Rostedt
723e48c5293SSteven Rostedt    $cp_exec =~ s/\$SSH_COMMAND/$cmd/g;
724e48c5293SSteven Rostedt    return run_command "$cp_exec";
725e48c5293SSteven Rostedt}
726e48c5293SSteven Rostedt
727e48c5293SSteven Rostedtsub run_scp {
728e48c5293SSteven Rostedt    my ($src, $dst) = @_;
729e48c5293SSteven Rostedt    my $cp_scp = $scp_to_target;
730e48c5293SSteven Rostedt
731e48c5293SSteven Rostedt    $cp_scp =~ s/\$SRC_FILE/$src/g;
732e48c5293SSteven Rostedt    $cp_scp =~ s/\$DST_FILE/$dst/g;
733e48c5293SSteven Rostedt
734e48c5293SSteven Rostedt    return run_command "$cp_scp";
735e48c5293SSteven Rostedt}
736e48c5293SSteven Rostedt
7375f9b6cedSSteven Rostedtsub get_grub_index {
7385f9b6cedSSteven Rostedt
739a75fececSSteven Rostedt    if ($reboot_type ne "grub") {
740a75fececSSteven Rostedt	return;
741a75fececSSteven Rostedt    }
7425a391fbfSSteven Rostedt    return if (defined($grub_number));
7435f9b6cedSSteven Rostedt
7445f9b6cedSSteven Rostedt    doprint "Find grub menu ... ";
7455f9b6cedSSteven Rostedt    $grub_number = -1;
746e48c5293SSteven Rostedt
747e48c5293SSteven Rostedt    my $ssh_grub = $ssh_exec;
748e48c5293SSteven Rostedt    $ssh_grub =~ s,\$SSH_COMMAND,cat /boot/grub/menu.lst,g;
749e48c5293SSteven Rostedt
750e48c5293SSteven Rostedt    open(IN, "$ssh_grub |")
7515f9b6cedSSteven Rostedt	or die "unable to get menu.lst";
752e48c5293SSteven Rostedt
7535f9b6cedSSteven Rostedt    while (<IN>) {
754a75fececSSteven Rostedt	if (/^\s*title\s+$grub_menu\s*$/) {
7555f9b6cedSSteven Rostedt	    $grub_number++;
7565f9b6cedSSteven Rostedt	    last;
7575f9b6cedSSteven Rostedt	} elsif (/^\s*title\s/) {
7585f9b6cedSSteven Rostedt	    $grub_number++;
7595f9b6cedSSteven Rostedt	}
7605f9b6cedSSteven Rostedt    }
7615f9b6cedSSteven Rostedt    close(IN);
7625f9b6cedSSteven Rostedt
763a75fececSSteven Rostedt    die "Could not find '$grub_menu' in /boot/grub/menu on $machine"
7645f9b6cedSSteven Rostedt	if ($grub_number < 0);
7655f9b6cedSSteven Rostedt    doprint "$grub_number\n";
7662545eb61SSteven Rostedt}
7672545eb61SSteven Rostedt
7682545eb61SSteven Rostedtsub wait_for_input
7692545eb61SSteven Rostedt{
7702545eb61SSteven Rostedt    my ($fp, $time) = @_;
7712545eb61SSteven Rostedt    my $rin;
7722545eb61SSteven Rostedt    my $ready;
7732545eb61SSteven Rostedt    my $line;
7742545eb61SSteven Rostedt    my $ch;
7752545eb61SSteven Rostedt
7762545eb61SSteven Rostedt    if (!defined($time)) {
7772545eb61SSteven Rostedt	$time = $timeout;
7782545eb61SSteven Rostedt    }
7792545eb61SSteven Rostedt
7802545eb61SSteven Rostedt    $rin = '';
7812545eb61SSteven Rostedt    vec($rin, fileno($fp), 1) = 1;
7822545eb61SSteven Rostedt    $ready = select($rin, undef, undef, $time);
7832545eb61SSteven Rostedt
7842545eb61SSteven Rostedt    $line = "";
7852545eb61SSteven Rostedt
7862545eb61SSteven Rostedt    # try to read one char at a time
7872545eb61SSteven Rostedt    while (sysread $fp, $ch, 1) {
7882545eb61SSteven Rostedt	$line .= $ch;
7892545eb61SSteven Rostedt	last if ($ch eq "\n");
7902545eb61SSteven Rostedt    }
7912545eb61SSteven Rostedt
7922545eb61SSteven Rostedt    if (!length($line)) {
7932545eb61SSteven Rostedt	return undef;
7942545eb61SSteven Rostedt    }
7952545eb61SSteven Rostedt
7962545eb61SSteven Rostedt    return $line;
7972545eb61SSteven Rostedt}
7982545eb61SSteven Rostedt
79975c3fda7SSteven Rostedtsub reboot_to {
800a75fececSSteven Rostedt    if ($reboot_type eq "grub") {
8014da46da2SSteven Rostedt	run_ssh "'(echo \"savedefault --default=$grub_number --once\" | grub --batch && reboot)'";
802a75fececSSteven Rostedt	return;
803a75fececSSteven Rostedt    }
804a75fececSSteven Rostedt
805a75fececSSteven Rostedt    run_command "$reboot_script";
8062545eb61SSteven Rostedt}
8072545eb61SSteven Rostedt
808a57419b3SSteven Rostedtsub get_sha1 {
809a57419b3SSteven Rostedt    my ($commit) = @_;
810a57419b3SSteven Rostedt
811a57419b3SSteven Rostedt    doprint "git rev-list --max-count=1 $commit ... ";
812a57419b3SSteven Rostedt    my $sha1 = `git rev-list --max-count=1 $commit`;
813a57419b3SSteven Rostedt    my $ret = $?;
814a57419b3SSteven Rostedt
815a57419b3SSteven Rostedt    logit $sha1;
816a57419b3SSteven Rostedt
817a57419b3SSteven Rostedt    if ($ret) {
818a57419b3SSteven Rostedt	doprint "FAILED\n";
819a57419b3SSteven Rostedt	dodie "Failed to get git $commit";
820a57419b3SSteven Rostedt    }
821a57419b3SSteven Rostedt
822a57419b3SSteven Rostedt    print "SUCCESS\n";
823a57419b3SSteven Rostedt
824a57419b3SSteven Rostedt    chomp $sha1;
825a57419b3SSteven Rostedt
826a57419b3SSteven Rostedt    return $sha1;
827a57419b3SSteven Rostedt}
828a57419b3SSteven Rostedt
8295a391fbfSSteven Rostedtsub monitor {
8302545eb61SSteven Rostedt    my $booted = 0;
8312545eb61SSteven Rostedt    my $bug = 0;
8325c42fc5bSSteven Rostedt    my $skip_call_trace = 0;
8332b7d9b21SSteven Rostedt    my $loops;
8342545eb61SSteven Rostedt
8357faafbd6SSteven Rostedt    wait_for_monitor 5;
8362545eb61SSteven Rostedt
8372545eb61SSteven Rostedt    my $line;
8382545eb61SSteven Rostedt    my $full_line = "";
8392545eb61SSteven Rostedt
8407faafbd6SSteven Rostedt    open(DMESG, "> $dmesg") or
8417faafbd6SSteven Rostedt	die "unable to write to $dmesg";
8422545eb61SSteven Rostedt
84375c3fda7SSteven Rostedt    reboot_to;
8442545eb61SSteven Rostedt
8451c8a617aSSteven Rostedt    my $success_start;
8461c8a617aSSteven Rostedt    my $failure_start;
8472d01b26aSSteven Rostedt    my $monitor_start = time;
8482d01b26aSSteven Rostedt    my $done = 0;
849f1a5b962SSteven Rostedt    my $version_found = 0;
8501c8a617aSSteven Rostedt
8512d01b26aSSteven Rostedt    while (!$done) {
8522545eb61SSteven Rostedt
8532b7d9b21SSteven Rostedt	if ($booted) {
854a75fececSSteven Rostedt	    $line = wait_for_input($monitor_fp, $booted_timeout);
855cd4f1d53SSteven Rostedt	    if (!defined($line)) {
856cd4f1d53SSteven Rostedt		my $s = $booted_timeout == 1 ? "" : "s";
857cd4f1d53SSteven Rostedt		doprint "Successful boot found: break after $booted_timeout second$s\n";
858cd4f1d53SSteven Rostedt		last;
859cd4f1d53SSteven Rostedt	    }
8602b7d9b21SSteven Rostedt	} else {
8617faafbd6SSteven Rostedt	    $line = wait_for_input($monitor_fp);
862cd4f1d53SSteven Rostedt	    if (!defined($line)) {
863cd4f1d53SSteven Rostedt		my $s = $timeout == 1 ? "" : "s";
864cd4f1d53SSteven Rostedt		doprint "Timed out after $timeout second$s\n";
865cd4f1d53SSteven Rostedt		last;
8662b7d9b21SSteven Rostedt	    }
867cd4f1d53SSteven Rostedt	}
8682545eb61SSteven Rostedt
8692545eb61SSteven Rostedt	doprint $line;
8707faafbd6SSteven Rostedt	print DMESG $line;
8712545eb61SSteven Rostedt
8722545eb61SSteven Rostedt	# we are not guaranteed to get a full line
8732545eb61SSteven Rostedt	$full_line .= $line;
8742545eb61SSteven Rostedt
875a75fececSSteven Rostedt	if ($full_line =~ /$success_line/) {
8762545eb61SSteven Rostedt	    $booted = 1;
8771c8a617aSSteven Rostedt	    $success_start = time;
8781c8a617aSSteven Rostedt	}
8791c8a617aSSteven Rostedt
8801c8a617aSSteven Rostedt	if ($booted && defined($stop_after_success) &&
8811c8a617aSSteven Rostedt	    $stop_after_success >= 0) {
8821c8a617aSSteven Rostedt	    my $now = time;
8831c8a617aSSteven Rostedt	    if ($now - $success_start >= $stop_after_success) {
8841c8a617aSSteven Rostedt		doprint "Test forced to stop after $stop_after_success seconds after success\n";
8851c8a617aSSteven Rostedt		last;
8861c8a617aSSteven Rostedt	    }
8872545eb61SSteven Rostedt	}
8882545eb61SSteven Rostedt
8895c42fc5bSSteven Rostedt	if ($full_line =~ /\[ backtrace testing \]/) {
8905c42fc5bSSteven Rostedt	    $skip_call_trace = 1;
8915c42fc5bSSteven Rostedt	}
8925c42fc5bSSteven Rostedt
8932545eb61SSteven Rostedt	if ($full_line =~ /call trace:/i) {
8944651920eSSteven Rostedt	    if (!$bug && !$skip_call_trace) {
8951c8a617aSSteven Rostedt		$bug = 1;
8961c8a617aSSteven Rostedt		$failure_start = time;
8971c8a617aSSteven Rostedt	    }
8981c8a617aSSteven Rostedt	}
8991c8a617aSSteven Rostedt
9001c8a617aSSteven Rostedt	if ($bug && defined($stop_after_failure) &&
9011c8a617aSSteven Rostedt	    $stop_after_failure >= 0) {
9021c8a617aSSteven Rostedt	    my $now = time;
9031c8a617aSSteven Rostedt	    if ($now - $failure_start >= $stop_after_failure) {
9041c8a617aSSteven Rostedt		doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
9051c8a617aSSteven Rostedt		last;
9061c8a617aSSteven Rostedt	    }
9075c42fc5bSSteven Rostedt	}
9085c42fc5bSSteven Rostedt
9095c42fc5bSSteven Rostedt	if ($full_line =~ /\[ end of backtrace testing \]/) {
9105c42fc5bSSteven Rostedt	    $skip_call_trace = 0;
9115c42fc5bSSteven Rostedt	}
9125c42fc5bSSteven Rostedt
9135c42fc5bSSteven Rostedt	if ($full_line =~ /Kernel panic -/) {
91410abf118SSteven Rostedt	    $failure_start = time;
9152545eb61SSteven Rostedt	    $bug = 1;
9162545eb61SSteven Rostedt	}
9172545eb61SSteven Rostedt
918f1a5b962SSteven Rostedt	# Detect triple faults by testing the banner
919f1a5b962SSteven Rostedt	if ($full_line =~ /\bLinux version (\S+).*\n/) {
920f1a5b962SSteven Rostedt	    if ($1 eq $version) {
921f1a5b962SSteven Rostedt		$version_found = 1;
922f1a5b962SSteven Rostedt	    } elsif ($version_found && $detect_triplefault) {
923f1a5b962SSteven Rostedt		# We already booted into the kernel we are testing,
924f1a5b962SSteven Rostedt		# but now we booted into another kernel?
925f1a5b962SSteven Rostedt		# Consider this a triple fault.
926f1a5b962SSteven Rostedt		doprint "Aleady booted in Linux kernel $version, but now\n";
927f1a5b962SSteven Rostedt		doprint "we booted into Linux kernel $1.\n";
928f1a5b962SSteven Rostedt		doprint "Assuming that this is a triple fault.\n";
929f1a5b962SSteven Rostedt		doprint "To disable this: set DETECT_TRIPLE_FAULT to 0\n";
930f1a5b962SSteven Rostedt		last;
931f1a5b962SSteven Rostedt	    }
932f1a5b962SSteven Rostedt	}
933f1a5b962SSteven Rostedt
9342545eb61SSteven Rostedt	if ($line =~ /\n/) {
9352545eb61SSteven Rostedt	    $full_line = "";
9362545eb61SSteven Rostedt	}
9372d01b26aSSteven Rostedt
9382d01b26aSSteven Rostedt	if ($stop_test_after > 0 && !$booted && !$bug) {
9392d01b26aSSteven Rostedt	    if (time - $monitor_start > $stop_test_after) {
9404d62bf51SSteven Rostedt		doprint "STOP_TEST_AFTER ($stop_test_after seconds) timed out\n";
9412d01b26aSSteven Rostedt		$done = 1;
9422d01b26aSSteven Rostedt	    }
9432d01b26aSSteven Rostedt	}
9442545eb61SSteven Rostedt    }
9452545eb61SSteven Rostedt
9467faafbd6SSteven Rostedt    close(DMESG);
9472545eb61SSteven Rostedt
9482545eb61SSteven Rostedt    if ($bug) {
9492b7d9b21SSteven Rostedt	return 0 if ($in_bisect);
950576f627cSSteven Rostedt	fail "failed - got a bug report" and return 0;
9512545eb61SSteven Rostedt    }
9525f9b6cedSSteven Rostedt
953a75fececSSteven Rostedt    if (!$booted) {
954a75fececSSteven Rostedt	return 0 if ($in_bisect);
955576f627cSSteven Rostedt	fail "failed - never got a boot prompt." and return 0;
956a75fececSSteven Rostedt    }
957a75fececSSteven Rostedt
9582b7d9b21SSteven Rostedt    return 1;
9592545eb61SSteven Rostedt}
9602545eb61SSteven Rostedt
9612545eb61SSteven Rostedtsub install {
9622545eb61SSteven Rostedt
963e48c5293SSteven Rostedt    run_scp "$outputdir/$build_target", "$target_image" or
9645c42fc5bSSteven Rostedt	dodie "failed to copy image";
9655f9b6cedSSteven Rostedt
9665f9b6cedSSteven Rostedt    my $install_mods = 0;
9675f9b6cedSSteven Rostedt
9685f9b6cedSSteven Rostedt    # should we process modules?
9695f9b6cedSSteven Rostedt    $install_mods = 0;
97051ad1dd1SSteven Rostedt    open(IN, "$output_config") or dodie("Can't read config file");
9715f9b6cedSSteven Rostedt    while (<IN>) {
9725f9b6cedSSteven Rostedt	if (/CONFIG_MODULES(=y)?/) {
9735f9b6cedSSteven Rostedt	    $install_mods = 1 if (defined($1));
9745f9b6cedSSteven Rostedt	    last;
9755f9b6cedSSteven Rostedt	}
9765f9b6cedSSteven Rostedt    }
9775f9b6cedSSteven Rostedt    close(IN);
9785f9b6cedSSteven Rostedt
9795f9b6cedSSteven Rostedt    if (!$install_mods) {
9805f9b6cedSSteven Rostedt	doprint "No modules needed\n";
9815f9b6cedSSteven Rostedt	return;
9822545eb61SSteven Rostedt    }
9832545eb61SSteven Rostedt
984a75fececSSteven Rostedt    run_command "$make INSTALL_MOD_PATH=$tmpdir modules_install" or
9855f9b6cedSSteven Rostedt	dodie "Failed to install modules";
9865f9b6cedSSteven Rostedt
9872545eb61SSteven Rostedt    my $modlib = "/lib/modules/$version";
988a57419b3SSteven Rostedt    my $modtar = "ktest-mods.tar.bz2";
9892545eb61SSteven Rostedt
990e48c5293SSteven Rostedt    run_ssh "rm -rf $modlib" or
9915c42fc5bSSteven Rostedt	dodie "failed to remove old mods: $modlib";
9922545eb61SSteven Rostedt
9935c42fc5bSSteven Rostedt    # would be nice if scp -r did not follow symbolic links
994a75fececSSteven Rostedt    run_command "cd $tmpdir && tar -cjf $modtar lib/modules/$version" or
9955c42fc5bSSteven Rostedt	dodie "making tarball";
9965c42fc5bSSteven Rostedt
997e48c5293SSteven Rostedt    run_scp "$tmpdir/$modtar", "/tmp" or
9985c42fc5bSSteven Rostedt	dodie "failed to copy modules";
9995c42fc5bSSteven Rostedt
1000a75fececSSteven Rostedt    unlink "$tmpdir/$modtar";
10015c42fc5bSSteven Rostedt
1002e48c5293SSteven Rostedt    run_ssh "'(cd / && tar xf /tmp/$modtar)'" or
10035c42fc5bSSteven Rostedt	dodie "failed to tar modules";
10045c42fc5bSSteven Rostedt
1005e48c5293SSteven Rostedt    run_ssh "rm -f /tmp/$modtar";
10068b37ca8cSSteven Rostedt
10078b37ca8cSSteven Rostedt    return if (!defined($post_install));
10088b37ca8cSSteven Rostedt
1009e48c5293SSteven Rostedt    my $cp_post_install = $post_install;
1010ca6a21f8SSteven Rostedt    $cp_post_install =~ s/\$KERNEL_VERSION/$version/g;
1011e48c5293SSteven Rostedt    run_command "$cp_post_install" or
1012576f627cSSteven Rostedt	dodie "Failed to run post install";
10132545eb61SSteven Rostedt}
10142545eb61SSteven Rostedt
10156c5ee0beSSteven Rostedtsub check_buildlog {
10166c5ee0beSSteven Rostedt    my ($patch) = @_;
10176c5ee0beSSteven Rostedt
10186c5ee0beSSteven Rostedt    my @files = `git show $patch | diffstat -l`;
10196c5ee0beSSteven Rostedt
10206c5ee0beSSteven Rostedt    open(IN, "git show $patch |") or
10216c5ee0beSSteven Rostedt	dodie "failed to show $patch";
10226c5ee0beSSteven Rostedt    while (<IN>) {
10236c5ee0beSSteven Rostedt	if (m,^--- a/(.*),) {
10246c5ee0beSSteven Rostedt	    chomp $1;
10256c5ee0beSSteven Rostedt	    $files[$#files] = $1;
10266c5ee0beSSteven Rostedt	}
10276c5ee0beSSteven Rostedt    }
10286c5ee0beSSteven Rostedt    close(IN);
10296c5ee0beSSteven Rostedt
10306c5ee0beSSteven Rostedt    open(IN, $buildlog) or dodie "Can't open $buildlog";
10316c5ee0beSSteven Rostedt    while (<IN>) {
10326c5ee0beSSteven Rostedt	if (/^\s*(.*?):.*(warning|error)/) {
10336c5ee0beSSteven Rostedt	    my $err = $1;
10346c5ee0beSSteven Rostedt	    foreach my $file (@files) {
1035a75fececSSteven Rostedt		my $fullpath = "$builddir/$file";
10366c5ee0beSSteven Rostedt		if ($file eq $err || $fullpath eq $err) {
10372b7d9b21SSteven Rostedt		    fail "$file built with warnings" and return 0;
10386c5ee0beSSteven Rostedt		}
10396c5ee0beSSteven Rostedt	    }
10406c5ee0beSSteven Rostedt	}
10416c5ee0beSSteven Rostedt    }
10426c5ee0beSSteven Rostedt    close(IN);
10432b7d9b21SSteven Rostedt
10442b7d9b21SSteven Rostedt    return 1;
10456c5ee0beSSteven Rostedt}
10466c5ee0beSSteven Rostedt
1047612b9e9bSSteven Rostedtsub make_oldconfig {
1048612b9e9bSSteven Rostedt    my ($defconfig) = @_;
1049612b9e9bSSteven Rostedt
1050612b9e9bSSteven Rostedt    if (!run_command "$defconfig $make oldnoconfig") {
1051612b9e9bSSteven Rostedt	# Perhaps oldnoconfig doesn't exist in this version of the kernel
1052612b9e9bSSteven Rostedt	# try a yes '' | oldconfig
1053612b9e9bSSteven Rostedt	doprint "oldnoconfig failed, trying yes '' | make oldconfig\n";
1054612b9e9bSSteven Rostedt	run_command "yes '' | $defconfig $make oldconfig" or
1055612b9e9bSSteven Rostedt	    dodie "failed make config oldconfig";
1056612b9e9bSSteven Rostedt    }
1057612b9e9bSSteven Rostedt}
1058612b9e9bSSteven Rostedt
10592545eb61SSteven Rostedtsub build {
10602545eb61SSteven Rostedt    my ($type) = @_;
10615c42fc5bSSteven Rostedt    my $defconfig = "";
10622545eb61SSteven Rostedt
10637faafbd6SSteven Rostedt    unlink $buildlog;
10647faafbd6SSteven Rostedt
106575c3fda7SSteven Rostedt    if ($type =~ /^useconfig:(.*)/) {
106651ad1dd1SSteven Rostedt	run_command "cp $1 $output_config" or
106775c3fda7SSteven Rostedt	    dodie "could not copy $1 to .config";
10685f9b6cedSSteven Rostedt
106975c3fda7SSteven Rostedt	$type = "oldconfig";
107075c3fda7SSteven Rostedt    }
107175c3fda7SSteven Rostedt
10725c42fc5bSSteven Rostedt    # old config can ask questions
10735c42fc5bSSteven Rostedt    if ($type eq "oldconfig") {
10749386c6abSSteven Rostedt	$type = "oldnoconfig";
107575c3fda7SSteven Rostedt
107675c3fda7SSteven Rostedt	# allow for empty configs
107751ad1dd1SSteven Rostedt	run_command "touch $output_config";
107875c3fda7SSteven Rostedt
107951ad1dd1SSteven Rostedt	run_command "mv $output_config $outputdir/config_temp" or
10805c42fc5bSSteven Rostedt	    dodie "moving .config";
10815c42fc5bSSteven Rostedt
10825f9b6cedSSteven Rostedt	if (!$noclean && !run_command "$make mrproper") {
10835c42fc5bSSteven Rostedt	    dodie "make mrproper";
10845c42fc5bSSteven Rostedt	}
10855c42fc5bSSteven Rostedt
108651ad1dd1SSteven Rostedt	run_command "mv $outputdir/config_temp $output_config" or
10875c42fc5bSSteven Rostedt	    dodie "moving config_temp";
10885c42fc5bSSteven Rostedt
10895c42fc5bSSteven Rostedt    } elsif (!$noclean) {
109051ad1dd1SSteven Rostedt	unlink "$output_config";
10915f9b6cedSSteven Rostedt	run_command "$make mrproper" or
10925c42fc5bSSteven Rostedt	    dodie "make mrproper";
10935c42fc5bSSteven Rostedt    }
10942545eb61SSteven Rostedt
10952545eb61SSteven Rostedt    # add something to distinguish this build
1096a75fececSSteven Rostedt    open(OUT, "> $outputdir/localversion") or dodie("Can't make localversion file");
1097a75fececSSteven Rostedt    print OUT "$localversion\n";
10982545eb61SSteven Rostedt    close(OUT);
10992545eb61SSteven Rostedt
11005f9b6cedSSteven Rostedt    if (defined($minconfig)) {
11015f9b6cedSSteven Rostedt	$defconfig = "KCONFIG_ALLCONFIG=$minconfig";
11022545eb61SSteven Rostedt    }
11032545eb61SSteven Rostedt
1104612b9e9bSSteven Rostedt    if ($type eq "oldnoconfig") {
1105612b9e9bSSteven Rostedt	make_oldconfig $defconfig;
1106612b9e9bSSteven Rostedt    } else {
11079386c6abSSteven Rostedt	run_command "$defconfig $make $type" or
11085c42fc5bSSteven Rostedt	    dodie "failed make config";
1109612b9e9bSSteven Rostedt    }
11102545eb61SSteven Rostedt
1111a75fececSSteven Rostedt    $redirect = "$buildlog";
1112a75fececSSteven Rostedt    if (!run_command "$make $build_options") {
11136c5ee0beSSteven Rostedt	undef $redirect;
11145f9b6cedSSteven Rostedt	# bisect may need this to pass
11152b7d9b21SSteven Rostedt	return 0 if ($in_bisect);
11162b7d9b21SSteven Rostedt	fail "failed build" and return 0;
11172545eb61SSteven Rostedt    }
11186c5ee0beSSteven Rostedt    undef $redirect;
11195f9b6cedSSteven Rostedt
11202b7d9b21SSteven Rostedt    return 1;
11212545eb61SSteven Rostedt}
11222545eb61SSteven Rostedt
112375c3fda7SSteven Rostedtsub halt {
1124e48c5293SSteven Rostedt    if (!run_ssh "halt" or defined($power_off)) {
1125576f627cSSteven Rostedt	if (defined($poweroff_after_halt)) {
1126576f627cSSteven Rostedt	    sleep $poweroff_after_halt;
1127576f627cSSteven Rostedt	    run_command "$power_off";
1128576f627cSSteven Rostedt	}
1129576f627cSSteven Rostedt    } else {
113075c3fda7SSteven Rostedt	# nope? the zap it!
1131a75fececSSteven Rostedt	run_command "$power_off";
113275c3fda7SSteven Rostedt    }
113375c3fda7SSteven Rostedt}
113475c3fda7SSteven Rostedt
11355f9b6cedSSteven Rostedtsub success {
11365f9b6cedSSteven Rostedt    my ($i) = @_;
11375f9b6cedSSteven Rostedt
1138e48c5293SSteven Rostedt    $successes++;
1139e48c5293SSteven Rostedt
1140*9064af52SSteven Rostedt    my $name = "";
1141*9064af52SSteven Rostedt
1142*9064af52SSteven Rostedt    if (defined($test_name)) {
1143*9064af52SSteven Rostedt	$name = " ($test_name)";
1144*9064af52SSteven Rostedt    }
1145*9064af52SSteven Rostedt
11465f9b6cedSSteven Rostedt    doprint "\n\n*******************************************\n";
11475f9b6cedSSteven Rostedt    doprint     "*******************************************\n";
1148*9064af52SSteven Rostedt    doprint     "KTEST RESULT: TEST $i$name SUCCESS!!!!         **\n";
11495f9b6cedSSteven Rostedt    doprint     "*******************************************\n";
11505f9b6cedSSteven Rostedt    doprint     "*******************************************\n";
11515f9b6cedSSteven Rostedt
1152576f627cSSteven Rostedt    if ($i != $opt{"NUM_TESTS"} && !do_not_reboot) {
1153a75fececSSteven Rostedt	doprint "Reboot and wait $sleep_time seconds\n";
11545f9b6cedSSteven Rostedt	reboot;
11557faafbd6SSteven Rostedt	start_monitor;
1156a75fececSSteven Rostedt	wait_for_monitor $sleep_time;
11577faafbd6SSteven Rostedt	end_monitor;
11585f9b6cedSSteven Rostedt    }
11595f9b6cedSSteven Rostedt}
11605f9b6cedSSteven Rostedt
11615f9b6cedSSteven Rostedtsub get_version {
11625f9b6cedSSteven Rostedt    # get the release name
11635f9b6cedSSteven Rostedt    doprint "$make kernelrelease ... ";
11645f9b6cedSSteven Rostedt    $version = `$make kernelrelease | tail -1`;
11655f9b6cedSSteven Rostedt    chomp($version);
11665f9b6cedSSteven Rostedt    doprint "$version\n";
11675f9b6cedSSteven Rostedt}
11685f9b6cedSSteven Rostedt
1169c960bb9fSSteven Rostedtsub answer_bisect {
1170c960bb9fSSteven Rostedt    for (;;) {
1171c960bb9fSSteven Rostedt	doprint "Pass or fail? [p/f]";
1172c960bb9fSSteven Rostedt	my $ans = <STDIN>;
1173c960bb9fSSteven Rostedt	chomp $ans;
1174c960bb9fSSteven Rostedt	if ($ans eq "p" || $ans eq "P") {
1175c960bb9fSSteven Rostedt	    return 1;
1176c960bb9fSSteven Rostedt	} elsif ($ans eq "f" || $ans eq "F") {
1177c960bb9fSSteven Rostedt	    return 0;
1178c960bb9fSSteven Rostedt	} else {
1179c960bb9fSSteven Rostedt	    print "Please answer 'P' or 'F'\n";
1180c960bb9fSSteven Rostedt	}
1181c960bb9fSSteven Rostedt    }
1182c960bb9fSSteven Rostedt}
1183c960bb9fSSteven Rostedt
11845a391fbfSSteven Rostedtsub child_run_test {
11857faafbd6SSteven Rostedt    my $failed = 0;
11865a391fbfSSteven Rostedt
11877faafbd6SSteven Rostedt    # child should have no power
1188a75fececSSteven Rostedt    $reboot_on_error = 0;
1189a75fececSSteven Rostedt    $poweroff_on_error = 0;
1190a75fececSSteven Rostedt    $die_on_failure = 1;
11917faafbd6SSteven Rostedt
11927faafbd6SSteven Rostedt    run_command $run_test or $failed = 1;
11935a391fbfSSteven Rostedt    exit $failed;
11945a391fbfSSteven Rostedt}
11955a391fbfSSteven Rostedt
11965a391fbfSSteven Rostedtmy $child_done;
11975a391fbfSSteven Rostedt
11985a391fbfSSteven Rostedtsub child_finished {
11995a391fbfSSteven Rostedt    $child_done = 1;
12005a391fbfSSteven Rostedt}
12015a391fbfSSteven Rostedt
12025a391fbfSSteven Rostedtsub do_run_test {
12035a391fbfSSteven Rostedt    my $child_pid;
12045a391fbfSSteven Rostedt    my $child_exit;
12055a391fbfSSteven Rostedt    my $line;
12065a391fbfSSteven Rostedt    my $full_line;
12075a391fbfSSteven Rostedt    my $bug = 0;
12085a391fbfSSteven Rostedt
12097faafbd6SSteven Rostedt    wait_for_monitor 1;
12105a391fbfSSteven Rostedt
12117faafbd6SSteven Rostedt    doprint "run test $run_test\n";
12125a391fbfSSteven Rostedt
12135a391fbfSSteven Rostedt    $child_done = 0;
12145a391fbfSSteven Rostedt
12155a391fbfSSteven Rostedt    $SIG{CHLD} = qw(child_finished);
12165a391fbfSSteven Rostedt
12175a391fbfSSteven Rostedt    $child_pid = fork;
12185a391fbfSSteven Rostedt
12195a391fbfSSteven Rostedt    child_run_test if (!$child_pid);
12205a391fbfSSteven Rostedt
12215a391fbfSSteven Rostedt    $full_line = "";
12225a391fbfSSteven Rostedt
12235a391fbfSSteven Rostedt    do {
12247faafbd6SSteven Rostedt	$line = wait_for_input($monitor_fp, 1);
12255a391fbfSSteven Rostedt	if (defined($line)) {
12265a391fbfSSteven Rostedt
12275a391fbfSSteven Rostedt	    # we are not guaranteed to get a full line
12285a391fbfSSteven Rostedt	    $full_line .= $line;
12298ea0e063SSteven Rostedt	    doprint $line;
12305a391fbfSSteven Rostedt
12315a391fbfSSteven Rostedt	    if ($full_line =~ /call trace:/i) {
12325a391fbfSSteven Rostedt		$bug = 1;
12335a391fbfSSteven Rostedt	    }
12345a391fbfSSteven Rostedt
12355a391fbfSSteven Rostedt	    if ($full_line =~ /Kernel panic -/) {
12365a391fbfSSteven Rostedt		$bug = 1;
12375a391fbfSSteven Rostedt	    }
12385a391fbfSSteven Rostedt
12395a391fbfSSteven Rostedt	    if ($line =~ /\n/) {
12405a391fbfSSteven Rostedt		$full_line = "";
12415a391fbfSSteven Rostedt	    }
12425a391fbfSSteven Rostedt	}
12435a391fbfSSteven Rostedt    } while (!$child_done && !$bug);
12445a391fbfSSteven Rostedt
12455a391fbfSSteven Rostedt    if ($bug) {
12468ea0e063SSteven Rostedt	my $failure_start = time;
12478ea0e063SSteven Rostedt	my $now;
12488ea0e063SSteven Rostedt	do {
12498ea0e063SSteven Rostedt	    $line = wait_for_input($monitor_fp, 1);
12508ea0e063SSteven Rostedt	    if (defined($line)) {
12518ea0e063SSteven Rostedt		doprint $line;
12528ea0e063SSteven Rostedt	    }
12538ea0e063SSteven Rostedt	    $now = time;
12548ea0e063SSteven Rostedt	    if ($now - $failure_start >= $stop_after_failure) {
12558ea0e063SSteven Rostedt		last;
12568ea0e063SSteven Rostedt	    }
12578ea0e063SSteven Rostedt	} while (defined($line));
12588ea0e063SSteven Rostedt
12595a391fbfSSteven Rostedt	doprint "Detected kernel crash!\n";
12605a391fbfSSteven Rostedt	# kill the child with extreme prejudice
12615a391fbfSSteven Rostedt	kill 9, $child_pid;
12625a391fbfSSteven Rostedt    }
12635a391fbfSSteven Rostedt
12645a391fbfSSteven Rostedt    waitpid $child_pid, 0;
12655a391fbfSSteven Rostedt    $child_exit = $?;
12665a391fbfSSteven Rostedt
12675a391fbfSSteven Rostedt    if ($bug || $child_exit) {
12682b7d9b21SSteven Rostedt	return 0 if $in_bisect;
12692b7d9b21SSteven Rostedt	fail "test failed" and return 0;
12705a391fbfSSteven Rostedt    }
12712b7d9b21SSteven Rostedt    return 1;
12725a391fbfSSteven Rostedt}
12735a391fbfSSteven Rostedt
1274a75fececSSteven Rostedtsub run_git_bisect {
1275a75fececSSteven Rostedt    my ($command) = @_;
1276a75fececSSteven Rostedt
1277a75fececSSteven Rostedt    doprint "$command ... ";
1278a75fececSSteven Rostedt
1279a75fececSSteven Rostedt    my $output = `$command 2>&1`;
1280a75fececSSteven Rostedt    my $ret = $?;
1281a75fececSSteven Rostedt
1282a75fececSSteven Rostedt    logit $output;
1283a75fececSSteven Rostedt
1284a75fececSSteven Rostedt    if ($ret) {
1285a75fececSSteven Rostedt	doprint "FAILED\n";
1286a75fececSSteven Rostedt	dodie "Failed to git bisect";
1287a75fececSSteven Rostedt    }
1288a75fececSSteven Rostedt
1289a75fececSSteven Rostedt    doprint "SUCCESS\n";
1290a75fececSSteven Rostedt    if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\))\s+\[([[:xdigit:]]+)\]/) {
1291a75fececSSteven Rostedt	doprint "$1 [$2]\n";
1292a75fececSSteven Rostedt    } elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) {
1293a75fececSSteven Rostedt	$bisect_bad = $1;
1294a75fececSSteven Rostedt	doprint "Found bad commit... $1\n";
1295a75fececSSteven Rostedt	return 0;
1296a75fececSSteven Rostedt    } else {
1297a75fececSSteven Rostedt	# we already logged it, just print it now.
1298a75fececSSteven Rostedt	print $output;
1299a75fececSSteven Rostedt    }
1300a75fececSSteven Rostedt
1301a75fececSSteven Rostedt    return 1;
1302a75fececSSteven Rostedt}
1303a75fececSSteven Rostedt
1304c23dca7cSSteven Rostedtsub bisect_reboot {
1305c23dca7cSSteven Rostedt    doprint "Reboot and sleep $bisect_sleep_time seconds\n";
1306c23dca7cSSteven Rostedt    reboot;
1307c23dca7cSSteven Rostedt    start_monitor;
1308c23dca7cSSteven Rostedt    wait_for_monitor $bisect_sleep_time;
1309c23dca7cSSteven Rostedt    end_monitor;
1310c23dca7cSSteven Rostedt}
1311c23dca7cSSteven Rostedt
1312c23dca7cSSteven Rostedt# returns 1 on success, 0 on failure, -1 on skip
13130a05c769SSteven Rostedtsub run_bisect_test {
13140a05c769SSteven Rostedt    my ($type, $buildtype) = @_;
13155f9b6cedSSteven Rostedt
13162b7d9b21SSteven Rostedt    my $failed = 0;
13175f9b6cedSSteven Rostedt    my $result;
13185f9b6cedSSteven Rostedt    my $output;
13195f9b6cedSSteven Rostedt    my $ret;
13205f9b6cedSSteven Rostedt
13210a05c769SSteven Rostedt    $in_bisect = 1;
13220a05c769SSteven Rostedt
13230a05c769SSteven Rostedt    build $buildtype or $failed = 1;
13245f9b6cedSSteven Rostedt
13255f9b6cedSSteven Rostedt    if ($type ne "build") {
1326c23dca7cSSteven Rostedt	if ($failed && $bisect_skip) {
1327c23dca7cSSteven Rostedt	    $in_bisect = 0;
1328c23dca7cSSteven Rostedt	    return -1;
1329c23dca7cSSteven Rostedt	}
13307faafbd6SSteven Rostedt	dodie "Failed on build" if $failed;
13315f9b6cedSSteven Rostedt
13325f9b6cedSSteven Rostedt	# Now boot the box
13335f9b6cedSSteven Rostedt	get_grub_index;
13345f9b6cedSSteven Rostedt	get_version;
13355f9b6cedSSteven Rostedt	install;
13367faafbd6SSteven Rostedt
13377faafbd6SSteven Rostedt	start_monitor;
13382b7d9b21SSteven Rostedt	monitor or $failed = 1;
13395f9b6cedSSteven Rostedt
13405f9b6cedSSteven Rostedt	if ($type ne "boot") {
1341c23dca7cSSteven Rostedt	    if ($failed && $bisect_skip) {
1342c23dca7cSSteven Rostedt		end_monitor;
1343c23dca7cSSteven Rostedt		bisect_reboot;
1344c23dca7cSSteven Rostedt		$in_bisect = 0;
1345c23dca7cSSteven Rostedt		return -1;
1346c23dca7cSSteven Rostedt	    }
13477faafbd6SSteven Rostedt	    dodie "Failed on boot" if $failed;
13485a391fbfSSteven Rostedt
13492b7d9b21SSteven Rostedt	    do_run_test or $failed = 1;
13505f9b6cedSSteven Rostedt	}
13517faafbd6SSteven Rostedt	end_monitor;
13525f9b6cedSSteven Rostedt    }
13535f9b6cedSSteven Rostedt
13545f9b6cedSSteven Rostedt    if ($failed) {
13550a05c769SSteven Rostedt	$result = 0;
13565f9b6cedSSteven Rostedt    } else {
13570a05c769SSteven Rostedt	$result = 1;
13585f9b6cedSSteven Rostedt    }
13594025bc62SSteven Rostedt
13604025bc62SSteven Rostedt    # reboot the box to a kernel we can ssh to
13614025bc62SSteven Rostedt    if ($type ne "build") {
13624025bc62SSteven Rostedt	bisect_reboot;
13634025bc62SSteven Rostedt    }
13640a05c769SSteven Rostedt    $in_bisect = 0;
13650a05c769SSteven Rostedt
13660a05c769SSteven Rostedt    return $result;
13670a05c769SSteven Rostedt}
13680a05c769SSteven Rostedt
13690a05c769SSteven Rostedtsub run_bisect {
13700a05c769SSteven Rostedt    my ($type) = @_;
13710a05c769SSteven Rostedt    my $buildtype = "oldconfig";
13720a05c769SSteven Rostedt
13730a05c769SSteven Rostedt    # We should have a minconfig to use?
13740a05c769SSteven Rostedt    if (defined($minconfig)) {
13750a05c769SSteven Rostedt	$buildtype = "useconfig:$minconfig";
13760a05c769SSteven Rostedt    }
13770a05c769SSteven Rostedt
13780a05c769SSteven Rostedt    my $ret = run_bisect_test $type, $buildtype;
13790a05c769SSteven Rostedt
1380c960bb9fSSteven Rostedt    if ($bisect_manual) {
1381c960bb9fSSteven Rostedt	$ret = answer_bisect;
1382c960bb9fSSteven Rostedt    }
13835f9b6cedSSteven Rostedt
1384d6ce2a0bSSteven Rostedt    # Are we looking for where it worked, not failed?
1385d6ce2a0bSSteven Rostedt    if ($reverse_bisect) {
13860a05c769SSteven Rostedt	$ret = !$ret;
1387d6ce2a0bSSteven Rostedt    }
1388d6ce2a0bSSteven Rostedt
1389c23dca7cSSteven Rostedt    if ($ret > 0) {
13900a05c769SSteven Rostedt	return "good";
1391c23dca7cSSteven Rostedt    } elsif ($ret == 0) {
13920a05c769SSteven Rostedt	return  "bad";
1393c23dca7cSSteven Rostedt    } elsif ($bisect_skip) {
1394c23dca7cSSteven Rostedt	doprint "HIT A BAD COMMIT ... SKIPPING\n";
1395c23dca7cSSteven Rostedt	return "skip";
13960a05c769SSteven Rostedt    }
13975f9b6cedSSteven Rostedt}
13985f9b6cedSSteven Rostedt
13995f9b6cedSSteven Rostedtsub bisect {
14005f9b6cedSSteven Rostedt    my ($i) = @_;
14015f9b6cedSSteven Rostedt
14025f9b6cedSSteven Rostedt    my $result;
14035f9b6cedSSteven Rostedt
14045f9b6cedSSteven Rostedt    die "BISECT_GOOD[$i] not defined\n"	if (!defined($opt{"BISECT_GOOD[$i]"}));
14055f9b6cedSSteven Rostedt    die "BISECT_BAD[$i] not defined\n"	if (!defined($opt{"BISECT_BAD[$i]"}));
14065f9b6cedSSteven Rostedt    die "BISECT_TYPE[$i] not defined\n"	if (!defined($opt{"BISECT_TYPE[$i]"}));
14075f9b6cedSSteven Rostedt
14085f9b6cedSSteven Rostedt    my $good = $opt{"BISECT_GOOD[$i]"};
14095f9b6cedSSteven Rostedt    my $bad = $opt{"BISECT_BAD[$i]"};
14105f9b6cedSSteven Rostedt    my $type = $opt{"BISECT_TYPE[$i]"};
1411a75fececSSteven Rostedt    my $start = $opt{"BISECT_START[$i]"};
1412a75fececSSteven Rostedt    my $replay = $opt{"BISECT_REPLAY[$i]"};
14133410f6fdSSteven Rostedt    my $start_files = $opt{"BISECT_FILES[$i]"};
14143410f6fdSSteven Rostedt
14153410f6fdSSteven Rostedt    if (defined($start_files)) {
14163410f6fdSSteven Rostedt	$start_files = " -- " . $start_files;
14173410f6fdSSteven Rostedt    } else {
14183410f6fdSSteven Rostedt	$start_files = "";
14193410f6fdSSteven Rostedt    }
14205f9b6cedSSteven Rostedt
1421a57419b3SSteven Rostedt    # convert to true sha1's
1422a57419b3SSteven Rostedt    $good = get_sha1($good);
1423a57419b3SSteven Rostedt    $bad = get_sha1($bad);
1424a57419b3SSteven Rostedt
1425d6ce2a0bSSteven Rostedt    if (defined($opt{"BISECT_REVERSE[$i]"}) &&
1426d6ce2a0bSSteven Rostedt	$opt{"BISECT_REVERSE[$i]"} == 1) {
1427d6ce2a0bSSteven Rostedt	doprint "Performing a reverse bisect (bad is good, good is bad!)\n";
1428d6ce2a0bSSteven Rostedt	$reverse_bisect = 1;
1429d6ce2a0bSSteven Rostedt    } else {
1430d6ce2a0bSSteven Rostedt	$reverse_bisect = 0;
1431d6ce2a0bSSteven Rostedt    }
1432d6ce2a0bSSteven Rostedt
14335a391fbfSSteven Rostedt    # Can't have a test without having a test to run
14345a391fbfSSteven Rostedt    if ($type eq "test" && !defined($run_test)) {
14355a391fbfSSteven Rostedt	$type = "boot";
14365a391fbfSSteven Rostedt    }
14375a391fbfSSteven Rostedt
1438a75fececSSteven Rostedt    my $check = $opt{"BISECT_CHECK[$i]"};
1439a75fececSSteven Rostedt    if (defined($check) && $check ne "0") {
1440a75fececSSteven Rostedt
1441a75fececSSteven Rostedt	# get current HEAD
1442a57419b3SSteven Rostedt	my $head = get_sha1("HEAD");
1443a75fececSSteven Rostedt
1444a75fececSSteven Rostedt	if ($check ne "good") {
1445a75fececSSteven Rostedt	    doprint "TESTING BISECT BAD [$bad]\n";
1446a75fececSSteven Rostedt	    run_command "git checkout $bad" or
1447a75fececSSteven Rostedt		die "Failed to checkout $bad";
1448a75fececSSteven Rostedt
1449a75fececSSteven Rostedt	    $result = run_bisect $type;
1450a75fececSSteven Rostedt
1451a75fececSSteven Rostedt	    if ($result ne "bad") {
1452a75fececSSteven Rostedt		fail "Tested BISECT_BAD [$bad] and it succeeded" and return 0;
1453a75fececSSteven Rostedt	    }
1454a75fececSSteven Rostedt	}
1455a75fececSSteven Rostedt
1456a75fececSSteven Rostedt	if ($check ne "bad") {
1457a75fececSSteven Rostedt	    doprint "TESTING BISECT GOOD [$good]\n";
1458a75fececSSteven Rostedt	    run_command "git checkout $good" or
1459a75fececSSteven Rostedt		die "Failed to checkout $good";
1460a75fececSSteven Rostedt
1461a75fececSSteven Rostedt	    $result = run_bisect $type;
1462a75fececSSteven Rostedt
1463a75fececSSteven Rostedt	    if ($result ne "good") {
1464a75fececSSteven Rostedt		fail "Tested BISECT_GOOD [$good] and it failed" and return 0;
1465a75fececSSteven Rostedt	    }
1466a75fececSSteven Rostedt	}
1467a75fececSSteven Rostedt
1468a75fececSSteven Rostedt	# checkout where we started
1469a75fececSSteven Rostedt	run_command "git checkout $head" or
1470a75fececSSteven Rostedt	    die "Failed to checkout $head";
1471a75fececSSteven Rostedt    }
1472a75fececSSteven Rostedt
14733410f6fdSSteven Rostedt    run_command "git bisect start$start_files" or
1474a75fececSSteven Rostedt	dodie "could not start bisect";
1475a75fececSSteven Rostedt
1476a75fececSSteven Rostedt    run_command "git bisect good $good" or
1477a75fececSSteven Rostedt	dodie "could not set bisect good to $good";
1478a75fececSSteven Rostedt
1479a75fececSSteven Rostedt    run_git_bisect "git bisect bad $bad" or
1480a75fececSSteven Rostedt	dodie "could not set bisect bad to $bad";
1481a75fececSSteven Rostedt
1482a75fececSSteven Rostedt    if (defined($replay)) {
1483a75fececSSteven Rostedt	run_command "git bisect replay $replay" or
1484a75fececSSteven Rostedt	    dodie "failed to run replay";
1485a75fececSSteven Rostedt    }
1486a75fececSSteven Rostedt
1487a75fececSSteven Rostedt    if (defined($start)) {
1488a75fececSSteven Rostedt	run_command "git checkout $start" or
1489a75fececSSteven Rostedt	    dodie "failed to checkout $start";
1490a75fececSSteven Rostedt    }
1491a75fececSSteven Rostedt
1492a75fececSSteven Rostedt    my $test;
14935f9b6cedSSteven Rostedt    do {
14945f9b6cedSSteven Rostedt	$result = run_bisect $type;
1495a75fececSSteven Rostedt	$test = run_git_bisect "git bisect $result";
1496a75fececSSteven Rostedt    } while ($test);
14975f9b6cedSSteven Rostedt
14985f9b6cedSSteven Rostedt    run_command "git bisect log" or
14995f9b6cedSSteven Rostedt	dodie "could not capture git bisect log";
15005f9b6cedSSteven Rostedt
15015f9b6cedSSteven Rostedt    run_command "git bisect reset" or
15025f9b6cedSSteven Rostedt	dodie "could not reset git bisect";
15035f9b6cedSSteven Rostedt
15045f9b6cedSSteven Rostedt    doprint "Bad commit was [$bisect_bad]\n";
15055f9b6cedSSteven Rostedt
15060a05c769SSteven Rostedt    success $i;
15070a05c769SSteven Rostedt}
15080a05c769SSteven Rostedt
15090a05c769SSteven Rostedtmy %config_ignore;
15100a05c769SSteven Rostedtmy %config_set;
15110a05c769SSteven Rostedt
15120a05c769SSteven Rostedtmy %config_list;
15130a05c769SSteven Rostedtmy %null_config;
15140a05c769SSteven Rostedt
15150a05c769SSteven Rostedtmy %dependency;
15160a05c769SSteven Rostedt
15170a05c769SSteven Rostedtsub process_config_ignore {
15180a05c769SSteven Rostedt    my ($config) = @_;
15190a05c769SSteven Rostedt
15200a05c769SSteven Rostedt    open (IN, $config)
15210a05c769SSteven Rostedt	or dodie "Failed to read $config";
15220a05c769SSteven Rostedt
15230a05c769SSteven Rostedt    while (<IN>) {
15249bf71749SSteven Rostedt	if (/^((CONFIG\S*)=.*)/) {
15250a05c769SSteven Rostedt	    $config_ignore{$2} = $1;
15260a05c769SSteven Rostedt	}
15270a05c769SSteven Rostedt    }
15280a05c769SSteven Rostedt
15290a05c769SSteven Rostedt    close(IN);
15300a05c769SSteven Rostedt}
15310a05c769SSteven Rostedt
15320a05c769SSteven Rostedtsub read_current_config {
15330a05c769SSteven Rostedt    my ($config_ref) = @_;
15340a05c769SSteven Rostedt
15350a05c769SSteven Rostedt    %{$config_ref} = ();
15360a05c769SSteven Rostedt    undef %{$config_ref};
15370a05c769SSteven Rostedt
15380a05c769SSteven Rostedt    my @key = keys %{$config_ref};
15390a05c769SSteven Rostedt    if ($#key >= 0) {
15400a05c769SSteven Rostedt	print "did not delete!\n";
15410a05c769SSteven Rostedt	exit;
15420a05c769SSteven Rostedt    }
15430a05c769SSteven Rostedt    open (IN, "$output_config");
15440a05c769SSteven Rostedt
15450a05c769SSteven Rostedt    while (<IN>) {
15460a05c769SSteven Rostedt	if (/^(CONFIG\S+)=(.*)/) {
15470a05c769SSteven Rostedt	    ${$config_ref}{$1} = $2;
15480a05c769SSteven Rostedt	}
15490a05c769SSteven Rostedt    }
15500a05c769SSteven Rostedt    close(IN);
15510a05c769SSteven Rostedt}
15520a05c769SSteven Rostedt
15530a05c769SSteven Rostedtsub get_dependencies {
15540a05c769SSteven Rostedt    my ($config) = @_;
15550a05c769SSteven Rostedt
15560a05c769SSteven Rostedt    my $arr = $dependency{$config};
15570a05c769SSteven Rostedt    if (!defined($arr)) {
15580a05c769SSteven Rostedt	return ();
15590a05c769SSteven Rostedt    }
15600a05c769SSteven Rostedt
15610a05c769SSteven Rostedt    my @deps = @{$arr};
15620a05c769SSteven Rostedt
15630a05c769SSteven Rostedt    foreach my $dep (@{$arr}) {
15640a05c769SSteven Rostedt	print "ADD DEP $dep\n";
15650a05c769SSteven Rostedt	@deps = (@deps, get_dependencies $dep);
15660a05c769SSteven Rostedt    }
15670a05c769SSteven Rostedt
15680a05c769SSteven Rostedt    return @deps;
15690a05c769SSteven Rostedt}
15700a05c769SSteven Rostedt
15710a05c769SSteven Rostedtsub create_config {
15720a05c769SSteven Rostedt    my @configs = @_;
15730a05c769SSteven Rostedt
15740a05c769SSteven Rostedt    open(OUT, ">$output_config") or dodie "Can not write to $output_config";
15750a05c769SSteven Rostedt
15760a05c769SSteven Rostedt    foreach my $config (@configs) {
15770a05c769SSteven Rostedt	print OUT "$config_set{$config}\n";
15780a05c769SSteven Rostedt	my @deps = get_dependencies $config;
15790a05c769SSteven Rostedt	foreach my $dep (@deps) {
15800a05c769SSteven Rostedt	    print OUT "$config_set{$dep}\n";
15810a05c769SSteven Rostedt	}
15820a05c769SSteven Rostedt    }
15830a05c769SSteven Rostedt
15840a05c769SSteven Rostedt    foreach my $config (keys %config_ignore) {
15850a05c769SSteven Rostedt	print OUT "$config_ignore{$config}\n";
15860a05c769SSteven Rostedt    }
15870a05c769SSteven Rostedt    close(OUT);
15880a05c769SSteven Rostedt
15890a05c769SSteven Rostedt#    exit;
1590612b9e9bSSteven Rostedt    make_oldconfig "";
15910a05c769SSteven Rostedt}
15920a05c769SSteven Rostedt
15930a05c769SSteven Rostedtsub compare_configs {
15940a05c769SSteven Rostedt    my (%a, %b) = @_;
15950a05c769SSteven Rostedt
15960a05c769SSteven Rostedt    foreach my $item (keys %a) {
15970a05c769SSteven Rostedt	if (!defined($b{$item})) {
15980a05c769SSteven Rostedt	    print "diff $item\n";
15990a05c769SSteven Rostedt	    return 1;
16000a05c769SSteven Rostedt	}
16010a05c769SSteven Rostedt	delete $b{$item};
16020a05c769SSteven Rostedt    }
16030a05c769SSteven Rostedt
16040a05c769SSteven Rostedt    my @keys = keys %b;
16050a05c769SSteven Rostedt    if ($#keys) {
16060a05c769SSteven Rostedt	print "diff2 $keys[0]\n";
16070a05c769SSteven Rostedt    }
16080a05c769SSteven Rostedt    return -1 if ($#keys >= 0);
16090a05c769SSteven Rostedt
16100a05c769SSteven Rostedt    return 0;
16110a05c769SSteven Rostedt}
16120a05c769SSteven Rostedt
16130a05c769SSteven Rostedtsub run_config_bisect_test {
16140a05c769SSteven Rostedt    my ($type) = @_;
16150a05c769SSteven Rostedt
16160a05c769SSteven Rostedt    return run_bisect_test $type, "oldconfig";
16170a05c769SSteven Rostedt}
16180a05c769SSteven Rostedt
16190a05c769SSteven Rostedtsub process_passed {
16200a05c769SSteven Rostedt    my (%configs) = @_;
16210a05c769SSteven Rostedt
16220a05c769SSteven Rostedt    doprint "These configs had no failure: (Enabling them for further compiles)\n";
16230a05c769SSteven Rostedt    # Passed! All these configs are part of a good compile.
16240a05c769SSteven Rostedt    # Add them to the min options.
16250a05c769SSteven Rostedt    foreach my $config (keys %configs) {
16260a05c769SSteven Rostedt	if (defined($config_list{$config})) {
16270a05c769SSteven Rostedt	    doprint " removing $config\n";
16280a05c769SSteven Rostedt	    $config_ignore{$config} = $config_list{$config};
16290a05c769SSteven Rostedt	    delete $config_list{$config};
16300a05c769SSteven Rostedt	}
16310a05c769SSteven Rostedt    }
1632f1a27850SSteven Rostedt    doprint "config copied to $outputdir/config_good\n";
1633f1a27850SSteven Rostedt    run_command "cp -f $output_config $outputdir/config_good";
16340a05c769SSteven Rostedt}
16350a05c769SSteven Rostedt
16360a05c769SSteven Rostedtsub process_failed {
16370a05c769SSteven Rostedt    my ($config) = @_;
16380a05c769SSteven Rostedt
16390a05c769SSteven Rostedt    doprint "\n\n***************************************\n";
16400a05c769SSteven Rostedt    doprint "Found bad config: $config\n";
16410a05c769SSteven Rostedt    doprint "***************************************\n\n";
16420a05c769SSteven Rostedt}
16430a05c769SSteven Rostedt
16440a05c769SSteven Rostedtsub run_config_bisect {
16450a05c769SSteven Rostedt
16460a05c769SSteven Rostedt    my @start_list = keys %config_list;
16470a05c769SSteven Rostedt
16480a05c769SSteven Rostedt    if ($#start_list < 0) {
16490a05c769SSteven Rostedt	doprint "No more configs to test!!!\n";
16500a05c769SSteven Rostedt	return -1;
16510a05c769SSteven Rostedt    }
16520a05c769SSteven Rostedt
16530a05c769SSteven Rostedt    doprint "***** RUN TEST ***\n";
16540a05c769SSteven Rostedt    my $type = $opt{"CONFIG_BISECT_TYPE[$iteration]"};
16550a05c769SSteven Rostedt    my $ret;
16560a05c769SSteven Rostedt    my %current_config;
16570a05c769SSteven Rostedt
16580a05c769SSteven Rostedt    my $count = $#start_list + 1;
16590a05c769SSteven Rostedt    doprint "  $count configs to test\n";
16600a05c769SSteven Rostedt
16610a05c769SSteven Rostedt    my $half = int($#start_list / 2);
16620a05c769SSteven Rostedt
16630a05c769SSteven Rostedt    do {
16640a05c769SSteven Rostedt	my @tophalf = @start_list[0 .. $half];
16650a05c769SSteven Rostedt
16660a05c769SSteven Rostedt	create_config @tophalf;
16670a05c769SSteven Rostedt	read_current_config \%current_config;
16680a05c769SSteven Rostedt
16690a05c769SSteven Rostedt	$count = $#tophalf + 1;
16700a05c769SSteven Rostedt	doprint "Testing $count configs\n";
16710a05c769SSteven Rostedt	my $found = 0;
16720a05c769SSteven Rostedt	# make sure we test something
16730a05c769SSteven Rostedt	foreach my $config (@tophalf) {
16740a05c769SSteven Rostedt	    if (defined($current_config{$config})) {
16750a05c769SSteven Rostedt		logit " $config\n";
16760a05c769SSteven Rostedt		$found = 1;
16770a05c769SSteven Rostedt	    }
16780a05c769SSteven Rostedt	}
16790a05c769SSteven Rostedt	if (!$found) {
16800a05c769SSteven Rostedt	    # try the other half
16810a05c769SSteven Rostedt	    doprint "Top half produced no set configs, trying bottom half\n";
16824c8cc55bSSteven Rostedt	    @tophalf = @start_list[$half + 1 .. $#start_list];
16830a05c769SSteven Rostedt	    create_config @tophalf;
16840a05c769SSteven Rostedt	    read_current_config \%current_config;
16850a05c769SSteven Rostedt	    foreach my $config (@tophalf) {
16860a05c769SSteven Rostedt		if (defined($current_config{$config})) {
16870a05c769SSteven Rostedt		    logit " $config\n";
16880a05c769SSteven Rostedt		    $found = 1;
16890a05c769SSteven Rostedt		}
16900a05c769SSteven Rostedt	    }
16910a05c769SSteven Rostedt	    if (!$found) {
16920a05c769SSteven Rostedt		doprint "Failed: Can't make new config with current configs\n";
16930a05c769SSteven Rostedt		foreach my $config (@start_list) {
16940a05c769SSteven Rostedt		    doprint "  CONFIG: $config\n";
16950a05c769SSteven Rostedt		}
16960a05c769SSteven Rostedt		return -1;
16970a05c769SSteven Rostedt	    }
16980a05c769SSteven Rostedt	    $count = $#tophalf + 1;
16990a05c769SSteven Rostedt	    doprint "Testing $count configs\n";
17000a05c769SSteven Rostedt	}
17010a05c769SSteven Rostedt
17020a05c769SSteven Rostedt	$ret = run_config_bisect_test $type;
1703c960bb9fSSteven Rostedt	if ($bisect_manual) {
1704c960bb9fSSteven Rostedt	    $ret = answer_bisect;
1705c960bb9fSSteven Rostedt	}
17060a05c769SSteven Rostedt	if ($ret) {
17070a05c769SSteven Rostedt	    process_passed %current_config;
17080a05c769SSteven Rostedt	    return 0;
17090a05c769SSteven Rostedt	}
17100a05c769SSteven Rostedt
17110a05c769SSteven Rostedt	doprint "This config had a failure.\n";
17120a05c769SSteven Rostedt	doprint "Removing these configs that were not set in this config:\n";
1713f1a27850SSteven Rostedt	doprint "config copied to $outputdir/config_bad\n";
1714f1a27850SSteven Rostedt	run_command "cp -f $output_config $outputdir/config_bad";
17150a05c769SSteven Rostedt
17160a05c769SSteven Rostedt	# A config exists in this group that was bad.
17170a05c769SSteven Rostedt	foreach my $config (keys %config_list) {
17180a05c769SSteven Rostedt	    if (!defined($current_config{$config})) {
17190a05c769SSteven Rostedt		doprint " removing $config\n";
17200a05c769SSteven Rostedt		delete $config_list{$config};
17210a05c769SSteven Rostedt	    }
17220a05c769SSteven Rostedt	}
17230a05c769SSteven Rostedt
17240a05c769SSteven Rostedt	@start_list = @tophalf;
17250a05c769SSteven Rostedt
17260a05c769SSteven Rostedt	if ($#start_list == 0) {
17270a05c769SSteven Rostedt	    process_failed $start_list[0];
17280a05c769SSteven Rostedt	    return 1;
17290a05c769SSteven Rostedt	}
17300a05c769SSteven Rostedt
17310a05c769SSteven Rostedt	# remove half the configs we are looking at and see if
17320a05c769SSteven Rostedt	# they are good.
17330a05c769SSteven Rostedt	$half = int($#start_list / 2);
17344c8cc55bSSteven Rostedt    } while ($#start_list > 0);
17350a05c769SSteven Rostedt
1736c960bb9fSSteven Rostedt    # we found a single config, try it again unless we are running manually
1737c960bb9fSSteven Rostedt
1738c960bb9fSSteven Rostedt    if ($bisect_manual) {
1739c960bb9fSSteven Rostedt	process_failed $start_list[0];
1740c960bb9fSSteven Rostedt	return 1;
1741c960bb9fSSteven Rostedt    }
1742c960bb9fSSteven Rostedt
17430a05c769SSteven Rostedt    my @tophalf = @start_list[0 .. 0];
17440a05c769SSteven Rostedt
17450a05c769SSteven Rostedt    $ret = run_config_bisect_test $type;
17460a05c769SSteven Rostedt    if ($ret) {
17470a05c769SSteven Rostedt	process_passed %current_config;
17480a05c769SSteven Rostedt	return 0;
17490a05c769SSteven Rostedt    }
17500a05c769SSteven Rostedt
17510a05c769SSteven Rostedt    process_failed $start_list[0];
17520a05c769SSteven Rostedt    return 1;
17530a05c769SSteven Rostedt}
17540a05c769SSteven Rostedt
17550a05c769SSteven Rostedtsub config_bisect {
17560a05c769SSteven Rostedt    my ($i) = @_;
17570a05c769SSteven Rostedt
17580a05c769SSteven Rostedt    my $start_config = $opt{"CONFIG_BISECT[$i]"};
17590a05c769SSteven Rostedt
17600a05c769SSteven Rostedt    my $tmpconfig = "$tmpdir/use_config";
17610a05c769SSteven Rostedt
176230f75da5SSteven Rostedt    if (defined($config_bisect_good)) {
176330f75da5SSteven Rostedt	process_config_ignore $config_bisect_good;
176430f75da5SSteven Rostedt    }
176530f75da5SSteven Rostedt
17660a05c769SSteven Rostedt    # Make the file with the bad config and the min config
17670a05c769SSteven Rostedt    if (defined($minconfig)) {
17680a05c769SSteven Rostedt	# read the min config for things to ignore
17690a05c769SSteven Rostedt	run_command "cp $minconfig $tmpconfig" or
17700a05c769SSteven Rostedt	    dodie "failed to copy $minconfig to $tmpconfig";
17710a05c769SSteven Rostedt    } else {
17720a05c769SSteven Rostedt	unlink $tmpconfig;
17730a05c769SSteven Rostedt    }
17740a05c769SSteven Rostedt
17750a05c769SSteven Rostedt    # Add other configs
17760a05c769SSteven Rostedt    if (defined($addconfig)) {
17770a05c769SSteven Rostedt	run_command "cat $addconfig >> $tmpconfig" or
17780a05c769SSteven Rostedt	    dodie "failed to append $addconfig";
17790a05c769SSteven Rostedt    }
17800a05c769SSteven Rostedt
17810a05c769SSteven Rostedt    my $defconfig = "";
17820a05c769SSteven Rostedt    if (-f $tmpconfig) {
17830a05c769SSteven Rostedt	$defconfig = "KCONFIG_ALLCONFIG=$tmpconfig";
17840a05c769SSteven Rostedt	process_config_ignore $tmpconfig;
17850a05c769SSteven Rostedt    }
17860a05c769SSteven Rostedt
17870a05c769SSteven Rostedt    # now process the start config
17880a05c769SSteven Rostedt    run_command "cp $start_config $output_config" or
17890a05c769SSteven Rostedt	dodie "failed to copy $start_config to $output_config";
17900a05c769SSteven Rostedt
17910a05c769SSteven Rostedt    # read directly what we want to check
17920a05c769SSteven Rostedt    my %config_check;
17930a05c769SSteven Rostedt    open (IN, $output_config)
17940a05c769SSteven Rostedt	or dodie "faied to open $output_config";
17950a05c769SSteven Rostedt
17960a05c769SSteven Rostedt    while (<IN>) {
17970a05c769SSteven Rostedt	if (/^((CONFIG\S*)=.*)/) {
17980a05c769SSteven Rostedt	    $config_check{$2} = $1;
17990a05c769SSteven Rostedt	}
18000a05c769SSteven Rostedt    }
18010a05c769SSteven Rostedt    close(IN);
18020a05c769SSteven Rostedt
18030a05c769SSteven Rostedt    # Now run oldconfig with the minconfig (and addconfigs)
1804612b9e9bSSteven Rostedt    make_oldconfig $defconfig;
18050a05c769SSteven Rostedt
18060a05c769SSteven Rostedt    # check to see what we lost (or gained)
18070a05c769SSteven Rostedt    open (IN, $output_config)
18080a05c769SSteven Rostedt	or dodie "Failed to read $start_config";
18090a05c769SSteven Rostedt
18100a05c769SSteven Rostedt    my %removed_configs;
18110a05c769SSteven Rostedt    my %added_configs;
18120a05c769SSteven Rostedt
18130a05c769SSteven Rostedt    while (<IN>) {
18140a05c769SSteven Rostedt	if (/^((CONFIG\S*)=.*)/) {
18150a05c769SSteven Rostedt	    # save off all options
18160a05c769SSteven Rostedt	    $config_set{$2} = $1;
18170a05c769SSteven Rostedt	    if (defined($config_check{$2})) {
18180a05c769SSteven Rostedt		if (defined($config_ignore{$2})) {
18190a05c769SSteven Rostedt		    $removed_configs{$2} = $1;
18200a05c769SSteven Rostedt		} else {
18210a05c769SSteven Rostedt		    $config_list{$2} = $1;
18220a05c769SSteven Rostedt		}
18230a05c769SSteven Rostedt	    } elsif (!defined($config_ignore{$2})) {
18240a05c769SSteven Rostedt		$added_configs{$2} = $1;
18250a05c769SSteven Rostedt		$config_list{$2} = $1;
18260a05c769SSteven Rostedt	    }
18270a05c769SSteven Rostedt	}
18280a05c769SSteven Rostedt    }
18290a05c769SSteven Rostedt    close(IN);
18300a05c769SSteven Rostedt
18310a05c769SSteven Rostedt    my @confs = keys %removed_configs;
18320a05c769SSteven Rostedt    if ($#confs >= 0) {
18330a05c769SSteven Rostedt	doprint "Configs overridden by default configs and removed from check:\n";
18340a05c769SSteven Rostedt	foreach my $config (@confs) {
18350a05c769SSteven Rostedt	    doprint " $config\n";
18360a05c769SSteven Rostedt	}
18370a05c769SSteven Rostedt    }
18380a05c769SSteven Rostedt    @confs = keys %added_configs;
18390a05c769SSteven Rostedt    if ($#confs >= 0) {
18400a05c769SSteven Rostedt	doprint "Configs appearing in make oldconfig and added:\n";
18410a05c769SSteven Rostedt	foreach my $config (@confs) {
18420a05c769SSteven Rostedt	    doprint " $config\n";
18430a05c769SSteven Rostedt	}
18440a05c769SSteven Rostedt    }
18450a05c769SSteven Rostedt
18460a05c769SSteven Rostedt    my %config_test;
18470a05c769SSteven Rostedt    my $once = 0;
18480a05c769SSteven Rostedt
18490a05c769SSteven Rostedt    # Sometimes kconfig does weird things. We must make sure
18500a05c769SSteven Rostedt    # that the config we autocreate has everything we need
18510a05c769SSteven Rostedt    # to test, otherwise we may miss testing configs, or
18520a05c769SSteven Rostedt    # may not be able to create a new config.
18530a05c769SSteven Rostedt    # Here we create a config with everything set.
18540a05c769SSteven Rostedt    create_config (keys %config_list);
18550a05c769SSteven Rostedt    read_current_config \%config_test;
18560a05c769SSteven Rostedt    foreach my $config (keys %config_list) {
18570a05c769SSteven Rostedt	if (!defined($config_test{$config})) {
18580a05c769SSteven Rostedt	    if (!$once) {
18590a05c769SSteven Rostedt		$once = 1;
18600a05c769SSteven Rostedt		doprint "Configs not produced by kconfig (will not be checked):\n";
18610a05c769SSteven Rostedt	    }
18620a05c769SSteven Rostedt	    doprint "  $config\n";
18630a05c769SSteven Rostedt	    delete $config_list{$config};
18640a05c769SSteven Rostedt	}
18650a05c769SSteven Rostedt    }
18660a05c769SSteven Rostedt    my $ret;
18670a05c769SSteven Rostedt    do {
18680a05c769SSteven Rostedt	$ret = run_config_bisect;
18690a05c769SSteven Rostedt    } while (!$ret);
18700a05c769SSteven Rostedt
18710a05c769SSteven Rostedt    return $ret if ($ret < 0);
18725f9b6cedSSteven Rostedt
18735f9b6cedSSteven Rostedt    success $i;
18745f9b6cedSSteven Rostedt}
18755f9b6cedSSteven Rostedt
187627d934b2SSteven Rostedtsub patchcheck_reboot {
187727d934b2SSteven Rostedt    doprint "Reboot and sleep $patchcheck_sleep_time seconds\n";
187827d934b2SSteven Rostedt    reboot;
187927d934b2SSteven Rostedt    start_monitor;
188027d934b2SSteven Rostedt    wait_for_monitor $patchcheck_sleep_time;
188127d934b2SSteven Rostedt    end_monitor;
188227d934b2SSteven Rostedt}
188327d934b2SSteven Rostedt
18846c5ee0beSSteven Rostedtsub patchcheck {
18856c5ee0beSSteven Rostedt    my ($i) = @_;
18866c5ee0beSSteven Rostedt
18876c5ee0beSSteven Rostedt    die "PATCHCHECK_START[$i] not defined\n"
18886c5ee0beSSteven Rostedt	if (!defined($opt{"PATCHCHECK_START[$i]"}));
18896c5ee0beSSteven Rostedt    die "PATCHCHECK_TYPE[$i] not defined\n"
18906c5ee0beSSteven Rostedt	if (!defined($opt{"PATCHCHECK_TYPE[$i]"}));
18916c5ee0beSSteven Rostedt
18926c5ee0beSSteven Rostedt    my $start = $opt{"PATCHCHECK_START[$i]"};
18936c5ee0beSSteven Rostedt
18946c5ee0beSSteven Rostedt    my $end = "HEAD";
18956c5ee0beSSteven Rostedt    if (defined($opt{"PATCHCHECK_END[$i]"})) {
18966c5ee0beSSteven Rostedt	$end = $opt{"PATCHCHECK_END[$i]"};
18976c5ee0beSSteven Rostedt    }
18986c5ee0beSSteven Rostedt
1899a57419b3SSteven Rostedt    # Get the true sha1's since we can use things like HEAD~3
1900a57419b3SSteven Rostedt    $start = get_sha1($start);
1901a57419b3SSteven Rostedt    $end = get_sha1($end);
1902a57419b3SSteven Rostedt
19036c5ee0beSSteven Rostedt    my $type = $opt{"PATCHCHECK_TYPE[$i]"};
19046c5ee0beSSteven Rostedt
19056c5ee0beSSteven Rostedt    # Can't have a test without having a test to run
19066c5ee0beSSteven Rostedt    if ($type eq "test" && !defined($run_test)) {
19076c5ee0beSSteven Rostedt	$type = "boot";
19086c5ee0beSSteven Rostedt    }
19096c5ee0beSSteven Rostedt
19106c5ee0beSSteven Rostedt    open (IN, "git log --pretty=oneline $end|") or
19116c5ee0beSSteven Rostedt	dodie "could not get git list";
19126c5ee0beSSteven Rostedt
19136c5ee0beSSteven Rostedt    my @list;
19146c5ee0beSSteven Rostedt
19156c5ee0beSSteven Rostedt    while (<IN>) {
19166c5ee0beSSteven Rostedt	chomp;
19176c5ee0beSSteven Rostedt	$list[$#list+1] = $_;
19186c5ee0beSSteven Rostedt	last if (/^$start/);
19196c5ee0beSSteven Rostedt    }
19206c5ee0beSSteven Rostedt    close(IN);
19216c5ee0beSSteven Rostedt
19226c5ee0beSSteven Rostedt    if ($list[$#list] !~ /^$start/) {
19232b7d9b21SSteven Rostedt	fail "SHA1 $start not found";
19246c5ee0beSSteven Rostedt    }
19256c5ee0beSSteven Rostedt
19266c5ee0beSSteven Rostedt    # go backwards in the list
19276c5ee0beSSteven Rostedt    @list = reverse @list;
19286c5ee0beSSteven Rostedt
19296c5ee0beSSteven Rostedt    my $save_clean = $noclean;
19306c5ee0beSSteven Rostedt
19316c5ee0beSSteven Rostedt    $in_patchcheck = 1;
19326c5ee0beSSteven Rostedt    foreach my $item (@list) {
19336c5ee0beSSteven Rostedt	my $sha1 = $item;
19346c5ee0beSSteven Rostedt	$sha1 =~ s/^([[:xdigit:]]+).*/$1/;
19356c5ee0beSSteven Rostedt
19366c5ee0beSSteven Rostedt	doprint "\nProcessing commit $item\n\n";
19376c5ee0beSSteven Rostedt
19386c5ee0beSSteven Rostedt	run_command "git checkout $sha1" or
19396c5ee0beSSteven Rostedt	    die "Failed to checkout $sha1";
19406c5ee0beSSteven Rostedt
19416c5ee0beSSteven Rostedt	# only clean on the first and last patch
19426c5ee0beSSteven Rostedt	if ($item eq $list[0] ||
19436c5ee0beSSteven Rostedt	    $item eq $list[$#list]) {
19446c5ee0beSSteven Rostedt	    $noclean = $save_clean;
19456c5ee0beSSteven Rostedt	} else {
19466c5ee0beSSteven Rostedt	    $noclean = 1;
19476c5ee0beSSteven Rostedt	}
19486c5ee0beSSteven Rostedt
19496c5ee0beSSteven Rostedt	if (defined($minconfig)) {
19502b7d9b21SSteven Rostedt	    build "useconfig:$minconfig" or return 0;
19516c5ee0beSSteven Rostedt	} else {
19526c5ee0beSSteven Rostedt	    # ?? no config to use?
19532b7d9b21SSteven Rostedt	    build "oldconfig" or return 0;
19546c5ee0beSSteven Rostedt	}
19556c5ee0beSSteven Rostedt
19562b7d9b21SSteven Rostedt	check_buildlog $sha1 or return 0;
19576c5ee0beSSteven Rostedt
19586c5ee0beSSteven Rostedt	next if ($type eq "build");
19596c5ee0beSSteven Rostedt
19606c5ee0beSSteven Rostedt	get_grub_index;
19616c5ee0beSSteven Rostedt	get_version;
19626c5ee0beSSteven Rostedt	install;
19636c5ee0beSSteven Rostedt
19647faafbd6SSteven Rostedt	my $failed = 0;
19657faafbd6SSteven Rostedt
19667faafbd6SSteven Rostedt	start_monitor;
19677faafbd6SSteven Rostedt	monitor or $failed = 1;
19687faafbd6SSteven Rostedt
19697faafbd6SSteven Rostedt	if (!$failed && $type ne "boot"){
19707faafbd6SSteven Rostedt	    do_run_test or $failed = 1;
19717faafbd6SSteven Rostedt	}
19727faafbd6SSteven Rostedt	end_monitor;
19737faafbd6SSteven Rostedt	return 0 if ($failed);
19747faafbd6SSteven Rostedt
197527d934b2SSteven Rostedt	patchcheck_reboot;
197627d934b2SSteven Rostedt
19776c5ee0beSSteven Rostedt    }
19786c5ee0beSSteven Rostedt    $in_patchcheck = 0;
19796c5ee0beSSteven Rostedt    success $i;
19802b7d9b21SSteven Rostedt
19812b7d9b21SSteven Rostedt    return 1;
19826c5ee0beSSteven Rostedt}
19836c5ee0beSSteven Rostedt
19848d1491baSSteven Rostedt$#ARGV < 1 or die "ktest.pl version: $VERSION\n   usage: ktest.pl config-file\n";
19852545eb61SSteven Rostedt
19868d1491baSSteven Rostedtif ($#ARGV == 0) {
19878d1491baSSteven Rostedt    $ktest_config = $ARGV[0];
19888d1491baSSteven Rostedt    if (! -f $ktest_config) {
19898d1491baSSteven Rostedt	print "$ktest_config does not exist.\n";
19908d1491baSSteven Rostedt	my $ans;
19918d1491baSSteven Rostedt        for (;;) {
19928d1491baSSteven Rostedt	    print "Create it? [Y/n] ";
19938d1491baSSteven Rostedt	    $ans = <STDIN>;
19948d1491baSSteven Rostedt	    chomp $ans;
19958d1491baSSteven Rostedt	    if ($ans =~ /^\s*$/) {
19968d1491baSSteven Rostedt		$ans = "y";
19978d1491baSSteven Rostedt	    }
19988d1491baSSteven Rostedt	    last if ($ans =~ /^y$/i || $ans =~ /^n$/i);
19998d1491baSSteven Rostedt	    print "Please answer either 'y' or 'n'.\n";
20008d1491baSSteven Rostedt	}
20018d1491baSSteven Rostedt	if ($ans !~ /^y$/i) {
20028d1491baSSteven Rostedt	    exit 0;
20038d1491baSSteven Rostedt	}
20048d1491baSSteven Rostedt    }
20058d1491baSSteven Rostedt} else {
20068d1491baSSteven Rostedt    $ktest_config = "ktest.conf";
20078d1491baSSteven Rostedt}
20088d1491baSSteven Rostedt
20098d1491baSSteven Rostedtif (! -f $ktest_config) {
20108d1491baSSteven Rostedt    open(OUT, ">$ktest_config") or die "Can not create $ktest_config";
20118d1491baSSteven Rostedt    print OUT << "EOF"
20128d1491baSSteven Rostedt# Generated by ktest.pl
20138d1491baSSteven Rostedt#
20148d1491baSSteven Rostedt# Define each test with TEST_START
20158d1491baSSteven Rostedt# The config options below it will override the defaults
20168d1491baSSteven RostedtTEST_START
20178d1491baSSteven Rostedt
20188d1491baSSteven RostedtDEFAULTS
20198d1491baSSteven RostedtEOF
20208d1491baSSteven Rostedt;
20218d1491baSSteven Rostedt    close(OUT);
20228d1491baSSteven Rostedt}
20238d1491baSSteven Rostedtread_config $ktest_config;
20248d1491baSSteven Rostedt
20258d1491baSSteven Rostedt# Append any configs entered in manually to the config file.
20268d1491baSSteven Rostedtmy @new_configs = keys %entered_configs;
20278d1491baSSteven Rostedtif ($#new_configs >= 0) {
20288d1491baSSteven Rostedt    print "\nAppending entered in configs to $ktest_config\n";
20298d1491baSSteven Rostedt    open(OUT, ">>$ktest_config") or die "Can not append to $ktest_config";
20308d1491baSSteven Rostedt    foreach my $config (@new_configs) {
20318d1491baSSteven Rostedt	print OUT "$config = $entered_configs{$config}\n";
20328d1491baSSteven Rostedt	$opt{$config} = $entered_configs{$config};
20338d1491baSSteven Rostedt    }
20348d1491baSSteven Rostedt}
20352545eb61SSteven Rostedt
20362b7d9b21SSteven Rostedtif ($opt{"CLEAR_LOG"} && defined($opt{"LOG_FILE"})) {
20372b7d9b21SSteven Rostedt    unlink $opt{"LOG_FILE"};
20382b7d9b21SSteven Rostedt}
20392545eb61SSteven Rostedt
20402b7d9b21SSteven Rostedtdoprint "\n\nSTARTING AUTOMATED TESTS\n\n";
20412b7d9b21SSteven Rostedt
2042a57419b3SSteven Rostedtfor (my $i = 0, my $repeat = 1; $i <= $opt{"NUM_TESTS"}; $i += $repeat) {
2043a57419b3SSteven Rostedt
2044a57419b3SSteven Rostedt    if (!$i) {
2045a57419b3SSteven Rostedt	doprint "DEFAULT OPTIONS:\n";
2046a57419b3SSteven Rostedt    } else {
2047a57419b3SSteven Rostedt	doprint "\nTEST $i OPTIONS";
2048a57419b3SSteven Rostedt	if (defined($repeat_tests{$i})) {
2049a57419b3SSteven Rostedt	    $repeat = $repeat_tests{$i};
2050a57419b3SSteven Rostedt	    doprint " ITERATE $repeat";
2051a57419b3SSteven Rostedt	}
2052a57419b3SSteven Rostedt	doprint "\n";
2053a57419b3SSteven Rostedt    }
2054a57419b3SSteven Rostedt
20552b7d9b21SSteven Rostedt    foreach my $option (sort keys %opt) {
2056a57419b3SSteven Rostedt
2057a57419b3SSteven Rostedt	if ($option =~ /\[(\d+)\]$/) {
2058a57419b3SSteven Rostedt	    next if ($i != $1);
2059a57419b3SSteven Rostedt	} else {
2060a57419b3SSteven Rostedt	    next if ($i);
2061a57419b3SSteven Rostedt	}
2062a57419b3SSteven Rostedt
20632b7d9b21SSteven Rostedt	doprint "$option = $opt{$option}\n";
20642b7d9b21SSteven Rostedt    }
2065a57419b3SSteven Rostedt}
20662545eb61SSteven Rostedt
20672a62512bSSteven Rostedtsub __set_test_option {
20685a391fbfSSteven Rostedt    my ($name, $i) = @_;
20695a391fbfSSteven Rostedt
20705a391fbfSSteven Rostedt    my $option = "$name\[$i\]";
20715a391fbfSSteven Rostedt
20725a391fbfSSteven Rostedt    if (defined($opt{$option})) {
20735a391fbfSSteven Rostedt	return $opt{$option};
20745a391fbfSSteven Rostedt    }
20755a391fbfSSteven Rostedt
2076a57419b3SSteven Rostedt    foreach my $test (keys %repeat_tests) {
2077a57419b3SSteven Rostedt	if ($i >= $test &&
2078a57419b3SSteven Rostedt	    $i < $test + $repeat_tests{$test}) {
2079a57419b3SSteven Rostedt	    $option = "$name\[$test\]";
2080a57419b3SSteven Rostedt	    if (defined($opt{$option})) {
2081a57419b3SSteven Rostedt		return $opt{$option};
2082a57419b3SSteven Rostedt	    }
2083a57419b3SSteven Rostedt	}
2084a57419b3SSteven Rostedt    }
2085a57419b3SSteven Rostedt
20865a391fbfSSteven Rostedt    if (defined($opt{$name})) {
20875a391fbfSSteven Rostedt	return $opt{$name};
20885a391fbfSSteven Rostedt    }
20895a391fbfSSteven Rostedt
20905a391fbfSSteven Rostedt    return undef;
20915a391fbfSSteven Rostedt}
20925a391fbfSSteven Rostedt
20932a62512bSSteven Rostedtsub eval_option {
20942a62512bSSteven Rostedt    my ($option, $i) = @_;
20952a62512bSSteven Rostedt
20962a62512bSSteven Rostedt    # Add space to evaluate the character before $
20972a62512bSSteven Rostedt    $option = " $option";
20982a62512bSSteven Rostedt    my $retval = "";
20992a62512bSSteven Rostedt
21002a62512bSSteven Rostedt    while ($option =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) {
21012a62512bSSteven Rostedt	my $start = $1;
21022a62512bSSteven Rostedt	my $var = $2;
21032a62512bSSteven Rostedt	my $end = $3;
21042a62512bSSteven Rostedt
21052a62512bSSteven Rostedt	# Append beginning of line
21062a62512bSSteven Rostedt	$retval = "$retval$start";
21072a62512bSSteven Rostedt
21082a62512bSSteven Rostedt	# If the iteration option OPT[$i] exists, then use that.
21092a62512bSSteven Rostedt	# otherwise see if the default OPT (without [$i]) exists.
21102a62512bSSteven Rostedt
21112a62512bSSteven Rostedt	my $o = "$var\[$i\]";
21122a62512bSSteven Rostedt
21132a62512bSSteven Rostedt	if (defined($opt{$o})) {
21142a62512bSSteven Rostedt	    $o = $opt{$o};
21152a62512bSSteven Rostedt	    $retval = "$retval$o";
21162a62512bSSteven Rostedt	} elsif (defined($opt{$var})) {
21172a62512bSSteven Rostedt	    $o = $opt{$var};
21182a62512bSSteven Rostedt	    $retval = "$retval$o";
21192a62512bSSteven Rostedt	} else {
21202a62512bSSteven Rostedt	    $retval = "$retval\$\{$var\}";
21212a62512bSSteven Rostedt	}
21222a62512bSSteven Rostedt
21232a62512bSSteven Rostedt	$option = $end;
21242a62512bSSteven Rostedt    }
21252a62512bSSteven Rostedt
21262a62512bSSteven Rostedt    $retval = "$retval$option";
21272a62512bSSteven Rostedt
21282a62512bSSteven Rostedt    $retval =~ s/^ //;
21292a62512bSSteven Rostedt
21302a62512bSSteven Rostedt    return $retval;
21312a62512bSSteven Rostedt}
21322a62512bSSteven Rostedt
21332a62512bSSteven Rostedtsub set_test_option {
21342a62512bSSteven Rostedt    my ($name, $i) = @_;
21352a62512bSSteven Rostedt
21362a62512bSSteven Rostedt    my $option = __set_test_option($name, $i);
21372a62512bSSteven Rostedt    return $option if (!defined($option));
21382a62512bSSteven Rostedt
21392a62512bSSteven Rostedt    my $prev = "";
21402a62512bSSteven Rostedt
21412a62512bSSteven Rostedt    # Since an option can evaluate to another option,
21422a62512bSSteven Rostedt    # keep iterating until we do not evaluate any more
21432a62512bSSteven Rostedt    # options.
21442a62512bSSteven Rostedt    my $r = 0;
21452a62512bSSteven Rostedt    while ($prev ne $option) {
21462a62512bSSteven Rostedt	# Check for recursive evaluations.
21472a62512bSSteven Rostedt	# 100 deep should be more than enough.
21482a62512bSSteven Rostedt	if ($r++ > 100) {
21492a62512bSSteven Rostedt	    die "Over 100 evaluations accurred with $name\n" .
21502a62512bSSteven Rostedt		"Check for recursive variables\n";
21512a62512bSSteven Rostedt	}
21522a62512bSSteven Rostedt	$prev = $option;
21532a62512bSSteven Rostedt	$option = eval_option($option, $i);
21542a62512bSSteven Rostedt    }
21552a62512bSSteven Rostedt
21562a62512bSSteven Rostedt    return $option;
21572a62512bSSteven Rostedt}
21582a62512bSSteven Rostedt
21592545eb61SSteven Rostedt# First we need to do is the builds
2160a75fececSSteven Rostedtfor (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
21612545eb61SSteven Rostedt
2162576f627cSSteven Rostedt    $iteration = $i;
2163576f627cSSteven Rostedt
2164a75fececSSteven Rostedt    my $makecmd = set_test_option("MAKE_CMD", $i);
2165a75fececSSteven Rostedt
2166a75fececSSteven Rostedt    $machine = set_test_option("MACHINE", $i);
2167e48c5293SSteven Rostedt    $ssh_user = set_test_option("SSH_USER", $i);
2168a75fececSSteven Rostedt    $tmpdir = set_test_option("TMP_DIR", $i);
2169a75fececSSteven Rostedt    $outputdir = set_test_option("OUTPUT_DIR", $i);
2170a75fececSSteven Rostedt    $builddir = set_test_option("BUILD_DIR", $i);
2171a75fececSSteven Rostedt    $test_type = set_test_option("TEST_TYPE", $i);
2172a75fececSSteven Rostedt    $build_type = set_test_option("BUILD_TYPE", $i);
2173a75fececSSteven Rostedt    $build_options = set_test_option("BUILD_OPTIONS", $i);
2174a75fececSSteven Rostedt    $power_cycle = set_test_option("POWER_CYCLE", $i);
2175e48c5293SSteven Rostedt    $reboot = set_test_option("REBOOT", $i);
2176a75fececSSteven Rostedt    $noclean = set_test_option("BUILD_NOCLEAN", $i);
2177a75fececSSteven Rostedt    $minconfig = set_test_option("MIN_CONFIG", $i);
2178a75fececSSteven Rostedt    $run_test = set_test_option("TEST", $i);
2179a75fececSSteven Rostedt    $addconfig = set_test_option("ADD_CONFIG", $i);
2180a75fececSSteven Rostedt    $reboot_type = set_test_option("REBOOT_TYPE", $i);
2181a75fececSSteven Rostedt    $grub_menu = set_test_option("GRUB_MENU", $i);
21828b37ca8cSSteven Rostedt    $post_install = set_test_option("POST_INSTALL", $i);
2183a75fececSSteven Rostedt    $reboot_script = set_test_option("REBOOT_SCRIPT", $i);
2184a75fececSSteven Rostedt    $reboot_on_error = set_test_option("REBOOT_ON_ERROR", $i);
2185a75fececSSteven Rostedt    $poweroff_on_error = set_test_option("POWEROFF_ON_ERROR", $i);
2186a75fececSSteven Rostedt    $die_on_failure = set_test_option("DIE_ON_FAILURE", $i);
2187a75fececSSteven Rostedt    $power_off = set_test_option("POWER_OFF", $i);
2188576f627cSSteven Rostedt    $powercycle_after_reboot = set_test_option("POWERCYCLE_AFTER_REBOOT", $i);
2189576f627cSSteven Rostedt    $poweroff_after_halt = set_test_option("POWEROFF_AFTER_HALT", $i);
2190a75fececSSteven Rostedt    $sleep_time = set_test_option("SLEEP_TIME", $i);
2191a75fececSSteven Rostedt    $bisect_sleep_time = set_test_option("BISECT_SLEEP_TIME", $i);
219227d934b2SSteven Rostedt    $patchcheck_sleep_time = set_test_option("PATCHCHECK_SLEEP_TIME", $i);
2193c960bb9fSSteven Rostedt    $bisect_manual = set_test_option("BISECT_MANUAL", $i);
2194c23dca7cSSteven Rostedt    $bisect_skip = set_test_option("BISECT_SKIP", $i);
219530f75da5SSteven Rostedt    $config_bisect_good = set_test_option("CONFIG_BISECT_GOOD", $i);
2196a75fececSSteven Rostedt    $store_failures = set_test_option("STORE_FAILURES", $i);
2197*9064af52SSteven Rostedt    $test_name = set_test_option("TEST_NAME", $i);
2198a75fececSSteven Rostedt    $timeout = set_test_option("TIMEOUT", $i);
2199a75fececSSteven Rostedt    $booted_timeout = set_test_option("BOOTED_TIMEOUT", $i);
2200a75fececSSteven Rostedt    $console = set_test_option("CONSOLE", $i);
2201f1a5b962SSteven Rostedt    $detect_triplefault = set_test_option("DETECT_TRIPLE_FAULT", $i);
2202a75fececSSteven Rostedt    $success_line = set_test_option("SUCCESS_LINE", $i);
22031c8a617aSSteven Rostedt    $stop_after_success = set_test_option("STOP_AFTER_SUCCESS", $i);
22041c8a617aSSteven Rostedt    $stop_after_failure = set_test_option("STOP_AFTER_FAILURE", $i);
22052d01b26aSSteven Rostedt    $stop_test_after = set_test_option("STOP_TEST_AFTER", $i);
2206a75fececSSteven Rostedt    $build_target = set_test_option("BUILD_TARGET", $i);
2207e48c5293SSteven Rostedt    $ssh_exec = set_test_option("SSH_EXEC", $i);
2208e48c5293SSteven Rostedt    $scp_to_target = set_test_option("SCP_TO_TARGET", $i);
2209a75fececSSteven Rostedt    $target_image = set_test_option("TARGET_IMAGE", $i);
2210a75fececSSteven Rostedt    $localversion = set_test_option("LOCALVERSION", $i);
2211a75fececSSteven Rostedt
2212a75fececSSteven Rostedt    chdir $builddir || die "can't change directory to $builddir";
2213a75fececSSteven Rostedt
2214a75fececSSteven Rostedt    if (!-d $tmpdir) {
2215a75fececSSteven Rostedt	mkpath($tmpdir) or
2216a75fececSSteven Rostedt	    die "can't create $tmpdir";
2217a75fececSSteven Rostedt    }
2218a75fececSSteven Rostedt
2219e48c5293SSteven Rostedt    $ENV{"SSH_USER"} = $ssh_user;
2220e48c5293SSteven Rostedt    $ENV{"MACHINE"} = $machine;
2221e48c5293SSteven Rostedt
2222a75fececSSteven Rostedt    $target = "$ssh_user\@$machine";
2223a75fececSSteven Rostedt
2224a75fececSSteven Rostedt    $buildlog = "$tmpdir/buildlog-$machine";
2225a75fececSSteven Rostedt    $dmesg = "$tmpdir/dmesg-$machine";
2226a75fececSSteven Rostedt    $make = "$makecmd O=$outputdir";
222751ad1dd1SSteven Rostedt    $output_config = "$outputdir/.config";
2228a75fececSSteven Rostedt
2229a75fececSSteven Rostedt    if ($reboot_type eq "grub") {
2230576f627cSSteven Rostedt	dodie "GRUB_MENU not defined" if (!defined($grub_menu));
2231a75fececSSteven Rostedt    } elsif (!defined($reboot_script)) {
2232576f627cSSteven Rostedt	dodie "REBOOT_SCRIPT not defined"
2233a75fececSSteven Rostedt    }
2234a75fececSSteven Rostedt
2235a75fececSSteven Rostedt    my $run_type = $build_type;
2236a75fececSSteven Rostedt    if ($test_type eq "patchcheck") {
2237a75fececSSteven Rostedt	$run_type = $opt{"PATCHCHECK_TYPE[$i]"};
2238a75fececSSteven Rostedt    } elsif ($test_type eq "bisect") {
2239a75fececSSteven Rostedt	$run_type = $opt{"BISECT_TYPE[$i]"};
22400a05c769SSteven Rostedt    } elsif ($test_type eq "config_bisect") {
22410a05c769SSteven Rostedt	$run_type = $opt{"CONFIG_BISECT_TYPE[$i]"};
2242a75fececSSteven Rostedt    }
2243a75fececSSteven Rostedt
2244a75fececSSteven Rostedt    # mistake in config file?
2245a75fececSSteven Rostedt    if (!defined($run_type)) {
2246a75fececSSteven Rostedt	$run_type = "ERROR";
2247a75fececSSteven Rostedt    }
22482545eb61SSteven Rostedt
22492545eb61SSteven Rostedt    doprint "\n\n";
2250a75fececSSteven Rostedt    doprint "RUNNING TEST $i of $opt{NUM_TESTS} with option $test_type $run_type\n\n";
22517faafbd6SSteven Rostedt
22527faafbd6SSteven Rostedt    unlink $dmesg;
22537faafbd6SSteven Rostedt    unlink $buildlog;
22542545eb61SSteven Rostedt
22552b7d9b21SSteven Rostedt    if (!defined($minconfig)) {
22562b7d9b21SSteven Rostedt	$minconfig = $addconfig;
22572b7d9b21SSteven Rostedt
22582b7d9b21SSteven Rostedt    } elsif (defined($addconfig)) {
22599be2e6b5SSteven Rostedt	run_command "cat $addconfig $minconfig > $tmpdir/add_config" or
22602b7d9b21SSteven Rostedt	    dodie "Failed to create temp config";
22619be2e6b5SSteven Rostedt	$minconfig = "$tmpdir/add_config";
22622b7d9b21SSteven Rostedt    }
22632b7d9b21SSteven Rostedt
22646c5ee0beSSteven Rostedt    my $checkout = $opt{"CHECKOUT[$i]"};
22656c5ee0beSSteven Rostedt    if (defined($checkout)) {
22666c5ee0beSSteven Rostedt	run_command "git checkout $checkout" or
22676c5ee0beSSteven Rostedt	    die "failed to checkout $checkout";
22686c5ee0beSSteven Rostedt    }
22696c5ee0beSSteven Rostedt
2270a75fececSSteven Rostedt    if ($test_type eq "bisect") {
22715f9b6cedSSteven Rostedt	bisect $i;
22725f9b6cedSSteven Rostedt	next;
22730a05c769SSteven Rostedt    } elsif ($test_type eq "config_bisect") {
22740a05c769SSteven Rostedt	config_bisect $i;
22750a05c769SSteven Rostedt	next;
2276a75fececSSteven Rostedt    } elsif ($test_type eq "patchcheck") {
22776c5ee0beSSteven Rostedt	patchcheck $i;
22786c5ee0beSSteven Rostedt	next;
22795f9b6cedSSteven Rostedt    }
22805f9b6cedSSteven Rostedt
22817faafbd6SSteven Rostedt    if ($build_type ne "nobuild") {
22827faafbd6SSteven Rostedt	build $build_type or next;
22832545eb61SSteven Rostedt    }
22842545eb61SSteven Rostedt
2285a75fececSSteven Rostedt    if ($test_type ne "build") {
22865f9b6cedSSteven Rostedt	get_grub_index;
22875f9b6cedSSteven Rostedt	get_version;
22882545eb61SSteven Rostedt	install;
22895a391fbfSSteven Rostedt
22907faafbd6SSteven Rostedt	my $failed = 0;
22917faafbd6SSteven Rostedt	start_monitor;
22927faafbd6SSteven Rostedt	monitor or $failed = 1;;
2293a75fececSSteven Rostedt
2294a75fececSSteven Rostedt	if (!$failed && $test_type ne "boot" && defined($run_test)) {
22957faafbd6SSteven Rostedt	    do_run_test or $failed = 1;
22965a391fbfSSteven Rostedt	}
22977faafbd6SSteven Rostedt	end_monitor;
22987faafbd6SSteven Rostedt	next if ($failed);
2299a75fececSSteven Rostedt    }
23005a391fbfSSteven Rostedt
23015f9b6cedSSteven Rostedt    success $i;
230275c3fda7SSteven Rostedt}
23032545eb61SSteven Rostedt
23045c42fc5bSSteven Rostedtif ($opt{"POWEROFF_ON_SUCCESS"}) {
230575c3fda7SSteven Rostedt    halt;
2306576f627cSSteven Rostedt} elsif ($opt{"REBOOT_ON_SUCCESS"} && !do_not_reboot) {
230775c3fda7SSteven Rostedt    reboot;
23085c42fc5bSSteven Rostedt}
230975c3fda7SSteven Rostedt
2310e48c5293SSteven Rostedtdoprint "\n    $successes of $opt{NUM_TESTS} tests were successful\n\n";
2311e48c5293SSteven Rostedt
23122545eb61SSteven Rostedtexit 0;
2313