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