xref: /openbmc/linux/tools/testing/ktest/ktest.pl (revision 3a0e75ad)
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 $rin;
1884    my $rout;
1885    my $nr;
1886    my $buf;
1887    my $line;
1888    my $ch;
1889
1890    if (!defined($time)) {
1891	$time = $timeout;
1892    }
1893
1894    $rin = '';
1895    vec($rin, fileno($fp), 1) = 1;
1896    vec($rin, fileno(\*STDIN), 1) = 1;
1897
1898    while (1) {
1899	$nr = select($rout=$rin, undef, undef, $time);
1900
1901	if ($nr <= 0) {
1902	    return undef;
1903	}
1904
1905	# copy data from stdin to the console
1906	if (vec($rout, fileno(\*STDIN), 1) == 1) {
1907	    sysread(\*STDIN, $buf, 1000);
1908	    syswrite($fp, $buf, 1000);
1909	    next;
1910	}
1911
1912	$line = "";
1913
1914	# try to read one char at a time
1915	while (sysread $fp, $ch, 1) {
1916	    $line .= $ch;
1917	    last if ($ch eq "\n");
1918	}
1919
1920	if (!length($line)) {
1921	    return undef;
1922	}
1923
1924	return $line;
1925    }
1926}
1927
1928sub reboot_to {
1929    if (defined($switch_to_test)) {
1930	run_command $switch_to_test;
1931    }
1932
1933    if ($reboot_type eq "grub") {
1934	run_ssh "'(echo \"savedefault --default=$grub_number --once\" | grub --batch)'";
1935    } elsif ($reboot_type eq "grub2") {
1936	run_ssh "$grub_reboot $grub_number";
1937    } elsif ($reboot_type eq "syslinux") {
1938	run_ssh "$syslinux --once \\\"$syslinux_label\\\" $syslinux_path";
1939    } elsif (defined $reboot_script) {
1940	run_command "$reboot_script";
1941    }
1942    reboot;
1943}
1944
1945sub get_sha1 {
1946    my ($commit) = @_;
1947
1948    doprint "git rev-list --max-count=1 $commit ... ";
1949    my $sha1 = `git rev-list --max-count=1 $commit`;
1950    my $ret = $?;
1951
1952    logit $sha1;
1953
1954    if ($ret) {
1955	doprint "FAILED\n";
1956	dodie "Failed to get git $commit";
1957    }
1958
1959    print "SUCCESS\n";
1960
1961    chomp $sha1;
1962
1963    return $sha1;
1964}
1965
1966sub monitor {
1967    my $booted = 0;
1968    my $bug = 0;
1969    my $bug_ignored = 0;
1970    my $skip_call_trace = 0;
1971    my $loops;
1972
1973    my $start_time = time;
1974
1975    wait_for_monitor 5;
1976
1977    my $line;
1978    my $full_line = "";
1979
1980    open(DMESG, "> $dmesg") or
1981	die "unable to write to $dmesg";
1982
1983    reboot_to;
1984
1985    my $success_start;
1986    my $failure_start;
1987    my $monitor_start = time;
1988    my $done = 0;
1989    my $version_found = 0;
1990
1991    while (!$done) {
1992
1993	if ($bug && defined($stop_after_failure) &&
1994	    $stop_after_failure >= 0) {
1995	    my $time = $stop_after_failure - (time - $failure_start);
1996	    $line = wait_for_input($monitor_fp, $time);
1997	    if (!defined($line)) {
1998		doprint "bug timed out after $booted_timeout seconds\n";
1999		doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
2000		last;
2001	    }
2002	} elsif ($booted) {
2003	    $line = wait_for_input($monitor_fp, $booted_timeout);
2004	    if (!defined($line)) {
2005		my $s = $booted_timeout == 1 ? "" : "s";
2006		doprint "Successful boot found: break after $booted_timeout second$s\n";
2007		last;
2008	    }
2009	} else {
2010	    $line = wait_for_input($monitor_fp);
2011	    if (!defined($line)) {
2012		my $s = $timeout == 1 ? "" : "s";
2013		doprint "Timed out after $timeout second$s\n";
2014		last;
2015	    }
2016	}
2017
2018	doprint $line;
2019	print DMESG $line;
2020
2021	# we are not guaranteed to get a full line
2022	$full_line .= $line;
2023
2024	if ($full_line =~ /$success_line/) {
2025	    $booted = 1;
2026	    $success_start = time;
2027	}
2028
2029	if ($booted && defined($stop_after_success) &&
2030	    $stop_after_success >= 0) {
2031	    my $now = time;
2032	    if ($now - $success_start >= $stop_after_success) {
2033		doprint "Test forced to stop after $stop_after_success seconds after success\n";
2034		last;
2035	    }
2036	}
2037
2038	if ($full_line =~ /\[ backtrace testing \]/) {
2039	    $skip_call_trace = 1;
2040	}
2041
2042	if ($full_line =~ /call trace:/i) {
2043	    if (!$bug && !$skip_call_trace) {
2044		if ($ignore_errors) {
2045		    $bug_ignored = 1;
2046		} else {
2047		    $bug = 1;
2048		    $failure_start = time;
2049		}
2050	    }
2051	}
2052
2053	if ($bug && defined($stop_after_failure) &&
2054	    $stop_after_failure >= 0) {
2055	    my $now = time;
2056	    if ($now - $failure_start >= $stop_after_failure) {
2057		doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
2058		last;
2059	    }
2060	}
2061
2062	if ($full_line =~ /\[ end of backtrace testing \]/) {
2063	    $skip_call_trace = 0;
2064	}
2065
2066	if ($full_line =~ /Kernel panic -/) {
2067	    $failure_start = time;
2068	    $bug = 1;
2069	}
2070
2071	# Detect triple faults by testing the banner
2072	if ($full_line =~ /\bLinux version (\S+).*\n/) {
2073	    if ($1 eq $version) {
2074		$version_found = 1;
2075	    } elsif ($version_found && $detect_triplefault) {
2076		# We already booted into the kernel we are testing,
2077		# but now we booted into another kernel?
2078		# Consider this a triple fault.
2079		doprint "Already booted in Linux kernel $version, but now\n";
2080		doprint "we booted into Linux kernel $1.\n";
2081		doprint "Assuming that this is a triple fault.\n";
2082		doprint "To disable this: set DETECT_TRIPLE_FAULT to 0\n";
2083		last;
2084	    }
2085	}
2086
2087	if ($line =~ /\n/) {
2088	    $full_line = "";
2089	}
2090
2091	if ($stop_test_after > 0 && !$booted && !$bug) {
2092	    if (time - $monitor_start > $stop_test_after) {
2093		doprint "STOP_TEST_AFTER ($stop_test_after seconds) timed out\n";
2094		$done = 1;
2095	    }
2096	}
2097    }
2098
2099    my $end_time = time;
2100    $reboot_time = $end_time - $start_time;
2101
2102    close(DMESG);
2103
2104    if ($bug) {
2105	return 0 if ($in_bisect);
2106	fail "failed - got a bug report" and return 0;
2107    }
2108
2109    if (!$booted) {
2110	return 0 if ($in_bisect);
2111	fail "failed - never got a boot prompt." and return 0;
2112    }
2113
2114    if ($bug_ignored) {
2115	doprint "WARNING: Call Trace detected but ignored due to IGNORE_ERRORS=1\n";
2116    }
2117
2118    return 1;
2119}
2120
2121sub eval_kernel_version {
2122    my ($option) = @_;
2123
2124    $option =~ s/\$KERNEL_VERSION/$version/g;
2125
2126    return $option;
2127}
2128
2129sub do_post_install {
2130
2131    return if (!defined($post_install));
2132
2133    my $cp_post_install = eval_kernel_version $post_install;
2134    run_command "$cp_post_install" or
2135	dodie "Failed to run post install";
2136}
2137
2138# Sometimes the reboot fails, and will hang. We try to ssh to the box
2139# and if we fail, we force another reboot, that should powercycle it.
2140sub test_booted {
2141    if (!run_ssh "echo testing connection") {
2142	reboot $sleep_time;
2143    }
2144}
2145
2146sub install {
2147
2148    return if ($no_install);
2149
2150    my $start_time = time;
2151
2152    if (defined($pre_install)) {
2153	my $cp_pre_install = eval_kernel_version $pre_install;
2154	run_command "$cp_pre_install" or
2155	    dodie "Failed to run pre install";
2156    }
2157
2158    my $cp_target = eval_kernel_version $target_image;
2159
2160    test_booted;
2161
2162    run_scp_install "$outputdir/$build_target", "$cp_target" or
2163	dodie "failed to copy image";
2164
2165    my $install_mods = 0;
2166
2167    # should we process modules?
2168    $install_mods = 0;
2169    open(IN, "$output_config") or dodie("Can't read config file");
2170    while (<IN>) {
2171	if (/CONFIG_MODULES(=y)?/) {
2172	    if (defined($1)) {
2173		$install_mods = 1;
2174		last;
2175	    }
2176	}
2177    }
2178    close(IN);
2179
2180    if (!$install_mods) {
2181	do_post_install;
2182	doprint "No modules needed\n";
2183	my $end_time = time;
2184	$install_time = $end_time - $start_time;
2185	return;
2186    }
2187
2188    run_command "$make INSTALL_MOD_STRIP=1 INSTALL_MOD_PATH=$tmpdir modules_install" or
2189	dodie "Failed to install modules";
2190
2191    my $modlib = "/lib/modules/$version";
2192    my $modtar = "ktest-mods.tar.bz2";
2193
2194    run_ssh "rm -rf $modlib" or
2195	dodie "failed to remove old mods: $modlib";
2196
2197    # would be nice if scp -r did not follow symbolic links
2198    run_command "cd $tmpdir && tar -cjf $modtar lib/modules/$version" or
2199	dodie "making tarball";
2200
2201    run_scp_mod "$tmpdir/$modtar", "/tmp" or
2202	dodie "failed to copy modules";
2203
2204    unlink "$tmpdir/$modtar";
2205
2206    run_ssh "'(cd / && tar xjf /tmp/$modtar)'" or
2207	dodie "failed to tar modules";
2208
2209    run_ssh "rm -f /tmp/$modtar";
2210
2211    do_post_install;
2212
2213    my $end_time = time;
2214    $install_time = $end_time - $start_time;
2215}
2216
2217sub get_version {
2218    # get the release name
2219    return if ($have_version);
2220    doprint "$make kernelrelease ... ";
2221    $version = `$make -s kernelrelease | tail -1`;
2222    chomp($version);
2223    doprint "$version\n";
2224    $have_version = 1;
2225}
2226
2227sub start_monitor_and_install {
2228    # Make sure the stable kernel has finished booting
2229
2230    # Install bisects, don't need console
2231    if (defined $console) {
2232	start_monitor;
2233	wait_for_monitor 5;
2234	end_monitor;
2235    }
2236
2237    get_grub_index;
2238    get_version;
2239    install;
2240
2241    start_monitor if (defined $console);
2242    return monitor;
2243}
2244
2245my $check_build_re = ".*:.*(warning|error|Error):.*";
2246my $utf8_quote = "\\x{e2}\\x{80}(\\x{98}|\\x{99})";
2247
2248sub process_warning_line {
2249    my ($line) = @_;
2250
2251    chomp $line;
2252
2253    # for distcc heterogeneous systems, some compilers
2254    # do things differently causing warning lines
2255    # to be slightly different. This makes an attempt
2256    # to fixe those issues.
2257
2258    # chop off the index into the line
2259    # using distcc, some compilers give different indexes
2260    # depending on white space
2261    $line =~ s/^(\s*\S+:\d+:)\d+/$1/;
2262
2263    # Some compilers use UTF-8 extended for quotes and some don't.
2264    $line =~ s/$utf8_quote/'/g;
2265
2266    return $line;
2267}
2268
2269# Read buildlog and check against warnings file for any
2270# new warnings.
2271#
2272# Returns 1 if OK
2273#         0 otherwise
2274sub check_buildlog {
2275    return 1 if (!defined $warnings_file);
2276
2277    my %warnings_list;
2278
2279    # Failed builds should not reboot the target
2280    my $save_no_reboot = $no_reboot;
2281    $no_reboot = 1;
2282
2283    if (-f $warnings_file) {
2284	open(IN, $warnings_file) or
2285	    dodie "Error opening $warnings_file";
2286
2287	while (<IN>) {
2288	    if (/$check_build_re/) {
2289		my $warning = process_warning_line $_;
2290
2291		$warnings_list{$warning} = 1;
2292	    }
2293	}
2294	close(IN);
2295    }
2296
2297    # If warnings file didn't exist, and WARNINGS_FILE exist,
2298    # then we fail on any warning!
2299
2300    open(IN, $buildlog) or dodie "Can't open $buildlog";
2301    while (<IN>) {
2302	if (/$check_build_re/) {
2303	    my $warning = process_warning_line $_;
2304
2305	    if (!defined $warnings_list{$warning}) {
2306		fail "New warning found (not in $warnings_file)\n$_\n";
2307		$no_reboot = $save_no_reboot;
2308		return 0;
2309	    }
2310	}
2311    }
2312    $no_reboot = $save_no_reboot;
2313    close(IN);
2314}
2315
2316sub check_patch_buildlog {
2317    my ($patch) = @_;
2318
2319    my @files = `git show $patch | diffstat -l`;
2320
2321    foreach my $file (@files) {
2322	chomp $file;
2323    }
2324
2325    open(IN, "git show $patch |") or
2326	dodie "failed to show $patch";
2327    while (<IN>) {
2328	if (m,^--- a/(.*),) {
2329	    chomp $1;
2330	    $files[$#files] = $1;
2331	}
2332    }
2333    close(IN);
2334
2335    open(IN, $buildlog) or dodie "Can't open $buildlog";
2336    while (<IN>) {
2337	if (/^\s*(.*?):.*(warning|error)/) {
2338	    my $err = $1;
2339	    foreach my $file (@files) {
2340		my $fullpath = "$builddir/$file";
2341		if ($file eq $err || $fullpath eq $err) {
2342		    fail "$file built with warnings" and return 0;
2343		}
2344	    }
2345	}
2346    }
2347    close(IN);
2348
2349    return 1;
2350}
2351
2352sub apply_min_config {
2353    my $outconfig = "$output_config.new";
2354
2355    # Read the config file and remove anything that
2356    # is in the force_config hash (from minconfig and others)
2357    # then add the force config back.
2358
2359    doprint "Applying minimum configurations into $output_config.new\n";
2360
2361    open (OUT, ">$outconfig") or
2362	dodie "Can't create $outconfig";
2363
2364    if (-f $output_config) {
2365	open (IN, $output_config) or
2366	    dodie "Failed to open $output_config";
2367	while (<IN>) {
2368	    if (/^(# )?(CONFIG_[^\s=]*)/) {
2369		next if (defined($force_config{$2}));
2370	    }
2371	    print OUT;
2372	}
2373	close IN;
2374    }
2375    foreach my $config (keys %force_config) {
2376	print OUT "$force_config{$config}\n";
2377    }
2378    close OUT;
2379
2380    run_command "mv $outconfig $output_config";
2381}
2382
2383sub make_oldconfig {
2384
2385    my @force_list = keys %force_config;
2386
2387    if ($#force_list >= 0) {
2388	apply_min_config;
2389    }
2390
2391    if (!run_command "$make olddefconfig") {
2392	# Perhaps olddefconfig doesn't exist in this version of the kernel
2393	# try oldnoconfig
2394	doprint "olddefconfig failed, trying make oldnoconfig\n";
2395	if (!run_command "$make oldnoconfig") {
2396	    doprint "oldnoconfig failed, trying yes '' | make oldconfig\n";
2397	    # try a yes '' | oldconfig
2398	    run_command "yes '' | $make oldconfig" or
2399		dodie "failed make config oldconfig";
2400	}
2401    }
2402}
2403
2404# read a config file and use this to force new configs.
2405sub load_force_config {
2406    my ($config) = @_;
2407
2408    doprint "Loading force configs from $config\n";
2409    open(IN, $config) or
2410	dodie "failed to read $config";
2411    while (<IN>) {
2412	chomp;
2413	if (/^(CONFIG[^\s=]*)(\s*=.*)/) {
2414	    $force_config{$1} = $_;
2415	} elsif (/^# (CONFIG_\S*) is not set/) {
2416	    $force_config{$1} = $_;
2417	}
2418    }
2419    close IN;
2420}
2421
2422sub build {
2423    my ($type) = @_;
2424
2425    unlink $buildlog;
2426
2427    my $start_time = time;
2428
2429    # Failed builds should not reboot the target
2430    my $save_no_reboot = $no_reboot;
2431    $no_reboot = 1;
2432
2433    # Calculate a new version from here.
2434    $have_version = 0;
2435
2436    if (defined($pre_build)) {
2437	my $ret = run_command $pre_build;
2438	if (!$ret && defined($pre_build_die) &&
2439	    $pre_build_die) {
2440	    dodie "failed to pre_build\n";
2441	}
2442    }
2443
2444    if ($type =~ /^useconfig:(.*)/) {
2445	run_command "cp $1 $output_config" or
2446	    dodie "could not copy $1 to .config";
2447
2448	$type = "oldconfig";
2449    }
2450
2451    # old config can ask questions
2452    if ($type eq "oldconfig") {
2453	$type = "olddefconfig";
2454
2455	# allow for empty configs
2456	run_command "touch $output_config";
2457
2458	if (!$noclean) {
2459	    run_command "mv $output_config $outputdir/config_temp" or
2460		dodie "moving .config";
2461
2462	    run_command "$make mrproper" or dodie "make mrproper";
2463
2464	    run_command "mv $outputdir/config_temp $output_config" or
2465		dodie "moving config_temp";
2466	}
2467
2468    } elsif (!$noclean) {
2469	unlink "$output_config";
2470	run_command "$make mrproper" or
2471	    dodie "make mrproper";
2472    }
2473
2474    # add something to distinguish this build
2475    open(OUT, "> $outputdir/localversion") or dodie("Can't make localversion file");
2476    print OUT "$localversion\n";
2477    close(OUT);
2478
2479    if (defined($minconfig)) {
2480	load_force_config($minconfig);
2481    }
2482
2483    if ($type ne "olddefconfig") {
2484	run_command "$make $type" or
2485	    dodie "failed make config";
2486    }
2487    # Run old config regardless, to enforce min configurations
2488    make_oldconfig;
2489
2490    my $build_ret = run_command "$make $build_options", $buildlog;
2491
2492    if (defined($post_build)) {
2493	# Because a post build may change the kernel version
2494	# do it now.
2495	get_version;
2496	my $ret = run_command $post_build;
2497	if (!$ret && defined($post_build_die) &&
2498	    $post_build_die) {
2499	    dodie "failed to post_build\n";
2500	}
2501    }
2502
2503    if (!$build_ret) {
2504	# bisect may need this to pass
2505	if ($in_bisect) {
2506	    $no_reboot = $save_no_reboot;
2507	    return 0;
2508	}
2509	fail "failed build" and return 0;
2510    }
2511
2512    $no_reboot = $save_no_reboot;
2513
2514    my $end_time = time;
2515    $build_time = $end_time - $start_time;
2516
2517    return 1;
2518}
2519
2520sub halt {
2521    if (!run_ssh "halt" or defined($power_off)) {
2522	if (defined($poweroff_after_halt)) {
2523	    sleep $poweroff_after_halt;
2524	    run_command "$power_off";
2525	}
2526    } else {
2527	# nope? the zap it!
2528	run_command "$power_off";
2529    }
2530}
2531
2532sub success {
2533    my ($i) = @_;
2534
2535    $successes++;
2536
2537    my $name = "";
2538
2539    if (defined($test_name)) {
2540	$name = " ($test_name)";
2541    }
2542
2543    print_times;
2544
2545    doprint "\n\n*******************************************\n";
2546    doprint     "*******************************************\n";
2547    doprint     "KTEST RESULT: TEST $i$name SUCCESS!!!!         **\n";
2548    doprint     "*******************************************\n";
2549    doprint     "*******************************************\n";
2550
2551    if (defined($store_successes)) {
2552        save_logs "success", $store_successes;
2553    }
2554
2555    if ($i != $opt{"NUM_TESTS"} && !do_not_reboot) {
2556	doprint "Reboot and wait $sleep_time seconds\n";
2557	reboot_to_good $sleep_time;
2558    }
2559
2560    if (defined($post_test)) {
2561	run_command $post_test;
2562    }
2563}
2564
2565sub answer_bisect {
2566    for (;;) {
2567	doprint "Pass, fail, or skip? [p/f/s]";
2568	my $ans = <STDIN>;
2569	chomp $ans;
2570	if ($ans eq "p" || $ans eq "P") {
2571	    return 1;
2572	} elsif ($ans eq "f" || $ans eq "F") {
2573	    return 0;
2574	} elsif ($ans eq "s" || $ans eq "S") {
2575	    return -1;
2576	} else {
2577	    print "Please answer 'p', 'f', or 's'\n";
2578	}
2579    }
2580}
2581
2582sub child_run_test {
2583
2584    # child should have no power
2585    $reboot_on_error = 0;
2586    $poweroff_on_error = 0;
2587    $die_on_failure = 1;
2588
2589    run_command $run_test, $testlog;
2590
2591    exit $run_command_status;
2592}
2593
2594my $child_done;
2595
2596sub child_finished {
2597    $child_done = 1;
2598}
2599
2600sub do_run_test {
2601    my $child_pid;
2602    my $child_exit;
2603    my $line;
2604    my $full_line;
2605    my $bug = 0;
2606    my $bug_ignored = 0;
2607
2608    my $start_time = time;
2609
2610    wait_for_monitor 1;
2611
2612    doprint "run test $run_test\n";
2613
2614    $child_done = 0;
2615
2616    $SIG{CHLD} = qw(child_finished);
2617
2618    $child_pid = fork;
2619
2620    child_run_test if (!$child_pid);
2621
2622    $full_line = "";
2623
2624    do {
2625	$line = wait_for_input($monitor_fp, 1);
2626	if (defined($line)) {
2627
2628	    # we are not guaranteed to get a full line
2629	    $full_line .= $line;
2630	    doprint $line;
2631
2632	    if ($full_line =~ /call trace:/i) {
2633		if ($ignore_errors) {
2634		    $bug_ignored = 1;
2635		} else {
2636		    $bug = 1;
2637		}
2638	    }
2639
2640	    if ($full_line =~ /Kernel panic -/) {
2641		$bug = 1;
2642	    }
2643
2644	    if ($line =~ /\n/) {
2645		$full_line = "";
2646	    }
2647	}
2648    } while (!$child_done && !$bug);
2649
2650    if (!$bug && $bug_ignored) {
2651	doprint "WARNING: Call Trace detected but ignored due to IGNORE_ERRORS=1\n";
2652    }
2653
2654    if ($bug) {
2655	my $failure_start = time;
2656	my $now;
2657	do {
2658	    $line = wait_for_input($monitor_fp, 1);
2659	    if (defined($line)) {
2660		doprint $line;
2661	    }
2662	    $now = time;
2663	    if ($now - $failure_start >= $stop_after_failure) {
2664		last;
2665	    }
2666	} while (defined($line));
2667
2668	doprint "Detected kernel crash!\n";
2669	# kill the child with extreme prejudice
2670	kill 9, $child_pid;
2671    }
2672
2673    waitpid $child_pid, 0;
2674    $child_exit = $? >> 8;
2675
2676    my $end_time = time;
2677    $test_time = $end_time - $start_time;
2678
2679    if (!$bug && $in_bisect) {
2680	if (defined($bisect_ret_good)) {
2681	    if ($child_exit == $bisect_ret_good) {
2682		return 1;
2683	    }
2684	}
2685	if (defined($bisect_ret_skip)) {
2686	    if ($child_exit == $bisect_ret_skip) {
2687		return -1;
2688	    }
2689	}
2690	if (defined($bisect_ret_abort)) {
2691	    if ($child_exit == $bisect_ret_abort) {
2692		fail "test abort" and return -2;
2693	    }
2694	}
2695	if (defined($bisect_ret_bad)) {
2696	    if ($child_exit == $bisect_ret_skip) {
2697		return 0;
2698	    }
2699	}
2700	if (defined($bisect_ret_default)) {
2701	    if ($bisect_ret_default eq "good") {
2702		return 1;
2703	    } elsif ($bisect_ret_default eq "bad") {
2704		return 0;
2705	    } elsif ($bisect_ret_default eq "skip") {
2706		return -1;
2707	    } elsif ($bisect_ret_default eq "abort") {
2708		return -2;
2709	    } else {
2710		fail "unknown default action: $bisect_ret_default"
2711		    and return -2;
2712	    }
2713	}
2714    }
2715
2716    if ($bug || $child_exit) {
2717	return 0 if $in_bisect;
2718	fail "test failed" and return 0;
2719    }
2720    return 1;
2721}
2722
2723sub run_git_bisect {
2724    my ($command) = @_;
2725
2726    doprint "$command ... ";
2727
2728    my $output = `$command 2>&1`;
2729    my $ret = $?;
2730
2731    logit $output;
2732
2733    if ($ret) {
2734	doprint "FAILED\n";
2735	dodie "Failed to git bisect";
2736    }
2737
2738    doprint "SUCCESS\n";
2739    if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\))\s+\[([[:xdigit:]]+)\]/) {
2740	doprint "$1 [$2]\n";
2741    } elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) {
2742	$bisect_bad_commit = $1;
2743	doprint "Found bad commit... $1\n";
2744	return 0;
2745    } else {
2746	# we already logged it, just print it now.
2747	print $output;
2748    }
2749
2750    return 1;
2751}
2752
2753sub bisect_reboot {
2754    doprint "Reboot and sleep $bisect_sleep_time seconds\n";
2755    reboot_to_good $bisect_sleep_time;
2756}
2757
2758# returns 1 on success, 0 on failure, -1 on skip
2759sub run_bisect_test {
2760    my ($type, $buildtype) = @_;
2761
2762    my $failed = 0;
2763    my $result;
2764    my $output;
2765    my $ret;
2766
2767    $in_bisect = 1;
2768
2769    build $buildtype or $failed = 1;
2770
2771    if ($type ne "build") {
2772	if ($failed && $bisect_skip) {
2773	    $in_bisect = 0;
2774	    return -1;
2775	}
2776	dodie "Failed on build" if $failed;
2777
2778	# Now boot the box
2779	start_monitor_and_install or $failed = 1;
2780
2781	if ($type ne "boot") {
2782	    if ($failed && $bisect_skip) {
2783		end_monitor;
2784		bisect_reboot;
2785		$in_bisect = 0;
2786		return -1;
2787	    }
2788	    dodie "Failed on boot" if $failed;
2789
2790	    do_run_test or $failed = 1;
2791	}
2792	end_monitor;
2793    }
2794
2795    if ($failed) {
2796	$result = 0;
2797    } else {
2798	$result = 1;
2799    }
2800
2801    # reboot the box to a kernel we can ssh to
2802    if ($type ne "build") {
2803	bisect_reboot;
2804    }
2805    $in_bisect = 0;
2806
2807    return $result;
2808}
2809
2810sub run_bisect {
2811    my ($type) = @_;
2812    my $buildtype = "oldconfig";
2813
2814    # We should have a minconfig to use?
2815    if (defined($minconfig)) {
2816	$buildtype = "useconfig:$minconfig";
2817    }
2818
2819    # If the user sets bisect_tries to less than 1, then no tries
2820    # is a success.
2821    my $ret = 1;
2822
2823    # Still let the user manually decide that though.
2824    if ($bisect_tries < 1 && $bisect_manual) {
2825	$ret = answer_bisect;
2826    }
2827
2828    for (my $i = 0; $i < $bisect_tries; $i++) {
2829	if ($bisect_tries > 1) {
2830	    my $t = $i + 1;
2831	    doprint("Running bisect trial $t of $bisect_tries:\n");
2832	}
2833	$ret = run_bisect_test $type, $buildtype;
2834
2835	if ($bisect_manual) {
2836	    $ret = answer_bisect;
2837	}
2838
2839	last if (!$ret);
2840    }
2841
2842    # Are we looking for where it worked, not failed?
2843    if ($reverse_bisect && $ret >= 0) {
2844	$ret = !$ret;
2845    }
2846
2847    if ($ret > 0) {
2848	return "good";
2849    } elsif ($ret == 0) {
2850	return  "bad";
2851    } elsif ($bisect_skip) {
2852	doprint "HIT A BAD COMMIT ... SKIPPING\n";
2853	return "skip";
2854    }
2855}
2856
2857sub update_bisect_replay {
2858    my $tmp_log = "$tmpdir/ktest_bisect_log";
2859    run_command "git bisect log > $tmp_log" or
2860	die "can't create bisect log";
2861    return $tmp_log;
2862}
2863
2864sub bisect {
2865    my ($i) = @_;
2866
2867    my $result;
2868
2869    die "BISECT_GOOD[$i] not defined\n"	if (!defined($bisect_good));
2870    die "BISECT_BAD[$i] not defined\n"	if (!defined($bisect_bad));
2871    die "BISECT_TYPE[$i] not defined\n"	if (!defined($bisect_type));
2872
2873    my $good = $bisect_good;
2874    my $bad = $bisect_bad;
2875    my $type = $bisect_type;
2876    my $start = $bisect_start;
2877    my $replay = $bisect_replay;
2878    my $start_files = $bisect_files;
2879
2880    if (defined($start_files)) {
2881	$start_files = " -- " . $start_files;
2882    } else {
2883	$start_files = "";
2884    }
2885
2886    # convert to true sha1's
2887    $good = get_sha1($good);
2888    $bad = get_sha1($bad);
2889
2890    if (defined($bisect_reverse) && $bisect_reverse == 1) {
2891	doprint "Performing a reverse bisect (bad is good, good is bad!)\n";
2892	$reverse_bisect = 1;
2893    } else {
2894	$reverse_bisect = 0;
2895    }
2896
2897    # Can't have a test without having a test to run
2898    if ($type eq "test" && !defined($run_test)) {
2899	$type = "boot";
2900    }
2901
2902    # Check if a bisect was running
2903    my $bisect_start_file = "$builddir/.git/BISECT_START";
2904
2905    my $check = $bisect_check;
2906    my $do_check = defined($check) && $check ne "0";
2907
2908    if ( -f $bisect_start_file ) {
2909	print "Bisect in progress found\n";
2910	if ($do_check) {
2911	    print " If you say yes, then no checks of good or bad will be done\n";
2912	}
2913	if (defined($replay)) {
2914	    print "** BISECT_REPLAY is defined in config file **";
2915	    print " Ignore config option and perform new git bisect log?\n";
2916	    if (read_ync " (yes, no, or cancel) ") {
2917		$replay = update_bisect_replay;
2918		$do_check = 0;
2919	    }
2920	} elsif (read_yn "read git log and continue?") {
2921	    $replay = update_bisect_replay;
2922	    $do_check = 0;
2923	}
2924    }
2925
2926    if ($do_check) {
2927
2928	# get current HEAD
2929	my $head = get_sha1("HEAD");
2930
2931	if ($check ne "good") {
2932	    doprint "TESTING BISECT BAD [$bad]\n";
2933	    run_command "git checkout $bad" or
2934		die "Failed to checkout $bad";
2935
2936	    $result = run_bisect $type;
2937
2938	    if ($result ne "bad") {
2939		fail "Tested BISECT_BAD [$bad] and it succeeded" and return 0;
2940	    }
2941	}
2942
2943	if ($check ne "bad") {
2944	    doprint "TESTING BISECT GOOD [$good]\n";
2945	    run_command "git checkout $good" or
2946		die "Failed to checkout $good";
2947
2948	    $result = run_bisect $type;
2949
2950	    if ($result ne "good") {
2951		fail "Tested BISECT_GOOD [$good] and it failed" and return 0;
2952	    }
2953	}
2954
2955	# checkout where we started
2956	run_command "git checkout $head" or
2957	    die "Failed to checkout $head";
2958    }
2959
2960    run_command "git bisect start$start_files" or
2961	dodie "could not start bisect";
2962
2963    if (defined($replay)) {
2964	run_command "git bisect replay $replay" or
2965	    dodie "failed to run replay";
2966    } else {
2967
2968	run_command "git bisect good $good" or
2969	    dodie "could not set bisect good to $good";
2970
2971	run_git_bisect "git bisect bad $bad" or
2972	    dodie "could not set bisect bad to $bad";
2973
2974    }
2975
2976    if (defined($start)) {
2977	run_command "git checkout $start" or
2978	    dodie "failed to checkout $start";
2979    }
2980
2981    my $test;
2982    do {
2983	$result = run_bisect $type;
2984	$test = run_git_bisect "git bisect $result";
2985	print_times;
2986    } while ($test);
2987
2988    run_command "git bisect log" or
2989	dodie "could not capture git bisect log";
2990
2991    run_command "git bisect reset" or
2992	dodie "could not reset git bisect";
2993
2994    doprint "Bad commit was [$bisect_bad_commit]\n";
2995
2996    success $i;
2997}
2998
2999# config_ignore holds the configs that were set (or unset) for
3000# a good config and we will ignore these configs for the rest
3001# of a config bisect. These configs stay as they were.
3002my %config_ignore;
3003
3004# config_set holds what all configs were set as.
3005my %config_set;
3006
3007# config_off holds the set of configs that the bad config had disabled.
3008# We need to record them and set them in the .config when running
3009# olddefconfig, because olddefconfig keeps the defaults.
3010my %config_off;
3011
3012# config_off_tmp holds a set of configs to turn off for now
3013my @config_off_tmp;
3014
3015# config_list is the set of configs that are being tested
3016my %config_list;
3017my %null_config;
3018
3019my %dependency;
3020
3021sub assign_configs {
3022    my ($hash, $config) = @_;
3023
3024    doprint "Reading configs from $config\n";
3025
3026    open (IN, $config)
3027	or dodie "Failed to read $config";
3028
3029    while (<IN>) {
3030	chomp;
3031	if (/^((CONFIG\S*)=.*)/) {
3032	    ${$hash}{$2} = $1;
3033	} elsif (/^(# (CONFIG\S*) is not set)/) {
3034	    ${$hash}{$2} = $1;
3035	}
3036    }
3037
3038    close(IN);
3039}
3040
3041sub process_config_ignore {
3042    my ($config) = @_;
3043
3044    assign_configs \%config_ignore, $config;
3045}
3046
3047sub get_dependencies {
3048    my ($config) = @_;
3049
3050    my $arr = $dependency{$config};
3051    if (!defined($arr)) {
3052	return ();
3053    }
3054
3055    my @deps = @{$arr};
3056
3057    foreach my $dep (@{$arr}) {
3058	print "ADD DEP $dep\n";
3059	@deps = (@deps, get_dependencies $dep);
3060    }
3061
3062    return @deps;
3063}
3064
3065sub save_config {
3066    my ($pc, $file) = @_;
3067
3068    my %configs = %{$pc};
3069
3070    doprint "Saving configs into $file\n";
3071
3072    open(OUT, ">$file") or dodie "Can not write to $file";
3073
3074    foreach my $config (keys %configs) {
3075	print OUT "$configs{$config}\n";
3076    }
3077    close(OUT);
3078}
3079
3080sub create_config {
3081    my ($name, $pc) = @_;
3082
3083    doprint "Creating old config from $name configs\n";
3084
3085    save_config $pc, $output_config;
3086
3087    make_oldconfig;
3088}
3089
3090# compare two config hashes, and return configs with different vals.
3091# It returns B's config values, but you can use A to see what A was.
3092sub diff_config_vals {
3093    my ($pa, $pb) = @_;
3094
3095    # crappy Perl way to pass in hashes.
3096    my %a = %{$pa};
3097    my %b = %{$pb};
3098
3099    my %ret;
3100
3101    foreach my $item (keys %a) {
3102	if (defined($b{$item}) && $b{$item} ne $a{$item}) {
3103	    $ret{$item} = $b{$item};
3104	}
3105    }
3106
3107    return %ret;
3108}
3109
3110# compare two config hashes and return the configs in B but not A
3111sub diff_configs {
3112    my ($pa, $pb) = @_;
3113
3114    my %ret;
3115
3116    # crappy Perl way to pass in hashes.
3117    my %a = %{$pa};
3118    my %b = %{$pb};
3119
3120    foreach my $item (keys %b) {
3121	if (!defined($a{$item})) {
3122	    $ret{$item} = $b{$item};
3123	}
3124    }
3125
3126    return %ret;
3127}
3128
3129# return if two configs are equal or not
3130# 0 is equal +1 b has something a does not
3131# +1 if a and b have a different item.
3132# -1 if a has something b does not
3133sub compare_configs {
3134    my ($pa, $pb) = @_;
3135
3136    my %ret;
3137
3138    # crappy Perl way to pass in hashes.
3139    my %a = %{$pa};
3140    my %b = %{$pb};
3141
3142    foreach my $item (keys %b) {
3143	if (!defined($a{$item})) {
3144	    return 1;
3145	}
3146	if ($a{$item} ne $b{$item}) {
3147	    return 1;
3148	}
3149    }
3150
3151    foreach my $item (keys %a) {
3152	if (!defined($b{$item})) {
3153	    return -1;
3154	}
3155    }
3156
3157    return 0;
3158}
3159
3160sub run_config_bisect_test {
3161    my ($type) = @_;
3162
3163    my $ret = run_bisect_test $type, "oldconfig";
3164
3165    if ($bisect_manual) {
3166	$ret = answer_bisect;
3167    }
3168
3169    return $ret;
3170}
3171
3172sub process_failed {
3173    my ($config) = @_;
3174
3175    doprint "\n\n***************************************\n";
3176    doprint "Found bad config: $config\n";
3177    doprint "***************************************\n\n";
3178}
3179
3180# used for config bisecting
3181my $good_config;
3182my $bad_config;
3183
3184sub process_new_config {
3185    my ($tc, $nc, $gc, $bc) = @_;
3186
3187    my %tmp_config = %{$tc};
3188    my %good_configs = %{$gc};
3189    my %bad_configs = %{$bc};
3190
3191    my %new_configs;
3192
3193    my $runtest = 1;
3194    my $ret;
3195
3196    create_config "tmp_configs", \%tmp_config;
3197    assign_configs \%new_configs, $output_config;
3198
3199    $ret = compare_configs \%new_configs, \%bad_configs;
3200    if (!$ret) {
3201	doprint "New config equals bad config, try next test\n";
3202	$runtest = 0;
3203    }
3204
3205    if ($runtest) {
3206	$ret = compare_configs \%new_configs, \%good_configs;
3207	if (!$ret) {
3208	    doprint "New config equals good config, try next test\n";
3209	    $runtest = 0;
3210	}
3211    }
3212
3213    %{$nc} = %new_configs;
3214
3215    return $runtest;
3216}
3217
3218sub run_config_bisect {
3219    my ($pgood, $pbad) = @_;
3220
3221    my $type = $config_bisect_type;
3222
3223    my %good_configs = %{$pgood};
3224    my %bad_configs = %{$pbad};
3225
3226    my %diff_configs = diff_config_vals \%good_configs, \%bad_configs;
3227    my %b_configs = diff_configs \%good_configs, \%bad_configs;
3228    my %g_configs = diff_configs \%bad_configs, \%good_configs;
3229
3230    my @diff_arr = keys %diff_configs;
3231    my $len_diff = $#diff_arr + 1;
3232
3233    my @b_arr = keys %b_configs;
3234    my $len_b = $#b_arr + 1;
3235
3236    my @g_arr = keys %g_configs;
3237    my $len_g = $#g_arr + 1;
3238
3239    my $runtest = 1;
3240    my %new_configs;
3241    my $ret;
3242
3243    # First, lets get it down to a single subset.
3244    # Is the problem with a difference in values?
3245    # Is the problem with a missing config?
3246    # Is the problem with a config that breaks things?
3247
3248    # Enable all of one set and see if we get a new bad
3249    # or good config.
3250
3251    # first set the good config to the bad values.
3252
3253    doprint "d=$len_diff g=$len_g b=$len_b\n";
3254
3255    # first lets enable things in bad config that are enabled in good config
3256
3257    if ($len_diff > 0) {
3258	if ($len_b > 0 || $len_g > 0) {
3259	    my %tmp_config = %bad_configs;
3260
3261	    doprint "Set tmp config to be bad config with good config values\n";
3262	    foreach my $item (@diff_arr) {
3263		$tmp_config{$item} = $good_configs{$item};
3264	    }
3265
3266	    $runtest = process_new_config \%tmp_config, \%new_configs,
3267			    \%good_configs, \%bad_configs;
3268	}
3269    }
3270
3271    if (!$runtest && $len_diff > 0) {
3272
3273	if ($len_diff == 1) {
3274	    process_failed $diff_arr[0];
3275	    return 1;
3276	}
3277	my %tmp_config = %bad_configs;
3278
3279	my $half = int($#diff_arr / 2);
3280	my @tophalf = @diff_arr[0 .. $half];
3281
3282	doprint "Settings bisect with top half:\n";
3283	doprint "Set tmp config to be bad config with some good config values\n";
3284	foreach my $item (@tophalf) {
3285	    $tmp_config{$item} = $good_configs{$item};
3286	}
3287
3288	$runtest = process_new_config \%tmp_config, \%new_configs,
3289			    \%good_configs, \%bad_configs;
3290
3291	if (!$runtest) {
3292	    my %tmp_config = %bad_configs;
3293
3294	    doprint "Try bottom half\n";
3295
3296	    my @bottomhalf = @diff_arr[$half+1 .. $#diff_arr];
3297
3298	    foreach my $item (@bottomhalf) {
3299		$tmp_config{$item} = $good_configs{$item};
3300	    }
3301
3302	    $runtest = process_new_config \%tmp_config, \%new_configs,
3303			    \%good_configs, \%bad_configs;
3304	}
3305    }
3306
3307    if ($runtest) {
3308	$ret = run_config_bisect_test $type;
3309	if ($ret) {
3310	    doprint "NEW GOOD CONFIG\n";
3311	    %good_configs = %new_configs;
3312	    run_command "mv $good_config ${good_config}.last";
3313	    save_config \%good_configs, $good_config;
3314	    %{$pgood} = %good_configs;
3315	} else {
3316	    doprint "NEW BAD CONFIG\n";
3317	    %bad_configs = %new_configs;
3318	    run_command "mv $bad_config ${bad_config}.last";
3319	    save_config \%bad_configs, $bad_config;
3320	    %{$pbad} = %bad_configs;
3321	}
3322	return 0;
3323    }
3324
3325    fail "Hmm, need to do a mix match?\n";
3326    return -1;
3327}
3328
3329sub config_bisect {
3330    my ($i) = @_;
3331
3332    my $type = $config_bisect_type;
3333    my $ret;
3334
3335    $bad_config = $config_bisect;
3336
3337    if (defined($config_bisect_good)) {
3338	$good_config = $config_bisect_good;
3339    } elsif (defined($minconfig)) {
3340	$good_config = $minconfig;
3341    } else {
3342	doprint "No config specified, checking if defconfig works";
3343	$ret = run_bisect_test $type, "defconfig";
3344	if (!$ret) {
3345	    fail "Have no good config to compare with, please set CONFIG_BISECT_GOOD";
3346	    return 1;
3347	}
3348	$good_config = $output_config;
3349    }
3350
3351    # we don't want min configs to cause issues here.
3352    doprint "Disabling 'MIN_CONFIG' for this test\n";
3353    undef $minconfig;
3354
3355    my %good_configs;
3356    my %bad_configs;
3357    my %tmp_configs;
3358
3359    doprint "Run good configs through make oldconfig\n";
3360    assign_configs \%tmp_configs, $good_config;
3361    create_config "$good_config", \%tmp_configs;
3362    assign_configs \%good_configs, $output_config;
3363
3364    doprint "Run bad configs through make oldconfig\n";
3365    assign_configs \%tmp_configs, $bad_config;
3366    create_config "$bad_config", \%tmp_configs;
3367    assign_configs \%bad_configs, $output_config;
3368
3369    $good_config = "$tmpdir/good_config";
3370    $bad_config = "$tmpdir/bad_config";
3371
3372    save_config \%good_configs, $good_config;
3373    save_config \%bad_configs, $bad_config;
3374
3375    if (defined($config_bisect_check) && $config_bisect_check ne "0") {
3376	if ($config_bisect_check ne "good") {
3377	    doprint "Testing bad config\n";
3378
3379	    $ret = run_bisect_test $type, "useconfig:$bad_config";
3380	    if ($ret) {
3381		fail "Bad config succeeded when expected to fail!";
3382		return 0;
3383	    }
3384	}
3385	if ($config_bisect_check ne "bad") {
3386	    doprint "Testing good config\n";
3387
3388	    $ret = run_bisect_test $type, "useconfig:$good_config";
3389	    if (!$ret) {
3390		fail "Good config failed when expected to succeed!";
3391		return 0;
3392	    }
3393	}
3394    }
3395
3396    do {
3397	$ret = run_config_bisect \%good_configs, \%bad_configs;
3398	print_times;
3399    } while (!$ret);
3400
3401    return $ret if ($ret < 0);
3402
3403    success $i;
3404}
3405
3406sub patchcheck_reboot {
3407    doprint "Reboot and sleep $patchcheck_sleep_time seconds\n";
3408    reboot_to_good $patchcheck_sleep_time;
3409}
3410
3411sub patchcheck {
3412    my ($i) = @_;
3413
3414    die "PATCHCHECK_START[$i] not defined\n"
3415	if (!defined($patchcheck_start));
3416    die "PATCHCHECK_TYPE[$i] not defined\n"
3417	if (!defined($patchcheck_type));
3418
3419    my $start = $patchcheck_start;
3420
3421    my $cherry = $patchcheck_cherry;
3422    if (!defined($cherry)) {
3423	$cherry = 0;
3424    }
3425
3426    my $end = "HEAD";
3427    if (defined($patchcheck_end)) {
3428	$end = $patchcheck_end;
3429    } elsif ($cherry) {
3430	die "PATCHCHECK_END must be defined with PATCHCHECK_CHERRY\n";
3431    }
3432
3433    # Get the true sha1's since we can use things like HEAD~3
3434    $start = get_sha1($start);
3435    $end = get_sha1($end);
3436
3437    my $type = $patchcheck_type;
3438
3439    # Can't have a test without having a test to run
3440    if ($type eq "test" && !defined($run_test)) {
3441	$type = "boot";
3442    }
3443
3444    if ($cherry) {
3445	open (IN, "git cherry -v $start $end|") or
3446	    dodie "could not get git list";
3447    } else {
3448	open (IN, "git log --pretty=oneline $end|") or
3449	    dodie "could not get git list";
3450    }
3451
3452    my @list;
3453
3454    while (<IN>) {
3455	chomp;
3456	# git cherry adds a '+' we want to remove
3457	s/^\+ //;
3458	$list[$#list+1] = $_;
3459	last if (/^$start/);
3460    }
3461    close(IN);
3462
3463    if (!$cherry) {
3464	if ($list[$#list] !~ /^$start/) {
3465	    fail "SHA1 $start not found";
3466	}
3467
3468	# go backwards in the list
3469	@list = reverse @list;
3470    }
3471
3472    doprint("Going to test the following commits:\n");
3473    foreach my $l (@list) {
3474	doprint "$l\n";
3475    }
3476
3477    my $save_clean = $noclean;
3478    my %ignored_warnings;
3479
3480    if (defined($ignore_warnings)) {
3481	foreach my $sha1 (split /\s+/, $ignore_warnings) {
3482	    $ignored_warnings{$sha1} = 1;
3483	}
3484    }
3485
3486    $in_patchcheck = 1;
3487    foreach my $item (@list) {
3488	my $sha1 = $item;
3489	$sha1 =~ s/^([[:xdigit:]]+).*/$1/;
3490
3491	doprint "\nProcessing commit \"$item\"\n\n";
3492
3493	run_command "git checkout $sha1" or
3494	    die "Failed to checkout $sha1";
3495
3496	# only clean on the first and last patch
3497	if ($item eq $list[0] ||
3498	    $item eq $list[$#list]) {
3499	    $noclean = $save_clean;
3500	} else {
3501	    $noclean = 1;
3502	}
3503
3504	if (defined($minconfig)) {
3505	    build "useconfig:$minconfig" or return 0;
3506	} else {
3507	    # ?? no config to use?
3508	    build "oldconfig" or return 0;
3509	}
3510
3511	# No need to do per patch checking if warnings file exists
3512	if (!defined($warnings_file) && !defined($ignored_warnings{$sha1})) {
3513	    check_patch_buildlog $sha1 or return 0;
3514	}
3515
3516	check_buildlog or return 0;
3517
3518	next if ($type eq "build");
3519
3520	my $failed = 0;
3521
3522	start_monitor_and_install or $failed = 1;
3523
3524	if (!$failed && $type ne "boot"){
3525	    do_run_test or $failed = 1;
3526	}
3527	end_monitor;
3528	if ($failed) {
3529	    print_times;
3530	    return 0;
3531	}
3532	patchcheck_reboot;
3533	print_times;
3534    }
3535    $in_patchcheck = 0;
3536    success $i;
3537
3538    return 1;
3539}
3540
3541my %depends;
3542my %depcount;
3543my $iflevel = 0;
3544my @ifdeps;
3545
3546# prevent recursion
3547my %read_kconfigs;
3548
3549sub add_dep {
3550    # $config depends on $dep
3551    my ($config, $dep) = @_;
3552
3553    if (defined($depends{$config})) {
3554	$depends{$config} .= " " . $dep;
3555    } else {
3556	$depends{$config} = $dep;
3557    }
3558
3559    # record the number of configs depending on $dep
3560    if (defined $depcount{$dep}) {
3561	$depcount{$dep}++;
3562    } else {
3563	$depcount{$dep} = 1;
3564    }
3565}
3566
3567# taken from streamline_config.pl
3568sub read_kconfig {
3569    my ($kconfig) = @_;
3570
3571    my $state = "NONE";
3572    my $config;
3573    my @kconfigs;
3574
3575    my $cont = 0;
3576    my $line;
3577
3578
3579    if (! -f $kconfig) {
3580	doprint "file $kconfig does not exist, skipping\n";
3581	return;
3582    }
3583
3584    open(KIN, "$kconfig")
3585	or die "Can't open $kconfig";
3586    while (<KIN>) {
3587	chomp;
3588
3589	# Make sure that lines ending with \ continue
3590	if ($cont) {
3591	    $_ = $line . " " . $_;
3592	}
3593
3594	if (s/\\$//) {
3595	    $cont = 1;
3596	    $line = $_;
3597	    next;
3598	}
3599
3600	$cont = 0;
3601
3602	# collect any Kconfig sources
3603	if (/^source\s*"(.*)"/) {
3604	    $kconfigs[$#kconfigs+1] = $1;
3605	}
3606
3607	# configs found
3608	if (/^\s*(menu)?config\s+(\S+)\s*$/) {
3609	    $state = "NEW";
3610	    $config = $2;
3611
3612	    for (my $i = 0; $i < $iflevel; $i++) {
3613		add_dep $config, $ifdeps[$i];
3614	    }
3615
3616	# collect the depends for the config
3617	} elsif ($state eq "NEW" && /^\s*depends\s+on\s+(.*)$/) {
3618
3619	    add_dep $config, $1;
3620
3621	# Get the configs that select this config
3622	} elsif ($state eq "NEW" && /^\s*select\s+(\S+)/) {
3623
3624	    # selected by depends on config
3625	    add_dep $1, $config;
3626
3627	# Check for if statements
3628	} elsif (/^if\s+(.*\S)\s*$/) {
3629	    my $deps = $1;
3630	    # remove beginning and ending non text
3631	    $deps =~ s/^[^a-zA-Z0-9_]*//;
3632	    $deps =~ s/[^a-zA-Z0-9_]*$//;
3633
3634	    my @deps = split /[^a-zA-Z0-9_]+/, $deps;
3635
3636	    $ifdeps[$iflevel++] = join ':', @deps;
3637
3638	} elsif (/^endif/) {
3639
3640	    $iflevel-- if ($iflevel);
3641
3642	# stop on "help"
3643	} elsif (/^\s*help\s*$/) {
3644	    $state = "NONE";
3645	}
3646    }
3647    close(KIN);
3648
3649    # read in any configs that were found.
3650    foreach $kconfig (@kconfigs) {
3651	if (!defined($read_kconfigs{$kconfig})) {
3652	    $read_kconfigs{$kconfig} = 1;
3653	    read_kconfig("$builddir/$kconfig");
3654	}
3655    }
3656}
3657
3658sub read_depends {
3659    # find out which arch this is by the kconfig file
3660    open (IN, $output_config)
3661	or dodie "Failed to read $output_config";
3662    my $arch;
3663    while (<IN>) {
3664	if (m,Linux/(\S+)\s+\S+\s+Kernel Configuration,) {
3665	    $arch = $1;
3666	    last;
3667	}
3668    }
3669    close IN;
3670
3671    if (!defined($arch)) {
3672	doprint "Could not find arch from config file\n";
3673	doprint "no dependencies used\n";
3674	return;
3675    }
3676
3677    # arch is really the subarch, we need to know
3678    # what directory to look at.
3679    if ($arch eq "i386" || $arch eq "x86_64") {
3680	$arch = "x86";
3681    } elsif ($arch =~ /^tile/) {
3682	$arch = "tile";
3683    }
3684
3685    my $kconfig = "$builddir/arch/$arch/Kconfig";
3686
3687    if (! -f $kconfig && $arch =~ /\d$/) {
3688	my $orig = $arch;
3689 	# some subarchs have numbers, truncate them
3690	$arch =~ s/\d*$//;
3691	$kconfig = "$builddir/arch/$arch/Kconfig";
3692	if (! -f $kconfig) {
3693	    doprint "No idea what arch dir $orig is for\n";
3694	    doprint "no dependencies used\n";
3695	    return;
3696	}
3697    }
3698
3699    read_kconfig($kconfig);
3700}
3701
3702sub make_new_config {
3703    my @configs = @_;
3704
3705    open (OUT, ">$output_config")
3706	or dodie "Failed to write $output_config";
3707
3708    foreach my $config (@configs) {
3709	print OUT "$config\n";
3710    }
3711    close OUT;
3712}
3713
3714sub chomp_config {
3715    my ($config) = @_;
3716
3717    $config =~ s/CONFIG_//;
3718
3719    return $config;
3720}
3721
3722sub get_depends {
3723    my ($dep) = @_;
3724
3725    my $kconfig = chomp_config $dep;
3726
3727    $dep = $depends{"$kconfig"};
3728
3729    # the dep string we have saves the dependencies as they
3730    # were found, including expressions like ! && ||. We
3731    # want to split this out into just an array of configs.
3732
3733    my $valid = "A-Za-z_0-9";
3734
3735    my @configs;
3736
3737    while ($dep =~ /[$valid]/) {
3738
3739	if ($dep =~ /^[^$valid]*([$valid]+)/) {
3740	    my $conf = "CONFIG_" . $1;
3741
3742	    $configs[$#configs + 1] = $conf;
3743
3744	    $dep =~ s/^[^$valid]*[$valid]+//;
3745	} else {
3746	    die "this should never happen";
3747	}
3748    }
3749
3750    return @configs;
3751}
3752
3753my %min_configs;
3754my %keep_configs;
3755my %save_configs;
3756my %processed_configs;
3757my %nochange_config;
3758
3759sub test_this_config {
3760    my ($config) = @_;
3761
3762    my $found;
3763
3764    # if we already processed this config, skip it
3765    if (defined($processed_configs{$config})) {
3766	return undef;
3767    }
3768    $processed_configs{$config} = 1;
3769
3770    # if this config failed during this round, skip it
3771    if (defined($nochange_config{$config})) {
3772	return undef;
3773    }
3774
3775    my $kconfig = chomp_config $config;
3776
3777    # Test dependencies first
3778    if (defined($depends{"$kconfig"})) {
3779	my @parents = get_depends $config;
3780	foreach my $parent (@parents) {
3781	    # if the parent is in the min config, check it first
3782	    next if (!defined($min_configs{$parent}));
3783	    $found = test_this_config($parent);
3784	    if (defined($found)) {
3785		return $found;
3786	    }
3787	}
3788    }
3789
3790    # Remove this config from the list of configs
3791    # do a make olddefconfig and then read the resulting
3792    # .config to make sure it is missing the config that
3793    # we had before
3794    my %configs = %min_configs;
3795    delete $configs{$config};
3796    make_new_config ((values %configs), (values %keep_configs));
3797    make_oldconfig;
3798    undef %configs;
3799    assign_configs \%configs, $output_config;
3800
3801    if (!defined($configs{$config}) || $configs{$config} =~ /^#/) {
3802	return $config;
3803    }
3804
3805    doprint "disabling config $config did not change .config\n";
3806
3807    $nochange_config{$config} = 1;
3808
3809    return undef;
3810}
3811
3812sub make_min_config {
3813    my ($i) = @_;
3814
3815    my $type = $minconfig_type;
3816    if ($type ne "boot" && $type ne "test") {
3817	fail "Invalid MIN_CONFIG_TYPE '$minconfig_type'\n" .
3818	    " make_min_config works only with 'boot' and 'test'\n" and return;
3819    }
3820
3821    if (!defined($output_minconfig)) {
3822	fail "OUTPUT_MIN_CONFIG not defined" and return;
3823    }
3824
3825    # If output_minconfig exists, and the start_minconfig
3826    # came from min_config, than ask if we should use
3827    # that instead.
3828    if (-f $output_minconfig && !$start_minconfig_defined) {
3829	print "$output_minconfig exists\n";
3830	if (!defined($use_output_minconfig)) {
3831	    if (read_yn " Use it as minconfig?") {
3832		$start_minconfig = $output_minconfig;
3833	    }
3834	} elsif ($use_output_minconfig > 0) {
3835	    doprint "Using $output_minconfig as MIN_CONFIG\n";
3836	    $start_minconfig = $output_minconfig;
3837	} else {
3838	    doprint "Set to still use MIN_CONFIG as starting point\n";
3839	}
3840    }
3841
3842    if (!defined($start_minconfig)) {
3843	fail "START_MIN_CONFIG or MIN_CONFIG not defined" and return;
3844    }
3845
3846    my $temp_config = "$tmpdir/temp_config";
3847
3848    # First things first. We build an allnoconfig to find
3849    # out what the defaults are that we can't touch.
3850    # Some are selections, but we really can't handle selections.
3851
3852    my $save_minconfig = $minconfig;
3853    undef $minconfig;
3854
3855    run_command "$make allnoconfig" or return 0;
3856
3857    read_depends;
3858
3859    process_config_ignore $output_config;
3860
3861    undef %save_configs;
3862    undef %min_configs;
3863
3864    if (defined($ignore_config)) {
3865	# make sure the file exists
3866	`touch $ignore_config`;
3867	assign_configs \%save_configs, $ignore_config;
3868    }
3869
3870    %keep_configs = %save_configs;
3871
3872    doprint "Load initial configs from $start_minconfig\n";
3873
3874    # Look at the current min configs, and save off all the
3875    # ones that were set via the allnoconfig
3876    assign_configs \%min_configs, $start_minconfig;
3877
3878    my @config_keys = keys %min_configs;
3879
3880    # All configs need a depcount
3881    foreach my $config (@config_keys) {
3882	my $kconfig = chomp_config $config;
3883	if (!defined $depcount{$kconfig}) {
3884		$depcount{$kconfig} = 0;
3885	}
3886    }
3887
3888    # Remove anything that was set by the make allnoconfig
3889    # we shouldn't need them as they get set for us anyway.
3890    foreach my $config (@config_keys) {
3891	# Remove anything in the ignore_config
3892	if (defined($keep_configs{$config})) {
3893	    my $file = $ignore_config;
3894	    $file =~ s,.*/(.*?)$,$1,;
3895	    doprint "$config set by $file ... ignored\n";
3896	    delete $min_configs{$config};
3897	    next;
3898	}
3899	# But make sure the settings are the same. If a min config
3900	# sets a selection, we do not want to get rid of it if
3901	# it is not the same as what we have. Just move it into
3902	# the keep configs.
3903	if (defined($config_ignore{$config})) {
3904	    if ($config_ignore{$config} ne $min_configs{$config}) {
3905		doprint "$config is in allnoconfig as '$config_ignore{$config}'";
3906		doprint " but it is '$min_configs{$config}' in minconfig .. keeping\n";
3907		$keep_configs{$config} = $min_configs{$config};
3908	    } else {
3909		doprint "$config set by allnoconfig ... ignored\n";
3910	    }
3911	    delete $min_configs{$config};
3912	}
3913    }
3914
3915    my $done = 0;
3916    my $take_two = 0;
3917
3918    while (!$done) {
3919
3920	my $config;
3921	my $found;
3922
3923	# Now disable each config one by one and do a make oldconfig
3924	# till we find a config that changes our list.
3925
3926	my @test_configs = keys %min_configs;
3927
3928	# Sort keys by who is most dependent on
3929	@test_configs = sort  { $depcount{chomp_config($b)} <=> $depcount{chomp_config($a)} }
3930			  @test_configs ;
3931
3932	# Put configs that did not modify the config at the end.
3933	my $reset = 1;
3934	for (my $i = 0; $i < $#test_configs; $i++) {
3935	    if (!defined($nochange_config{$test_configs[0]})) {
3936		$reset = 0;
3937		last;
3938	    }
3939	    # This config didn't change the .config last time.
3940	    # Place it at the end
3941	    my $config = shift @test_configs;
3942	    push @test_configs, $config;
3943	}
3944
3945	# if every test config has failed to modify the .config file
3946	# in the past, then reset and start over.
3947	if ($reset) {
3948	    undef %nochange_config;
3949	}
3950
3951	undef %processed_configs;
3952
3953	foreach my $config (@test_configs) {
3954
3955	    $found = test_this_config $config;
3956
3957	    last if (defined($found));
3958
3959	    # oh well, try another config
3960	}
3961
3962	if (!defined($found)) {
3963	    # we could have failed due to the nochange_config hash
3964	    # reset and try again
3965	    if (!$take_two) {
3966		undef %nochange_config;
3967		$take_two = 1;
3968		next;
3969	    }
3970	    doprint "No more configs found that we can disable\n";
3971	    $done = 1;
3972	    last;
3973	}
3974	$take_two = 0;
3975
3976	$config = $found;
3977
3978	doprint "Test with $config disabled\n";
3979
3980	# set in_bisect to keep build and monitor from dieing
3981	$in_bisect = 1;
3982
3983	my $failed = 0;
3984	build "oldconfig" or $failed = 1;
3985	if (!$failed) {
3986		start_monitor_and_install or $failed = 1;
3987
3988		if ($type eq "test" && !$failed) {
3989		    do_run_test or $failed = 1;
3990		}
3991
3992		end_monitor;
3993	}
3994
3995	$in_bisect = 0;
3996
3997	if ($failed) {
3998	    doprint "$min_configs{$config} is needed to boot the box... keeping\n";
3999	    # this config is needed, add it to the ignore list.
4000	    $keep_configs{$config} = $min_configs{$config};
4001	    $save_configs{$config} = $min_configs{$config};
4002	    delete $min_configs{$config};
4003
4004	    # update new ignore configs
4005	    if (defined($ignore_config)) {
4006		open (OUT, ">$temp_config")
4007		    or die "Can't write to $temp_config";
4008		foreach my $config (keys %save_configs) {
4009		    print OUT "$save_configs{$config}\n";
4010		}
4011		close OUT;
4012		run_command "mv $temp_config $ignore_config" or
4013		    dodie "failed to copy update to $ignore_config";
4014	    }
4015
4016	} else {
4017	    # We booted without this config, remove it from the minconfigs.
4018	    doprint "$config is not needed, disabling\n";
4019
4020	    delete $min_configs{$config};
4021
4022	    # Also disable anything that is not enabled in this config
4023	    my %configs;
4024	    assign_configs \%configs, $output_config;
4025	    my @config_keys = keys %min_configs;
4026	    foreach my $config (@config_keys) {
4027		if (!defined($configs{$config})) {
4028		    doprint "$config is not set, disabling\n";
4029		    delete $min_configs{$config};
4030		}
4031	    }
4032
4033	    # Save off all the current mandatory configs
4034	    open (OUT, ">$temp_config")
4035		or die "Can't write to $temp_config";
4036	    foreach my $config (keys %keep_configs) {
4037		print OUT "$keep_configs{$config}\n";
4038	    }
4039	    foreach my $config (keys %min_configs) {
4040		print OUT "$min_configs{$config}\n";
4041	    }
4042	    close OUT;
4043
4044	    run_command "mv $temp_config $output_minconfig" or
4045		dodie "failed to copy update to $output_minconfig";
4046	}
4047
4048	doprint "Reboot and wait $sleep_time seconds\n";
4049	reboot_to_good $sleep_time;
4050    }
4051
4052    success $i;
4053    return 1;
4054}
4055
4056sub make_warnings_file {
4057    my ($i) = @_;
4058
4059    if (!defined($warnings_file)) {
4060	dodie "Must define WARNINGS_FILE for make_warnings_file test";
4061    }
4062
4063    if ($build_type eq "nobuild") {
4064	dodie "BUILD_TYPE can not be 'nobuild' for make_warnings_file test";
4065    }
4066
4067    build $build_type or dodie "Failed to build";
4068
4069    open(OUT, ">$warnings_file") or dodie "Can't create $warnings_file";
4070
4071    open(IN, $buildlog) or dodie "Can't open $buildlog";
4072    while (<IN>) {
4073
4074	# Some compilers use UTF-8 extended for quotes
4075	# for distcc heterogeneous systems, this causes issues
4076	s/$utf8_quote/'/g;
4077
4078	if (/$check_build_re/) {
4079	    print OUT;
4080	}
4081    }
4082    close(IN);
4083
4084    close(OUT);
4085
4086    success $i;
4087}
4088
4089$#ARGV < 1 or die "ktest.pl version: $VERSION\n   usage: ktest.pl [config-file]\n";
4090
4091if ($#ARGV == 0) {
4092    $ktest_config = $ARGV[0];
4093    if (! -f $ktest_config) {
4094	print "$ktest_config does not exist.\n";
4095	if (!read_yn "Create it?") {
4096	    exit 0;
4097	}
4098    }
4099}
4100
4101if (! -f $ktest_config) {
4102    $newconfig = 1;
4103    get_test_case;
4104    open(OUT, ">$ktest_config") or die "Can not create $ktest_config";
4105    print OUT << "EOF"
4106# Generated by ktest.pl
4107#
4108
4109# PWD is a ktest.pl variable that will result in the process working
4110# directory that ktest.pl is executed in.
4111
4112# THIS_DIR is automatically assigned the PWD of the path that generated
4113# the config file. It is best to use this variable when assigning other
4114# directory paths within this directory. This allows you to easily
4115# move the test cases to other locations or to other machines.
4116#
4117THIS_DIR := $variable{"PWD"}
4118
4119# Define each test with TEST_START
4120# The config options below it will override the defaults
4121TEST_START
4122TEST_TYPE = $default{"TEST_TYPE"}
4123
4124DEFAULTS
4125EOF
4126;
4127    close(OUT);
4128}
4129read_config $ktest_config;
4130
4131if (defined($opt{"LOG_FILE"})) {
4132    $opt{"LOG_FILE"} = eval_option("LOG_FILE", $opt{"LOG_FILE"}, -1);
4133}
4134
4135# Append any configs entered in manually to the config file.
4136my @new_configs = keys %entered_configs;
4137if ($#new_configs >= 0) {
4138    print "\nAppending entered in configs to $ktest_config\n";
4139    open(OUT, ">>$ktest_config") or die "Can not append to $ktest_config";
4140    foreach my $config (@new_configs) {
4141	print OUT "$config = $entered_configs{$config}\n";
4142	$opt{$config} = process_variables($entered_configs{$config});
4143    }
4144}
4145
4146if ($opt{"CLEAR_LOG"} && defined($opt{"LOG_FILE"})) {
4147    unlink $opt{"LOG_FILE"};
4148}
4149
4150doprint "\n\nSTARTING AUTOMATED TESTS\n\n";
4151
4152for (my $i = 0, my $repeat = 1; $i <= $opt{"NUM_TESTS"}; $i += $repeat) {
4153
4154    if (!$i) {
4155	doprint "DEFAULT OPTIONS:\n";
4156    } else {
4157	doprint "\nTEST $i OPTIONS";
4158	if (defined($repeat_tests{$i})) {
4159	    $repeat = $repeat_tests{$i};
4160	    doprint " ITERATE $repeat";
4161	}
4162	doprint "\n";
4163    }
4164
4165    foreach my $option (sort keys %opt) {
4166
4167	if ($option =~ /\[(\d+)\]$/) {
4168	    next if ($i != $1);
4169	} else {
4170	    next if ($i);
4171	}
4172
4173	doprint "$option = $opt{$option}\n";
4174    }
4175}
4176
4177sub option_defined {
4178    my ($option) = @_;
4179
4180    if (defined($opt{$option}) && $opt{$option} !~ /^\s*$/) {
4181	return 1;
4182    }
4183
4184    return 0;
4185}
4186
4187sub __set_test_option {
4188    my ($name, $i) = @_;
4189
4190    my $option = "$name\[$i\]";
4191
4192    if (option_defined($option)) {
4193	return $opt{$option};
4194    }
4195
4196    foreach my $test (keys %repeat_tests) {
4197	if ($i >= $test &&
4198	    $i < $test + $repeat_tests{$test}) {
4199	    $option = "$name\[$test\]";
4200	    if (option_defined($option)) {
4201		return $opt{$option};
4202	    }
4203	}
4204    }
4205
4206    if (option_defined($name)) {
4207	return $opt{$name};
4208    }
4209
4210    return undef;
4211}
4212
4213sub set_test_option {
4214    my ($name, $i) = @_;
4215
4216    my $option = __set_test_option($name, $i);
4217    return $option if (!defined($option));
4218
4219    return eval_option($name, $option, $i);
4220}
4221
4222# First we need to do is the builds
4223for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
4224
4225    # Do not reboot on failing test options
4226    $no_reboot = 1;
4227    $reboot_success = 0;
4228
4229    $have_version = 0;
4230
4231    $iteration = $i;
4232
4233    $build_time = 0;
4234    $install_time = 0;
4235    $reboot_time = 0;
4236    $test_time = 0;
4237
4238    undef %force_config;
4239
4240    my $makecmd = set_test_option("MAKE_CMD", $i);
4241
4242    $outputdir = set_test_option("OUTPUT_DIR", $i);
4243    $builddir = set_test_option("BUILD_DIR", $i);
4244
4245    chdir $builddir || die "can't change directory to $builddir";
4246
4247    if (!-d $outputdir) {
4248	mkpath($outputdir) or
4249	    die "can't create $outputdir";
4250    }
4251
4252    $make = "$makecmd O=$outputdir";
4253
4254    # Load all the options into their mapped variable names
4255    foreach my $opt (keys %option_map) {
4256	${$option_map{$opt}} = set_test_option($opt, $i);
4257    }
4258
4259    $start_minconfig_defined = 1;
4260
4261    # The first test may override the PRE_KTEST option
4262    if (defined($pre_ktest) && $i == 1) {
4263	doprint "\n";
4264	run_command $pre_ktest;
4265    }
4266
4267    # Any test can override the POST_KTEST option
4268    # The last test takes precedence.
4269    if (defined($post_ktest)) {
4270	$final_post_ktest = $post_ktest;
4271    }
4272
4273    if (!defined($start_minconfig)) {
4274	$start_minconfig_defined = 0;
4275	$start_minconfig = $minconfig;
4276    }
4277
4278    if (!-d $tmpdir) {
4279	mkpath($tmpdir) or
4280	    die "can't create $tmpdir";
4281    }
4282
4283    $ENV{"SSH_USER"} = $ssh_user;
4284    $ENV{"MACHINE"} = $machine;
4285
4286    $buildlog = "$tmpdir/buildlog-$machine";
4287    $testlog = "$tmpdir/testlog-$machine";
4288    $dmesg = "$tmpdir/dmesg-$machine";
4289    $output_config = "$outputdir/.config";
4290
4291    if (!$buildonly) {
4292	$target = "$ssh_user\@$machine";
4293	if ($reboot_type eq "grub") {
4294	    dodie "GRUB_MENU not defined" if (!defined($grub_menu));
4295	} elsif ($reboot_type eq "grub2") {
4296	    dodie "GRUB_MENU not defined" if (!defined($grub_menu));
4297	    dodie "GRUB_FILE not defined" if (!defined($grub_file));
4298	} elsif ($reboot_type eq "syslinux") {
4299	    dodie "SYSLINUX_LABEL not defined" if (!defined($syslinux_label));
4300	}
4301    }
4302
4303    my $run_type = $build_type;
4304    if ($test_type eq "patchcheck") {
4305	$run_type = $patchcheck_type;
4306    } elsif ($test_type eq "bisect") {
4307	$run_type = $bisect_type;
4308    } elsif ($test_type eq "config_bisect") {
4309	$run_type = $config_bisect_type;
4310    } elsif ($test_type eq "make_min_config") {
4311	$run_type = "";
4312    } elsif ($test_type eq "make_warnings_file") {
4313	$run_type = "";
4314    }
4315
4316    # mistake in config file?
4317    if (!defined($run_type)) {
4318	$run_type = "ERROR";
4319    }
4320
4321    my $installme = "";
4322    $installme = " no_install" if ($no_install);
4323
4324    my $name = "";
4325
4326    if (defined($test_name)) {
4327	$name = " ($test_name)";
4328    }
4329
4330    doprint "\n\n";
4331    doprint "RUNNING TEST $i of $opt{NUM_TESTS}$name with option $test_type $run_type$installme\n\n";
4332
4333    if (defined($pre_test)) {
4334	run_command $pre_test;
4335    }
4336
4337    unlink $dmesg;
4338    unlink $buildlog;
4339    unlink $testlog;
4340
4341    if (defined($addconfig)) {
4342	my $min = $minconfig;
4343	if (!defined($minconfig)) {
4344	    $min = "";
4345	}
4346	run_command "cat $addconfig $min > $tmpdir/add_config" or
4347	    dodie "Failed to create temp config";
4348	$minconfig = "$tmpdir/add_config";
4349    }
4350
4351    if (defined($checkout)) {
4352	run_command "git checkout $checkout" or
4353	    die "failed to checkout $checkout";
4354    }
4355
4356    $no_reboot = 0;
4357
4358    # A test may opt to not reboot the box
4359    if ($reboot_on_success) {
4360	$reboot_success = 1;
4361    }
4362
4363    if ($test_type eq "bisect") {
4364	bisect $i;
4365	next;
4366    } elsif ($test_type eq "config_bisect") {
4367	config_bisect $i;
4368	next;
4369    } elsif ($test_type eq "patchcheck") {
4370	patchcheck $i;
4371	next;
4372    } elsif ($test_type eq "make_min_config") {
4373	make_min_config $i;
4374	next;
4375    } elsif ($test_type eq "make_warnings_file") {
4376	$no_reboot = 1;
4377	make_warnings_file $i;
4378	next;
4379    }
4380
4381    if ($build_type ne "nobuild") {
4382	build $build_type or next;
4383	check_buildlog or next;
4384    }
4385
4386    if ($test_type eq "install") {
4387	get_version;
4388	install;
4389	success $i;
4390	next;
4391    }
4392
4393    if ($test_type ne "build") {
4394	my $failed = 0;
4395	start_monitor_and_install or $failed = 1;
4396
4397	if (!$failed && $test_type ne "boot" && defined($run_test)) {
4398	    do_run_test or $failed = 1;
4399	}
4400	end_monitor;
4401	if ($failed) {
4402	    print_times;
4403	    next;
4404	}
4405    }
4406
4407    print_times;
4408
4409    success $i;
4410}
4411
4412if (defined($final_post_ktest)) {
4413    run_command $final_post_ktest;
4414}
4415
4416if ($opt{"POWEROFF_ON_SUCCESS"}) {
4417    halt;
4418} elsif ($opt{"REBOOT_ON_SUCCESS"} && !do_not_reboot && $reboot_success) {
4419    reboot_to_good;
4420} elsif (defined($switch_to_good)) {
4421    # still need to get to the good kernel
4422    run_command $switch_to_good;
4423}
4424
4425
4426doprint "\n    $successes of $opt{NUM_TESTS} tests were successful\n\n";
4427
4428exit 0;
4429