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