blob: 7bce412bbdcc2d9c0e5fd537a3ebf4e4eb85f45a [file] [log] [blame]
Steven Rostedt2545eb62010-11-02 15:01:32 -04001#!/usr/bin/perl -w
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04002#
Uwe Kleine-Königcce1dac2011-01-24 21:12:01 +01003# Copyright 2010 - Steven Rostedt <srostedt@redhat.com>, Red Hat Inc.
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04004# Licensed under the terms of the GNU GPL License version 2
5#
Steven Rostedt2545eb62010-11-02 15:01:32 -04006
7use strict;
8use IPC::Open2;
9use Fcntl qw(F_GETFL F_SETFL O_NONBLOCK);
Steven Rostedt7faafbd2010-11-02 14:58:22 -040010use File::Path qw(mkpath);
11use File::Copy qw(cp);
Steven Rostedt2545eb62010-11-02 15:01:32 -040012use FileHandle;
13
Steven Rostedte48c5292010-11-02 14:35:37 -040014my $VERSION = "0.2";
15
Steven Rostedt2545eb62010-11-02 15:01:32 -040016$| = 1;
17
18my %opt;
Steven Rostedta57419b2010-11-02 15:13:54 -040019my %repeat_tests;
20my %repeats;
Steven Rostedta75fece2010-11-02 14:58:27 -040021my %default;
Steven Rostedt2545eb62010-11-02 15:01:32 -040022
23#default opts
Steven Rostedta57419b2010-11-02 15:13:54 -040024$default{"NUM_TESTS"} = 1;
Steven Rostedta75fece2010-11-02 14:58:27 -040025$default{"REBOOT_TYPE"} = "grub";
26$default{"TEST_TYPE"} = "test";
27$default{"BUILD_TYPE"} = "randconfig";
28$default{"MAKE_CMD"} = "make";
29$default{"TIMEOUT"} = 120;
Steven Rostedt48920632011-06-14 20:42:19 -040030$default{"TMP_DIR"} = "/tmp/ktest/\${MACHINE}";
Steven Rostedta75fece2010-11-02 14:58:27 -040031$default{"SLEEP_TIME"} = 60; # sleep time between tests
32$default{"BUILD_NOCLEAN"} = 0;
33$default{"REBOOT_ON_ERROR"} = 0;
34$default{"POWEROFF_ON_ERROR"} = 0;
35$default{"REBOOT_ON_SUCCESS"} = 1;
36$default{"POWEROFF_ON_SUCCESS"} = 0;
37$default{"BUILD_OPTIONS"} = "";
38$default{"BISECT_SLEEP_TIME"} = 60; # sleep time between bisects
Steven Rostedt27d934b2011-05-20 09:18:18 -040039$default{"PATCHCHECK_SLEEP_TIME"} = 60; # sleep time between patch checks
Steven Rostedta75fece2010-11-02 14:58:27 -040040$default{"CLEAR_LOG"} = 0;
Steven Rostedtc960bb92011-03-08 09:22:39 -050041$default{"BISECT_MANUAL"} = 0;
Steven Rostedtc23dca72011-03-08 09:26:31 -050042$default{"BISECT_SKIP"} = 1;
Steven Rostedta75fece2010-11-02 14:58:27 -040043$default{"SUCCESS_LINE"} = "login:";
Steven Rostedtf1a5b962011-06-13 10:30:00 -040044$default{"DETECT_TRIPLE_FAULT"} = 1;
Steven Rostedte0a87422011-09-30 17:50:48 -040045$default{"NO_INSTALL"} = 0;
Steven Rostedta75fece2010-11-02 14:58:27 -040046$default{"BOOTED_TIMEOUT"} = 1;
47$default{"DIE_ON_FAILURE"} = 1;
Steven Rostedte48c5292010-11-02 14:35:37 -040048$default{"SSH_EXEC"} = "ssh \$SSH_USER\@\$MACHINE \$SSH_COMMAND";
49$default{"SCP_TO_TARGET"} = "scp \$SRC_FILE \$SSH_USER\@\$MACHINE:\$DST_FILE";
50$default{"REBOOT"} = "ssh \$SSH_USER\@\$MACHINE reboot";
Steven Rostedt1c8a6172010-11-09 12:55:40 -050051$default{"STOP_AFTER_SUCCESS"} = 10;
52$default{"STOP_AFTER_FAILURE"} = 60;
Steven Rostedt2d01b262011-03-08 09:47:54 -050053$default{"STOP_TEST_AFTER"} = 600;
Steven Rostedt8d1491b2010-11-18 15:39:48 -050054$default{"LOCALVERSION"} = "-test";
Steven Rostedt2545eb62010-11-02 15:01:32 -040055
Steven Rostedt8d1491b2010-11-18 15:39:48 -050056my $ktest_config;
Steven Rostedt2545eb62010-11-02 15:01:32 -040057my $version;
Steven Rostedta75fece2010-11-02 14:58:27 -040058my $machine;
Steven Rostedte48c5292010-11-02 14:35:37 -040059my $ssh_user;
Steven Rostedta75fece2010-11-02 14:58:27 -040060my $tmpdir;
61my $builddir;
62my $outputdir;
Steven Rostedt51ad1dd2010-11-08 16:43:21 -050063my $output_config;
Steven Rostedta75fece2010-11-02 14:58:27 -040064my $test_type;
Steven Rostedt7faafbd2010-11-02 14:58:22 -040065my $build_type;
Steven Rostedta75fece2010-11-02 14:58:27 -040066my $build_options;
Steven Rostedt0bd6c1a2011-06-14 20:39:31 -040067my $pre_build;
68my $post_build;
69my $pre_build_die;
70my $post_build_die;
Steven Rostedta75fece2010-11-02 14:58:27 -040071my $reboot_type;
72my $reboot_script;
73my $power_cycle;
Steven Rostedte48c5292010-11-02 14:35:37 -040074my $reboot;
Steven Rostedta75fece2010-11-02 14:58:27 -040075my $reboot_on_error;
76my $poweroff_on_error;
77my $die_on_failure;
Steven Rostedt576f6272010-11-02 14:58:38 -040078my $powercycle_after_reboot;
79my $poweroff_after_halt;
Steven Rostedte48c5292010-11-02 14:35:37 -040080my $ssh_exec;
81my $scp_to_target;
Steven Rostedta75fece2010-11-02 14:58:27 -040082my $power_off;
83my $grub_menu;
Steven Rostedt2545eb62010-11-02 15:01:32 -040084my $grub_number;
85my $target;
86my $make;
Steven Rostedt8b37ca82010-11-02 14:58:33 -040087my $post_install;
Steven Rostedte0a87422011-09-30 17:50:48 -040088my $no_install;
Steven Rostedt5c42fc52010-11-02 14:57:01 -040089my $noclean;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -040090my $minconfig;
Steven Rostedt4c4ab122011-07-15 21:16:17 -040091my $start_minconfig;
Steven Rostedt35ce5952011-07-15 21:57:25 -040092my $start_minconfig_defined;
Steven Rostedt4c4ab122011-07-15 21:16:17 -040093my $output_minconfig;
94my $ignore_config;
Steven Rostedt2b7d9b22010-11-02 14:58:15 -040095my $addconfig;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -040096my $in_bisect = 0;
97my $bisect_bad = "";
Steven Rostedtd6ce2a02010-11-02 14:58:05 -040098my $reverse_bisect;
Steven Rostedtc960bb92011-03-08 09:22:39 -050099my $bisect_manual;
Steven Rostedtc23dca72011-03-08 09:26:31 -0500100my $bisect_skip;
Steven Rostedt30f75da2011-06-13 10:35:35 -0400101my $config_bisect_good;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -0400102my $in_patchcheck = 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -0400103my $run_test;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -0400104my $redirect;
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400105my $buildlog;
106my $dmesg;
107my $monitor_fp;
108my $monitor_pid;
109my $monitor_cnt = 0;
Steven Rostedta75fece2010-11-02 14:58:27 -0400110my $sleep_time;
111my $bisect_sleep_time;
Steven Rostedt27d934b2011-05-20 09:18:18 -0400112my $patchcheck_sleep_time;
Steven Rostedt19902072011-06-14 20:46:25 -0400113my $ignore_warnings;
Steven Rostedta75fece2010-11-02 14:58:27 -0400114my $store_failures;
Steven Rostedt9064af52011-06-13 10:38:48 -0400115my $test_name;
Steven Rostedta75fece2010-11-02 14:58:27 -0400116my $timeout;
117my $booted_timeout;
Steven Rostedtf1a5b962011-06-13 10:30:00 -0400118my $detect_triplefault;
Steven Rostedta75fece2010-11-02 14:58:27 -0400119my $console;
Steven Rostedt2b803362011-09-30 18:00:23 -0400120my $reboot_success_line;
Steven Rostedta75fece2010-11-02 14:58:27 -0400121my $success_line;
Steven Rostedt1c8a6172010-11-09 12:55:40 -0500122my $stop_after_success;
123my $stop_after_failure;
Steven Rostedt2d01b262011-03-08 09:47:54 -0500124my $stop_test_after;
Steven Rostedta75fece2010-11-02 14:58:27 -0400125my $build_target;
126my $target_image;
127my $localversion;
Steven Rostedt576f6272010-11-02 14:58:38 -0400128my $iteration = 0;
Steven Rostedte48c5292010-11-02 14:35:37 -0400129my $successes = 0;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400130
Steven Rostedt8d1491b2010-11-18 15:39:48 -0500131my %entered_configs;
132my %config_help;
Steven Rostedt77d942c2011-05-20 13:36:58 -0400133my %variable;
Steven Rostedtfcb3f162011-06-13 10:40:58 -0400134my %force_config;
Steven Rostedt8d1491b2010-11-18 15:39:48 -0500135
Steven Rostedt4ab1cce2011-09-30 18:12:20 -0400136# do not force reboots on config problems
137my $no_reboot = 1;
138
Steven Rostedt8d1491b2010-11-18 15:39:48 -0500139$config_help{"MACHINE"} = << "EOF"
140 The machine hostname that you will test.
141EOF
142 ;
143$config_help{"SSH_USER"} = << "EOF"
144 The box is expected to have ssh on normal bootup, provide the user
145 (most likely root, since you need privileged operations)
146EOF
147 ;
148$config_help{"BUILD_DIR"} = << "EOF"
149 The directory that contains the Linux source code (full path).
150EOF
151 ;
152$config_help{"OUTPUT_DIR"} = << "EOF"
153 The directory that the objects will be built (full path).
154 (can not be same as BUILD_DIR)
155EOF
156 ;
157$config_help{"BUILD_TARGET"} = << "EOF"
158 The location of the compiled file to copy to the target.
159 (relative to OUTPUT_DIR)
160EOF
161 ;
162$config_help{"TARGET_IMAGE"} = << "EOF"
163 The place to put your image on the test machine.
164EOF
165 ;
166$config_help{"POWER_CYCLE"} = << "EOF"
167 A script or command to reboot the box.
168
169 Here is a digital loggers power switch example
170 POWER_CYCLE = wget --no-proxy -O /dev/null -q --auth-no-challenge 'http://admin:admin\@power/outlet?5=CCL'
171
172 Here is an example to reboot a virtual box on the current host
173 with the name "Guest".
174 POWER_CYCLE = virsh destroy Guest; sleep 5; virsh start Guest
175EOF
176 ;
177$config_help{"CONSOLE"} = << "EOF"
178 The script or command that reads the console
179
180 If you use ttywatch server, something like the following would work.
181CONSOLE = nc -d localhost 3001
182
183 For a virtual machine with guest name "Guest".
184CONSOLE = virsh console Guest
185EOF
186 ;
187$config_help{"LOCALVERSION"} = << "EOF"
188 Required version ending to differentiate the test
189 from other linux builds on the system.
190EOF
191 ;
192$config_help{"REBOOT_TYPE"} = << "EOF"
193 Way to reboot the box to the test kernel.
194 Only valid options so far are "grub" and "script".
195
196 If you specify grub, it will assume grub version 1
197 and will search in /boot/grub/menu.lst for the title \$GRUB_MENU
198 and select that target to reboot to the kernel. If this is not
199 your setup, then specify "script" and have a command or script
200 specified in REBOOT_SCRIPT to boot to the target.
201
202 The entry in /boot/grub/menu.lst must be entered in manually.
203 The test will not modify that file.
204EOF
205 ;
206$config_help{"GRUB_MENU"} = << "EOF"
207 The grub title name for the test kernel to boot
208 (Only mandatory if REBOOT_TYPE = grub)
209
210 Note, ktest.pl will not update the grub menu.lst, you need to
211 manually add an option for the test. ktest.pl will search
212 the grub menu.lst for this option to find what kernel to
213 reboot into.
214
215 For example, if in the /boot/grub/menu.lst the test kernel title has:
216 title Test Kernel
217 kernel vmlinuz-test
218 GRUB_MENU = Test Kernel
219EOF
220 ;
221$config_help{"REBOOT_SCRIPT"} = << "EOF"
222 A script to reboot the target into the test kernel
223 (Only mandatory if REBOOT_TYPE = script)
224EOF
225 ;
226
Steven Rostedt35ce5952011-07-15 21:57:25 -0400227sub read_yn {
228 my ($prompt) = @_;
229
230 my $ans;
231
232 for (;;) {
233 print "$prompt [Y/n] ";
234 $ans = <STDIN>;
235 chomp $ans;
236 if ($ans =~ /^\s*$/) {
237 $ans = "y";
238 }
239 last if ($ans =~ /^y$/i || $ans =~ /^n$/i);
240 print "Please answer either 'y' or 'n'.\n";
241 }
242 if ($ans !~ /^y$/i) {
243 return 0;
244 }
245 return 1;
246}
Steven Rostedt8d1491b2010-11-18 15:39:48 -0500247
248sub get_ktest_config {
249 my ($config) = @_;
250
251 return if (defined($opt{$config}));
252
253 if (defined($config_help{$config})) {
254 print "\n";
255 print $config_help{$config};
256 }
257
258 for (;;) {
259 print "$config = ";
260 if (defined($default{$config})) {
261 print "\[$default{$config}\] ";
262 }
263 $entered_configs{$config} = <STDIN>;
264 $entered_configs{$config} =~ s/^\s*(.*\S)\s*$/$1/;
265 if ($entered_configs{$config} =~ /^\s*$/) {
266 if ($default{$config}) {
267 $entered_configs{$config} = $default{$config};
268 } else {
269 print "Your answer can not be blank\n";
270 next;
271 }
272 }
273 last;
274 }
275}
276
277sub get_ktest_configs {
278 get_ktest_config("MACHINE");
279 get_ktest_config("SSH_USER");
280 get_ktest_config("BUILD_DIR");
281 get_ktest_config("OUTPUT_DIR");
282 get_ktest_config("BUILD_TARGET");
283 get_ktest_config("TARGET_IMAGE");
284 get_ktest_config("POWER_CYCLE");
285 get_ktest_config("CONSOLE");
286 get_ktest_config("LOCALVERSION");
287
288 my $rtype = $opt{"REBOOT_TYPE"};
289
290 if (!defined($rtype)) {
291 if (!defined($opt{"GRUB_MENU"})) {
292 get_ktest_config("REBOOT_TYPE");
293 $rtype = $entered_configs{"REBOOT_TYPE"};
294 } else {
295 $rtype = "grub";
296 }
297 }
298
299 if ($rtype eq "grub") {
300 get_ktest_config("GRUB_MENU");
301 } else {
302 get_ktest_config("REBOOT_SCRIPT");
303 }
304}
305
Steven Rostedt77d942c2011-05-20 13:36:58 -0400306sub process_variables {
307 my ($value) = @_;
308 my $retval = "";
309
310 # We want to check for '\', and it is just easier
311 # to check the previous characet of '$' and not need
312 # to worry if '$' is the first character. By adding
313 # a space to $value, we can just check [^\\]\$ and
314 # it will still work.
315 $value = " $value";
316
317 while ($value =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) {
318 my $begin = $1;
319 my $var = $2;
320 my $end = $3;
321 # append beginning of value to retval
322 $retval = "$retval$begin";
323 if (defined($variable{$var})) {
324 $retval = "$retval$variable{$var}";
325 } else {
326 # put back the origin piece.
327 $retval = "$retval\$\{$var\}";
328 }
329 $value = $end;
330 }
331 $retval = "$retval$value";
332
333 # remove the space added in the beginning
334 $retval =~ s/ //;
335
336 return "$retval"
337}
338
Steven Rostedta57419b2010-11-02 15:13:54 -0400339sub set_value {
Steven Rostedt3d1cc412011-09-30 22:14:21 -0400340 my ($lvalue, $rvalue, $override, $overrides, $name) = @_;
Steven Rostedta57419b2010-11-02 15:13:54 -0400341
342 if (defined($opt{$lvalue})) {
Steven Rostedt3d1cc412011-09-30 22:14:21 -0400343 if (!$override || defined(${$overrides}{$lvalue})) {
344 my $extra = "";
345 if ($override) {
346 $extra = "In the same override section!\n";
347 }
348 die "$name: $.: Option $lvalue defined more than once!\n$extra";
349 }
350 ${$overrides}{$lvalue} = $rvalue;
Steven Rostedta57419b2010-11-02 15:13:54 -0400351 }
Steven Rostedt21a96792010-11-08 16:45:50 -0500352 if ($rvalue =~ /^\s*$/) {
353 delete $opt{$lvalue};
354 } else {
Steven Rostedt77d942c2011-05-20 13:36:58 -0400355 $rvalue = process_variables($rvalue);
Steven Rostedt21a96792010-11-08 16:45:50 -0500356 $opt{$lvalue} = $rvalue;
357 }
Steven Rostedta57419b2010-11-02 15:13:54 -0400358}
359
Steven Rostedt77d942c2011-05-20 13:36:58 -0400360sub set_variable {
361 my ($lvalue, $rvalue) = @_;
362
363 if ($rvalue =~ /^\s*$/) {
364 delete $variable{$lvalue};
365 } else {
366 $rvalue = process_variables($rvalue);
367 $variable{$lvalue} = $rvalue;
368 }
369}
370
Steven Rostedtab7a3f52011-09-30 20:24:07 -0400371sub process_compare {
372 my ($lval, $cmp, $rval) = @_;
373
374 # remove whitespace
375
376 $lval =~ s/^\s*//;
377 $lval =~ s/\s*$//;
378
379 $rval =~ s/^\s*//;
380 $rval =~ s/\s*$//;
381
382 if ($cmp eq "==") {
383 return $lval eq $rval;
384 } elsif ($cmp eq "!=") {
385 return $lval ne $rval;
386 }
387
388 my $statement = "$lval $cmp $rval";
389 my $ret = eval $statement;
390
391 # $@ stores error of eval
392 if ($@) {
393 return -1;
394 }
395
396 return $ret;
397}
398
Steven Rostedt45d73a52011-09-30 19:44:53 -0400399sub process_if {
400 my ($name, $value) = @_;
401
402 my $val = process_variables($value);
403
Steven Rostedtab7a3f52011-09-30 20:24:07 -0400404 if ($val =~ /(.*)(==|\!=|>=|<=|>|<)(.*)/) {
405 my $ret = process_compare($1, $2, $3);
406 if ($ret < 0) {
407 die "$name: $.: Unable to process comparison\n";
408 }
409 return $ret;
410 }
411
Steven Rostedt45d73a52011-09-30 19:44:53 -0400412 if ($val =~ /^\s*0\s*$/) {
413 return 0;
414 } elsif ($val =~ /^\s*\d+\s*$/) {
415 return 1;
416 }
417
418 die ("$name: $.: Undefined variable $val in if statement\n");
419 return 1;
420}
421
Steven Rostedt2ed3b162011-09-30 21:00:00 -0400422sub __read_config {
423 my ($config, $current_test_num) = @_;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400424
Steven Rostedt2ed3b162011-09-30 21:00:00 -0400425 my $in;
426 open($in, $config) || die "can't read file $config";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400427
Steven Rostedta57419b2010-11-02 15:13:54 -0400428 my $name = $config;
429 $name =~ s,.*/(.*),$1,;
430
Steven Rostedt2ed3b162011-09-30 21:00:00 -0400431 my $test_num = $$current_test_num;
Steven Rostedta57419b2010-11-02 15:13:54 -0400432 my $default = 1;
433 my $repeat = 1;
434 my $num_tests_set = 0;
435 my $skip = 0;
436 my $rest;
Steven Rostedt0df213c2011-06-14 20:51:37 -0400437 my $test_case = 0;
Steven Rostedt45d73a52011-09-30 19:44:53 -0400438 my $if = 0;
439 my $if_set = 0;
Steven Rostedt3d1cc412011-09-30 22:14:21 -0400440 my $override = 0;
441
442 my %overrides;
Steven Rostedta57419b2010-11-02 15:13:54 -0400443
Steven Rostedt2ed3b162011-09-30 21:00:00 -0400444 while (<$in>) {
Steven Rostedt2545eb62010-11-02 15:01:32 -0400445
446 # ignore blank lines and comments
447 next if (/^\s*$/ || /\s*\#/);
448
Steven Rostedt0050b6b2011-09-30 21:10:30 -0400449 if (/^\s*(TEST_START|DEFAULTS)\b(.*)/) {
Steven Rostedta57419b2010-11-02 15:13:54 -0400450
Steven Rostedt0050b6b2011-09-30 21:10:30 -0400451 my $type = $1;
452 $rest = $2;
Steven Rostedta57419b2010-11-02 15:13:54 -0400453
Steven Rostedt0050b6b2011-09-30 21:10:30 -0400454 my $old_test_num;
455 my $old_repeat;
Steven Rostedt3d1cc412011-09-30 22:14:21 -0400456 $override = 0;
Steven Rostedt0050b6b2011-09-30 21:10:30 -0400457
458 if ($type eq "TEST_START") {
459
460 if ($num_tests_set) {
461 die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
462 }
463
464 $old_test_num = $test_num;
465 $old_repeat = $repeat;
466
467 $test_num += $repeat;
468 $default = 0;
469 $repeat = 1;
470 } else {
471 $default = 1;
Steven Rostedta57419b2010-11-02 15:13:54 -0400472 }
473
Steven Rostedt45d73a52011-09-30 19:44:53 -0400474 if ($rest =~ /\s+SKIP\b(.*)/) {
Steven Rostedta57419b2010-11-02 15:13:54 -0400475 $rest = $1;
476 $skip = 1;
477 } else {
Steven Rostedt0df213c2011-06-14 20:51:37 -0400478 $test_case = 1;
Steven Rostedta57419b2010-11-02 15:13:54 -0400479 $skip = 0;
480 }
481
Steven Rostedt3d1cc412011-09-30 22:14:21 -0400482 if (!$skip) {
483 if ($type eq "TEST_START") {
484 if ($rest =~ /\s+ITERATE\s+(\d+)(.*)$/) {
485 $repeat = $1;
486 $rest = $2;
487 $repeat_tests{"$test_num"} = $repeat;
488 }
489 } elsif ($rest =~ /\sOVERRIDE\b(.*)/) {
490 # DEFAULT only
491 $rest = $1;
492 $override = 1;
493 # Clear previous overrides
494 %overrides = ();
495 }
Steven Rostedta57419b2010-11-02 15:13:54 -0400496 }
497
Steven Rostedtab7a3f52011-09-30 20:24:07 -0400498 if ($rest =~ /\sIF\s+(.*)/) {
499 $rest = "";
Steven Rostedt45d73a52011-09-30 19:44:53 -0400500 if (process_if($name, $1)) {
501 $if_set = 1;
502 } else {
503 $skip = 1;
504 }
505 $if = 1;
506 } else {
507 $if = 0;
Steven Rostedta57419b2010-11-02 15:13:54 -0400508 }
509
510 if ($rest !~ /^\s*$/) {
Steven Rostedt0050b6b2011-09-30 21:10:30 -0400511 die "$name: $.: Gargbage found after $type\n$_";
Steven Rostedta57419b2010-11-02 15:13:54 -0400512 }
513
Steven Rostedt0050b6b2011-09-30 21:10:30 -0400514 if ($skip && $type eq "TEST_START") {
Steven Rostedta57419b2010-11-02 15:13:54 -0400515 $test_num = $old_test_num;
Steven Rostedte48c5292010-11-02 14:35:37 -0400516 $repeat = $old_repeat;
Steven Rostedta57419b2010-11-02 15:13:54 -0400517 }
518
Steven Rostedtab7a3f52011-09-30 20:24:07 -0400519 } elsif (/^\s*ELSE\b(.*)$/) {
Steven Rostedt45d73a52011-09-30 19:44:53 -0400520 if (!$if) {
521 die "$name: $.: ELSE found with out matching IF section\n$_";
522 }
523 $rest = $1;
524 if ($if_set) {
525 $skip = 1;
Steven Rostedtab7a3f52011-09-30 20:24:07 -0400526 $rest = "";
Steven Rostedt45d73a52011-09-30 19:44:53 -0400527 } else {
528 $skip = 0;
529
Steven Rostedtab7a3f52011-09-30 20:24:07 -0400530 if ($rest =~ /\sIF\s+(.*)/) {
Steven Rostedt45d73a52011-09-30 19:44:53 -0400531 # May be a ELSE IF section.
532 if (!process_if($name, $1)) {
533 $skip = 1;
534 }
Steven Rostedtab7a3f52011-09-30 20:24:07 -0400535 $rest = "";
Steven Rostedt45d73a52011-09-30 19:44:53 -0400536 } else {
537 $if = 0;
538 }
539 }
540
Steven Rostedtab7a3f52011-09-30 20:24:07 -0400541 if ($rest !~ /^\s*$/) {
542 die "$name: $.: Gargbage found after DEFAULTS\n$_";
543 }
544
Steven Rostedt2ed3b162011-09-30 21:00:00 -0400545 } elsif (/^\s*INCLUDE\s+(\S+)/) {
546
547 next if ($skip);
548
549 if (!$default) {
550 die "$name: $.: INCLUDE can only be done in default sections\n$_";
551 }
552
553 my $file = process_variables($1);
554
555 if ($file !~ m,^/,) {
556 # check the path of the config file first
557 if ($config =~ m,(.*)/,) {
558 if (-f "$1/$file") {
559 $file = "$1/$file";
560 }
561 }
562 }
563
564 if ( ! -r $file ) {
565 die "$name: $.: Can't read file $file\n$_";
566 }
567
568 if (__read_config($file, \$test_num)) {
569 $test_case = 1;
570 }
571
Steven Rostedta57419b2010-11-02 15:13:54 -0400572 } elsif (/^\s*([A-Z_\[\]\d]+)\s*=\s*(.*?)\s*$/) {
573
574 next if ($skip);
575
Steven Rostedt2545eb62010-11-02 15:01:32 -0400576 my $lvalue = $1;
577 my $rvalue = $2;
578
Steven Rostedta57419b2010-11-02 15:13:54 -0400579 if (!$default &&
580 ($lvalue eq "NUM_TESTS" ||
581 $lvalue eq "LOG_FILE" ||
582 $lvalue eq "CLEAR_LOG")) {
583 die "$name: $.: $lvalue must be set in DEFAULTS section\n";
Steven Rostedta75fece2010-11-02 14:58:27 -0400584 }
Steven Rostedta57419b2010-11-02 15:13:54 -0400585
586 if ($lvalue eq "NUM_TESTS") {
587 if ($test_num) {
588 die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
589 }
590 if (!$default) {
591 die "$name: $.: NUM_TESTS must be set in default section\n";
592 }
593 $num_tests_set = 1;
594 }
595
596 if ($default || $lvalue =~ /\[\d+\]$/) {
Steven Rostedt3d1cc412011-09-30 22:14:21 -0400597 set_value($lvalue, $rvalue, $override, \%overrides, $name);
Steven Rostedta57419b2010-11-02 15:13:54 -0400598 } else {
599 my $val = "$lvalue\[$test_num\]";
Steven Rostedt3d1cc412011-09-30 22:14:21 -0400600 set_value($val, $rvalue, $override, \%overrides, $name);
Steven Rostedta57419b2010-11-02 15:13:54 -0400601
602 if ($repeat > 1) {
603 $repeats{$val} = $repeat;
604 }
605 }
Steven Rostedt77d942c2011-05-20 13:36:58 -0400606 } elsif (/^\s*([A-Z_\[\]\d]+)\s*:=\s*(.*?)\s*$/) {
607 next if ($skip);
608
609 my $lvalue = $1;
610 my $rvalue = $2;
611
612 # process config variables.
613 # Config variables are only active while reading the
614 # config and can be defined anywhere. They also ignore
615 # TEST_START and DEFAULTS, but are skipped if they are in
616 # on of these sections that have SKIP defined.
617 # The save variable can be
618 # defined multiple times and the new one simply overrides
619 # the prevous one.
620 set_variable($lvalue, $rvalue);
621
Steven Rostedta57419b2010-11-02 15:13:54 -0400622 } else {
623 die "$name: $.: Garbage found in config\n$_";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400624 }
625 }
626
Steven Rostedta57419b2010-11-02 15:13:54 -0400627 if ($test_num) {
628 $test_num += $repeat - 1;
629 $opt{"NUM_TESTS"} = $test_num;
630 }
631
Steven Rostedt2ed3b162011-09-30 21:00:00 -0400632 close($in);
633
634 $$current_test_num = $test_num;
635
636 return $test_case;
637}
638
639sub read_config {
640 my ($config) = @_;
641
642 my $test_case;
643 my $test_num = 0;
644
645 $test_case = __read_config $config, \$test_num;
646
Steven Rostedt8d1491b2010-11-18 15:39:48 -0500647 # make sure we have all mandatory configs
648 get_ktest_configs;
649
Steven Rostedt0df213c2011-06-14 20:51:37 -0400650 # was a test specified?
651 if (!$test_case) {
652 print "No test case specified.\n";
653 print "What test case would you like to run?\n";
654 my $ans = <STDIN>;
655 chomp $ans;
656 $default{"TEST_TYPE"} = $ans;
657 }
658
Steven Rostedta75fece2010-11-02 14:58:27 -0400659 # set any defaults
660
661 foreach my $default (keys %default) {
662 if (!defined($opt{$default})) {
663 $opt{$default} = $default{$default};
664 }
665 }
Steven Rostedt2545eb62010-11-02 15:01:32 -0400666}
667
Steven Rostedt23715c3c2011-06-13 11:03:34 -0400668sub __eval_option {
669 my ($option, $i) = @_;
670
671 # Add space to evaluate the character before $
672 $option = " $option";
673 my $retval = "";
674
675 while ($option =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) {
676 my $start = $1;
677 my $var = $2;
678 my $end = $3;
679
680 # Append beginning of line
681 $retval = "$retval$start";
682
683 # If the iteration option OPT[$i] exists, then use that.
684 # otherwise see if the default OPT (without [$i]) exists.
685
686 my $o = "$var\[$i\]";
687
688 if (defined($opt{$o})) {
689 $o = $opt{$o};
690 $retval = "$retval$o";
691 } elsif (defined($opt{$var})) {
692 $o = $opt{$var};
693 $retval = "$retval$o";
694 } else {
695 $retval = "$retval\$\{$var\}";
696 }
697
698 $option = $end;
699 }
700
701 $retval = "$retval$option";
702
703 $retval =~ s/^ //;
704
705 return $retval;
706}
707
708sub eval_option {
709 my ($option, $i) = @_;
710
711 my $prev = "";
712
713 # Since an option can evaluate to another option,
714 # keep iterating until we do not evaluate any more
715 # options.
716 my $r = 0;
717 while ($prev ne $option) {
718 # Check for recursive evaluations.
719 # 100 deep should be more than enough.
720 if ($r++ > 100) {
721 die "Over 100 evaluations accurred with $option\n" .
722 "Check for recursive variables\n";
723 }
724 $prev = $option;
725 $option = __eval_option($option, $i);
726 }
727
728 return $option;
729}
730
Steven Rostedtd1e2f222010-11-08 16:39:57 -0500731sub _logit {
Steven Rostedt2545eb62010-11-02 15:01:32 -0400732 if (defined($opt{"LOG_FILE"})) {
733 open(OUT, ">> $opt{LOG_FILE}") or die "Can't write to $opt{LOG_FILE}";
734 print OUT @_;
735 close(OUT);
736 }
737}
738
Steven Rostedtd1e2f222010-11-08 16:39:57 -0500739sub logit {
740 if (defined($opt{"LOG_FILE"})) {
741 _logit @_;
742 } else {
743 print @_;
744 }
745}
746
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400747sub doprint {
748 print @_;
Steven Rostedtd1e2f222010-11-08 16:39:57 -0500749 _logit @_;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400750}
751
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400752sub run_command;
Andrew Jones2728be42011-08-12 15:32:05 +0200753sub start_monitor;
754sub end_monitor;
755sub wait_for_monitor;
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400756
757sub reboot {
Andrew Jones2728be42011-08-12 15:32:05 +0200758 my ($time) = @_;
759
Steven Rostedt2b803362011-09-30 18:00:23 -0400760 if (defined($time)) {
761 start_monitor;
762 # flush out current monitor
763 # May contain the reboot success line
764 wait_for_monitor 1;
765 }
766
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400767 # try to reboot normally
Steven Rostedte48c5292010-11-02 14:35:37 -0400768 if (run_command $reboot) {
Steven Rostedt576f6272010-11-02 14:58:38 -0400769 if (defined($powercycle_after_reboot)) {
770 sleep $powercycle_after_reboot;
771 run_command "$power_cycle";
772 }
773 } else {
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400774 # nope? power cycle it.
Steven Rostedta75fece2010-11-02 14:58:27 -0400775 run_command "$power_cycle";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400776 }
Andrew Jones2728be42011-08-12 15:32:05 +0200777
778 if (defined($time)) {
Steven Rostedt2b803362011-09-30 18:00:23 -0400779 wait_for_monitor($time, $reboot_success_line);
Andrew Jones2728be42011-08-12 15:32:05 +0200780 end_monitor;
781 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400782}
783
Steven Rostedt576f6272010-11-02 14:58:38 -0400784sub do_not_reboot {
785 my $i = $iteration;
786
Steven Rostedt4ab1cce2011-09-30 18:12:20 -0400787 return $test_type eq "build" || $no_reboot ||
Steven Rostedt576f6272010-11-02 14:58:38 -0400788 ($test_type eq "patchcheck" && $opt{"PATCHCHECK_TYPE[$i]"} eq "build") ||
789 ($test_type eq "bisect" && $opt{"BISECT_TYPE[$i]"} eq "build");
790}
791
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400792sub dodie {
Steven Rostedt5a391fb2010-11-02 14:57:43 -0400793 doprint "CRITICAL FAILURE... ", @_, "\n";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400794
Steven Rostedt576f6272010-11-02 14:58:38 -0400795 my $i = $iteration;
796
797 if ($reboot_on_error && !do_not_reboot) {
798
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400799 doprint "REBOOTING\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400800 reboot;
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400801
Steven Rostedta75fece2010-11-02 14:58:27 -0400802 } elsif ($poweroff_on_error && defined($power_off)) {
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400803 doprint "POWERING OFF\n";
Steven Rostedta75fece2010-11-02 14:58:27 -0400804 `$power_off`;
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400805 }
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400806
Steven Rostedtf80802c2011-03-07 13:18:47 -0500807 if (defined($opt{"LOG_FILE"})) {
808 print " See $opt{LOG_FILE} for more info.\n";
809 }
810
Steven Rostedt576f6272010-11-02 14:58:38 -0400811 die @_, "\n";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400812}
813
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400814sub open_console {
815 my ($fp) = @_;
816
817 my $flags;
818
Steven Rostedta75fece2010-11-02 14:58:27 -0400819 my $pid = open($fp, "$console|") or
820 dodie "Can't open console $console";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400821
822 $flags = fcntl($fp, F_GETFL, 0) or
Steven Rostedt576f6272010-11-02 14:58:38 -0400823 dodie "Can't get flags for the socket: $!";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400824 $flags = fcntl($fp, F_SETFL, $flags | O_NONBLOCK) or
Steven Rostedt576f6272010-11-02 14:58:38 -0400825 dodie "Can't set flags for the socket: $!";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400826
827 return $pid;
828}
829
830sub close_console {
831 my ($fp, $pid) = @_;
832
833 doprint "kill child process $pid\n";
834 kill 2, $pid;
835
836 print "closing!\n";
837 close($fp);
838}
839
840sub start_monitor {
841 if ($monitor_cnt++) {
842 return;
843 }
844 $monitor_fp = \*MONFD;
845 $monitor_pid = open_console $monitor_fp;
Steven Rostedta75fece2010-11-02 14:58:27 -0400846
847 return;
848
849 open(MONFD, "Stop perl from warning about single use of MONFD");
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400850}
851
852sub end_monitor {
853 if (--$monitor_cnt) {
854 return;
855 }
856 close_console($monitor_fp, $monitor_pid);
857}
858
859sub wait_for_monitor {
Steven Rostedt2b803362011-09-30 18:00:23 -0400860 my ($time, $stop) = @_;
861 my $full_line = "";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400862 my $line;
Steven Rostedt2b803362011-09-30 18:00:23 -0400863 my $booted = 0;
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400864
Steven Rostedta75fece2010-11-02 14:58:27 -0400865 doprint "** Wait for monitor to settle down **\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400866
867 # read the monitor and wait for the system to calm down
Steven Rostedt2b803362011-09-30 18:00:23 -0400868 while (!$booted) {
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400869 $line = wait_for_input($monitor_fp, $time);
Steven Rostedt2b803362011-09-30 18:00:23 -0400870 last if (!defined($line));
871 print "$line";
872 $full_line .= $line;
873
874 if (defined($stop) && $full_line =~ /$stop/) {
875 doprint "wait for monitor detected $stop\n";
876 $booted = 1;
877 }
878
879 if ($line =~ /\n/) {
880 $full_line = "";
881 }
882 }
Steven Rostedta75fece2010-11-02 14:58:27 -0400883 print "** Monitor flushed **\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400884}
885
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400886sub fail {
887
Steven Rostedta75fece2010-11-02 14:58:27 -0400888 if ($die_on_failure) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400889 dodie @_;
890 }
891
Steven Rostedta75fece2010-11-02 14:58:27 -0400892 doprint "FAILED\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400893
Steven Rostedt576f6272010-11-02 14:58:38 -0400894 my $i = $iteration;
895
Steven Rostedta75fece2010-11-02 14:58:27 -0400896 # no need to reboot for just building.
Steven Rostedt576f6272010-11-02 14:58:38 -0400897 if (!do_not_reboot) {
Steven Rostedta75fece2010-11-02 14:58:27 -0400898 doprint "REBOOTING\n";
Andrew Jones2728be42011-08-12 15:32:05 +0200899 reboot $sleep_time;
Steven Rostedta75fece2010-11-02 14:58:27 -0400900 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400901
Steven Rostedt9064af52011-06-13 10:38:48 -0400902 my $name = "";
903
904 if (defined($test_name)) {
905 $name = " ($test_name)";
906 }
907
Steven Rostedt576f6272010-11-02 14:58:38 -0400908 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
909 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
Steven Rostedt9064af52011-06-13 10:38:48 -0400910 doprint "KTEST RESULT: TEST $i$name Failed: ", @_, "\n";
Steven Rostedt576f6272010-11-02 14:58:38 -0400911 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
912 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
Steven Rostedta75fece2010-11-02 14:58:27 -0400913
914 return 1 if (!defined($store_failures));
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400915
916 my @t = localtime;
917 my $date = sprintf "%04d%02d%02d%02d%02d%02d",
918 1900+$t[5],$t[4],$t[3],$t[2],$t[1],$t[0];
919
Steven Rostedtcccae1a2010-11-09 12:21:32 -0500920 my $type = $build_type;
921 if ($type =~ /useconfig/) {
922 $type = "useconfig";
923 }
924
925 my $dir = "$machine-$test_type-$type-fail-$date";
Steven Rostedta75fece2010-11-02 14:58:27 -0400926 my $faildir = "$store_failures/$dir";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400927
928 if (!-d $faildir) {
929 mkpath($faildir) or
Steven Rostedta75fece2010-11-02 14:58:27 -0400930 die "can't create $faildir";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400931 }
Steven Rostedt51ad1dd2010-11-08 16:43:21 -0500932 if (-f "$output_config") {
933 cp "$output_config", "$faildir/config" or
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400934 die "failed to copy .config";
935 }
936 if (-f $buildlog) {
937 cp $buildlog, "$faildir/buildlog" or
938 die "failed to move $buildlog";
939 }
940 if (-f $dmesg) {
941 cp $dmesg, "$faildir/dmesg" or
942 die "failed to move $dmesg";
943 }
944
945 doprint "*** Saved info to $faildir ***\n";
946
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400947 return 1;
948}
949
Steven Rostedt2545eb62010-11-02 15:01:32 -0400950sub run_command {
951 my ($command) = @_;
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400952 my $dolog = 0;
953 my $dord = 0;
954 my $pid;
955
Steven Rostedte48c5292010-11-02 14:35:37 -0400956 $command =~ s/\$SSH_USER/$ssh_user/g;
957 $command =~ s/\$MACHINE/$machine/g;
958
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400959 doprint("$command ... ");
960
961 $pid = open(CMD, "$command 2>&1 |") or
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400962 (fail "unable to exec $command" and return 0);
Steven Rostedt2545eb62010-11-02 15:01:32 -0400963
964 if (defined($opt{"LOG_FILE"})) {
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400965 open(LOG, ">>$opt{LOG_FILE}") or
966 dodie "failed to write to log";
967 $dolog = 1;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -0400968 }
969
970 if (defined($redirect)) {
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400971 open (RD, ">$redirect") or
972 dodie "failed to write to redirect $redirect";
973 $dord = 1;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400974 }
975
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400976 while (<CMD>) {
977 print LOG if ($dolog);
978 print RD if ($dord);
979 }
Steven Rostedt2545eb62010-11-02 15:01:32 -0400980
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400981 waitpid($pid, 0);
Steven Rostedt2545eb62010-11-02 15:01:32 -0400982 my $failed = $?;
983
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400984 close(CMD);
985 close(LOG) if ($dolog);
986 close(RD) if ($dord);
987
Steven Rostedt2545eb62010-11-02 15:01:32 -0400988 if ($failed) {
989 doprint "FAILED!\n";
990 } else {
991 doprint "SUCCESS\n";
992 }
993
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400994 return !$failed;
995}
996
Steven Rostedte48c5292010-11-02 14:35:37 -0400997sub run_ssh {
998 my ($cmd) = @_;
999 my $cp_exec = $ssh_exec;
1000
1001 $cp_exec =~ s/\$SSH_COMMAND/$cmd/g;
1002 return run_command "$cp_exec";
1003}
1004
1005sub run_scp {
1006 my ($src, $dst) = @_;
1007 my $cp_scp = $scp_to_target;
1008
1009 $cp_scp =~ s/\$SRC_FILE/$src/g;
1010 $cp_scp =~ s/\$DST_FILE/$dst/g;
1011
1012 return run_command "$cp_scp";
1013}
1014
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001015sub get_grub_index {
1016
Steven Rostedta75fece2010-11-02 14:58:27 -04001017 if ($reboot_type ne "grub") {
1018 return;
1019 }
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001020 return if (defined($grub_number));
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001021
1022 doprint "Find grub menu ... ";
1023 $grub_number = -1;
Steven Rostedte48c5292010-11-02 14:35:37 -04001024
1025 my $ssh_grub = $ssh_exec;
1026 $ssh_grub =~ s,\$SSH_COMMAND,cat /boot/grub/menu.lst,g;
1027
1028 open(IN, "$ssh_grub |")
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001029 or die "unable to get menu.lst";
Steven Rostedte48c5292010-11-02 14:35:37 -04001030
Steven Rostedteaa1fe22011-09-14 17:20:39 -04001031 my $found = 0;
1032
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001033 while (<IN>) {
Steven Rostedta75fece2010-11-02 14:58:27 -04001034 if (/^\s*title\s+$grub_menu\s*$/) {
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001035 $grub_number++;
Steven Rostedteaa1fe22011-09-14 17:20:39 -04001036 $found = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001037 last;
1038 } elsif (/^\s*title\s/) {
1039 $grub_number++;
1040 }
1041 }
1042 close(IN);
1043
Steven Rostedta75fece2010-11-02 14:58:27 -04001044 die "Could not find '$grub_menu' in /boot/grub/menu on $machine"
Steven Rostedteaa1fe22011-09-14 17:20:39 -04001045 if (!$found);
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001046 doprint "$grub_number\n";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001047}
1048
Steven Rostedt2545eb62010-11-02 15:01:32 -04001049sub wait_for_input
1050{
1051 my ($fp, $time) = @_;
1052 my $rin;
1053 my $ready;
1054 my $line;
1055 my $ch;
1056
1057 if (!defined($time)) {
1058 $time = $timeout;
1059 }
1060
1061 $rin = '';
1062 vec($rin, fileno($fp), 1) = 1;
1063 $ready = select($rin, undef, undef, $time);
1064
1065 $line = "";
1066
1067 # try to read one char at a time
1068 while (sysread $fp, $ch, 1) {
1069 $line .= $ch;
1070 last if ($ch eq "\n");
1071 }
1072
1073 if (!length($line)) {
1074 return undef;
1075 }
1076
1077 return $line;
1078}
1079
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001080sub reboot_to {
Steven Rostedta75fece2010-11-02 14:58:27 -04001081 if ($reboot_type eq "grub") {
Steven Rostedt4da46da2011-06-01 23:25:13 -04001082 run_ssh "'(echo \"savedefault --default=$grub_number --once\" | grub --batch && reboot)'";
Steven Rostedta75fece2010-11-02 14:58:27 -04001083 return;
1084 }
1085
1086 run_command "$reboot_script";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001087}
1088
Steven Rostedta57419b2010-11-02 15:13:54 -04001089sub get_sha1 {
1090 my ($commit) = @_;
1091
1092 doprint "git rev-list --max-count=1 $commit ... ";
1093 my $sha1 = `git rev-list --max-count=1 $commit`;
1094 my $ret = $?;
1095
1096 logit $sha1;
1097
1098 if ($ret) {
1099 doprint "FAILED\n";
1100 dodie "Failed to get git $commit";
1101 }
1102
1103 print "SUCCESS\n";
1104
1105 chomp $sha1;
1106
1107 return $sha1;
1108}
1109
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001110sub monitor {
Steven Rostedt2545eb62010-11-02 15:01:32 -04001111 my $booted = 0;
1112 my $bug = 0;
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001113 my $skip_call_trace = 0;
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001114 my $loops;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001115
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001116 wait_for_monitor 5;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001117
1118 my $line;
1119 my $full_line = "";
1120
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001121 open(DMESG, "> $dmesg") or
1122 die "unable to write to $dmesg";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001123
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001124 reboot_to;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001125
Steven Rostedt1c8a6172010-11-09 12:55:40 -05001126 my $success_start;
1127 my $failure_start;
Steven Rostedt2d01b262011-03-08 09:47:54 -05001128 my $monitor_start = time;
1129 my $done = 0;
Steven Rostedtf1a5b962011-06-13 10:30:00 -04001130 my $version_found = 0;
Steven Rostedt1c8a6172010-11-09 12:55:40 -05001131
Steven Rostedt2d01b262011-03-08 09:47:54 -05001132 while (!$done) {
Steven Rostedt2545eb62010-11-02 15:01:32 -04001133
Steven Rostedtecaf8e52011-06-13 10:48:10 -04001134 if ($bug && defined($stop_after_failure) &&
1135 $stop_after_failure >= 0) {
1136 my $time = $stop_after_failure - (time - $failure_start);
1137 $line = wait_for_input($monitor_fp, $time);
1138 if (!defined($line)) {
1139 doprint "bug timed out after $booted_timeout seconds\n";
1140 doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
1141 last;
1142 }
1143 } elsif ($booted) {
Steven Rostedta75fece2010-11-02 14:58:27 -04001144 $line = wait_for_input($monitor_fp, $booted_timeout);
Steven Rostedtcd4f1d52011-06-13 10:26:27 -04001145 if (!defined($line)) {
1146 my $s = $booted_timeout == 1 ? "" : "s";
1147 doprint "Successful boot found: break after $booted_timeout second$s\n";
1148 last;
1149 }
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001150 } else {
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001151 $line = wait_for_input($monitor_fp);
Steven Rostedtcd4f1d52011-06-13 10:26:27 -04001152 if (!defined($line)) {
1153 my $s = $timeout == 1 ? "" : "s";
1154 doprint "Timed out after $timeout second$s\n";
1155 last;
1156 }
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001157 }
Steven Rostedt2545eb62010-11-02 15:01:32 -04001158
Steven Rostedt2545eb62010-11-02 15:01:32 -04001159 doprint $line;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001160 print DMESG $line;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001161
1162 # we are not guaranteed to get a full line
1163 $full_line .= $line;
1164
Steven Rostedta75fece2010-11-02 14:58:27 -04001165 if ($full_line =~ /$success_line/) {
Steven Rostedt2545eb62010-11-02 15:01:32 -04001166 $booted = 1;
Steven Rostedt1c8a6172010-11-09 12:55:40 -05001167 $success_start = time;
1168 }
1169
1170 if ($booted && defined($stop_after_success) &&
1171 $stop_after_success >= 0) {
1172 my $now = time;
1173 if ($now - $success_start >= $stop_after_success) {
1174 doprint "Test forced to stop after $stop_after_success seconds after success\n";
1175 last;
1176 }
Steven Rostedt2545eb62010-11-02 15:01:32 -04001177 }
1178
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001179 if ($full_line =~ /\[ backtrace testing \]/) {
1180 $skip_call_trace = 1;
1181 }
1182
Steven Rostedt2545eb62010-11-02 15:01:32 -04001183 if ($full_line =~ /call trace:/i) {
Steven Rostedt46519202011-03-08 09:40:31 -05001184 if (!$bug && !$skip_call_trace) {
Steven Rostedt1c8a6172010-11-09 12:55:40 -05001185 $bug = 1;
1186 $failure_start = time;
1187 }
1188 }
1189
1190 if ($bug && defined($stop_after_failure) &&
1191 $stop_after_failure >= 0) {
1192 my $now = time;
1193 if ($now - $failure_start >= $stop_after_failure) {
1194 doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
1195 last;
1196 }
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001197 }
1198
1199 if ($full_line =~ /\[ end of backtrace testing \]/) {
1200 $skip_call_trace = 0;
1201 }
1202
1203 if ($full_line =~ /Kernel panic -/) {
Steven Rostedt10abf112011-03-07 13:21:00 -05001204 $failure_start = time;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001205 $bug = 1;
1206 }
1207
Steven Rostedtf1a5b962011-06-13 10:30:00 -04001208 # Detect triple faults by testing the banner
1209 if ($full_line =~ /\bLinux version (\S+).*\n/) {
1210 if ($1 eq $version) {
1211 $version_found = 1;
1212 } elsif ($version_found && $detect_triplefault) {
1213 # We already booted into the kernel we are testing,
1214 # but now we booted into another kernel?
1215 # Consider this a triple fault.
1216 doprint "Aleady booted in Linux kernel $version, but now\n";
1217 doprint "we booted into Linux kernel $1.\n";
1218 doprint "Assuming that this is a triple fault.\n";
1219 doprint "To disable this: set DETECT_TRIPLE_FAULT to 0\n";
1220 last;
1221 }
1222 }
1223
Steven Rostedt2545eb62010-11-02 15:01:32 -04001224 if ($line =~ /\n/) {
1225 $full_line = "";
1226 }
Steven Rostedt2d01b262011-03-08 09:47:54 -05001227
1228 if ($stop_test_after > 0 && !$booted && !$bug) {
1229 if (time - $monitor_start > $stop_test_after) {
Steven Rostedt4d62bf52011-05-20 09:14:35 -04001230 doprint "STOP_TEST_AFTER ($stop_test_after seconds) timed out\n";
Steven Rostedt2d01b262011-03-08 09:47:54 -05001231 $done = 1;
1232 }
1233 }
Steven Rostedt2545eb62010-11-02 15:01:32 -04001234 }
1235
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001236 close(DMESG);
Steven Rostedt2545eb62010-11-02 15:01:32 -04001237
Steven Rostedt2545eb62010-11-02 15:01:32 -04001238 if ($bug) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001239 return 0 if ($in_bisect);
Steven Rostedt576f6272010-11-02 14:58:38 -04001240 fail "failed - got a bug report" and return 0;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001241 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001242
Steven Rostedta75fece2010-11-02 14:58:27 -04001243 if (!$booted) {
1244 return 0 if ($in_bisect);
Steven Rostedt576f6272010-11-02 14:58:38 -04001245 fail "failed - never got a boot prompt." and return 0;
Steven Rostedta75fece2010-11-02 14:58:27 -04001246 }
1247
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001248 return 1;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001249}
1250
Steven Rostedtdb05cfe2011-06-13 11:09:22 -04001251sub do_post_install {
1252
1253 return if (!defined($post_install));
1254
1255 my $cp_post_install = $post_install;
1256 $cp_post_install =~ s/\$KERNEL_VERSION/$version/g;
1257 run_command "$cp_post_install" or
1258 dodie "Failed to run post install";
1259}
1260
Steven Rostedt2545eb62010-11-02 15:01:32 -04001261sub install {
1262
Steven Rostedte0a87422011-09-30 17:50:48 -04001263 return if ($no_install);
1264
Steven Rostedte48c5292010-11-02 14:35:37 -04001265 run_scp "$outputdir/$build_target", "$target_image" or
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001266 dodie "failed to copy image";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001267
1268 my $install_mods = 0;
1269
1270 # should we process modules?
1271 $install_mods = 0;
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05001272 open(IN, "$output_config") or dodie("Can't read config file");
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001273 while (<IN>) {
1274 if (/CONFIG_MODULES(=y)?/) {
1275 $install_mods = 1 if (defined($1));
1276 last;
1277 }
1278 }
1279 close(IN);
1280
1281 if (!$install_mods) {
Steven Rostedtdb05cfe2011-06-13 11:09:22 -04001282 do_post_install;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001283 doprint "No modules needed\n";
1284 return;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001285 }
1286
Steven Rostedta75fece2010-11-02 14:58:27 -04001287 run_command "$make INSTALL_MOD_PATH=$tmpdir modules_install" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001288 dodie "Failed to install modules";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001289
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001290 my $modlib = "/lib/modules/$version";
Steven Rostedta57419b2010-11-02 15:13:54 -04001291 my $modtar = "ktest-mods.tar.bz2";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001292
Steven Rostedte48c5292010-11-02 14:35:37 -04001293 run_ssh "rm -rf $modlib" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001294 dodie "failed to remove old mods: $modlib";
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001295
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001296 # would be nice if scp -r did not follow symbolic links
Steven Rostedta75fece2010-11-02 14:58:27 -04001297 run_command "cd $tmpdir && tar -cjf $modtar lib/modules/$version" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001298 dodie "making tarball";
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001299
Steven Rostedte48c5292010-11-02 14:35:37 -04001300 run_scp "$tmpdir/$modtar", "/tmp" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001301 dodie "failed to copy modules";
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001302
Steven Rostedta75fece2010-11-02 14:58:27 -04001303 unlink "$tmpdir/$modtar";
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001304
Steven Rostedte7b13442011-06-14 20:44:36 -04001305 run_ssh "'(cd / && tar xjf /tmp/$modtar)'" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001306 dodie "failed to tar modules";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001307
Steven Rostedte48c5292010-11-02 14:35:37 -04001308 run_ssh "rm -f /tmp/$modtar";
Steven Rostedt8b37ca82010-11-02 14:58:33 -04001309
Steven Rostedtdb05cfe2011-06-13 11:09:22 -04001310 do_post_install;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001311}
1312
Steven Rostedtddf607e2011-06-14 20:49:13 -04001313sub get_version {
1314 # get the release name
1315 doprint "$make kernelrelease ... ";
1316 $version = `$make kernelrelease | tail -1`;
1317 chomp($version);
1318 doprint "$version\n";
1319}
1320
1321sub start_monitor_and_boot {
1322 get_grub_index;
1323 get_version;
1324 install;
1325
1326 start_monitor;
1327 return monitor;
1328}
1329
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001330sub check_buildlog {
1331 my ($patch) = @_;
1332
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001333 my @files = `git show $patch | diffstat -l`;
1334
1335 open(IN, "git show $patch |") or
1336 dodie "failed to show $patch";
1337 while (<IN>) {
1338 if (m,^--- a/(.*),) {
1339 chomp $1;
1340 $files[$#files] = $1;
1341 }
1342 }
1343 close(IN);
1344
1345 open(IN, $buildlog) or dodie "Can't open $buildlog";
1346 while (<IN>) {
1347 if (/^\s*(.*?):.*(warning|error)/) {
1348 my $err = $1;
1349 foreach my $file (@files) {
Steven Rostedta75fece2010-11-02 14:58:27 -04001350 my $fullpath = "$builddir/$file";
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001351 if ($file eq $err || $fullpath eq $err) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001352 fail "$file built with warnings" and return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001353 }
1354 }
1355 }
1356 }
1357 close(IN);
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001358
1359 return 1;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001360}
1361
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001362sub apply_min_config {
1363 my $outconfig = "$output_config.new";
Steven Rostedt612b9e92011-03-07 13:27:43 -05001364
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001365 # Read the config file and remove anything that
1366 # is in the force_config hash (from minconfig and others)
1367 # then add the force config back.
1368
1369 doprint "Applying minimum configurations into $output_config.new\n";
1370
1371 open (OUT, ">$outconfig") or
1372 dodie "Can't create $outconfig";
1373
1374 if (-f $output_config) {
1375 open (IN, $output_config) or
1376 dodie "Failed to open $output_config";
1377 while (<IN>) {
1378 if (/^(# )?(CONFIG_[^\s=]*)/) {
1379 next if (defined($force_config{$2}));
1380 }
1381 print OUT;
1382 }
1383 close IN;
1384 }
1385 foreach my $config (keys %force_config) {
1386 print OUT "$force_config{$config}\n";
1387 }
1388 close OUT;
1389
1390 run_command "mv $outconfig $output_config";
1391}
1392
1393sub make_oldconfig {
1394
Steven Rostedt4c4ab122011-07-15 21:16:17 -04001395 my @force_list = keys %force_config;
1396
1397 if ($#force_list >= 0) {
1398 apply_min_config;
1399 }
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001400
1401 if (!run_command "$make oldnoconfig") {
Steven Rostedt612b9e92011-03-07 13:27:43 -05001402 # Perhaps oldnoconfig doesn't exist in this version of the kernel
1403 # try a yes '' | oldconfig
1404 doprint "oldnoconfig failed, trying yes '' | make oldconfig\n";
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001405 run_command "yes '' | $make oldconfig" or
Steven Rostedt612b9e92011-03-07 13:27:43 -05001406 dodie "failed make config oldconfig";
1407 }
1408}
1409
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001410# read a config file and use this to force new configs.
1411sub load_force_config {
1412 my ($config) = @_;
1413
1414 open(IN, $config) or
1415 dodie "failed to read $config";
1416 while (<IN>) {
1417 chomp;
1418 if (/^(CONFIG[^\s=]*)(\s*=.*)/) {
1419 $force_config{$1} = $_;
1420 } elsif (/^# (CONFIG_\S*) is not set/) {
1421 $force_config{$1} = $_;
1422 }
1423 }
1424 close IN;
1425}
1426
Steven Rostedt2545eb62010-11-02 15:01:32 -04001427sub build {
1428 my ($type) = @_;
1429
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001430 unlink $buildlog;
1431
Steven Rostedt4ab1cce2011-09-30 18:12:20 -04001432 # Failed builds should not reboot the target
1433 my $save_no_reboot = $no_reboot;
1434 $no_reboot = 1;
1435
Steven Rostedt0bd6c1a2011-06-14 20:39:31 -04001436 if (defined($pre_build)) {
1437 my $ret = run_command $pre_build;
1438 if (!$ret && defined($pre_build_die) &&
1439 $pre_build_die) {
1440 dodie "failed to pre_build\n";
1441 }
1442 }
1443
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001444 if ($type =~ /^useconfig:(.*)/) {
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05001445 run_command "cp $1 $output_config" or
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001446 dodie "could not copy $1 to .config";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001447
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001448 $type = "oldconfig";
1449 }
1450
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001451 # old config can ask questions
1452 if ($type eq "oldconfig") {
Steven Rostedt9386c6a2010-11-08 16:35:48 -05001453 $type = "oldnoconfig";
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001454
1455 # allow for empty configs
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05001456 run_command "touch $output_config";
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001457
Andrew Jones13488232011-08-12 15:32:04 +02001458 if (!$noclean) {
1459 run_command "mv $output_config $outputdir/config_temp" or
1460 dodie "moving .config";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001461
Andrew Jones13488232011-08-12 15:32:04 +02001462 run_command "$make mrproper" or dodie "make mrproper";
1463
1464 run_command "mv $outputdir/config_temp $output_config" or
1465 dodie "moving config_temp";
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001466 }
1467
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001468 } elsif (!$noclean) {
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05001469 unlink "$output_config";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001470 run_command "$make mrproper" or
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001471 dodie "make mrproper";
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001472 }
Steven Rostedt2545eb62010-11-02 15:01:32 -04001473
1474 # add something to distinguish this build
Steven Rostedta75fece2010-11-02 14:58:27 -04001475 open(OUT, "> $outputdir/localversion") or dodie("Can't make localversion file");
1476 print OUT "$localversion\n";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001477 close(OUT);
1478
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001479 if (defined($minconfig)) {
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001480 load_force_config($minconfig);
Steven Rostedt2545eb62010-11-02 15:01:32 -04001481 }
1482
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001483 if ($type ne "oldnoconfig") {
1484 run_command "$make $type" or
Steven Rostedt612b9e92011-03-07 13:27:43 -05001485 dodie "failed make config";
1486 }
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001487 # Run old config regardless, to enforce min configurations
1488 make_oldconfig;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001489
Steven Rostedta75fece2010-11-02 14:58:27 -04001490 $redirect = "$buildlog";
Steven Rostedt0bd6c1a2011-06-14 20:39:31 -04001491 my $build_ret = run_command "$make $build_options";
1492 undef $redirect;
1493
1494 if (defined($post_build)) {
1495 my $ret = run_command $post_build;
1496 if (!$ret && defined($post_build_die) &&
1497 $post_build_die) {
1498 dodie "failed to post_build\n";
1499 }
1500 }
1501
1502 if (!$build_ret) {
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001503 # bisect may need this to pass
Steven Rostedt4ab1cce2011-09-30 18:12:20 -04001504 if ($in_bisect) {
1505 $no_reboot = $save_no_reboot;
1506 return 0;
1507 }
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001508 fail "failed build" and return 0;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001509 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001510
Steven Rostedt4ab1cce2011-09-30 18:12:20 -04001511 $no_reboot = $save_no_reboot;
1512
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001513 return 1;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001514}
1515
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001516sub halt {
Steven Rostedte48c5292010-11-02 14:35:37 -04001517 if (!run_ssh "halt" or defined($power_off)) {
Steven Rostedt576f6272010-11-02 14:58:38 -04001518 if (defined($poweroff_after_halt)) {
1519 sleep $poweroff_after_halt;
1520 run_command "$power_off";
1521 }
1522 } else {
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001523 # nope? the zap it!
Steven Rostedta75fece2010-11-02 14:58:27 -04001524 run_command "$power_off";
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001525 }
1526}
1527
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001528sub success {
1529 my ($i) = @_;
1530
Steven Rostedte48c5292010-11-02 14:35:37 -04001531 $successes++;
1532
Steven Rostedt9064af52011-06-13 10:38:48 -04001533 my $name = "";
1534
1535 if (defined($test_name)) {
1536 $name = " ($test_name)";
1537 }
1538
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001539 doprint "\n\n*******************************************\n";
1540 doprint "*******************************************\n";
Steven Rostedt9064af52011-06-13 10:38:48 -04001541 doprint "KTEST RESULT: TEST $i$name SUCCESS!!!! **\n";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001542 doprint "*******************************************\n";
1543 doprint "*******************************************\n";
1544
Steven Rostedt576f6272010-11-02 14:58:38 -04001545 if ($i != $opt{"NUM_TESTS"} && !do_not_reboot) {
Steven Rostedta75fece2010-11-02 14:58:27 -04001546 doprint "Reboot and wait $sleep_time seconds\n";
Andrew Jones2728be42011-08-12 15:32:05 +02001547 reboot $sleep_time;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001548 }
1549}
1550
Steven Rostedtc960bb92011-03-08 09:22:39 -05001551sub answer_bisect {
1552 for (;;) {
1553 doprint "Pass or fail? [p/f]";
1554 my $ans = <STDIN>;
1555 chomp $ans;
1556 if ($ans eq "p" || $ans eq "P") {
1557 return 1;
1558 } elsif ($ans eq "f" || $ans eq "F") {
1559 return 0;
1560 } else {
1561 print "Please answer 'P' or 'F'\n";
1562 }
1563 }
1564}
1565
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001566sub child_run_test {
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001567 my $failed = 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001568
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001569 # child should have no power
Steven Rostedta75fece2010-11-02 14:58:27 -04001570 $reboot_on_error = 0;
1571 $poweroff_on_error = 0;
1572 $die_on_failure = 1;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001573
1574 run_command $run_test or $failed = 1;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001575 exit $failed;
1576}
1577
1578my $child_done;
1579
1580sub child_finished {
1581 $child_done = 1;
1582}
1583
1584sub do_run_test {
1585 my $child_pid;
1586 my $child_exit;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001587 my $line;
1588 my $full_line;
1589 my $bug = 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001590
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001591 wait_for_monitor 1;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001592
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001593 doprint "run test $run_test\n";
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001594
1595 $child_done = 0;
1596
1597 $SIG{CHLD} = qw(child_finished);
1598
1599 $child_pid = fork;
1600
1601 child_run_test if (!$child_pid);
1602
1603 $full_line = "";
1604
1605 do {
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001606 $line = wait_for_input($monitor_fp, 1);
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001607 if (defined($line)) {
1608
1609 # we are not guaranteed to get a full line
1610 $full_line .= $line;
Steven Rostedt8ea0e062011-03-08 09:44:35 -05001611 doprint $line;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001612
1613 if ($full_line =~ /call trace:/i) {
1614 $bug = 1;
1615 }
1616
1617 if ($full_line =~ /Kernel panic -/) {
1618 $bug = 1;
1619 }
1620
1621 if ($line =~ /\n/) {
1622 $full_line = "";
1623 }
1624 }
1625 } while (!$child_done && !$bug);
1626
1627 if ($bug) {
Steven Rostedt8ea0e062011-03-08 09:44:35 -05001628 my $failure_start = time;
1629 my $now;
1630 do {
1631 $line = wait_for_input($monitor_fp, 1);
1632 if (defined($line)) {
1633 doprint $line;
1634 }
1635 $now = time;
1636 if ($now - $failure_start >= $stop_after_failure) {
1637 last;
1638 }
1639 } while (defined($line));
1640
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001641 doprint "Detected kernel crash!\n";
1642 # kill the child with extreme prejudice
1643 kill 9, $child_pid;
1644 }
1645
1646 waitpid $child_pid, 0;
1647 $child_exit = $?;
1648
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001649 if ($bug || $child_exit) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001650 return 0 if $in_bisect;
1651 fail "test failed" and return 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001652 }
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001653 return 1;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001654}
1655
Steven Rostedta75fece2010-11-02 14:58:27 -04001656sub run_git_bisect {
1657 my ($command) = @_;
1658
1659 doprint "$command ... ";
1660
1661 my $output = `$command 2>&1`;
1662 my $ret = $?;
1663
1664 logit $output;
1665
1666 if ($ret) {
1667 doprint "FAILED\n";
1668 dodie "Failed to git bisect";
1669 }
1670
1671 doprint "SUCCESS\n";
1672 if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\))\s+\[([[:xdigit:]]+)\]/) {
1673 doprint "$1 [$2]\n";
1674 } elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) {
1675 $bisect_bad = $1;
1676 doprint "Found bad commit... $1\n";
1677 return 0;
1678 } else {
1679 # we already logged it, just print it now.
1680 print $output;
1681 }
1682
1683 return 1;
1684}
1685
Steven Rostedtc23dca72011-03-08 09:26:31 -05001686sub bisect_reboot {
1687 doprint "Reboot and sleep $bisect_sleep_time seconds\n";
Andrew Jones2728be42011-08-12 15:32:05 +02001688 reboot $bisect_sleep_time;
Steven Rostedtc23dca72011-03-08 09:26:31 -05001689}
1690
1691# returns 1 on success, 0 on failure, -1 on skip
Steven Rostedt0a05c762010-11-08 11:14:10 -05001692sub run_bisect_test {
1693 my ($type, $buildtype) = @_;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001694
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001695 my $failed = 0;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001696 my $result;
1697 my $output;
1698 my $ret;
1699
Steven Rostedt0a05c762010-11-08 11:14:10 -05001700 $in_bisect = 1;
1701
1702 build $buildtype or $failed = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001703
1704 if ($type ne "build") {
Steven Rostedtc23dca72011-03-08 09:26:31 -05001705 if ($failed && $bisect_skip) {
1706 $in_bisect = 0;
1707 return -1;
1708 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001709 dodie "Failed on build" if $failed;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001710
1711 # Now boot the box
Steven Rostedtddf607e2011-06-14 20:49:13 -04001712 start_monitor_and_boot or $failed = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001713
1714 if ($type ne "boot") {
Steven Rostedtc23dca72011-03-08 09:26:31 -05001715 if ($failed && $bisect_skip) {
1716 end_monitor;
1717 bisect_reboot;
1718 $in_bisect = 0;
1719 return -1;
1720 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001721 dodie "Failed on boot" if $failed;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001722
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001723 do_run_test or $failed = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001724 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001725 end_monitor;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001726 }
1727
1728 if ($failed) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001729 $result = 0;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001730 } else {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001731 $result = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001732 }
Steven Rostedt4025bc62011-05-20 09:16:29 -04001733
1734 # reboot the box to a kernel we can ssh to
1735 if ($type ne "build") {
1736 bisect_reboot;
1737 }
Steven Rostedt0a05c762010-11-08 11:14:10 -05001738 $in_bisect = 0;
1739
1740 return $result;
1741}
1742
1743sub run_bisect {
1744 my ($type) = @_;
1745 my $buildtype = "oldconfig";
1746
1747 # We should have a minconfig to use?
1748 if (defined($minconfig)) {
1749 $buildtype = "useconfig:$minconfig";
1750 }
1751
1752 my $ret = run_bisect_test $type, $buildtype;
1753
Steven Rostedtc960bb92011-03-08 09:22:39 -05001754 if ($bisect_manual) {
1755 $ret = answer_bisect;
1756 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001757
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04001758 # Are we looking for where it worked, not failed?
1759 if ($reverse_bisect) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001760 $ret = !$ret;
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04001761 }
1762
Steven Rostedtc23dca72011-03-08 09:26:31 -05001763 if ($ret > 0) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001764 return "good";
Steven Rostedtc23dca72011-03-08 09:26:31 -05001765 } elsif ($ret == 0) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001766 return "bad";
Steven Rostedtc23dca72011-03-08 09:26:31 -05001767 } elsif ($bisect_skip) {
1768 doprint "HIT A BAD COMMIT ... SKIPPING\n";
1769 return "skip";
Steven Rostedt0a05c762010-11-08 11:14:10 -05001770 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001771}
1772
1773sub bisect {
1774 my ($i) = @_;
1775
1776 my $result;
1777
1778 die "BISECT_GOOD[$i] not defined\n" if (!defined($opt{"BISECT_GOOD[$i]"}));
1779 die "BISECT_BAD[$i] not defined\n" if (!defined($opt{"BISECT_BAD[$i]"}));
1780 die "BISECT_TYPE[$i] not defined\n" if (!defined($opt{"BISECT_TYPE[$i]"}));
1781
1782 my $good = $opt{"BISECT_GOOD[$i]"};
1783 my $bad = $opt{"BISECT_BAD[$i]"};
1784 my $type = $opt{"BISECT_TYPE[$i]"};
Steven Rostedta75fece2010-11-02 14:58:27 -04001785 my $start = $opt{"BISECT_START[$i]"};
1786 my $replay = $opt{"BISECT_REPLAY[$i]"};
Steven Rostedt3410f6f2011-03-08 09:38:12 -05001787 my $start_files = $opt{"BISECT_FILES[$i]"};
1788
1789 if (defined($start_files)) {
1790 $start_files = " -- " . $start_files;
1791 } else {
1792 $start_files = "";
1793 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001794
Steven Rostedta57419b2010-11-02 15:13:54 -04001795 # convert to true sha1's
1796 $good = get_sha1($good);
1797 $bad = get_sha1($bad);
1798
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04001799 if (defined($opt{"BISECT_REVERSE[$i]"}) &&
1800 $opt{"BISECT_REVERSE[$i]"} == 1) {
1801 doprint "Performing a reverse bisect (bad is good, good is bad!)\n";
1802 $reverse_bisect = 1;
1803 } else {
1804 $reverse_bisect = 0;
1805 }
1806
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001807 # Can't have a test without having a test to run
1808 if ($type eq "test" && !defined($run_test)) {
1809 $type = "boot";
1810 }
1811
Steven Rostedta75fece2010-11-02 14:58:27 -04001812 my $check = $opt{"BISECT_CHECK[$i]"};
1813 if (defined($check) && $check ne "0") {
1814
1815 # get current HEAD
Steven Rostedta57419b2010-11-02 15:13:54 -04001816 my $head = get_sha1("HEAD");
Steven Rostedta75fece2010-11-02 14:58:27 -04001817
1818 if ($check ne "good") {
1819 doprint "TESTING BISECT BAD [$bad]\n";
1820 run_command "git checkout $bad" or
1821 die "Failed to checkout $bad";
1822
1823 $result = run_bisect $type;
1824
1825 if ($result ne "bad") {
1826 fail "Tested BISECT_BAD [$bad] and it succeeded" and return 0;
1827 }
1828 }
1829
1830 if ($check ne "bad") {
1831 doprint "TESTING BISECT GOOD [$good]\n";
1832 run_command "git checkout $good" or
1833 die "Failed to checkout $good";
1834
1835 $result = run_bisect $type;
1836
1837 if ($result ne "good") {
1838 fail "Tested BISECT_GOOD [$good] and it failed" and return 0;
1839 }
1840 }
1841
1842 # checkout where we started
1843 run_command "git checkout $head" or
1844 die "Failed to checkout $head";
1845 }
1846
Steven Rostedt3410f6f2011-03-08 09:38:12 -05001847 run_command "git bisect start$start_files" or
Steven Rostedta75fece2010-11-02 14:58:27 -04001848 dodie "could not start bisect";
1849
1850 run_command "git bisect good $good" or
1851 dodie "could not set bisect good to $good";
1852
1853 run_git_bisect "git bisect bad $bad" or
1854 dodie "could not set bisect bad to $bad";
1855
1856 if (defined($replay)) {
1857 run_command "git bisect replay $replay" or
1858 dodie "failed to run replay";
1859 }
1860
1861 if (defined($start)) {
1862 run_command "git checkout $start" or
1863 dodie "failed to checkout $start";
1864 }
1865
1866 my $test;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001867 do {
1868 $result = run_bisect $type;
Steven Rostedta75fece2010-11-02 14:58:27 -04001869 $test = run_git_bisect "git bisect $result";
1870 } while ($test);
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001871
1872 run_command "git bisect log" or
1873 dodie "could not capture git bisect log";
1874
1875 run_command "git bisect reset" or
1876 dodie "could not reset git bisect";
1877
1878 doprint "Bad commit was [$bisect_bad]\n";
1879
Steven Rostedt0a05c762010-11-08 11:14:10 -05001880 success $i;
1881}
1882
1883my %config_ignore;
1884my %config_set;
1885
1886my %config_list;
1887my %null_config;
1888
1889my %dependency;
1890
Steven Rostedt4c4ab122011-07-15 21:16:17 -04001891sub assign_configs {
1892 my ($hash, $config) = @_;
Steven Rostedt0a05c762010-11-08 11:14:10 -05001893
1894 open (IN, $config)
1895 or dodie "Failed to read $config";
1896
1897 while (<IN>) {
Steven Rostedt9bf71742011-06-01 23:27:19 -04001898 if (/^((CONFIG\S*)=.*)/) {
Steven Rostedt4c4ab122011-07-15 21:16:17 -04001899 ${$hash}{$2} = $1;
Steven Rostedt0a05c762010-11-08 11:14:10 -05001900 }
1901 }
1902
1903 close(IN);
1904}
1905
Steven Rostedt4c4ab122011-07-15 21:16:17 -04001906sub process_config_ignore {
1907 my ($config) = @_;
1908
1909 assign_configs \%config_ignore, $config;
1910}
1911
Steven Rostedt0a05c762010-11-08 11:14:10 -05001912sub read_current_config {
1913 my ($config_ref) = @_;
1914
1915 %{$config_ref} = ();
1916 undef %{$config_ref};
1917
1918 my @key = keys %{$config_ref};
1919 if ($#key >= 0) {
1920 print "did not delete!\n";
1921 exit;
1922 }
1923 open (IN, "$output_config");
1924
1925 while (<IN>) {
1926 if (/^(CONFIG\S+)=(.*)/) {
1927 ${$config_ref}{$1} = $2;
1928 }
1929 }
1930 close(IN);
1931}
1932
1933sub get_dependencies {
1934 my ($config) = @_;
1935
1936 my $arr = $dependency{$config};
1937 if (!defined($arr)) {
1938 return ();
1939 }
1940
1941 my @deps = @{$arr};
1942
1943 foreach my $dep (@{$arr}) {
1944 print "ADD DEP $dep\n";
1945 @deps = (@deps, get_dependencies $dep);
1946 }
1947
1948 return @deps;
1949}
1950
1951sub create_config {
1952 my @configs = @_;
1953
1954 open(OUT, ">$output_config") or dodie "Can not write to $output_config";
1955
1956 foreach my $config (@configs) {
1957 print OUT "$config_set{$config}\n";
1958 my @deps = get_dependencies $config;
1959 foreach my $dep (@deps) {
1960 print OUT "$config_set{$dep}\n";
1961 }
1962 }
1963
1964 foreach my $config (keys %config_ignore) {
1965 print OUT "$config_ignore{$config}\n";
1966 }
1967 close(OUT);
1968
1969# exit;
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001970 make_oldconfig;
Steven Rostedt0a05c762010-11-08 11:14:10 -05001971}
1972
1973sub compare_configs {
1974 my (%a, %b) = @_;
1975
1976 foreach my $item (keys %a) {
1977 if (!defined($b{$item})) {
1978 print "diff $item\n";
1979 return 1;
1980 }
1981 delete $b{$item};
1982 }
1983
1984 my @keys = keys %b;
1985 if ($#keys) {
1986 print "diff2 $keys[0]\n";
1987 }
1988 return -1 if ($#keys >= 0);
1989
1990 return 0;
1991}
1992
1993sub run_config_bisect_test {
1994 my ($type) = @_;
1995
1996 return run_bisect_test $type, "oldconfig";
1997}
1998
1999sub process_passed {
2000 my (%configs) = @_;
2001
2002 doprint "These configs had no failure: (Enabling them for further compiles)\n";
2003 # Passed! All these configs are part of a good compile.
2004 # Add them to the min options.
2005 foreach my $config (keys %configs) {
2006 if (defined($config_list{$config})) {
2007 doprint " removing $config\n";
2008 $config_ignore{$config} = $config_list{$config};
2009 delete $config_list{$config};
2010 }
2011 }
Steven Rostedtf1a27852010-11-11 11:34:38 -05002012 doprint "config copied to $outputdir/config_good\n";
2013 run_command "cp -f $output_config $outputdir/config_good";
Steven Rostedt0a05c762010-11-08 11:14:10 -05002014}
2015
2016sub process_failed {
2017 my ($config) = @_;
2018
2019 doprint "\n\n***************************************\n";
2020 doprint "Found bad config: $config\n";
2021 doprint "***************************************\n\n";
2022}
2023
2024sub run_config_bisect {
2025
2026 my @start_list = keys %config_list;
2027
2028 if ($#start_list < 0) {
2029 doprint "No more configs to test!!!\n";
2030 return -1;
2031 }
2032
2033 doprint "***** RUN TEST ***\n";
2034 my $type = $opt{"CONFIG_BISECT_TYPE[$iteration]"};
2035 my $ret;
2036 my %current_config;
2037
2038 my $count = $#start_list + 1;
2039 doprint " $count configs to test\n";
2040
2041 my $half = int($#start_list / 2);
2042
2043 do {
2044 my @tophalf = @start_list[0 .. $half];
2045
2046 create_config @tophalf;
2047 read_current_config \%current_config;
2048
2049 $count = $#tophalf + 1;
2050 doprint "Testing $count configs\n";
2051 my $found = 0;
2052 # make sure we test something
2053 foreach my $config (@tophalf) {
2054 if (defined($current_config{$config})) {
2055 logit " $config\n";
2056 $found = 1;
2057 }
2058 }
2059 if (!$found) {
2060 # try the other half
2061 doprint "Top half produced no set configs, trying bottom half\n";
Steven Rostedt4c8cc552011-06-01 23:22:30 -04002062 @tophalf = @start_list[$half + 1 .. $#start_list];
Steven Rostedt0a05c762010-11-08 11:14:10 -05002063 create_config @tophalf;
2064 read_current_config \%current_config;
2065 foreach my $config (@tophalf) {
2066 if (defined($current_config{$config})) {
2067 logit " $config\n";
2068 $found = 1;
2069 }
2070 }
2071 if (!$found) {
2072 doprint "Failed: Can't make new config with current configs\n";
2073 foreach my $config (@start_list) {
2074 doprint " CONFIG: $config\n";
2075 }
2076 return -1;
2077 }
2078 $count = $#tophalf + 1;
2079 doprint "Testing $count configs\n";
2080 }
2081
2082 $ret = run_config_bisect_test $type;
Steven Rostedtc960bb92011-03-08 09:22:39 -05002083 if ($bisect_manual) {
2084 $ret = answer_bisect;
2085 }
Steven Rostedt0a05c762010-11-08 11:14:10 -05002086 if ($ret) {
2087 process_passed %current_config;
2088 return 0;
2089 }
2090
2091 doprint "This config had a failure.\n";
2092 doprint "Removing these configs that were not set in this config:\n";
Steven Rostedtf1a27852010-11-11 11:34:38 -05002093 doprint "config copied to $outputdir/config_bad\n";
2094 run_command "cp -f $output_config $outputdir/config_bad";
Steven Rostedt0a05c762010-11-08 11:14:10 -05002095
2096 # A config exists in this group that was bad.
2097 foreach my $config (keys %config_list) {
2098 if (!defined($current_config{$config})) {
2099 doprint " removing $config\n";
2100 delete $config_list{$config};
2101 }
2102 }
2103
2104 @start_list = @tophalf;
2105
2106 if ($#start_list == 0) {
2107 process_failed $start_list[0];
2108 return 1;
2109 }
2110
2111 # remove half the configs we are looking at and see if
2112 # they are good.
2113 $half = int($#start_list / 2);
Steven Rostedt4c8cc552011-06-01 23:22:30 -04002114 } while ($#start_list > 0);
Steven Rostedt0a05c762010-11-08 11:14:10 -05002115
Steven Rostedtc960bb92011-03-08 09:22:39 -05002116 # we found a single config, try it again unless we are running manually
2117
2118 if ($bisect_manual) {
2119 process_failed $start_list[0];
2120 return 1;
2121 }
2122
Steven Rostedt0a05c762010-11-08 11:14:10 -05002123 my @tophalf = @start_list[0 .. 0];
2124
2125 $ret = run_config_bisect_test $type;
2126 if ($ret) {
2127 process_passed %current_config;
2128 return 0;
2129 }
2130
2131 process_failed $start_list[0];
2132 return 1;
2133}
2134
2135sub config_bisect {
2136 my ($i) = @_;
2137
2138 my $start_config = $opt{"CONFIG_BISECT[$i]"};
2139
2140 my $tmpconfig = "$tmpdir/use_config";
2141
Steven Rostedt30f75da2011-06-13 10:35:35 -04002142 if (defined($config_bisect_good)) {
2143 process_config_ignore $config_bisect_good;
2144 }
2145
Steven Rostedt0a05c762010-11-08 11:14:10 -05002146 # Make the file with the bad config and the min config
2147 if (defined($minconfig)) {
2148 # read the min config for things to ignore
2149 run_command "cp $minconfig $tmpconfig" or
2150 dodie "failed to copy $minconfig to $tmpconfig";
2151 } else {
2152 unlink $tmpconfig;
2153 }
2154
Steven Rostedt0a05c762010-11-08 11:14:10 -05002155 if (-f $tmpconfig) {
Steven Rostedtfcb3f162011-06-13 10:40:58 -04002156 load_force_config($tmpconfig);
Steven Rostedt0a05c762010-11-08 11:14:10 -05002157 process_config_ignore $tmpconfig;
2158 }
2159
2160 # now process the start config
2161 run_command "cp $start_config $output_config" or
2162 dodie "failed to copy $start_config to $output_config";
2163
2164 # read directly what we want to check
2165 my %config_check;
2166 open (IN, $output_config)
2167 or dodie "faied to open $output_config";
2168
2169 while (<IN>) {
2170 if (/^((CONFIG\S*)=.*)/) {
2171 $config_check{$2} = $1;
2172 }
2173 }
2174 close(IN);
2175
Steven Rostedt250bae82011-07-15 22:05:59 -04002176 # Now run oldconfig with the minconfig
Steven Rostedtfcb3f162011-06-13 10:40:58 -04002177 make_oldconfig;
Steven Rostedt0a05c762010-11-08 11:14:10 -05002178
2179 # check to see what we lost (or gained)
2180 open (IN, $output_config)
2181 or dodie "Failed to read $start_config";
2182
2183 my %removed_configs;
2184 my %added_configs;
2185
2186 while (<IN>) {
2187 if (/^((CONFIG\S*)=.*)/) {
2188 # save off all options
2189 $config_set{$2} = $1;
2190 if (defined($config_check{$2})) {
2191 if (defined($config_ignore{$2})) {
2192 $removed_configs{$2} = $1;
2193 } else {
2194 $config_list{$2} = $1;
2195 }
2196 } elsif (!defined($config_ignore{$2})) {
2197 $added_configs{$2} = $1;
2198 $config_list{$2} = $1;
2199 }
2200 }
2201 }
2202 close(IN);
2203
2204 my @confs = keys %removed_configs;
2205 if ($#confs >= 0) {
2206 doprint "Configs overridden by default configs and removed from check:\n";
2207 foreach my $config (@confs) {
2208 doprint " $config\n";
2209 }
2210 }
2211 @confs = keys %added_configs;
2212 if ($#confs >= 0) {
2213 doprint "Configs appearing in make oldconfig and added:\n";
2214 foreach my $config (@confs) {
2215 doprint " $config\n";
2216 }
2217 }
2218
2219 my %config_test;
2220 my $once = 0;
2221
2222 # Sometimes kconfig does weird things. We must make sure
2223 # that the config we autocreate has everything we need
2224 # to test, otherwise we may miss testing configs, or
2225 # may not be able to create a new config.
2226 # Here we create a config with everything set.
2227 create_config (keys %config_list);
2228 read_current_config \%config_test;
2229 foreach my $config (keys %config_list) {
2230 if (!defined($config_test{$config})) {
2231 if (!$once) {
2232 $once = 1;
2233 doprint "Configs not produced by kconfig (will not be checked):\n";
2234 }
2235 doprint " $config\n";
2236 delete $config_list{$config};
2237 }
2238 }
2239 my $ret;
2240 do {
2241 $ret = run_config_bisect;
2242 } while (!$ret);
2243
2244 return $ret if ($ret < 0);
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04002245
2246 success $i;
2247}
2248
Steven Rostedt27d934b2011-05-20 09:18:18 -04002249sub patchcheck_reboot {
2250 doprint "Reboot and sleep $patchcheck_sleep_time seconds\n";
Andrew Jones2728be42011-08-12 15:32:05 +02002251 reboot $patchcheck_sleep_time;
Steven Rostedt27d934b2011-05-20 09:18:18 -04002252}
2253
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002254sub patchcheck {
2255 my ($i) = @_;
2256
2257 die "PATCHCHECK_START[$i] not defined\n"
2258 if (!defined($opt{"PATCHCHECK_START[$i]"}));
2259 die "PATCHCHECK_TYPE[$i] not defined\n"
2260 if (!defined($opt{"PATCHCHECK_TYPE[$i]"}));
2261
2262 my $start = $opt{"PATCHCHECK_START[$i]"};
2263
2264 my $end = "HEAD";
2265 if (defined($opt{"PATCHCHECK_END[$i]"})) {
2266 $end = $opt{"PATCHCHECK_END[$i]"};
2267 }
2268
Steven Rostedta57419b2010-11-02 15:13:54 -04002269 # Get the true sha1's since we can use things like HEAD~3
2270 $start = get_sha1($start);
2271 $end = get_sha1($end);
2272
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002273 my $type = $opt{"PATCHCHECK_TYPE[$i]"};
2274
2275 # Can't have a test without having a test to run
2276 if ($type eq "test" && !defined($run_test)) {
2277 $type = "boot";
2278 }
2279
2280 open (IN, "git log --pretty=oneline $end|") or
2281 dodie "could not get git list";
2282
2283 my @list;
2284
2285 while (<IN>) {
2286 chomp;
2287 $list[$#list+1] = $_;
2288 last if (/^$start/);
2289 }
2290 close(IN);
2291
2292 if ($list[$#list] !~ /^$start/) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002293 fail "SHA1 $start not found";
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002294 }
2295
2296 # go backwards in the list
2297 @list = reverse @list;
2298
2299 my $save_clean = $noclean;
Steven Rostedt19902072011-06-14 20:46:25 -04002300 my %ignored_warnings;
2301
2302 if (defined($ignore_warnings)) {
2303 foreach my $sha1 (split /\s+/, $ignore_warnings) {
2304 $ignored_warnings{$sha1} = 1;
2305 }
2306 }
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002307
2308 $in_patchcheck = 1;
2309 foreach my $item (@list) {
2310 my $sha1 = $item;
2311 $sha1 =~ s/^([[:xdigit:]]+).*/$1/;
2312
2313 doprint "\nProcessing commit $item\n\n";
2314
2315 run_command "git checkout $sha1" or
2316 die "Failed to checkout $sha1";
2317
2318 # only clean on the first and last patch
2319 if ($item eq $list[0] ||
2320 $item eq $list[$#list]) {
2321 $noclean = $save_clean;
2322 } else {
2323 $noclean = 1;
2324 }
2325
2326 if (defined($minconfig)) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002327 build "useconfig:$minconfig" or return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002328 } else {
2329 # ?? no config to use?
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002330 build "oldconfig" or return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002331 }
2332
Steven Rostedt19902072011-06-14 20:46:25 -04002333
2334 if (!defined($ignored_warnings{$sha1})) {
2335 check_buildlog $sha1 or return 0;
2336 }
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002337
2338 next if ($type eq "build");
2339
Steven Rostedt7faafbd2010-11-02 14:58:22 -04002340 my $failed = 0;
2341
Steven Rostedtddf607e2011-06-14 20:49:13 -04002342 start_monitor_and_boot or $failed = 1;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04002343
2344 if (!$failed && $type ne "boot"){
2345 do_run_test or $failed = 1;
2346 }
2347 end_monitor;
2348 return 0 if ($failed);
2349
Steven Rostedt27d934b2011-05-20 09:18:18 -04002350 patchcheck_reboot;
2351
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002352 }
2353 $in_patchcheck = 0;
2354 success $i;
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002355
2356 return 1;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002357}
2358
Steven Rostedtb9066f62011-07-15 21:25:24 -04002359my %depends;
2360my $iflevel = 0;
2361my @ifdeps;
2362
2363# prevent recursion
2364my %read_kconfigs;
2365
2366# taken from streamline_config.pl
2367sub read_kconfig {
2368 my ($kconfig) = @_;
2369
2370 my $state = "NONE";
2371 my $config;
2372 my @kconfigs;
2373
2374 my $cont = 0;
2375 my $line;
2376
2377
2378 if (! -f $kconfig) {
2379 doprint "file $kconfig does not exist, skipping\n";
2380 return;
2381 }
2382
2383 open(KIN, "$kconfig")
2384 or die "Can't open $kconfig";
2385 while (<KIN>) {
2386 chomp;
2387
2388 # Make sure that lines ending with \ continue
2389 if ($cont) {
2390 $_ = $line . " " . $_;
2391 }
2392
2393 if (s/\\$//) {
2394 $cont = 1;
2395 $line = $_;
2396 next;
2397 }
2398
2399 $cont = 0;
2400
2401 # collect any Kconfig sources
2402 if (/^source\s*"(.*)"/) {
2403 $kconfigs[$#kconfigs+1] = $1;
2404 }
2405
2406 # configs found
2407 if (/^\s*(menu)?config\s+(\S+)\s*$/) {
2408 $state = "NEW";
2409 $config = $2;
2410
2411 for (my $i = 0; $i < $iflevel; $i++) {
2412 if ($i) {
2413 $depends{$config} .= " " . $ifdeps[$i];
2414 } else {
2415 $depends{$config} = $ifdeps[$i];
2416 }
2417 $state = "DEP";
2418 }
2419
2420 # collect the depends for the config
2421 } elsif ($state eq "NEW" && /^\s*depends\s+on\s+(.*)$/) {
2422
2423 if (defined($depends{$1})) {
2424 $depends{$config} .= " " . $1;
2425 } else {
2426 $depends{$config} = $1;
2427 }
2428
2429 # Get the configs that select this config
2430 } elsif ($state ne "NONE" && /^\s*select\s+(\S+)/) {
2431 if (defined($depends{$1})) {
2432 $depends{$1} .= " " . $config;
2433 } else {
2434 $depends{$1} = $config;
2435 }
2436
2437 # Check for if statements
2438 } elsif (/^if\s+(.*\S)\s*$/) {
2439 my $deps = $1;
2440 # remove beginning and ending non text
2441 $deps =~ s/^[^a-zA-Z0-9_]*//;
2442 $deps =~ s/[^a-zA-Z0-9_]*$//;
2443
2444 my @deps = split /[^a-zA-Z0-9_]+/, $deps;
2445
2446 $ifdeps[$iflevel++] = join ':', @deps;
2447
2448 } elsif (/^endif/) {
2449
2450 $iflevel-- if ($iflevel);
2451
2452 # stop on "help"
2453 } elsif (/^\s*help\s*$/) {
2454 $state = "NONE";
2455 }
2456 }
2457 close(KIN);
2458
2459 # read in any configs that were found.
2460 foreach $kconfig (@kconfigs) {
2461 if (!defined($read_kconfigs{$kconfig})) {
2462 $read_kconfigs{$kconfig} = 1;
2463 read_kconfig("$builddir/$kconfig");
2464 }
2465 }
2466}
2467
2468sub read_depends {
2469 # find out which arch this is by the kconfig file
2470 open (IN, $output_config)
2471 or dodie "Failed to read $output_config";
2472 my $arch;
2473 while (<IN>) {
2474 if (m,Linux/(\S+)\s+\S+\s+Kernel Configuration,) {
2475 $arch = $1;
2476 last;
2477 }
2478 }
2479 close IN;
2480
2481 if (!defined($arch)) {
2482 doprint "Could not find arch from config file\n";
2483 doprint "no dependencies used\n";
2484 return;
2485 }
2486
2487 # arch is really the subarch, we need to know
2488 # what directory to look at.
2489 if ($arch eq "i386" || $arch eq "x86_64") {
2490 $arch = "x86";
2491 } elsif ($arch =~ /^tile/) {
2492 $arch = "tile";
2493 }
2494
2495 my $kconfig = "$builddir/arch/$arch/Kconfig";
2496
2497 if (! -f $kconfig && $arch =~ /\d$/) {
2498 my $orig = $arch;
2499 # some subarchs have numbers, truncate them
2500 $arch =~ s/\d*$//;
2501 $kconfig = "$builddir/arch/$arch/Kconfig";
2502 if (! -f $kconfig) {
2503 doprint "No idea what arch dir $orig is for\n";
2504 doprint "no dependencies used\n";
2505 return;
2506 }
2507 }
2508
2509 read_kconfig($kconfig);
2510}
2511
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002512sub read_config_list {
2513 my ($config) = @_;
2514
2515 open (IN, $config)
2516 or dodie "Failed to read $config";
2517
2518 while (<IN>) {
2519 if (/^((CONFIG\S*)=.*)/) {
2520 if (!defined($config_ignore{$2})) {
2521 $config_list{$2} = $1;
2522 }
2523 }
2524 }
2525
2526 close(IN);
2527}
2528
2529sub read_output_config {
2530 my ($config) = @_;
2531
2532 assign_configs \%config_ignore, $config;
2533}
2534
2535sub make_new_config {
2536 my @configs = @_;
2537
2538 open (OUT, ">$output_config")
2539 or dodie "Failed to write $output_config";
2540
2541 foreach my $config (@configs) {
2542 print OUT "$config\n";
2543 }
2544 close OUT;
2545}
2546
Steven Rostedtb9066f62011-07-15 21:25:24 -04002547sub get_depends {
2548 my ($dep) = @_;
2549
2550 my $kconfig = $dep;
2551 $kconfig =~ s/CONFIG_//;
2552
2553 $dep = $depends{"$kconfig"};
2554
2555 # the dep string we have saves the dependencies as they
2556 # were found, including expressions like ! && ||. We
2557 # want to split this out into just an array of configs.
2558
2559 my $valid = "A-Za-z_0-9";
2560
2561 my @configs;
2562
2563 while ($dep =~ /[$valid]/) {
2564
2565 if ($dep =~ /^[^$valid]*([$valid]+)/) {
2566 my $conf = "CONFIG_" . $1;
2567
2568 $configs[$#configs + 1] = $conf;
2569
2570 $dep =~ s/^[^$valid]*[$valid]+//;
2571 } else {
2572 die "this should never happen";
2573 }
2574 }
2575
2576 return @configs;
2577}
2578
2579my %min_configs;
2580my %keep_configs;
Steven Rostedt43d1b652011-07-15 22:01:56 -04002581my %save_configs;
Steven Rostedtb9066f62011-07-15 21:25:24 -04002582my %processed_configs;
2583my %nochange_config;
2584
2585sub test_this_config {
2586 my ($config) = @_;
2587
2588 my $found;
2589
2590 # if we already processed this config, skip it
2591 if (defined($processed_configs{$config})) {
2592 return undef;
2593 }
2594 $processed_configs{$config} = 1;
2595
2596 # if this config failed during this round, skip it
2597 if (defined($nochange_config{$config})) {
2598 return undef;
2599 }
2600
2601 my $kconfig = $config;
2602 $kconfig =~ s/CONFIG_//;
2603
2604 # Test dependencies first
2605 if (defined($depends{"$kconfig"})) {
2606 my @parents = get_depends $config;
2607 foreach my $parent (@parents) {
2608 # if the parent is in the min config, check it first
2609 next if (!defined($min_configs{$parent}));
2610 $found = test_this_config($parent);
2611 if (defined($found)) {
2612 return $found;
2613 }
2614 }
2615 }
2616
2617 # Remove this config from the list of configs
2618 # do a make oldnoconfig and then read the resulting
2619 # .config to make sure it is missing the config that
2620 # we had before
2621 my %configs = %min_configs;
2622 delete $configs{$config};
2623 make_new_config ((values %configs), (values %keep_configs));
2624 make_oldconfig;
2625 undef %configs;
2626 assign_configs \%configs, $output_config;
2627
2628 return $config if (!defined($configs{$config}));
2629
2630 doprint "disabling config $config did not change .config\n";
2631
2632 $nochange_config{$config} = 1;
2633
2634 return undef;
2635}
2636
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002637sub make_min_config {
2638 my ($i) = @_;
2639
2640 if (!defined($output_minconfig)) {
2641 fail "OUTPUT_MIN_CONFIG not defined" and return;
2642 }
Steven Rostedt35ce5952011-07-15 21:57:25 -04002643
2644 # If output_minconfig exists, and the start_minconfig
2645 # came from min_config, than ask if we should use
2646 # that instead.
2647 if (-f $output_minconfig && !$start_minconfig_defined) {
2648 print "$output_minconfig exists\n";
2649 if (read_yn " Use it as minconfig?") {
2650 $start_minconfig = $output_minconfig;
2651 }
2652 }
2653
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002654 if (!defined($start_minconfig)) {
2655 fail "START_MIN_CONFIG or MIN_CONFIG not defined" and return;
2656 }
2657
Steven Rostedt35ce5952011-07-15 21:57:25 -04002658 my $temp_config = "$tmpdir/temp_config";
2659
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002660 # First things first. We build an allnoconfig to find
2661 # out what the defaults are that we can't touch.
2662 # Some are selections, but we really can't handle selections.
2663
2664 my $save_minconfig = $minconfig;
2665 undef $minconfig;
2666
2667 run_command "$make allnoconfig" or return 0;
2668
Steven Rostedtb9066f62011-07-15 21:25:24 -04002669 read_depends;
2670
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002671 process_config_ignore $output_config;
Steven Rostedtb9066f62011-07-15 21:25:24 -04002672
Steven Rostedt43d1b652011-07-15 22:01:56 -04002673 undef %save_configs;
Steven Rostedtb9066f62011-07-15 21:25:24 -04002674 undef %min_configs;
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002675
2676 if (defined($ignore_config)) {
2677 # make sure the file exists
2678 `touch $ignore_config`;
Steven Rostedt43d1b652011-07-15 22:01:56 -04002679 assign_configs \%save_configs, $ignore_config;
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002680 }
2681
Steven Rostedt43d1b652011-07-15 22:01:56 -04002682 %keep_configs = %save_configs;
2683
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002684 doprint "Load initial configs from $start_minconfig\n";
2685
2686 # Look at the current min configs, and save off all the
2687 # ones that were set via the allnoconfig
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002688 assign_configs \%min_configs, $start_minconfig;
2689
2690 my @config_keys = keys %min_configs;
2691
2692 # Remove anything that was set by the make allnoconfig
2693 # we shouldn't need them as they get set for us anyway.
2694 foreach my $config (@config_keys) {
2695 # Remove anything in the ignore_config
2696 if (defined($keep_configs{$config})) {
2697 my $file = $ignore_config;
2698 $file =~ s,.*/(.*?)$,$1,;
2699 doprint "$config set by $file ... ignored\n";
2700 delete $min_configs{$config};
2701 next;
2702 }
2703 # But make sure the settings are the same. If a min config
2704 # sets a selection, we do not want to get rid of it if
2705 # it is not the same as what we have. Just move it into
2706 # the keep configs.
2707 if (defined($config_ignore{$config})) {
2708 if ($config_ignore{$config} ne $min_configs{$config}) {
2709 doprint "$config is in allnoconfig as '$config_ignore{$config}'";
2710 doprint " but it is '$min_configs{$config}' in minconfig .. keeping\n";
2711 $keep_configs{$config} = $min_configs{$config};
2712 } else {
2713 doprint "$config set by allnoconfig ... ignored\n";
2714 }
2715 delete $min_configs{$config};
2716 }
2717 }
2718
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002719 my $done = 0;
Steven Rostedtb9066f62011-07-15 21:25:24 -04002720 my $take_two = 0;
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002721
2722 while (!$done) {
2723
2724 my $config;
2725 my $found;
2726
2727 # Now disable each config one by one and do a make oldconfig
2728 # till we find a config that changes our list.
2729
2730 # Put configs that did not modify the config at the end.
2731 my @test_configs = keys %min_configs;
2732 my $reset = 1;
2733 for (my $i = 0; $i < $#test_configs; $i++) {
2734 if (!defined($nochange_config{$test_configs[0]})) {
2735 $reset = 0;
2736 last;
2737 }
2738 # This config didn't change the .config last time.
2739 # Place it at the end
2740 my $config = shift @test_configs;
2741 push @test_configs, $config;
2742 }
2743
2744 # if every test config has failed to modify the .config file
2745 # in the past, then reset and start over.
2746 if ($reset) {
2747 undef %nochange_config;
2748 }
2749
Steven Rostedtb9066f62011-07-15 21:25:24 -04002750 undef %processed_configs;
2751
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002752 foreach my $config (@test_configs) {
2753
Steven Rostedtb9066f62011-07-15 21:25:24 -04002754 $found = test_this_config $config;
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002755
Steven Rostedtb9066f62011-07-15 21:25:24 -04002756 last if (defined($found));
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002757
2758 # oh well, try another config
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002759 }
2760
2761 if (!defined($found)) {
Steven Rostedtb9066f62011-07-15 21:25:24 -04002762 # we could have failed due to the nochange_config hash
2763 # reset and try again
2764 if (!$take_two) {
2765 undef %nochange_config;
2766 $take_two = 1;
2767 next;
2768 }
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002769 doprint "No more configs found that we can disable\n";
2770 $done = 1;
2771 last;
2772 }
Steven Rostedtb9066f62011-07-15 21:25:24 -04002773 $take_two = 0;
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002774
2775 $config = $found;
2776
2777 doprint "Test with $config disabled\n";
2778
2779 # set in_bisect to keep build and monitor from dieing
2780 $in_bisect = 1;
2781
2782 my $failed = 0;
2783 build "oldconfig";
2784 start_monitor_and_boot or $failed = 1;
2785 end_monitor;
2786
2787 $in_bisect = 0;
2788
2789 if ($failed) {
Steven Rostedtb9066f62011-07-15 21:25:24 -04002790 doprint "$min_configs{$config} is needed to boot the box... keeping\n";
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002791 # this config is needed, add it to the ignore list.
2792 $keep_configs{$config} = $min_configs{$config};
Steven Rostedt43d1b652011-07-15 22:01:56 -04002793 $save_configs{$config} = $min_configs{$config};
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002794 delete $min_configs{$config};
Steven Rostedt35ce5952011-07-15 21:57:25 -04002795
2796 # update new ignore configs
2797 if (defined($ignore_config)) {
2798 open (OUT, ">$temp_config")
2799 or die "Can't write to $temp_config";
Steven Rostedt43d1b652011-07-15 22:01:56 -04002800 foreach my $config (keys %save_configs) {
2801 print OUT "$save_configs{$config}\n";
Steven Rostedt35ce5952011-07-15 21:57:25 -04002802 }
2803 close OUT;
2804 run_command "mv $temp_config $ignore_config" or
2805 dodie "failed to copy update to $ignore_config";
2806 }
2807
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002808 } else {
2809 # We booted without this config, remove it from the minconfigs.
2810 doprint "$config is not needed, disabling\n";
2811
2812 delete $min_configs{$config};
2813
2814 # Also disable anything that is not enabled in this config
2815 my %configs;
2816 assign_configs \%configs, $output_config;
2817 my @config_keys = keys %min_configs;
2818 foreach my $config (@config_keys) {
2819 if (!defined($configs{$config})) {
2820 doprint "$config is not set, disabling\n";
2821 delete $min_configs{$config};
2822 }
2823 }
2824
2825 # Save off all the current mandidory configs
Steven Rostedt35ce5952011-07-15 21:57:25 -04002826 open (OUT, ">$temp_config")
2827 or die "Can't write to $temp_config";
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002828 foreach my $config (keys %keep_configs) {
2829 print OUT "$keep_configs{$config}\n";
2830 }
2831 foreach my $config (keys %min_configs) {
2832 print OUT "$min_configs{$config}\n";
2833 }
2834 close OUT;
Steven Rostedt35ce5952011-07-15 21:57:25 -04002835
2836 run_command "mv $temp_config $output_minconfig" or
2837 dodie "failed to copy update to $output_minconfig";
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002838 }
2839
2840 doprint "Reboot and wait $sleep_time seconds\n";
Andrew Jones2728be42011-08-12 15:32:05 +02002841 reboot $sleep_time;
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002842 }
2843
2844 success $i;
2845 return 1;
2846}
2847
Steven Rostedt8d1491b2010-11-18 15:39:48 -05002848$#ARGV < 1 or die "ktest.pl version: $VERSION\n usage: ktest.pl config-file\n";
Steven Rostedt2545eb62010-11-02 15:01:32 -04002849
Steven Rostedt8d1491b2010-11-18 15:39:48 -05002850if ($#ARGV == 0) {
2851 $ktest_config = $ARGV[0];
2852 if (! -f $ktest_config) {
2853 print "$ktest_config does not exist.\n";
Steven Rostedt35ce5952011-07-15 21:57:25 -04002854 if (!read_yn "Create it?") {
Steven Rostedt8d1491b2010-11-18 15:39:48 -05002855 exit 0;
2856 }
2857 }
2858} else {
2859 $ktest_config = "ktest.conf";
2860}
2861
2862if (! -f $ktest_config) {
2863 open(OUT, ">$ktest_config") or die "Can not create $ktest_config";
2864 print OUT << "EOF"
2865# Generated by ktest.pl
2866#
2867# Define each test with TEST_START
2868# The config options below it will override the defaults
2869TEST_START
2870
2871DEFAULTS
2872EOF
2873;
2874 close(OUT);
2875}
2876read_config $ktest_config;
2877
Steven Rostedt23715c3c2011-06-13 11:03:34 -04002878if (defined($opt{"LOG_FILE"})) {
2879 $opt{"LOG_FILE"} = eval_option($opt{"LOG_FILE"}, -1);
2880}
2881
Steven Rostedt8d1491b2010-11-18 15:39:48 -05002882# Append any configs entered in manually to the config file.
2883my @new_configs = keys %entered_configs;
2884if ($#new_configs >= 0) {
2885 print "\nAppending entered in configs to $ktest_config\n";
2886 open(OUT, ">>$ktest_config") or die "Can not append to $ktest_config";
2887 foreach my $config (@new_configs) {
2888 print OUT "$config = $entered_configs{$config}\n";
2889 $opt{$config} = $entered_configs{$config};
2890 }
2891}
Steven Rostedt2545eb62010-11-02 15:01:32 -04002892
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002893if ($opt{"CLEAR_LOG"} && defined($opt{"LOG_FILE"})) {
2894 unlink $opt{"LOG_FILE"};
2895}
Steven Rostedt2545eb62010-11-02 15:01:32 -04002896
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002897doprint "\n\nSTARTING AUTOMATED TESTS\n\n";
2898
Steven Rostedta57419b2010-11-02 15:13:54 -04002899for (my $i = 0, my $repeat = 1; $i <= $opt{"NUM_TESTS"}; $i += $repeat) {
2900
2901 if (!$i) {
2902 doprint "DEFAULT OPTIONS:\n";
2903 } else {
2904 doprint "\nTEST $i OPTIONS";
2905 if (defined($repeat_tests{$i})) {
2906 $repeat = $repeat_tests{$i};
2907 doprint " ITERATE $repeat";
2908 }
2909 doprint "\n";
2910 }
2911
2912 foreach my $option (sort keys %opt) {
2913
2914 if ($option =~ /\[(\d+)\]$/) {
2915 next if ($i != $1);
2916 } else {
2917 next if ($i);
2918 }
2919
2920 doprint "$option = $opt{$option}\n";
2921 }
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002922}
Steven Rostedt2545eb62010-11-02 15:01:32 -04002923
Steven Rostedt2a625122011-05-20 15:48:59 -04002924sub __set_test_option {
Steven Rostedt5a391fb2010-11-02 14:57:43 -04002925 my ($name, $i) = @_;
2926
2927 my $option = "$name\[$i\]";
2928
2929 if (defined($opt{$option})) {
2930 return $opt{$option};
2931 }
2932
Steven Rostedta57419b2010-11-02 15:13:54 -04002933 foreach my $test (keys %repeat_tests) {
2934 if ($i >= $test &&
2935 $i < $test + $repeat_tests{$test}) {
2936 $option = "$name\[$test\]";
2937 if (defined($opt{$option})) {
2938 return $opt{$option};
2939 }
2940 }
2941 }
2942
Steven Rostedt5a391fb2010-11-02 14:57:43 -04002943 if (defined($opt{$name})) {
2944 return $opt{$name};
2945 }
2946
2947 return undef;
2948}
2949
Steven Rostedt2a625122011-05-20 15:48:59 -04002950sub set_test_option {
2951 my ($name, $i) = @_;
2952
2953 my $option = __set_test_option($name, $i);
2954 return $option if (!defined($option));
2955
Steven Rostedt23715c3c2011-06-13 11:03:34 -04002956 return eval_option($option, $i);
Steven Rostedt2a625122011-05-20 15:48:59 -04002957}
2958
Steven Rostedt2545eb62010-11-02 15:01:32 -04002959# First we need to do is the builds
Steven Rostedta75fece2010-11-02 14:58:27 -04002960for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
Steven Rostedt2545eb62010-11-02 15:01:32 -04002961
Steven Rostedt4ab1cce2011-09-30 18:12:20 -04002962 # Do not reboot on failing test options
2963 $no_reboot = 1;
2964
Steven Rostedt576f6272010-11-02 14:58:38 -04002965 $iteration = $i;
2966
Steven Rostedta75fece2010-11-02 14:58:27 -04002967 my $makecmd = set_test_option("MAKE_CMD", $i);
2968
2969 $machine = set_test_option("MACHINE", $i);
Steven Rostedte48c5292010-11-02 14:35:37 -04002970 $ssh_user = set_test_option("SSH_USER", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002971 $tmpdir = set_test_option("TMP_DIR", $i);
2972 $outputdir = set_test_option("OUTPUT_DIR", $i);
2973 $builddir = set_test_option("BUILD_DIR", $i);
2974 $test_type = set_test_option("TEST_TYPE", $i);
2975 $build_type = set_test_option("BUILD_TYPE", $i);
2976 $build_options = set_test_option("BUILD_OPTIONS", $i);
Steven Rostedt0bd6c1a2011-06-14 20:39:31 -04002977 $pre_build = set_test_option("PRE_BUILD", $i);
2978 $post_build = set_test_option("POST_BUILD", $i);
2979 $pre_build_die = set_test_option("PRE_BUILD_DIE", $i);
2980 $post_build_die = set_test_option("POST_BUILD_DIE", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002981 $power_cycle = set_test_option("POWER_CYCLE", $i);
Steven Rostedte48c5292010-11-02 14:35:37 -04002982 $reboot = set_test_option("REBOOT", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002983 $noclean = set_test_option("BUILD_NOCLEAN", $i);
2984 $minconfig = set_test_option("MIN_CONFIG", $i);
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002985 $output_minconfig = set_test_option("OUTPUT_MIN_CONFIG", $i);
2986 $start_minconfig = set_test_option("START_MIN_CONFIG", $i);
2987 $ignore_config = set_test_option("IGNORE_CONFIG", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002988 $run_test = set_test_option("TEST", $i);
2989 $addconfig = set_test_option("ADD_CONFIG", $i);
2990 $reboot_type = set_test_option("REBOOT_TYPE", $i);
2991 $grub_menu = set_test_option("GRUB_MENU", $i);
Steven Rostedt8b37ca82010-11-02 14:58:33 -04002992 $post_install = set_test_option("POST_INSTALL", $i);
Steven Rostedte0a87422011-09-30 17:50:48 -04002993 $no_install = set_test_option("NO_INSTALL", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002994 $reboot_script = set_test_option("REBOOT_SCRIPT", $i);
2995 $reboot_on_error = set_test_option("REBOOT_ON_ERROR", $i);
2996 $poweroff_on_error = set_test_option("POWEROFF_ON_ERROR", $i);
2997 $die_on_failure = set_test_option("DIE_ON_FAILURE", $i);
2998 $power_off = set_test_option("POWER_OFF", $i);
Steven Rostedt576f6272010-11-02 14:58:38 -04002999 $powercycle_after_reboot = set_test_option("POWERCYCLE_AFTER_REBOOT", $i);
3000 $poweroff_after_halt = set_test_option("POWEROFF_AFTER_HALT", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04003001 $sleep_time = set_test_option("SLEEP_TIME", $i);
3002 $bisect_sleep_time = set_test_option("BISECT_SLEEP_TIME", $i);
Steven Rostedt27d934b2011-05-20 09:18:18 -04003003 $patchcheck_sleep_time = set_test_option("PATCHCHECK_SLEEP_TIME", $i);
Steven Rostedt19902072011-06-14 20:46:25 -04003004 $ignore_warnings = set_test_option("IGNORE_WARNINGS", $i);
Steven Rostedtc960bb92011-03-08 09:22:39 -05003005 $bisect_manual = set_test_option("BISECT_MANUAL", $i);
Steven Rostedtc23dca72011-03-08 09:26:31 -05003006 $bisect_skip = set_test_option("BISECT_SKIP", $i);
Steven Rostedt30f75da2011-06-13 10:35:35 -04003007 $config_bisect_good = set_test_option("CONFIG_BISECT_GOOD", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04003008 $store_failures = set_test_option("STORE_FAILURES", $i);
Steven Rostedt9064af52011-06-13 10:38:48 -04003009 $test_name = set_test_option("TEST_NAME", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04003010 $timeout = set_test_option("TIMEOUT", $i);
3011 $booted_timeout = set_test_option("BOOTED_TIMEOUT", $i);
3012 $console = set_test_option("CONSOLE", $i);
Steven Rostedtf1a5b962011-06-13 10:30:00 -04003013 $detect_triplefault = set_test_option("DETECT_TRIPLE_FAULT", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04003014 $success_line = set_test_option("SUCCESS_LINE", $i);
Steven Rostedt2b803362011-09-30 18:00:23 -04003015 $reboot_success_line = set_test_option("REBOOT_SUCCESS_LINE", $i);
Steven Rostedt1c8a6172010-11-09 12:55:40 -05003016 $stop_after_success = set_test_option("STOP_AFTER_SUCCESS", $i);
3017 $stop_after_failure = set_test_option("STOP_AFTER_FAILURE", $i);
Steven Rostedt2d01b262011-03-08 09:47:54 -05003018 $stop_test_after = set_test_option("STOP_TEST_AFTER", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04003019 $build_target = set_test_option("BUILD_TARGET", $i);
Steven Rostedte48c5292010-11-02 14:35:37 -04003020 $ssh_exec = set_test_option("SSH_EXEC", $i);
3021 $scp_to_target = set_test_option("SCP_TO_TARGET", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04003022 $target_image = set_test_option("TARGET_IMAGE", $i);
3023 $localversion = set_test_option("LOCALVERSION", $i);
3024
Steven Rostedt35ce5952011-07-15 21:57:25 -04003025 $start_minconfig_defined = 1;
3026
Steven Rostedt4c4ab122011-07-15 21:16:17 -04003027 if (!defined($start_minconfig)) {
Steven Rostedt35ce5952011-07-15 21:57:25 -04003028 $start_minconfig_defined = 0;
Steven Rostedt4c4ab122011-07-15 21:16:17 -04003029 $start_minconfig = $minconfig;
3030 }
3031
Steven Rostedta75fece2010-11-02 14:58:27 -04003032 chdir $builddir || die "can't change directory to $builddir";
3033
Andrew Jonesa908a662011-08-12 15:32:03 +02003034 foreach my $dir ($tmpdir, $outputdir) {
3035 if (!-d $dir) {
3036 mkpath($dir) or
3037 die "can't create $dir";
3038 }
Steven Rostedta75fece2010-11-02 14:58:27 -04003039 }
3040
Steven Rostedte48c5292010-11-02 14:35:37 -04003041 $ENV{"SSH_USER"} = $ssh_user;
3042 $ENV{"MACHINE"} = $machine;
3043
Steven Rostedta75fece2010-11-02 14:58:27 -04003044 $target = "$ssh_user\@$machine";
3045
3046 $buildlog = "$tmpdir/buildlog-$machine";
3047 $dmesg = "$tmpdir/dmesg-$machine";
3048 $make = "$makecmd O=$outputdir";
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05003049 $output_config = "$outputdir/.config";
Steven Rostedta75fece2010-11-02 14:58:27 -04003050
3051 if ($reboot_type eq "grub") {
Steven Rostedt576f6272010-11-02 14:58:38 -04003052 dodie "GRUB_MENU not defined" if (!defined($grub_menu));
Steven Rostedta75fece2010-11-02 14:58:27 -04003053 } elsif (!defined($reboot_script)) {
Steven Rostedt576f6272010-11-02 14:58:38 -04003054 dodie "REBOOT_SCRIPT not defined"
Steven Rostedta75fece2010-11-02 14:58:27 -04003055 }
3056
3057 my $run_type = $build_type;
3058 if ($test_type eq "patchcheck") {
3059 $run_type = $opt{"PATCHCHECK_TYPE[$i]"};
3060 } elsif ($test_type eq "bisect") {
3061 $run_type = $opt{"BISECT_TYPE[$i]"};
Steven Rostedt0a05c762010-11-08 11:14:10 -05003062 } elsif ($test_type eq "config_bisect") {
3063 $run_type = $opt{"CONFIG_BISECT_TYPE[$i]"};
Steven Rostedta75fece2010-11-02 14:58:27 -04003064 }
3065
Steven Rostedt4c4ab122011-07-15 21:16:17 -04003066 if ($test_type eq "make_min_config") {
3067 $run_type = "";
3068 }
3069
Steven Rostedta75fece2010-11-02 14:58:27 -04003070 # mistake in config file?
3071 if (!defined($run_type)) {
3072 $run_type = "ERROR";
3073 }
Steven Rostedt2545eb62010-11-02 15:01:32 -04003074
Steven Rostedte0a87422011-09-30 17:50:48 -04003075 my $installme = "";
3076 $installme = " no_install" if ($no_install);
3077
Steven Rostedt2545eb62010-11-02 15:01:32 -04003078 doprint "\n\n";
Steven Rostedte0a87422011-09-30 17:50:48 -04003079 doprint "RUNNING TEST $i of $opt{NUM_TESTS} with option $test_type $run_type$installme\n\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -04003080
3081 unlink $dmesg;
3082 unlink $buildlog;
Steven Rostedt2545eb62010-11-02 15:01:32 -04003083
Steven Rostedt250bae82011-07-15 22:05:59 -04003084 if (defined($addconfig)) {
3085 my $min = $minconfig;
3086 if (!defined($minconfig)) {
3087 $min = "";
3088 }
3089 run_command "cat $addconfig $min > $tmpdir/add_config" or
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04003090 dodie "Failed to create temp config";
Steven Rostedt9be2e6b2010-11-09 12:20:21 -05003091 $minconfig = "$tmpdir/add_config";
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04003092 }
3093
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04003094 my $checkout = $opt{"CHECKOUT[$i]"};
3095 if (defined($checkout)) {
3096 run_command "git checkout $checkout" or
3097 die "failed to checkout $checkout";
3098 }
3099
Steven Rostedt4ab1cce2011-09-30 18:12:20 -04003100 $no_reboot = 0;
3101
3102
Steven Rostedta75fece2010-11-02 14:58:27 -04003103 if ($test_type eq "bisect") {
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04003104 bisect $i;
3105 next;
Steven Rostedt0a05c762010-11-08 11:14:10 -05003106 } elsif ($test_type eq "config_bisect") {
3107 config_bisect $i;
3108 next;
Steven Rostedta75fece2010-11-02 14:58:27 -04003109 } elsif ($test_type eq "patchcheck") {
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04003110 patchcheck $i;
3111 next;
Steven Rostedt4c4ab122011-07-15 21:16:17 -04003112 } elsif ($test_type eq "make_min_config") {
3113 make_min_config $i;
3114 next;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04003115 }
3116
Steven Rostedt7faafbd2010-11-02 14:58:22 -04003117 if ($build_type ne "nobuild") {
3118 build $build_type or next;
Steven Rostedt2545eb62010-11-02 15:01:32 -04003119 }
3120
Steven Rostedtcd8e3682011-08-18 16:35:44 -04003121 if ($test_type eq "install") {
3122 get_version;
3123 install;
3124 success $i;
3125 next;
3126 }
3127
Steven Rostedta75fece2010-11-02 14:58:27 -04003128 if ($test_type ne "build") {
Steven Rostedta75fece2010-11-02 14:58:27 -04003129 my $failed = 0;
Steven Rostedtddf607e2011-06-14 20:49:13 -04003130 start_monitor_and_boot or $failed = 1;
Steven Rostedta75fece2010-11-02 14:58:27 -04003131
3132 if (!$failed && $test_type ne "boot" && defined($run_test)) {
3133 do_run_test or $failed = 1;
3134 }
3135 end_monitor;
3136 next if ($failed);
Steven Rostedt5a391fb2010-11-02 14:57:43 -04003137 }
3138
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04003139 success $i;
Steven Rostedt2545eb62010-11-02 15:01:32 -04003140}
3141
Steven Rostedt5c42fc52010-11-02 14:57:01 -04003142if ($opt{"POWEROFF_ON_SUCCESS"}) {
Steven Rostedt75c3fda72010-11-02 14:57:21 -04003143 halt;
Steven Rostedt576f6272010-11-02 14:58:38 -04003144} elsif ($opt{"REBOOT_ON_SUCCESS"} && !do_not_reboot) {
Steven Rostedt75c3fda72010-11-02 14:57:21 -04003145 reboot;
Steven Rostedt5c42fc52010-11-02 14:57:01 -04003146}
Steven Rostedt75c3fda72010-11-02 14:57:21 -04003147
Steven Rostedte48c5292010-11-02 14:35:37 -04003148doprint "\n $successes of $opt{NUM_TESTS} tests were successful\n\n";
3149
Steven Rostedt2545eb62010-11-02 15:01:32 -04003150exit 0;