blob: 76a5964595dac73f17e5a2be76d14911b3606675 [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 Rostedt9900b5d2011-09-30 22:41:14 -0400399sub value_defined {
400 my ($val) = @_;
401
402 return defined($variable{$2}) ||
403 defined($opt{$2});
404}
405
Steven Rostedt45d73a52011-09-30 19:44:53 -0400406sub process_if {
407 my ($name, $value) = @_;
408
409 my $val = process_variables($value);
410
Steven Rostedtab7a3f52011-09-30 20:24:07 -0400411 if ($val =~ /(.*)(==|\!=|>=|<=|>|<)(.*)/) {
412 my $ret = process_compare($1, $2, $3);
413 if ($ret < 0) {
414 die "$name: $.: Unable to process comparison\n";
415 }
416 return $ret;
417 }
418
Steven Rostedt9900b5d2011-09-30 22:41:14 -0400419 if ($val =~ /^\s*(NOT\s*)?DEFINED\s+(\S+)\s*$/) {
420 if (defined $1) {
421 return !value_defined($2);
422 } else {
423 return value_defined($2);
424 }
425 }
426
Steven Rostedt45d73a52011-09-30 19:44:53 -0400427 if ($val =~ /^\s*0\s*$/) {
428 return 0;
429 } elsif ($val =~ /^\s*\d+\s*$/) {
430 return 1;
431 }
432
Steven Rostedt9900b5d2011-09-30 22:41:14 -0400433 die ("$name: $.: Undefined content $val in if statement\n");
Steven Rostedt45d73a52011-09-30 19:44:53 -0400434 return 1;
435}
436
Steven Rostedt2ed3b162011-09-30 21:00:00 -0400437sub __read_config {
438 my ($config, $current_test_num) = @_;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400439
Steven Rostedt2ed3b162011-09-30 21:00:00 -0400440 my $in;
441 open($in, $config) || die "can't read file $config";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400442
Steven Rostedta57419b2010-11-02 15:13:54 -0400443 my $name = $config;
444 $name =~ s,.*/(.*),$1,;
445
Steven Rostedt2ed3b162011-09-30 21:00:00 -0400446 my $test_num = $$current_test_num;
Steven Rostedta57419b2010-11-02 15:13:54 -0400447 my $default = 1;
448 my $repeat = 1;
449 my $num_tests_set = 0;
450 my $skip = 0;
451 my $rest;
Steven Rostedt0df213c2011-06-14 20:51:37 -0400452 my $test_case = 0;
Steven Rostedt45d73a52011-09-30 19:44:53 -0400453 my $if = 0;
454 my $if_set = 0;
Steven Rostedt3d1cc412011-09-30 22:14:21 -0400455 my $override = 0;
456
457 my %overrides;
Steven Rostedta57419b2010-11-02 15:13:54 -0400458
Steven Rostedt2ed3b162011-09-30 21:00:00 -0400459 while (<$in>) {
Steven Rostedt2545eb62010-11-02 15:01:32 -0400460
461 # ignore blank lines and comments
462 next if (/^\s*$/ || /\s*\#/);
463
Steven Rostedt0050b6b2011-09-30 21:10:30 -0400464 if (/^\s*(TEST_START|DEFAULTS)\b(.*)/) {
Steven Rostedta57419b2010-11-02 15:13:54 -0400465
Steven Rostedt0050b6b2011-09-30 21:10:30 -0400466 my $type = $1;
467 $rest = $2;
Steven Rostedta57419b2010-11-02 15:13:54 -0400468
Steven Rostedt0050b6b2011-09-30 21:10:30 -0400469 my $old_test_num;
470 my $old_repeat;
Steven Rostedt3d1cc412011-09-30 22:14:21 -0400471 $override = 0;
Steven Rostedt0050b6b2011-09-30 21:10:30 -0400472
473 if ($type eq "TEST_START") {
474
475 if ($num_tests_set) {
476 die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
477 }
478
479 $old_test_num = $test_num;
480 $old_repeat = $repeat;
481
482 $test_num += $repeat;
483 $default = 0;
484 $repeat = 1;
485 } else {
486 $default = 1;
Steven Rostedta57419b2010-11-02 15:13:54 -0400487 }
488
Steven Rostedt45d73a52011-09-30 19:44:53 -0400489 if ($rest =~ /\s+SKIP\b(.*)/) {
Steven Rostedta57419b2010-11-02 15:13:54 -0400490 $rest = $1;
491 $skip = 1;
492 } else {
Steven Rostedt0df213c2011-06-14 20:51:37 -0400493 $test_case = 1;
Steven Rostedta57419b2010-11-02 15:13:54 -0400494 $skip = 0;
495 }
496
Steven Rostedt3d1cc412011-09-30 22:14:21 -0400497 if (!$skip) {
498 if ($type eq "TEST_START") {
499 if ($rest =~ /\s+ITERATE\s+(\d+)(.*)$/) {
500 $repeat = $1;
501 $rest = $2;
502 $repeat_tests{"$test_num"} = $repeat;
503 }
504 } elsif ($rest =~ /\sOVERRIDE\b(.*)/) {
505 # DEFAULT only
506 $rest = $1;
507 $override = 1;
508 # Clear previous overrides
509 %overrides = ();
510 }
Steven Rostedta57419b2010-11-02 15:13:54 -0400511 }
512
Steven Rostedtab7a3f52011-09-30 20:24:07 -0400513 if ($rest =~ /\sIF\s+(.*)/) {
514 $rest = "";
Steven Rostedt45d73a52011-09-30 19:44:53 -0400515 if (process_if($name, $1)) {
516 $if_set = 1;
517 } else {
518 $skip = 1;
519 }
520 $if = 1;
521 } else {
522 $if = 0;
Steven Rostedta57419b2010-11-02 15:13:54 -0400523 }
524
525 if ($rest !~ /^\s*$/) {
Steven Rostedt0050b6b2011-09-30 21:10:30 -0400526 die "$name: $.: Gargbage found after $type\n$_";
Steven Rostedta57419b2010-11-02 15:13:54 -0400527 }
528
Steven Rostedt0050b6b2011-09-30 21:10:30 -0400529 if ($skip && $type eq "TEST_START") {
Steven Rostedta57419b2010-11-02 15:13:54 -0400530 $test_num = $old_test_num;
Steven Rostedte48c5292010-11-02 14:35:37 -0400531 $repeat = $old_repeat;
Steven Rostedta57419b2010-11-02 15:13:54 -0400532 }
533
Steven Rostedtab7a3f52011-09-30 20:24:07 -0400534 } elsif (/^\s*ELSE\b(.*)$/) {
Steven Rostedt45d73a52011-09-30 19:44:53 -0400535 if (!$if) {
536 die "$name: $.: ELSE found with out matching IF section\n$_";
537 }
538 $rest = $1;
539 if ($if_set) {
540 $skip = 1;
Steven Rostedtab7a3f52011-09-30 20:24:07 -0400541 $rest = "";
Steven Rostedt45d73a52011-09-30 19:44:53 -0400542 } else {
543 $skip = 0;
544
Steven Rostedtab7a3f52011-09-30 20:24:07 -0400545 if ($rest =~ /\sIF\s+(.*)/) {
Steven Rostedt45d73a52011-09-30 19:44:53 -0400546 # May be a ELSE IF section.
547 if (!process_if($name, $1)) {
548 $skip = 1;
549 }
Steven Rostedtab7a3f52011-09-30 20:24:07 -0400550 $rest = "";
Steven Rostedt45d73a52011-09-30 19:44:53 -0400551 } else {
552 $if = 0;
553 }
554 }
555
Steven Rostedtab7a3f52011-09-30 20:24:07 -0400556 if ($rest !~ /^\s*$/) {
557 die "$name: $.: Gargbage found after DEFAULTS\n$_";
558 }
559
Steven Rostedt2ed3b162011-09-30 21:00:00 -0400560 } elsif (/^\s*INCLUDE\s+(\S+)/) {
561
562 next if ($skip);
563
564 if (!$default) {
565 die "$name: $.: INCLUDE can only be done in default sections\n$_";
566 }
567
568 my $file = process_variables($1);
569
570 if ($file !~ m,^/,) {
571 # check the path of the config file first
572 if ($config =~ m,(.*)/,) {
573 if (-f "$1/$file") {
574 $file = "$1/$file";
575 }
576 }
577 }
578
579 if ( ! -r $file ) {
580 die "$name: $.: Can't read file $file\n$_";
581 }
582
583 if (__read_config($file, \$test_num)) {
584 $test_case = 1;
585 }
586
Steven Rostedta57419b2010-11-02 15:13:54 -0400587 } elsif (/^\s*([A-Z_\[\]\d]+)\s*=\s*(.*?)\s*$/) {
588
589 next if ($skip);
590
Steven Rostedt2545eb62010-11-02 15:01:32 -0400591 my $lvalue = $1;
592 my $rvalue = $2;
593
Steven Rostedta57419b2010-11-02 15:13:54 -0400594 if (!$default &&
595 ($lvalue eq "NUM_TESTS" ||
596 $lvalue eq "LOG_FILE" ||
597 $lvalue eq "CLEAR_LOG")) {
598 die "$name: $.: $lvalue must be set in DEFAULTS section\n";
Steven Rostedta75fece2010-11-02 14:58:27 -0400599 }
Steven Rostedta57419b2010-11-02 15:13:54 -0400600
601 if ($lvalue eq "NUM_TESTS") {
602 if ($test_num) {
603 die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
604 }
605 if (!$default) {
606 die "$name: $.: NUM_TESTS must be set in default section\n";
607 }
608 $num_tests_set = 1;
609 }
610
611 if ($default || $lvalue =~ /\[\d+\]$/) {
Steven Rostedt3d1cc412011-09-30 22:14:21 -0400612 set_value($lvalue, $rvalue, $override, \%overrides, $name);
Steven Rostedta57419b2010-11-02 15:13:54 -0400613 } else {
614 my $val = "$lvalue\[$test_num\]";
Steven Rostedt3d1cc412011-09-30 22:14:21 -0400615 set_value($val, $rvalue, $override, \%overrides, $name);
Steven Rostedta57419b2010-11-02 15:13:54 -0400616
617 if ($repeat > 1) {
618 $repeats{$val} = $repeat;
619 }
620 }
Steven Rostedt77d942c2011-05-20 13:36:58 -0400621 } elsif (/^\s*([A-Z_\[\]\d]+)\s*:=\s*(.*?)\s*$/) {
622 next if ($skip);
623
624 my $lvalue = $1;
625 my $rvalue = $2;
626
627 # process config variables.
628 # Config variables are only active while reading the
629 # config and can be defined anywhere. They also ignore
630 # TEST_START and DEFAULTS, but are skipped if they are in
631 # on of these sections that have SKIP defined.
632 # The save variable can be
633 # defined multiple times and the new one simply overrides
634 # the prevous one.
635 set_variable($lvalue, $rvalue);
636
Steven Rostedta57419b2010-11-02 15:13:54 -0400637 } else {
638 die "$name: $.: Garbage found in config\n$_";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400639 }
640 }
641
Steven Rostedta57419b2010-11-02 15:13:54 -0400642 if ($test_num) {
643 $test_num += $repeat - 1;
644 $opt{"NUM_TESTS"} = $test_num;
645 }
646
Steven Rostedt2ed3b162011-09-30 21:00:00 -0400647 close($in);
648
649 $$current_test_num = $test_num;
650
651 return $test_case;
652}
653
654sub read_config {
655 my ($config) = @_;
656
657 my $test_case;
658 my $test_num = 0;
659
660 $test_case = __read_config $config, \$test_num;
661
Steven Rostedt8d1491b2010-11-18 15:39:48 -0500662 # make sure we have all mandatory configs
663 get_ktest_configs;
664
Steven Rostedt0df213c2011-06-14 20:51:37 -0400665 # was a test specified?
666 if (!$test_case) {
667 print "No test case specified.\n";
668 print "What test case would you like to run?\n";
669 my $ans = <STDIN>;
670 chomp $ans;
671 $default{"TEST_TYPE"} = $ans;
672 }
673
Steven Rostedta75fece2010-11-02 14:58:27 -0400674 # set any defaults
675
676 foreach my $default (keys %default) {
677 if (!defined($opt{$default})) {
678 $opt{$default} = $default{$default};
679 }
680 }
Steven Rostedt2545eb62010-11-02 15:01:32 -0400681}
682
Steven Rostedt23715c3c2011-06-13 11:03:34 -0400683sub __eval_option {
684 my ($option, $i) = @_;
685
686 # Add space to evaluate the character before $
687 $option = " $option";
688 my $retval = "";
689
690 while ($option =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) {
691 my $start = $1;
692 my $var = $2;
693 my $end = $3;
694
695 # Append beginning of line
696 $retval = "$retval$start";
697
698 # If the iteration option OPT[$i] exists, then use that.
699 # otherwise see if the default OPT (without [$i]) exists.
700
701 my $o = "$var\[$i\]";
702
703 if (defined($opt{$o})) {
704 $o = $opt{$o};
705 $retval = "$retval$o";
706 } elsif (defined($opt{$var})) {
707 $o = $opt{$var};
708 $retval = "$retval$o";
709 } else {
710 $retval = "$retval\$\{$var\}";
711 }
712
713 $option = $end;
714 }
715
716 $retval = "$retval$option";
717
718 $retval =~ s/^ //;
719
720 return $retval;
721}
722
723sub eval_option {
724 my ($option, $i) = @_;
725
726 my $prev = "";
727
728 # Since an option can evaluate to another option,
729 # keep iterating until we do not evaluate any more
730 # options.
731 my $r = 0;
732 while ($prev ne $option) {
733 # Check for recursive evaluations.
734 # 100 deep should be more than enough.
735 if ($r++ > 100) {
736 die "Over 100 evaluations accurred with $option\n" .
737 "Check for recursive variables\n";
738 }
739 $prev = $option;
740 $option = __eval_option($option, $i);
741 }
742
743 return $option;
744}
745
Steven Rostedtd1e2f222010-11-08 16:39:57 -0500746sub _logit {
Steven Rostedt2545eb62010-11-02 15:01:32 -0400747 if (defined($opt{"LOG_FILE"})) {
748 open(OUT, ">> $opt{LOG_FILE}") or die "Can't write to $opt{LOG_FILE}";
749 print OUT @_;
750 close(OUT);
751 }
752}
753
Steven Rostedtd1e2f222010-11-08 16:39:57 -0500754sub logit {
755 if (defined($opt{"LOG_FILE"})) {
756 _logit @_;
757 } else {
758 print @_;
759 }
760}
761
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400762sub doprint {
763 print @_;
Steven Rostedtd1e2f222010-11-08 16:39:57 -0500764 _logit @_;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400765}
766
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400767sub run_command;
Andrew Jones2728be42011-08-12 15:32:05 +0200768sub start_monitor;
769sub end_monitor;
770sub wait_for_monitor;
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400771
772sub reboot {
Andrew Jones2728be42011-08-12 15:32:05 +0200773 my ($time) = @_;
774
Steven Rostedt2b803362011-09-30 18:00:23 -0400775 if (defined($time)) {
776 start_monitor;
777 # flush out current monitor
778 # May contain the reboot success line
779 wait_for_monitor 1;
780 }
781
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400782 # try to reboot normally
Steven Rostedte48c5292010-11-02 14:35:37 -0400783 if (run_command $reboot) {
Steven Rostedt576f6272010-11-02 14:58:38 -0400784 if (defined($powercycle_after_reboot)) {
785 sleep $powercycle_after_reboot;
786 run_command "$power_cycle";
787 }
788 } else {
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400789 # nope? power cycle it.
Steven Rostedta75fece2010-11-02 14:58:27 -0400790 run_command "$power_cycle";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400791 }
Andrew Jones2728be42011-08-12 15:32:05 +0200792
793 if (defined($time)) {
Steven Rostedt2b803362011-09-30 18:00:23 -0400794 wait_for_monitor($time, $reboot_success_line);
Andrew Jones2728be42011-08-12 15:32:05 +0200795 end_monitor;
796 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400797}
798
Steven Rostedt576f6272010-11-02 14:58:38 -0400799sub do_not_reboot {
800 my $i = $iteration;
801
Steven Rostedt4ab1cce2011-09-30 18:12:20 -0400802 return $test_type eq "build" || $no_reboot ||
Steven Rostedt576f6272010-11-02 14:58:38 -0400803 ($test_type eq "patchcheck" && $opt{"PATCHCHECK_TYPE[$i]"} eq "build") ||
804 ($test_type eq "bisect" && $opt{"BISECT_TYPE[$i]"} eq "build");
805}
806
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400807sub dodie {
Steven Rostedt5a391fb2010-11-02 14:57:43 -0400808 doprint "CRITICAL FAILURE... ", @_, "\n";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400809
Steven Rostedt576f6272010-11-02 14:58:38 -0400810 my $i = $iteration;
811
812 if ($reboot_on_error && !do_not_reboot) {
813
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400814 doprint "REBOOTING\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400815 reboot;
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400816
Steven Rostedta75fece2010-11-02 14:58:27 -0400817 } elsif ($poweroff_on_error && defined($power_off)) {
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400818 doprint "POWERING OFF\n";
Steven Rostedta75fece2010-11-02 14:58:27 -0400819 `$power_off`;
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400820 }
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400821
Steven Rostedtf80802c2011-03-07 13:18:47 -0500822 if (defined($opt{"LOG_FILE"})) {
823 print " See $opt{LOG_FILE} for more info.\n";
824 }
825
Steven Rostedt576f6272010-11-02 14:58:38 -0400826 die @_, "\n";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400827}
828
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400829sub open_console {
830 my ($fp) = @_;
831
832 my $flags;
833
Steven Rostedta75fece2010-11-02 14:58:27 -0400834 my $pid = open($fp, "$console|") or
835 dodie "Can't open console $console";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400836
837 $flags = fcntl($fp, F_GETFL, 0) or
Steven Rostedt576f6272010-11-02 14:58:38 -0400838 dodie "Can't get flags for the socket: $!";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400839 $flags = fcntl($fp, F_SETFL, $flags | O_NONBLOCK) or
Steven Rostedt576f6272010-11-02 14:58:38 -0400840 dodie "Can't set flags for the socket: $!";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400841
842 return $pid;
843}
844
845sub close_console {
846 my ($fp, $pid) = @_;
847
848 doprint "kill child process $pid\n";
849 kill 2, $pid;
850
851 print "closing!\n";
852 close($fp);
853}
854
855sub start_monitor {
856 if ($monitor_cnt++) {
857 return;
858 }
859 $monitor_fp = \*MONFD;
860 $monitor_pid = open_console $monitor_fp;
Steven Rostedta75fece2010-11-02 14:58:27 -0400861
862 return;
863
864 open(MONFD, "Stop perl from warning about single use of MONFD");
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400865}
866
867sub end_monitor {
868 if (--$monitor_cnt) {
869 return;
870 }
871 close_console($monitor_fp, $monitor_pid);
872}
873
874sub wait_for_monitor {
Steven Rostedt2b803362011-09-30 18:00:23 -0400875 my ($time, $stop) = @_;
876 my $full_line = "";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400877 my $line;
Steven Rostedt2b803362011-09-30 18:00:23 -0400878 my $booted = 0;
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400879
Steven Rostedta75fece2010-11-02 14:58:27 -0400880 doprint "** Wait for monitor to settle down **\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400881
882 # read the monitor and wait for the system to calm down
Steven Rostedt2b803362011-09-30 18:00:23 -0400883 while (!$booted) {
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400884 $line = wait_for_input($monitor_fp, $time);
Steven Rostedt2b803362011-09-30 18:00:23 -0400885 last if (!defined($line));
886 print "$line";
887 $full_line .= $line;
888
889 if (defined($stop) && $full_line =~ /$stop/) {
890 doprint "wait for monitor detected $stop\n";
891 $booted = 1;
892 }
893
894 if ($line =~ /\n/) {
895 $full_line = "";
896 }
897 }
Steven Rostedta75fece2010-11-02 14:58:27 -0400898 print "** Monitor flushed **\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400899}
900
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400901sub fail {
902
Steven Rostedta75fece2010-11-02 14:58:27 -0400903 if ($die_on_failure) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400904 dodie @_;
905 }
906
Steven Rostedta75fece2010-11-02 14:58:27 -0400907 doprint "FAILED\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400908
Steven Rostedt576f6272010-11-02 14:58:38 -0400909 my $i = $iteration;
910
Steven Rostedta75fece2010-11-02 14:58:27 -0400911 # no need to reboot for just building.
Steven Rostedt576f6272010-11-02 14:58:38 -0400912 if (!do_not_reboot) {
Steven Rostedta75fece2010-11-02 14:58:27 -0400913 doprint "REBOOTING\n";
Andrew Jones2728be42011-08-12 15:32:05 +0200914 reboot $sleep_time;
Steven Rostedta75fece2010-11-02 14:58:27 -0400915 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400916
Steven Rostedt9064af52011-06-13 10:38:48 -0400917 my $name = "";
918
919 if (defined($test_name)) {
920 $name = " ($test_name)";
921 }
922
Steven Rostedt576f6272010-11-02 14:58:38 -0400923 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
924 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
Steven Rostedt9064af52011-06-13 10:38:48 -0400925 doprint "KTEST RESULT: TEST $i$name Failed: ", @_, "\n";
Steven Rostedt576f6272010-11-02 14:58:38 -0400926 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
927 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
Steven Rostedta75fece2010-11-02 14:58:27 -0400928
929 return 1 if (!defined($store_failures));
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400930
931 my @t = localtime;
932 my $date = sprintf "%04d%02d%02d%02d%02d%02d",
933 1900+$t[5],$t[4],$t[3],$t[2],$t[1],$t[0];
934
Steven Rostedtcccae1a2010-11-09 12:21:32 -0500935 my $type = $build_type;
936 if ($type =~ /useconfig/) {
937 $type = "useconfig";
938 }
939
940 my $dir = "$machine-$test_type-$type-fail-$date";
Steven Rostedta75fece2010-11-02 14:58:27 -0400941 my $faildir = "$store_failures/$dir";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400942
943 if (!-d $faildir) {
944 mkpath($faildir) or
Steven Rostedta75fece2010-11-02 14:58:27 -0400945 die "can't create $faildir";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400946 }
Steven Rostedt51ad1dd2010-11-08 16:43:21 -0500947 if (-f "$output_config") {
948 cp "$output_config", "$faildir/config" or
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400949 die "failed to copy .config";
950 }
951 if (-f $buildlog) {
952 cp $buildlog, "$faildir/buildlog" or
953 die "failed to move $buildlog";
954 }
955 if (-f $dmesg) {
956 cp $dmesg, "$faildir/dmesg" or
957 die "failed to move $dmesg";
958 }
959
960 doprint "*** Saved info to $faildir ***\n";
961
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400962 return 1;
963}
964
Steven Rostedt2545eb62010-11-02 15:01:32 -0400965sub run_command {
966 my ($command) = @_;
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400967 my $dolog = 0;
968 my $dord = 0;
969 my $pid;
970
Steven Rostedte48c5292010-11-02 14:35:37 -0400971 $command =~ s/\$SSH_USER/$ssh_user/g;
972 $command =~ s/\$MACHINE/$machine/g;
973
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400974 doprint("$command ... ");
975
976 $pid = open(CMD, "$command 2>&1 |") or
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400977 (fail "unable to exec $command" and return 0);
Steven Rostedt2545eb62010-11-02 15:01:32 -0400978
979 if (defined($opt{"LOG_FILE"})) {
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400980 open(LOG, ">>$opt{LOG_FILE}") or
981 dodie "failed to write to log";
982 $dolog = 1;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -0400983 }
984
985 if (defined($redirect)) {
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400986 open (RD, ">$redirect") or
987 dodie "failed to write to redirect $redirect";
988 $dord = 1;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400989 }
990
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400991 while (<CMD>) {
992 print LOG if ($dolog);
993 print RD if ($dord);
994 }
Steven Rostedt2545eb62010-11-02 15:01:32 -0400995
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400996 waitpid($pid, 0);
Steven Rostedt2545eb62010-11-02 15:01:32 -0400997 my $failed = $?;
998
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400999 close(CMD);
1000 close(LOG) if ($dolog);
1001 close(RD) if ($dord);
1002
Steven Rostedt2545eb62010-11-02 15:01:32 -04001003 if ($failed) {
1004 doprint "FAILED!\n";
1005 } else {
1006 doprint "SUCCESS\n";
1007 }
1008
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001009 return !$failed;
1010}
1011
Steven Rostedte48c5292010-11-02 14:35:37 -04001012sub run_ssh {
1013 my ($cmd) = @_;
1014 my $cp_exec = $ssh_exec;
1015
1016 $cp_exec =~ s/\$SSH_COMMAND/$cmd/g;
1017 return run_command "$cp_exec";
1018}
1019
1020sub run_scp {
1021 my ($src, $dst) = @_;
1022 my $cp_scp = $scp_to_target;
1023
1024 $cp_scp =~ s/\$SRC_FILE/$src/g;
1025 $cp_scp =~ s/\$DST_FILE/$dst/g;
1026
1027 return run_command "$cp_scp";
1028}
1029
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001030sub get_grub_index {
1031
Steven Rostedta75fece2010-11-02 14:58:27 -04001032 if ($reboot_type ne "grub") {
1033 return;
1034 }
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001035 return if (defined($grub_number));
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001036
1037 doprint "Find grub menu ... ";
1038 $grub_number = -1;
Steven Rostedte48c5292010-11-02 14:35:37 -04001039
1040 my $ssh_grub = $ssh_exec;
1041 $ssh_grub =~ s,\$SSH_COMMAND,cat /boot/grub/menu.lst,g;
1042
1043 open(IN, "$ssh_grub |")
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001044 or die "unable to get menu.lst";
Steven Rostedte48c5292010-11-02 14:35:37 -04001045
Steven Rostedteaa1fe22011-09-14 17:20:39 -04001046 my $found = 0;
1047
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001048 while (<IN>) {
Steven Rostedta75fece2010-11-02 14:58:27 -04001049 if (/^\s*title\s+$grub_menu\s*$/) {
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001050 $grub_number++;
Steven Rostedteaa1fe22011-09-14 17:20:39 -04001051 $found = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001052 last;
1053 } elsif (/^\s*title\s/) {
1054 $grub_number++;
1055 }
1056 }
1057 close(IN);
1058
Steven Rostedta75fece2010-11-02 14:58:27 -04001059 die "Could not find '$grub_menu' in /boot/grub/menu on $machine"
Steven Rostedteaa1fe22011-09-14 17:20:39 -04001060 if (!$found);
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001061 doprint "$grub_number\n";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001062}
1063
Steven Rostedt2545eb62010-11-02 15:01:32 -04001064sub wait_for_input
1065{
1066 my ($fp, $time) = @_;
1067 my $rin;
1068 my $ready;
1069 my $line;
1070 my $ch;
1071
1072 if (!defined($time)) {
1073 $time = $timeout;
1074 }
1075
1076 $rin = '';
1077 vec($rin, fileno($fp), 1) = 1;
1078 $ready = select($rin, undef, undef, $time);
1079
1080 $line = "";
1081
1082 # try to read one char at a time
1083 while (sysread $fp, $ch, 1) {
1084 $line .= $ch;
1085 last if ($ch eq "\n");
1086 }
1087
1088 if (!length($line)) {
1089 return undef;
1090 }
1091
1092 return $line;
1093}
1094
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001095sub reboot_to {
Steven Rostedta75fece2010-11-02 14:58:27 -04001096 if ($reboot_type eq "grub") {
Steven Rostedt4da46da2011-06-01 23:25:13 -04001097 run_ssh "'(echo \"savedefault --default=$grub_number --once\" | grub --batch && reboot)'";
Steven Rostedta75fece2010-11-02 14:58:27 -04001098 return;
1099 }
1100
1101 run_command "$reboot_script";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001102}
1103
Steven Rostedta57419b2010-11-02 15:13:54 -04001104sub get_sha1 {
1105 my ($commit) = @_;
1106
1107 doprint "git rev-list --max-count=1 $commit ... ";
1108 my $sha1 = `git rev-list --max-count=1 $commit`;
1109 my $ret = $?;
1110
1111 logit $sha1;
1112
1113 if ($ret) {
1114 doprint "FAILED\n";
1115 dodie "Failed to get git $commit";
1116 }
1117
1118 print "SUCCESS\n";
1119
1120 chomp $sha1;
1121
1122 return $sha1;
1123}
1124
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001125sub monitor {
Steven Rostedt2545eb62010-11-02 15:01:32 -04001126 my $booted = 0;
1127 my $bug = 0;
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001128 my $skip_call_trace = 0;
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001129 my $loops;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001130
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001131 wait_for_monitor 5;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001132
1133 my $line;
1134 my $full_line = "";
1135
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001136 open(DMESG, "> $dmesg") or
1137 die "unable to write to $dmesg";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001138
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001139 reboot_to;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001140
Steven Rostedt1c8a6172010-11-09 12:55:40 -05001141 my $success_start;
1142 my $failure_start;
Steven Rostedt2d01b262011-03-08 09:47:54 -05001143 my $monitor_start = time;
1144 my $done = 0;
Steven Rostedtf1a5b962011-06-13 10:30:00 -04001145 my $version_found = 0;
Steven Rostedt1c8a6172010-11-09 12:55:40 -05001146
Steven Rostedt2d01b262011-03-08 09:47:54 -05001147 while (!$done) {
Steven Rostedt2545eb62010-11-02 15:01:32 -04001148
Steven Rostedtecaf8e52011-06-13 10:48:10 -04001149 if ($bug && defined($stop_after_failure) &&
1150 $stop_after_failure >= 0) {
1151 my $time = $stop_after_failure - (time - $failure_start);
1152 $line = wait_for_input($monitor_fp, $time);
1153 if (!defined($line)) {
1154 doprint "bug timed out after $booted_timeout seconds\n";
1155 doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
1156 last;
1157 }
1158 } elsif ($booted) {
Steven Rostedta75fece2010-11-02 14:58:27 -04001159 $line = wait_for_input($monitor_fp, $booted_timeout);
Steven Rostedtcd4f1d52011-06-13 10:26:27 -04001160 if (!defined($line)) {
1161 my $s = $booted_timeout == 1 ? "" : "s";
1162 doprint "Successful boot found: break after $booted_timeout second$s\n";
1163 last;
1164 }
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001165 } else {
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001166 $line = wait_for_input($monitor_fp);
Steven Rostedtcd4f1d52011-06-13 10:26:27 -04001167 if (!defined($line)) {
1168 my $s = $timeout == 1 ? "" : "s";
1169 doprint "Timed out after $timeout second$s\n";
1170 last;
1171 }
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001172 }
Steven Rostedt2545eb62010-11-02 15:01:32 -04001173
Steven Rostedt2545eb62010-11-02 15:01:32 -04001174 doprint $line;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001175 print DMESG $line;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001176
1177 # we are not guaranteed to get a full line
1178 $full_line .= $line;
1179
Steven Rostedta75fece2010-11-02 14:58:27 -04001180 if ($full_line =~ /$success_line/) {
Steven Rostedt2545eb62010-11-02 15:01:32 -04001181 $booted = 1;
Steven Rostedt1c8a6172010-11-09 12:55:40 -05001182 $success_start = time;
1183 }
1184
1185 if ($booted && defined($stop_after_success) &&
1186 $stop_after_success >= 0) {
1187 my $now = time;
1188 if ($now - $success_start >= $stop_after_success) {
1189 doprint "Test forced to stop after $stop_after_success seconds after success\n";
1190 last;
1191 }
Steven Rostedt2545eb62010-11-02 15:01:32 -04001192 }
1193
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001194 if ($full_line =~ /\[ backtrace testing \]/) {
1195 $skip_call_trace = 1;
1196 }
1197
Steven Rostedt2545eb62010-11-02 15:01:32 -04001198 if ($full_line =~ /call trace:/i) {
Steven Rostedt46519202011-03-08 09:40:31 -05001199 if (!$bug && !$skip_call_trace) {
Steven Rostedt1c8a6172010-11-09 12:55:40 -05001200 $bug = 1;
1201 $failure_start = time;
1202 }
1203 }
1204
1205 if ($bug && defined($stop_after_failure) &&
1206 $stop_after_failure >= 0) {
1207 my $now = time;
1208 if ($now - $failure_start >= $stop_after_failure) {
1209 doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
1210 last;
1211 }
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001212 }
1213
1214 if ($full_line =~ /\[ end of backtrace testing \]/) {
1215 $skip_call_trace = 0;
1216 }
1217
1218 if ($full_line =~ /Kernel panic -/) {
Steven Rostedt10abf112011-03-07 13:21:00 -05001219 $failure_start = time;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001220 $bug = 1;
1221 }
1222
Steven Rostedtf1a5b962011-06-13 10:30:00 -04001223 # Detect triple faults by testing the banner
1224 if ($full_line =~ /\bLinux version (\S+).*\n/) {
1225 if ($1 eq $version) {
1226 $version_found = 1;
1227 } elsif ($version_found && $detect_triplefault) {
1228 # We already booted into the kernel we are testing,
1229 # but now we booted into another kernel?
1230 # Consider this a triple fault.
1231 doprint "Aleady booted in Linux kernel $version, but now\n";
1232 doprint "we booted into Linux kernel $1.\n";
1233 doprint "Assuming that this is a triple fault.\n";
1234 doprint "To disable this: set DETECT_TRIPLE_FAULT to 0\n";
1235 last;
1236 }
1237 }
1238
Steven Rostedt2545eb62010-11-02 15:01:32 -04001239 if ($line =~ /\n/) {
1240 $full_line = "";
1241 }
Steven Rostedt2d01b262011-03-08 09:47:54 -05001242
1243 if ($stop_test_after > 0 && !$booted && !$bug) {
1244 if (time - $monitor_start > $stop_test_after) {
Steven Rostedt4d62bf52011-05-20 09:14:35 -04001245 doprint "STOP_TEST_AFTER ($stop_test_after seconds) timed out\n";
Steven Rostedt2d01b262011-03-08 09:47:54 -05001246 $done = 1;
1247 }
1248 }
Steven Rostedt2545eb62010-11-02 15:01:32 -04001249 }
1250
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001251 close(DMESG);
Steven Rostedt2545eb62010-11-02 15:01:32 -04001252
Steven Rostedt2545eb62010-11-02 15:01:32 -04001253 if ($bug) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001254 return 0 if ($in_bisect);
Steven Rostedt576f6272010-11-02 14:58:38 -04001255 fail "failed - got a bug report" and return 0;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001256 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001257
Steven Rostedta75fece2010-11-02 14:58:27 -04001258 if (!$booted) {
1259 return 0 if ($in_bisect);
Steven Rostedt576f6272010-11-02 14:58:38 -04001260 fail "failed - never got a boot prompt." and return 0;
Steven Rostedta75fece2010-11-02 14:58:27 -04001261 }
1262
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001263 return 1;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001264}
1265
Steven Rostedtdb05cfe2011-06-13 11:09:22 -04001266sub do_post_install {
1267
1268 return if (!defined($post_install));
1269
1270 my $cp_post_install = $post_install;
1271 $cp_post_install =~ s/\$KERNEL_VERSION/$version/g;
1272 run_command "$cp_post_install" or
1273 dodie "Failed to run post install";
1274}
1275
Steven Rostedt2545eb62010-11-02 15:01:32 -04001276sub install {
1277
Steven Rostedte0a87422011-09-30 17:50:48 -04001278 return if ($no_install);
1279
Steven Rostedte48c5292010-11-02 14:35:37 -04001280 run_scp "$outputdir/$build_target", "$target_image" or
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001281 dodie "failed to copy image";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001282
1283 my $install_mods = 0;
1284
1285 # should we process modules?
1286 $install_mods = 0;
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05001287 open(IN, "$output_config") or dodie("Can't read config file");
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001288 while (<IN>) {
1289 if (/CONFIG_MODULES(=y)?/) {
1290 $install_mods = 1 if (defined($1));
1291 last;
1292 }
1293 }
1294 close(IN);
1295
1296 if (!$install_mods) {
Steven Rostedtdb05cfe2011-06-13 11:09:22 -04001297 do_post_install;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001298 doprint "No modules needed\n";
1299 return;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001300 }
1301
Steven Rostedta75fece2010-11-02 14:58:27 -04001302 run_command "$make INSTALL_MOD_PATH=$tmpdir modules_install" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001303 dodie "Failed to install modules";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001304
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001305 my $modlib = "/lib/modules/$version";
Steven Rostedta57419b2010-11-02 15:13:54 -04001306 my $modtar = "ktest-mods.tar.bz2";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001307
Steven Rostedte48c5292010-11-02 14:35:37 -04001308 run_ssh "rm -rf $modlib" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001309 dodie "failed to remove old mods: $modlib";
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001310
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001311 # would be nice if scp -r did not follow symbolic links
Steven Rostedta75fece2010-11-02 14:58:27 -04001312 run_command "cd $tmpdir && tar -cjf $modtar lib/modules/$version" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001313 dodie "making tarball";
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001314
Steven Rostedte48c5292010-11-02 14:35:37 -04001315 run_scp "$tmpdir/$modtar", "/tmp" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001316 dodie "failed to copy modules";
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001317
Steven Rostedta75fece2010-11-02 14:58:27 -04001318 unlink "$tmpdir/$modtar";
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001319
Steven Rostedte7b13442011-06-14 20:44:36 -04001320 run_ssh "'(cd / && tar xjf /tmp/$modtar)'" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001321 dodie "failed to tar modules";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001322
Steven Rostedte48c5292010-11-02 14:35:37 -04001323 run_ssh "rm -f /tmp/$modtar";
Steven Rostedt8b37ca82010-11-02 14:58:33 -04001324
Steven Rostedtdb05cfe2011-06-13 11:09:22 -04001325 do_post_install;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001326}
1327
Steven Rostedtddf607e2011-06-14 20:49:13 -04001328sub get_version {
1329 # get the release name
1330 doprint "$make kernelrelease ... ";
1331 $version = `$make kernelrelease | tail -1`;
1332 chomp($version);
1333 doprint "$version\n";
1334}
1335
1336sub start_monitor_and_boot {
1337 get_grub_index;
1338 get_version;
1339 install;
1340
1341 start_monitor;
1342 return monitor;
1343}
1344
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001345sub check_buildlog {
1346 my ($patch) = @_;
1347
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001348 my @files = `git show $patch | diffstat -l`;
1349
1350 open(IN, "git show $patch |") or
1351 dodie "failed to show $patch";
1352 while (<IN>) {
1353 if (m,^--- a/(.*),) {
1354 chomp $1;
1355 $files[$#files] = $1;
1356 }
1357 }
1358 close(IN);
1359
1360 open(IN, $buildlog) or dodie "Can't open $buildlog";
1361 while (<IN>) {
1362 if (/^\s*(.*?):.*(warning|error)/) {
1363 my $err = $1;
1364 foreach my $file (@files) {
Steven Rostedta75fece2010-11-02 14:58:27 -04001365 my $fullpath = "$builddir/$file";
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001366 if ($file eq $err || $fullpath eq $err) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001367 fail "$file built with warnings" and return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001368 }
1369 }
1370 }
1371 }
1372 close(IN);
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001373
1374 return 1;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001375}
1376
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001377sub apply_min_config {
1378 my $outconfig = "$output_config.new";
Steven Rostedt612b9e92011-03-07 13:27:43 -05001379
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001380 # Read the config file and remove anything that
1381 # is in the force_config hash (from minconfig and others)
1382 # then add the force config back.
1383
1384 doprint "Applying minimum configurations into $output_config.new\n";
1385
1386 open (OUT, ">$outconfig") or
1387 dodie "Can't create $outconfig";
1388
1389 if (-f $output_config) {
1390 open (IN, $output_config) or
1391 dodie "Failed to open $output_config";
1392 while (<IN>) {
1393 if (/^(# )?(CONFIG_[^\s=]*)/) {
1394 next if (defined($force_config{$2}));
1395 }
1396 print OUT;
1397 }
1398 close IN;
1399 }
1400 foreach my $config (keys %force_config) {
1401 print OUT "$force_config{$config}\n";
1402 }
1403 close OUT;
1404
1405 run_command "mv $outconfig $output_config";
1406}
1407
1408sub make_oldconfig {
1409
Steven Rostedt4c4ab122011-07-15 21:16:17 -04001410 my @force_list = keys %force_config;
1411
1412 if ($#force_list >= 0) {
1413 apply_min_config;
1414 }
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001415
1416 if (!run_command "$make oldnoconfig") {
Steven Rostedt612b9e92011-03-07 13:27:43 -05001417 # Perhaps oldnoconfig doesn't exist in this version of the kernel
1418 # try a yes '' | oldconfig
1419 doprint "oldnoconfig failed, trying yes '' | make oldconfig\n";
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001420 run_command "yes '' | $make oldconfig" or
Steven Rostedt612b9e92011-03-07 13:27:43 -05001421 dodie "failed make config oldconfig";
1422 }
1423}
1424
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001425# read a config file and use this to force new configs.
1426sub load_force_config {
1427 my ($config) = @_;
1428
1429 open(IN, $config) or
1430 dodie "failed to read $config";
1431 while (<IN>) {
1432 chomp;
1433 if (/^(CONFIG[^\s=]*)(\s*=.*)/) {
1434 $force_config{$1} = $_;
1435 } elsif (/^# (CONFIG_\S*) is not set/) {
1436 $force_config{$1} = $_;
1437 }
1438 }
1439 close IN;
1440}
1441
Steven Rostedt2545eb62010-11-02 15:01:32 -04001442sub build {
1443 my ($type) = @_;
1444
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001445 unlink $buildlog;
1446
Steven Rostedt4ab1cce2011-09-30 18:12:20 -04001447 # Failed builds should not reboot the target
1448 my $save_no_reboot = $no_reboot;
1449 $no_reboot = 1;
1450
Steven Rostedt0bd6c1a2011-06-14 20:39:31 -04001451 if (defined($pre_build)) {
1452 my $ret = run_command $pre_build;
1453 if (!$ret && defined($pre_build_die) &&
1454 $pre_build_die) {
1455 dodie "failed to pre_build\n";
1456 }
1457 }
1458
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001459 if ($type =~ /^useconfig:(.*)/) {
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05001460 run_command "cp $1 $output_config" or
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001461 dodie "could not copy $1 to .config";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001462
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001463 $type = "oldconfig";
1464 }
1465
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001466 # old config can ask questions
1467 if ($type eq "oldconfig") {
Steven Rostedt9386c6a2010-11-08 16:35:48 -05001468 $type = "oldnoconfig";
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001469
1470 # allow for empty configs
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05001471 run_command "touch $output_config";
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001472
Andrew Jones13488232011-08-12 15:32:04 +02001473 if (!$noclean) {
1474 run_command "mv $output_config $outputdir/config_temp" or
1475 dodie "moving .config";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001476
Andrew Jones13488232011-08-12 15:32:04 +02001477 run_command "$make mrproper" or dodie "make mrproper";
1478
1479 run_command "mv $outputdir/config_temp $output_config" or
1480 dodie "moving config_temp";
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001481 }
1482
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001483 } elsif (!$noclean) {
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05001484 unlink "$output_config";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001485 run_command "$make mrproper" or
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001486 dodie "make mrproper";
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001487 }
Steven Rostedt2545eb62010-11-02 15:01:32 -04001488
1489 # add something to distinguish this build
Steven Rostedta75fece2010-11-02 14:58:27 -04001490 open(OUT, "> $outputdir/localversion") or dodie("Can't make localversion file");
1491 print OUT "$localversion\n";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001492 close(OUT);
1493
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001494 if (defined($minconfig)) {
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001495 load_force_config($minconfig);
Steven Rostedt2545eb62010-11-02 15:01:32 -04001496 }
1497
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001498 if ($type ne "oldnoconfig") {
1499 run_command "$make $type" or
Steven Rostedt612b9e92011-03-07 13:27:43 -05001500 dodie "failed make config";
1501 }
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001502 # Run old config regardless, to enforce min configurations
1503 make_oldconfig;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001504
Steven Rostedta75fece2010-11-02 14:58:27 -04001505 $redirect = "$buildlog";
Steven Rostedt0bd6c1a2011-06-14 20:39:31 -04001506 my $build_ret = run_command "$make $build_options";
1507 undef $redirect;
1508
1509 if (defined($post_build)) {
1510 my $ret = run_command $post_build;
1511 if (!$ret && defined($post_build_die) &&
1512 $post_build_die) {
1513 dodie "failed to post_build\n";
1514 }
1515 }
1516
1517 if (!$build_ret) {
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001518 # bisect may need this to pass
Steven Rostedt4ab1cce2011-09-30 18:12:20 -04001519 if ($in_bisect) {
1520 $no_reboot = $save_no_reboot;
1521 return 0;
1522 }
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001523 fail "failed build" and return 0;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001524 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001525
Steven Rostedt4ab1cce2011-09-30 18:12:20 -04001526 $no_reboot = $save_no_reboot;
1527
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001528 return 1;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001529}
1530
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001531sub halt {
Steven Rostedte48c5292010-11-02 14:35:37 -04001532 if (!run_ssh "halt" or defined($power_off)) {
Steven Rostedt576f6272010-11-02 14:58:38 -04001533 if (defined($poweroff_after_halt)) {
1534 sleep $poweroff_after_halt;
1535 run_command "$power_off";
1536 }
1537 } else {
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001538 # nope? the zap it!
Steven Rostedta75fece2010-11-02 14:58:27 -04001539 run_command "$power_off";
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001540 }
1541}
1542
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001543sub success {
1544 my ($i) = @_;
1545
Steven Rostedte48c5292010-11-02 14:35:37 -04001546 $successes++;
1547
Steven Rostedt9064af52011-06-13 10:38:48 -04001548 my $name = "";
1549
1550 if (defined($test_name)) {
1551 $name = " ($test_name)";
1552 }
1553
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001554 doprint "\n\n*******************************************\n";
1555 doprint "*******************************************\n";
Steven Rostedt9064af52011-06-13 10:38:48 -04001556 doprint "KTEST RESULT: TEST $i$name SUCCESS!!!! **\n";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001557 doprint "*******************************************\n";
1558 doprint "*******************************************\n";
1559
Steven Rostedt576f6272010-11-02 14:58:38 -04001560 if ($i != $opt{"NUM_TESTS"} && !do_not_reboot) {
Steven Rostedta75fece2010-11-02 14:58:27 -04001561 doprint "Reboot and wait $sleep_time seconds\n";
Andrew Jones2728be42011-08-12 15:32:05 +02001562 reboot $sleep_time;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001563 }
1564}
1565
Steven Rostedtc960bb92011-03-08 09:22:39 -05001566sub answer_bisect {
1567 for (;;) {
1568 doprint "Pass or fail? [p/f]";
1569 my $ans = <STDIN>;
1570 chomp $ans;
1571 if ($ans eq "p" || $ans eq "P") {
1572 return 1;
1573 } elsif ($ans eq "f" || $ans eq "F") {
1574 return 0;
1575 } else {
1576 print "Please answer 'P' or 'F'\n";
1577 }
1578 }
1579}
1580
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001581sub child_run_test {
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001582 my $failed = 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001583
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001584 # child should have no power
Steven Rostedta75fece2010-11-02 14:58:27 -04001585 $reboot_on_error = 0;
1586 $poweroff_on_error = 0;
1587 $die_on_failure = 1;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001588
1589 run_command $run_test or $failed = 1;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001590 exit $failed;
1591}
1592
1593my $child_done;
1594
1595sub child_finished {
1596 $child_done = 1;
1597}
1598
1599sub do_run_test {
1600 my $child_pid;
1601 my $child_exit;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001602 my $line;
1603 my $full_line;
1604 my $bug = 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001605
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001606 wait_for_monitor 1;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001607
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001608 doprint "run test $run_test\n";
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001609
1610 $child_done = 0;
1611
1612 $SIG{CHLD} = qw(child_finished);
1613
1614 $child_pid = fork;
1615
1616 child_run_test if (!$child_pid);
1617
1618 $full_line = "";
1619
1620 do {
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001621 $line = wait_for_input($monitor_fp, 1);
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001622 if (defined($line)) {
1623
1624 # we are not guaranteed to get a full line
1625 $full_line .= $line;
Steven Rostedt8ea0e062011-03-08 09:44:35 -05001626 doprint $line;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001627
1628 if ($full_line =~ /call trace:/i) {
1629 $bug = 1;
1630 }
1631
1632 if ($full_line =~ /Kernel panic -/) {
1633 $bug = 1;
1634 }
1635
1636 if ($line =~ /\n/) {
1637 $full_line = "";
1638 }
1639 }
1640 } while (!$child_done && !$bug);
1641
1642 if ($bug) {
Steven Rostedt8ea0e062011-03-08 09:44:35 -05001643 my $failure_start = time;
1644 my $now;
1645 do {
1646 $line = wait_for_input($monitor_fp, 1);
1647 if (defined($line)) {
1648 doprint $line;
1649 }
1650 $now = time;
1651 if ($now - $failure_start >= $stop_after_failure) {
1652 last;
1653 }
1654 } while (defined($line));
1655
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001656 doprint "Detected kernel crash!\n";
1657 # kill the child with extreme prejudice
1658 kill 9, $child_pid;
1659 }
1660
1661 waitpid $child_pid, 0;
1662 $child_exit = $?;
1663
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001664 if ($bug || $child_exit) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001665 return 0 if $in_bisect;
1666 fail "test failed" and return 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001667 }
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001668 return 1;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001669}
1670
Steven Rostedta75fece2010-11-02 14:58:27 -04001671sub run_git_bisect {
1672 my ($command) = @_;
1673
1674 doprint "$command ... ";
1675
1676 my $output = `$command 2>&1`;
1677 my $ret = $?;
1678
1679 logit $output;
1680
1681 if ($ret) {
1682 doprint "FAILED\n";
1683 dodie "Failed to git bisect";
1684 }
1685
1686 doprint "SUCCESS\n";
1687 if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\))\s+\[([[:xdigit:]]+)\]/) {
1688 doprint "$1 [$2]\n";
1689 } elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) {
1690 $bisect_bad = $1;
1691 doprint "Found bad commit... $1\n";
1692 return 0;
1693 } else {
1694 # we already logged it, just print it now.
1695 print $output;
1696 }
1697
1698 return 1;
1699}
1700
Steven Rostedtc23dca72011-03-08 09:26:31 -05001701sub bisect_reboot {
1702 doprint "Reboot and sleep $bisect_sleep_time seconds\n";
Andrew Jones2728be42011-08-12 15:32:05 +02001703 reboot $bisect_sleep_time;
Steven Rostedtc23dca72011-03-08 09:26:31 -05001704}
1705
1706# returns 1 on success, 0 on failure, -1 on skip
Steven Rostedt0a05c762010-11-08 11:14:10 -05001707sub run_bisect_test {
1708 my ($type, $buildtype) = @_;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001709
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001710 my $failed = 0;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001711 my $result;
1712 my $output;
1713 my $ret;
1714
Steven Rostedt0a05c762010-11-08 11:14:10 -05001715 $in_bisect = 1;
1716
1717 build $buildtype or $failed = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001718
1719 if ($type ne "build") {
Steven Rostedtc23dca72011-03-08 09:26:31 -05001720 if ($failed && $bisect_skip) {
1721 $in_bisect = 0;
1722 return -1;
1723 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001724 dodie "Failed on build" if $failed;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001725
1726 # Now boot the box
Steven Rostedtddf607e2011-06-14 20:49:13 -04001727 start_monitor_and_boot or $failed = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001728
1729 if ($type ne "boot") {
Steven Rostedtc23dca72011-03-08 09:26:31 -05001730 if ($failed && $bisect_skip) {
1731 end_monitor;
1732 bisect_reboot;
1733 $in_bisect = 0;
1734 return -1;
1735 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001736 dodie "Failed on boot" if $failed;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001737
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001738 do_run_test or $failed = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001739 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001740 end_monitor;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001741 }
1742
1743 if ($failed) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001744 $result = 0;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001745 } else {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001746 $result = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001747 }
Steven Rostedt4025bc62011-05-20 09:16:29 -04001748
1749 # reboot the box to a kernel we can ssh to
1750 if ($type ne "build") {
1751 bisect_reboot;
1752 }
Steven Rostedt0a05c762010-11-08 11:14:10 -05001753 $in_bisect = 0;
1754
1755 return $result;
1756}
1757
1758sub run_bisect {
1759 my ($type) = @_;
1760 my $buildtype = "oldconfig";
1761
1762 # We should have a minconfig to use?
1763 if (defined($minconfig)) {
1764 $buildtype = "useconfig:$minconfig";
1765 }
1766
1767 my $ret = run_bisect_test $type, $buildtype;
1768
Steven Rostedtc960bb92011-03-08 09:22:39 -05001769 if ($bisect_manual) {
1770 $ret = answer_bisect;
1771 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001772
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04001773 # Are we looking for where it worked, not failed?
1774 if ($reverse_bisect) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001775 $ret = !$ret;
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04001776 }
1777
Steven Rostedtc23dca72011-03-08 09:26:31 -05001778 if ($ret > 0) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001779 return "good";
Steven Rostedtc23dca72011-03-08 09:26:31 -05001780 } elsif ($ret == 0) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001781 return "bad";
Steven Rostedtc23dca72011-03-08 09:26:31 -05001782 } elsif ($bisect_skip) {
1783 doprint "HIT A BAD COMMIT ... SKIPPING\n";
1784 return "skip";
Steven Rostedt0a05c762010-11-08 11:14:10 -05001785 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001786}
1787
1788sub bisect {
1789 my ($i) = @_;
1790
1791 my $result;
1792
1793 die "BISECT_GOOD[$i] not defined\n" if (!defined($opt{"BISECT_GOOD[$i]"}));
1794 die "BISECT_BAD[$i] not defined\n" if (!defined($opt{"BISECT_BAD[$i]"}));
1795 die "BISECT_TYPE[$i] not defined\n" if (!defined($opt{"BISECT_TYPE[$i]"}));
1796
1797 my $good = $opt{"BISECT_GOOD[$i]"};
1798 my $bad = $opt{"BISECT_BAD[$i]"};
1799 my $type = $opt{"BISECT_TYPE[$i]"};
Steven Rostedta75fece2010-11-02 14:58:27 -04001800 my $start = $opt{"BISECT_START[$i]"};
1801 my $replay = $opt{"BISECT_REPLAY[$i]"};
Steven Rostedt3410f6f2011-03-08 09:38:12 -05001802 my $start_files = $opt{"BISECT_FILES[$i]"};
1803
1804 if (defined($start_files)) {
1805 $start_files = " -- " . $start_files;
1806 } else {
1807 $start_files = "";
1808 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001809
Steven Rostedta57419b2010-11-02 15:13:54 -04001810 # convert to true sha1's
1811 $good = get_sha1($good);
1812 $bad = get_sha1($bad);
1813
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04001814 if (defined($opt{"BISECT_REVERSE[$i]"}) &&
1815 $opt{"BISECT_REVERSE[$i]"} == 1) {
1816 doprint "Performing a reverse bisect (bad is good, good is bad!)\n";
1817 $reverse_bisect = 1;
1818 } else {
1819 $reverse_bisect = 0;
1820 }
1821
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001822 # Can't have a test without having a test to run
1823 if ($type eq "test" && !defined($run_test)) {
1824 $type = "boot";
1825 }
1826
Steven Rostedta75fece2010-11-02 14:58:27 -04001827 my $check = $opt{"BISECT_CHECK[$i]"};
1828 if (defined($check) && $check ne "0") {
1829
1830 # get current HEAD
Steven Rostedta57419b2010-11-02 15:13:54 -04001831 my $head = get_sha1("HEAD");
Steven Rostedta75fece2010-11-02 14:58:27 -04001832
1833 if ($check ne "good") {
1834 doprint "TESTING BISECT BAD [$bad]\n";
1835 run_command "git checkout $bad" or
1836 die "Failed to checkout $bad";
1837
1838 $result = run_bisect $type;
1839
1840 if ($result ne "bad") {
1841 fail "Tested BISECT_BAD [$bad] and it succeeded" and return 0;
1842 }
1843 }
1844
1845 if ($check ne "bad") {
1846 doprint "TESTING BISECT GOOD [$good]\n";
1847 run_command "git checkout $good" or
1848 die "Failed to checkout $good";
1849
1850 $result = run_bisect $type;
1851
1852 if ($result ne "good") {
1853 fail "Tested BISECT_GOOD [$good] and it failed" and return 0;
1854 }
1855 }
1856
1857 # checkout where we started
1858 run_command "git checkout $head" or
1859 die "Failed to checkout $head";
1860 }
1861
Steven Rostedt3410f6f2011-03-08 09:38:12 -05001862 run_command "git bisect start$start_files" or
Steven Rostedta75fece2010-11-02 14:58:27 -04001863 dodie "could not start bisect";
1864
1865 run_command "git bisect good $good" or
1866 dodie "could not set bisect good to $good";
1867
1868 run_git_bisect "git bisect bad $bad" or
1869 dodie "could not set bisect bad to $bad";
1870
1871 if (defined($replay)) {
1872 run_command "git bisect replay $replay" or
1873 dodie "failed to run replay";
1874 }
1875
1876 if (defined($start)) {
1877 run_command "git checkout $start" or
1878 dodie "failed to checkout $start";
1879 }
1880
1881 my $test;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001882 do {
1883 $result = run_bisect $type;
Steven Rostedta75fece2010-11-02 14:58:27 -04001884 $test = run_git_bisect "git bisect $result";
1885 } while ($test);
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001886
1887 run_command "git bisect log" or
1888 dodie "could not capture git bisect log";
1889
1890 run_command "git bisect reset" or
1891 dodie "could not reset git bisect";
1892
1893 doprint "Bad commit was [$bisect_bad]\n";
1894
Steven Rostedt0a05c762010-11-08 11:14:10 -05001895 success $i;
1896}
1897
1898my %config_ignore;
1899my %config_set;
1900
1901my %config_list;
1902my %null_config;
1903
1904my %dependency;
1905
Steven Rostedt4c4ab122011-07-15 21:16:17 -04001906sub assign_configs {
1907 my ($hash, $config) = @_;
Steven Rostedt0a05c762010-11-08 11:14:10 -05001908
1909 open (IN, $config)
1910 or dodie "Failed to read $config";
1911
1912 while (<IN>) {
Steven Rostedt9bf71742011-06-01 23:27:19 -04001913 if (/^((CONFIG\S*)=.*)/) {
Steven Rostedt4c4ab122011-07-15 21:16:17 -04001914 ${$hash}{$2} = $1;
Steven Rostedt0a05c762010-11-08 11:14:10 -05001915 }
1916 }
1917
1918 close(IN);
1919}
1920
Steven Rostedt4c4ab122011-07-15 21:16:17 -04001921sub process_config_ignore {
1922 my ($config) = @_;
1923
1924 assign_configs \%config_ignore, $config;
1925}
1926
Steven Rostedt0a05c762010-11-08 11:14:10 -05001927sub read_current_config {
1928 my ($config_ref) = @_;
1929
1930 %{$config_ref} = ();
1931 undef %{$config_ref};
1932
1933 my @key = keys %{$config_ref};
1934 if ($#key >= 0) {
1935 print "did not delete!\n";
1936 exit;
1937 }
1938 open (IN, "$output_config");
1939
1940 while (<IN>) {
1941 if (/^(CONFIG\S+)=(.*)/) {
1942 ${$config_ref}{$1} = $2;
1943 }
1944 }
1945 close(IN);
1946}
1947
1948sub get_dependencies {
1949 my ($config) = @_;
1950
1951 my $arr = $dependency{$config};
1952 if (!defined($arr)) {
1953 return ();
1954 }
1955
1956 my @deps = @{$arr};
1957
1958 foreach my $dep (@{$arr}) {
1959 print "ADD DEP $dep\n";
1960 @deps = (@deps, get_dependencies $dep);
1961 }
1962
1963 return @deps;
1964}
1965
1966sub create_config {
1967 my @configs = @_;
1968
1969 open(OUT, ">$output_config") or dodie "Can not write to $output_config";
1970
1971 foreach my $config (@configs) {
1972 print OUT "$config_set{$config}\n";
1973 my @deps = get_dependencies $config;
1974 foreach my $dep (@deps) {
1975 print OUT "$config_set{$dep}\n";
1976 }
1977 }
1978
1979 foreach my $config (keys %config_ignore) {
1980 print OUT "$config_ignore{$config}\n";
1981 }
1982 close(OUT);
1983
1984# exit;
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001985 make_oldconfig;
Steven Rostedt0a05c762010-11-08 11:14:10 -05001986}
1987
1988sub compare_configs {
1989 my (%a, %b) = @_;
1990
1991 foreach my $item (keys %a) {
1992 if (!defined($b{$item})) {
1993 print "diff $item\n";
1994 return 1;
1995 }
1996 delete $b{$item};
1997 }
1998
1999 my @keys = keys %b;
2000 if ($#keys) {
2001 print "diff2 $keys[0]\n";
2002 }
2003 return -1 if ($#keys >= 0);
2004
2005 return 0;
2006}
2007
2008sub run_config_bisect_test {
2009 my ($type) = @_;
2010
2011 return run_bisect_test $type, "oldconfig";
2012}
2013
2014sub process_passed {
2015 my (%configs) = @_;
2016
2017 doprint "These configs had no failure: (Enabling them for further compiles)\n";
2018 # Passed! All these configs are part of a good compile.
2019 # Add them to the min options.
2020 foreach my $config (keys %configs) {
2021 if (defined($config_list{$config})) {
2022 doprint " removing $config\n";
2023 $config_ignore{$config} = $config_list{$config};
2024 delete $config_list{$config};
2025 }
2026 }
Steven Rostedtf1a27852010-11-11 11:34:38 -05002027 doprint "config copied to $outputdir/config_good\n";
2028 run_command "cp -f $output_config $outputdir/config_good";
Steven Rostedt0a05c762010-11-08 11:14:10 -05002029}
2030
2031sub process_failed {
2032 my ($config) = @_;
2033
2034 doprint "\n\n***************************************\n";
2035 doprint "Found bad config: $config\n";
2036 doprint "***************************************\n\n";
2037}
2038
2039sub run_config_bisect {
2040
2041 my @start_list = keys %config_list;
2042
2043 if ($#start_list < 0) {
2044 doprint "No more configs to test!!!\n";
2045 return -1;
2046 }
2047
2048 doprint "***** RUN TEST ***\n";
2049 my $type = $opt{"CONFIG_BISECT_TYPE[$iteration]"};
2050 my $ret;
2051 my %current_config;
2052
2053 my $count = $#start_list + 1;
2054 doprint " $count configs to test\n";
2055
2056 my $half = int($#start_list / 2);
2057
2058 do {
2059 my @tophalf = @start_list[0 .. $half];
2060
2061 create_config @tophalf;
2062 read_current_config \%current_config;
2063
2064 $count = $#tophalf + 1;
2065 doprint "Testing $count configs\n";
2066 my $found = 0;
2067 # make sure we test something
2068 foreach my $config (@tophalf) {
2069 if (defined($current_config{$config})) {
2070 logit " $config\n";
2071 $found = 1;
2072 }
2073 }
2074 if (!$found) {
2075 # try the other half
2076 doprint "Top half produced no set configs, trying bottom half\n";
Steven Rostedt4c8cc552011-06-01 23:22:30 -04002077 @tophalf = @start_list[$half + 1 .. $#start_list];
Steven Rostedt0a05c762010-11-08 11:14:10 -05002078 create_config @tophalf;
2079 read_current_config \%current_config;
2080 foreach my $config (@tophalf) {
2081 if (defined($current_config{$config})) {
2082 logit " $config\n";
2083 $found = 1;
2084 }
2085 }
2086 if (!$found) {
2087 doprint "Failed: Can't make new config with current configs\n";
2088 foreach my $config (@start_list) {
2089 doprint " CONFIG: $config\n";
2090 }
2091 return -1;
2092 }
2093 $count = $#tophalf + 1;
2094 doprint "Testing $count configs\n";
2095 }
2096
2097 $ret = run_config_bisect_test $type;
Steven Rostedtc960bb92011-03-08 09:22:39 -05002098 if ($bisect_manual) {
2099 $ret = answer_bisect;
2100 }
Steven Rostedt0a05c762010-11-08 11:14:10 -05002101 if ($ret) {
2102 process_passed %current_config;
2103 return 0;
2104 }
2105
2106 doprint "This config had a failure.\n";
2107 doprint "Removing these configs that were not set in this config:\n";
Steven Rostedtf1a27852010-11-11 11:34:38 -05002108 doprint "config copied to $outputdir/config_bad\n";
2109 run_command "cp -f $output_config $outputdir/config_bad";
Steven Rostedt0a05c762010-11-08 11:14:10 -05002110
2111 # A config exists in this group that was bad.
2112 foreach my $config (keys %config_list) {
2113 if (!defined($current_config{$config})) {
2114 doprint " removing $config\n";
2115 delete $config_list{$config};
2116 }
2117 }
2118
2119 @start_list = @tophalf;
2120
2121 if ($#start_list == 0) {
2122 process_failed $start_list[0];
2123 return 1;
2124 }
2125
2126 # remove half the configs we are looking at and see if
2127 # they are good.
2128 $half = int($#start_list / 2);
Steven Rostedt4c8cc552011-06-01 23:22:30 -04002129 } while ($#start_list > 0);
Steven Rostedt0a05c762010-11-08 11:14:10 -05002130
Steven Rostedtc960bb92011-03-08 09:22:39 -05002131 # we found a single config, try it again unless we are running manually
2132
2133 if ($bisect_manual) {
2134 process_failed $start_list[0];
2135 return 1;
2136 }
2137
Steven Rostedt0a05c762010-11-08 11:14:10 -05002138 my @tophalf = @start_list[0 .. 0];
2139
2140 $ret = run_config_bisect_test $type;
2141 if ($ret) {
2142 process_passed %current_config;
2143 return 0;
2144 }
2145
2146 process_failed $start_list[0];
2147 return 1;
2148}
2149
2150sub config_bisect {
2151 my ($i) = @_;
2152
2153 my $start_config = $opt{"CONFIG_BISECT[$i]"};
2154
2155 my $tmpconfig = "$tmpdir/use_config";
2156
Steven Rostedt30f75da2011-06-13 10:35:35 -04002157 if (defined($config_bisect_good)) {
2158 process_config_ignore $config_bisect_good;
2159 }
2160
Steven Rostedt0a05c762010-11-08 11:14:10 -05002161 # Make the file with the bad config and the min config
2162 if (defined($minconfig)) {
2163 # read the min config for things to ignore
2164 run_command "cp $minconfig $tmpconfig" or
2165 dodie "failed to copy $minconfig to $tmpconfig";
2166 } else {
2167 unlink $tmpconfig;
2168 }
2169
Steven Rostedt0a05c762010-11-08 11:14:10 -05002170 if (-f $tmpconfig) {
Steven Rostedtfcb3f162011-06-13 10:40:58 -04002171 load_force_config($tmpconfig);
Steven Rostedt0a05c762010-11-08 11:14:10 -05002172 process_config_ignore $tmpconfig;
2173 }
2174
2175 # now process the start config
2176 run_command "cp $start_config $output_config" or
2177 dodie "failed to copy $start_config to $output_config";
2178
2179 # read directly what we want to check
2180 my %config_check;
2181 open (IN, $output_config)
2182 or dodie "faied to open $output_config";
2183
2184 while (<IN>) {
2185 if (/^((CONFIG\S*)=.*)/) {
2186 $config_check{$2} = $1;
2187 }
2188 }
2189 close(IN);
2190
Steven Rostedt250bae82011-07-15 22:05:59 -04002191 # Now run oldconfig with the minconfig
Steven Rostedtfcb3f162011-06-13 10:40:58 -04002192 make_oldconfig;
Steven Rostedt0a05c762010-11-08 11:14:10 -05002193
2194 # check to see what we lost (or gained)
2195 open (IN, $output_config)
2196 or dodie "Failed to read $start_config";
2197
2198 my %removed_configs;
2199 my %added_configs;
2200
2201 while (<IN>) {
2202 if (/^((CONFIG\S*)=.*)/) {
2203 # save off all options
2204 $config_set{$2} = $1;
2205 if (defined($config_check{$2})) {
2206 if (defined($config_ignore{$2})) {
2207 $removed_configs{$2} = $1;
2208 } else {
2209 $config_list{$2} = $1;
2210 }
2211 } elsif (!defined($config_ignore{$2})) {
2212 $added_configs{$2} = $1;
2213 $config_list{$2} = $1;
2214 }
2215 }
2216 }
2217 close(IN);
2218
2219 my @confs = keys %removed_configs;
2220 if ($#confs >= 0) {
2221 doprint "Configs overridden by default configs and removed from check:\n";
2222 foreach my $config (@confs) {
2223 doprint " $config\n";
2224 }
2225 }
2226 @confs = keys %added_configs;
2227 if ($#confs >= 0) {
2228 doprint "Configs appearing in make oldconfig and added:\n";
2229 foreach my $config (@confs) {
2230 doprint " $config\n";
2231 }
2232 }
2233
2234 my %config_test;
2235 my $once = 0;
2236
2237 # Sometimes kconfig does weird things. We must make sure
2238 # that the config we autocreate has everything we need
2239 # to test, otherwise we may miss testing configs, or
2240 # may not be able to create a new config.
2241 # Here we create a config with everything set.
2242 create_config (keys %config_list);
2243 read_current_config \%config_test;
2244 foreach my $config (keys %config_list) {
2245 if (!defined($config_test{$config})) {
2246 if (!$once) {
2247 $once = 1;
2248 doprint "Configs not produced by kconfig (will not be checked):\n";
2249 }
2250 doprint " $config\n";
2251 delete $config_list{$config};
2252 }
2253 }
2254 my $ret;
2255 do {
2256 $ret = run_config_bisect;
2257 } while (!$ret);
2258
2259 return $ret if ($ret < 0);
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04002260
2261 success $i;
2262}
2263
Steven Rostedt27d934b2011-05-20 09:18:18 -04002264sub patchcheck_reboot {
2265 doprint "Reboot and sleep $patchcheck_sleep_time seconds\n";
Andrew Jones2728be42011-08-12 15:32:05 +02002266 reboot $patchcheck_sleep_time;
Steven Rostedt27d934b2011-05-20 09:18:18 -04002267}
2268
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002269sub patchcheck {
2270 my ($i) = @_;
2271
2272 die "PATCHCHECK_START[$i] not defined\n"
2273 if (!defined($opt{"PATCHCHECK_START[$i]"}));
2274 die "PATCHCHECK_TYPE[$i] not defined\n"
2275 if (!defined($opt{"PATCHCHECK_TYPE[$i]"}));
2276
2277 my $start = $opt{"PATCHCHECK_START[$i]"};
2278
2279 my $end = "HEAD";
2280 if (defined($opt{"PATCHCHECK_END[$i]"})) {
2281 $end = $opt{"PATCHCHECK_END[$i]"};
2282 }
2283
Steven Rostedta57419b2010-11-02 15:13:54 -04002284 # Get the true sha1's since we can use things like HEAD~3
2285 $start = get_sha1($start);
2286 $end = get_sha1($end);
2287
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002288 my $type = $opt{"PATCHCHECK_TYPE[$i]"};
2289
2290 # Can't have a test without having a test to run
2291 if ($type eq "test" && !defined($run_test)) {
2292 $type = "boot";
2293 }
2294
2295 open (IN, "git log --pretty=oneline $end|") or
2296 dodie "could not get git list";
2297
2298 my @list;
2299
2300 while (<IN>) {
2301 chomp;
2302 $list[$#list+1] = $_;
2303 last if (/^$start/);
2304 }
2305 close(IN);
2306
2307 if ($list[$#list] !~ /^$start/) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002308 fail "SHA1 $start not found";
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002309 }
2310
2311 # go backwards in the list
2312 @list = reverse @list;
2313
2314 my $save_clean = $noclean;
Steven Rostedt19902072011-06-14 20:46:25 -04002315 my %ignored_warnings;
2316
2317 if (defined($ignore_warnings)) {
2318 foreach my $sha1 (split /\s+/, $ignore_warnings) {
2319 $ignored_warnings{$sha1} = 1;
2320 }
2321 }
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002322
2323 $in_patchcheck = 1;
2324 foreach my $item (@list) {
2325 my $sha1 = $item;
2326 $sha1 =~ s/^([[:xdigit:]]+).*/$1/;
2327
2328 doprint "\nProcessing commit $item\n\n";
2329
2330 run_command "git checkout $sha1" or
2331 die "Failed to checkout $sha1";
2332
2333 # only clean on the first and last patch
2334 if ($item eq $list[0] ||
2335 $item eq $list[$#list]) {
2336 $noclean = $save_clean;
2337 } else {
2338 $noclean = 1;
2339 }
2340
2341 if (defined($minconfig)) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002342 build "useconfig:$minconfig" or return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002343 } else {
2344 # ?? no config to use?
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002345 build "oldconfig" or return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002346 }
2347
Steven Rostedt19902072011-06-14 20:46:25 -04002348
2349 if (!defined($ignored_warnings{$sha1})) {
2350 check_buildlog $sha1 or return 0;
2351 }
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002352
2353 next if ($type eq "build");
2354
Steven Rostedt7faafbd2010-11-02 14:58:22 -04002355 my $failed = 0;
2356
Steven Rostedtddf607e2011-06-14 20:49:13 -04002357 start_monitor_and_boot or $failed = 1;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04002358
2359 if (!$failed && $type ne "boot"){
2360 do_run_test or $failed = 1;
2361 }
2362 end_monitor;
2363 return 0 if ($failed);
2364
Steven Rostedt27d934b2011-05-20 09:18:18 -04002365 patchcheck_reboot;
2366
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002367 }
2368 $in_patchcheck = 0;
2369 success $i;
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002370
2371 return 1;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002372}
2373
Steven Rostedtb9066f62011-07-15 21:25:24 -04002374my %depends;
2375my $iflevel = 0;
2376my @ifdeps;
2377
2378# prevent recursion
2379my %read_kconfigs;
2380
2381# taken from streamline_config.pl
2382sub read_kconfig {
2383 my ($kconfig) = @_;
2384
2385 my $state = "NONE";
2386 my $config;
2387 my @kconfigs;
2388
2389 my $cont = 0;
2390 my $line;
2391
2392
2393 if (! -f $kconfig) {
2394 doprint "file $kconfig does not exist, skipping\n";
2395 return;
2396 }
2397
2398 open(KIN, "$kconfig")
2399 or die "Can't open $kconfig";
2400 while (<KIN>) {
2401 chomp;
2402
2403 # Make sure that lines ending with \ continue
2404 if ($cont) {
2405 $_ = $line . " " . $_;
2406 }
2407
2408 if (s/\\$//) {
2409 $cont = 1;
2410 $line = $_;
2411 next;
2412 }
2413
2414 $cont = 0;
2415
2416 # collect any Kconfig sources
2417 if (/^source\s*"(.*)"/) {
2418 $kconfigs[$#kconfigs+1] = $1;
2419 }
2420
2421 # configs found
2422 if (/^\s*(menu)?config\s+(\S+)\s*$/) {
2423 $state = "NEW";
2424 $config = $2;
2425
2426 for (my $i = 0; $i < $iflevel; $i++) {
2427 if ($i) {
2428 $depends{$config} .= " " . $ifdeps[$i];
2429 } else {
2430 $depends{$config} = $ifdeps[$i];
2431 }
2432 $state = "DEP";
2433 }
2434
2435 # collect the depends for the config
2436 } elsif ($state eq "NEW" && /^\s*depends\s+on\s+(.*)$/) {
2437
2438 if (defined($depends{$1})) {
2439 $depends{$config} .= " " . $1;
2440 } else {
2441 $depends{$config} = $1;
2442 }
2443
2444 # Get the configs that select this config
2445 } elsif ($state ne "NONE" && /^\s*select\s+(\S+)/) {
2446 if (defined($depends{$1})) {
2447 $depends{$1} .= " " . $config;
2448 } else {
2449 $depends{$1} = $config;
2450 }
2451
2452 # Check for if statements
2453 } elsif (/^if\s+(.*\S)\s*$/) {
2454 my $deps = $1;
2455 # remove beginning and ending non text
2456 $deps =~ s/^[^a-zA-Z0-9_]*//;
2457 $deps =~ s/[^a-zA-Z0-9_]*$//;
2458
2459 my @deps = split /[^a-zA-Z0-9_]+/, $deps;
2460
2461 $ifdeps[$iflevel++] = join ':', @deps;
2462
2463 } elsif (/^endif/) {
2464
2465 $iflevel-- if ($iflevel);
2466
2467 # stop on "help"
2468 } elsif (/^\s*help\s*$/) {
2469 $state = "NONE";
2470 }
2471 }
2472 close(KIN);
2473
2474 # read in any configs that were found.
2475 foreach $kconfig (@kconfigs) {
2476 if (!defined($read_kconfigs{$kconfig})) {
2477 $read_kconfigs{$kconfig} = 1;
2478 read_kconfig("$builddir/$kconfig");
2479 }
2480 }
2481}
2482
2483sub read_depends {
2484 # find out which arch this is by the kconfig file
2485 open (IN, $output_config)
2486 or dodie "Failed to read $output_config";
2487 my $arch;
2488 while (<IN>) {
2489 if (m,Linux/(\S+)\s+\S+\s+Kernel Configuration,) {
2490 $arch = $1;
2491 last;
2492 }
2493 }
2494 close IN;
2495
2496 if (!defined($arch)) {
2497 doprint "Could not find arch from config file\n";
2498 doprint "no dependencies used\n";
2499 return;
2500 }
2501
2502 # arch is really the subarch, we need to know
2503 # what directory to look at.
2504 if ($arch eq "i386" || $arch eq "x86_64") {
2505 $arch = "x86";
2506 } elsif ($arch =~ /^tile/) {
2507 $arch = "tile";
2508 }
2509
2510 my $kconfig = "$builddir/arch/$arch/Kconfig";
2511
2512 if (! -f $kconfig && $arch =~ /\d$/) {
2513 my $orig = $arch;
2514 # some subarchs have numbers, truncate them
2515 $arch =~ s/\d*$//;
2516 $kconfig = "$builddir/arch/$arch/Kconfig";
2517 if (! -f $kconfig) {
2518 doprint "No idea what arch dir $orig is for\n";
2519 doprint "no dependencies used\n";
2520 return;
2521 }
2522 }
2523
2524 read_kconfig($kconfig);
2525}
2526
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002527sub read_config_list {
2528 my ($config) = @_;
2529
2530 open (IN, $config)
2531 or dodie "Failed to read $config";
2532
2533 while (<IN>) {
2534 if (/^((CONFIG\S*)=.*)/) {
2535 if (!defined($config_ignore{$2})) {
2536 $config_list{$2} = $1;
2537 }
2538 }
2539 }
2540
2541 close(IN);
2542}
2543
2544sub read_output_config {
2545 my ($config) = @_;
2546
2547 assign_configs \%config_ignore, $config;
2548}
2549
2550sub make_new_config {
2551 my @configs = @_;
2552
2553 open (OUT, ">$output_config")
2554 or dodie "Failed to write $output_config";
2555
2556 foreach my $config (@configs) {
2557 print OUT "$config\n";
2558 }
2559 close OUT;
2560}
2561
Steven Rostedtb9066f62011-07-15 21:25:24 -04002562sub get_depends {
2563 my ($dep) = @_;
2564
2565 my $kconfig = $dep;
2566 $kconfig =~ s/CONFIG_//;
2567
2568 $dep = $depends{"$kconfig"};
2569
2570 # the dep string we have saves the dependencies as they
2571 # were found, including expressions like ! && ||. We
2572 # want to split this out into just an array of configs.
2573
2574 my $valid = "A-Za-z_0-9";
2575
2576 my @configs;
2577
2578 while ($dep =~ /[$valid]/) {
2579
2580 if ($dep =~ /^[^$valid]*([$valid]+)/) {
2581 my $conf = "CONFIG_" . $1;
2582
2583 $configs[$#configs + 1] = $conf;
2584
2585 $dep =~ s/^[^$valid]*[$valid]+//;
2586 } else {
2587 die "this should never happen";
2588 }
2589 }
2590
2591 return @configs;
2592}
2593
2594my %min_configs;
2595my %keep_configs;
Steven Rostedt43d1b652011-07-15 22:01:56 -04002596my %save_configs;
Steven Rostedtb9066f62011-07-15 21:25:24 -04002597my %processed_configs;
2598my %nochange_config;
2599
2600sub test_this_config {
2601 my ($config) = @_;
2602
2603 my $found;
2604
2605 # if we already processed this config, skip it
2606 if (defined($processed_configs{$config})) {
2607 return undef;
2608 }
2609 $processed_configs{$config} = 1;
2610
2611 # if this config failed during this round, skip it
2612 if (defined($nochange_config{$config})) {
2613 return undef;
2614 }
2615
2616 my $kconfig = $config;
2617 $kconfig =~ s/CONFIG_//;
2618
2619 # Test dependencies first
2620 if (defined($depends{"$kconfig"})) {
2621 my @parents = get_depends $config;
2622 foreach my $parent (@parents) {
2623 # if the parent is in the min config, check it first
2624 next if (!defined($min_configs{$parent}));
2625 $found = test_this_config($parent);
2626 if (defined($found)) {
2627 return $found;
2628 }
2629 }
2630 }
2631
2632 # Remove this config from the list of configs
2633 # do a make oldnoconfig and then read the resulting
2634 # .config to make sure it is missing the config that
2635 # we had before
2636 my %configs = %min_configs;
2637 delete $configs{$config};
2638 make_new_config ((values %configs), (values %keep_configs));
2639 make_oldconfig;
2640 undef %configs;
2641 assign_configs \%configs, $output_config;
2642
2643 return $config if (!defined($configs{$config}));
2644
2645 doprint "disabling config $config did not change .config\n";
2646
2647 $nochange_config{$config} = 1;
2648
2649 return undef;
2650}
2651
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002652sub make_min_config {
2653 my ($i) = @_;
2654
2655 if (!defined($output_minconfig)) {
2656 fail "OUTPUT_MIN_CONFIG not defined" and return;
2657 }
Steven Rostedt35ce5952011-07-15 21:57:25 -04002658
2659 # If output_minconfig exists, and the start_minconfig
2660 # came from min_config, than ask if we should use
2661 # that instead.
2662 if (-f $output_minconfig && !$start_minconfig_defined) {
2663 print "$output_minconfig exists\n";
2664 if (read_yn " Use it as minconfig?") {
2665 $start_minconfig = $output_minconfig;
2666 }
2667 }
2668
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002669 if (!defined($start_minconfig)) {
2670 fail "START_MIN_CONFIG or MIN_CONFIG not defined" and return;
2671 }
2672
Steven Rostedt35ce5952011-07-15 21:57:25 -04002673 my $temp_config = "$tmpdir/temp_config";
2674
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002675 # First things first. We build an allnoconfig to find
2676 # out what the defaults are that we can't touch.
2677 # Some are selections, but we really can't handle selections.
2678
2679 my $save_minconfig = $minconfig;
2680 undef $minconfig;
2681
2682 run_command "$make allnoconfig" or return 0;
2683
Steven Rostedtb9066f62011-07-15 21:25:24 -04002684 read_depends;
2685
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002686 process_config_ignore $output_config;
Steven Rostedtb9066f62011-07-15 21:25:24 -04002687
Steven Rostedt43d1b652011-07-15 22:01:56 -04002688 undef %save_configs;
Steven Rostedtb9066f62011-07-15 21:25:24 -04002689 undef %min_configs;
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002690
2691 if (defined($ignore_config)) {
2692 # make sure the file exists
2693 `touch $ignore_config`;
Steven Rostedt43d1b652011-07-15 22:01:56 -04002694 assign_configs \%save_configs, $ignore_config;
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002695 }
2696
Steven Rostedt43d1b652011-07-15 22:01:56 -04002697 %keep_configs = %save_configs;
2698
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002699 doprint "Load initial configs from $start_minconfig\n";
2700
2701 # Look at the current min configs, and save off all the
2702 # ones that were set via the allnoconfig
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002703 assign_configs \%min_configs, $start_minconfig;
2704
2705 my @config_keys = keys %min_configs;
2706
2707 # Remove anything that was set by the make allnoconfig
2708 # we shouldn't need them as they get set for us anyway.
2709 foreach my $config (@config_keys) {
2710 # Remove anything in the ignore_config
2711 if (defined($keep_configs{$config})) {
2712 my $file = $ignore_config;
2713 $file =~ s,.*/(.*?)$,$1,;
2714 doprint "$config set by $file ... ignored\n";
2715 delete $min_configs{$config};
2716 next;
2717 }
2718 # But make sure the settings are the same. If a min config
2719 # sets a selection, we do not want to get rid of it if
2720 # it is not the same as what we have. Just move it into
2721 # the keep configs.
2722 if (defined($config_ignore{$config})) {
2723 if ($config_ignore{$config} ne $min_configs{$config}) {
2724 doprint "$config is in allnoconfig as '$config_ignore{$config}'";
2725 doprint " but it is '$min_configs{$config}' in minconfig .. keeping\n";
2726 $keep_configs{$config} = $min_configs{$config};
2727 } else {
2728 doprint "$config set by allnoconfig ... ignored\n";
2729 }
2730 delete $min_configs{$config};
2731 }
2732 }
2733
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002734 my $done = 0;
Steven Rostedtb9066f62011-07-15 21:25:24 -04002735 my $take_two = 0;
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002736
2737 while (!$done) {
2738
2739 my $config;
2740 my $found;
2741
2742 # Now disable each config one by one and do a make oldconfig
2743 # till we find a config that changes our list.
2744
2745 # Put configs that did not modify the config at the end.
2746 my @test_configs = keys %min_configs;
2747 my $reset = 1;
2748 for (my $i = 0; $i < $#test_configs; $i++) {
2749 if (!defined($nochange_config{$test_configs[0]})) {
2750 $reset = 0;
2751 last;
2752 }
2753 # This config didn't change the .config last time.
2754 # Place it at the end
2755 my $config = shift @test_configs;
2756 push @test_configs, $config;
2757 }
2758
2759 # if every test config has failed to modify the .config file
2760 # in the past, then reset and start over.
2761 if ($reset) {
2762 undef %nochange_config;
2763 }
2764
Steven Rostedtb9066f62011-07-15 21:25:24 -04002765 undef %processed_configs;
2766
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002767 foreach my $config (@test_configs) {
2768
Steven Rostedtb9066f62011-07-15 21:25:24 -04002769 $found = test_this_config $config;
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002770
Steven Rostedtb9066f62011-07-15 21:25:24 -04002771 last if (defined($found));
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002772
2773 # oh well, try another config
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002774 }
2775
2776 if (!defined($found)) {
Steven Rostedtb9066f62011-07-15 21:25:24 -04002777 # we could have failed due to the nochange_config hash
2778 # reset and try again
2779 if (!$take_two) {
2780 undef %nochange_config;
2781 $take_two = 1;
2782 next;
2783 }
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002784 doprint "No more configs found that we can disable\n";
2785 $done = 1;
2786 last;
2787 }
Steven Rostedtb9066f62011-07-15 21:25:24 -04002788 $take_two = 0;
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002789
2790 $config = $found;
2791
2792 doprint "Test with $config disabled\n";
2793
2794 # set in_bisect to keep build and monitor from dieing
2795 $in_bisect = 1;
2796
2797 my $failed = 0;
2798 build "oldconfig";
2799 start_monitor_and_boot or $failed = 1;
2800 end_monitor;
2801
2802 $in_bisect = 0;
2803
2804 if ($failed) {
Steven Rostedtb9066f62011-07-15 21:25:24 -04002805 doprint "$min_configs{$config} is needed to boot the box... keeping\n";
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002806 # this config is needed, add it to the ignore list.
2807 $keep_configs{$config} = $min_configs{$config};
Steven Rostedt43d1b652011-07-15 22:01:56 -04002808 $save_configs{$config} = $min_configs{$config};
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002809 delete $min_configs{$config};
Steven Rostedt35ce5952011-07-15 21:57:25 -04002810
2811 # update new ignore configs
2812 if (defined($ignore_config)) {
2813 open (OUT, ">$temp_config")
2814 or die "Can't write to $temp_config";
Steven Rostedt43d1b652011-07-15 22:01:56 -04002815 foreach my $config (keys %save_configs) {
2816 print OUT "$save_configs{$config}\n";
Steven Rostedt35ce5952011-07-15 21:57:25 -04002817 }
2818 close OUT;
2819 run_command "mv $temp_config $ignore_config" or
2820 dodie "failed to copy update to $ignore_config";
2821 }
2822
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002823 } else {
2824 # We booted without this config, remove it from the minconfigs.
2825 doprint "$config is not needed, disabling\n";
2826
2827 delete $min_configs{$config};
2828
2829 # Also disable anything that is not enabled in this config
2830 my %configs;
2831 assign_configs \%configs, $output_config;
2832 my @config_keys = keys %min_configs;
2833 foreach my $config (@config_keys) {
2834 if (!defined($configs{$config})) {
2835 doprint "$config is not set, disabling\n";
2836 delete $min_configs{$config};
2837 }
2838 }
2839
2840 # Save off all the current mandidory configs
Steven Rostedt35ce5952011-07-15 21:57:25 -04002841 open (OUT, ">$temp_config")
2842 or die "Can't write to $temp_config";
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002843 foreach my $config (keys %keep_configs) {
2844 print OUT "$keep_configs{$config}\n";
2845 }
2846 foreach my $config (keys %min_configs) {
2847 print OUT "$min_configs{$config}\n";
2848 }
2849 close OUT;
Steven Rostedt35ce5952011-07-15 21:57:25 -04002850
2851 run_command "mv $temp_config $output_minconfig" or
2852 dodie "failed to copy update to $output_minconfig";
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002853 }
2854
2855 doprint "Reboot and wait $sleep_time seconds\n";
Andrew Jones2728be42011-08-12 15:32:05 +02002856 reboot $sleep_time;
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002857 }
2858
2859 success $i;
2860 return 1;
2861}
2862
Steven Rostedt8d1491b2010-11-18 15:39:48 -05002863$#ARGV < 1 or die "ktest.pl version: $VERSION\n usage: ktest.pl config-file\n";
Steven Rostedt2545eb62010-11-02 15:01:32 -04002864
Steven Rostedt8d1491b2010-11-18 15:39:48 -05002865if ($#ARGV == 0) {
2866 $ktest_config = $ARGV[0];
2867 if (! -f $ktest_config) {
2868 print "$ktest_config does not exist.\n";
Steven Rostedt35ce5952011-07-15 21:57:25 -04002869 if (!read_yn "Create it?") {
Steven Rostedt8d1491b2010-11-18 15:39:48 -05002870 exit 0;
2871 }
2872 }
2873} else {
2874 $ktest_config = "ktest.conf";
2875}
2876
2877if (! -f $ktest_config) {
2878 open(OUT, ">$ktest_config") or die "Can not create $ktest_config";
2879 print OUT << "EOF"
2880# Generated by ktest.pl
2881#
2882# Define each test with TEST_START
2883# The config options below it will override the defaults
2884TEST_START
2885
2886DEFAULTS
2887EOF
2888;
2889 close(OUT);
2890}
2891read_config $ktest_config;
2892
Steven Rostedt23715c3c2011-06-13 11:03:34 -04002893if (defined($opt{"LOG_FILE"})) {
2894 $opt{"LOG_FILE"} = eval_option($opt{"LOG_FILE"}, -1);
2895}
2896
Steven Rostedt8d1491b2010-11-18 15:39:48 -05002897# Append any configs entered in manually to the config file.
2898my @new_configs = keys %entered_configs;
2899if ($#new_configs >= 0) {
2900 print "\nAppending entered in configs to $ktest_config\n";
2901 open(OUT, ">>$ktest_config") or die "Can not append to $ktest_config";
2902 foreach my $config (@new_configs) {
2903 print OUT "$config = $entered_configs{$config}\n";
2904 $opt{$config} = $entered_configs{$config};
2905 }
2906}
Steven Rostedt2545eb62010-11-02 15:01:32 -04002907
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002908if ($opt{"CLEAR_LOG"} && defined($opt{"LOG_FILE"})) {
2909 unlink $opt{"LOG_FILE"};
2910}
Steven Rostedt2545eb62010-11-02 15:01:32 -04002911
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002912doprint "\n\nSTARTING AUTOMATED TESTS\n\n";
2913
Steven Rostedta57419b2010-11-02 15:13:54 -04002914for (my $i = 0, my $repeat = 1; $i <= $opt{"NUM_TESTS"}; $i += $repeat) {
2915
2916 if (!$i) {
2917 doprint "DEFAULT OPTIONS:\n";
2918 } else {
2919 doprint "\nTEST $i OPTIONS";
2920 if (defined($repeat_tests{$i})) {
2921 $repeat = $repeat_tests{$i};
2922 doprint " ITERATE $repeat";
2923 }
2924 doprint "\n";
2925 }
2926
2927 foreach my $option (sort keys %opt) {
2928
2929 if ($option =~ /\[(\d+)\]$/) {
2930 next if ($i != $1);
2931 } else {
2932 next if ($i);
2933 }
2934
2935 doprint "$option = $opt{$option}\n";
2936 }
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002937}
Steven Rostedt2545eb62010-11-02 15:01:32 -04002938
Steven Rostedt2a625122011-05-20 15:48:59 -04002939sub __set_test_option {
Steven Rostedt5a391fb2010-11-02 14:57:43 -04002940 my ($name, $i) = @_;
2941
2942 my $option = "$name\[$i\]";
2943
2944 if (defined($opt{$option})) {
2945 return $opt{$option};
2946 }
2947
Steven Rostedta57419b2010-11-02 15:13:54 -04002948 foreach my $test (keys %repeat_tests) {
2949 if ($i >= $test &&
2950 $i < $test + $repeat_tests{$test}) {
2951 $option = "$name\[$test\]";
2952 if (defined($opt{$option})) {
2953 return $opt{$option};
2954 }
2955 }
2956 }
2957
Steven Rostedt5a391fb2010-11-02 14:57:43 -04002958 if (defined($opt{$name})) {
2959 return $opt{$name};
2960 }
2961
2962 return undef;
2963}
2964
Steven Rostedt2a625122011-05-20 15:48:59 -04002965sub set_test_option {
2966 my ($name, $i) = @_;
2967
2968 my $option = __set_test_option($name, $i);
2969 return $option if (!defined($option));
2970
Steven Rostedt23715c3c2011-06-13 11:03:34 -04002971 return eval_option($option, $i);
Steven Rostedt2a625122011-05-20 15:48:59 -04002972}
2973
Steven Rostedt2545eb62010-11-02 15:01:32 -04002974# First we need to do is the builds
Steven Rostedta75fece2010-11-02 14:58:27 -04002975for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
Steven Rostedt2545eb62010-11-02 15:01:32 -04002976
Steven Rostedt4ab1cce2011-09-30 18:12:20 -04002977 # Do not reboot on failing test options
2978 $no_reboot = 1;
2979
Steven Rostedt576f6272010-11-02 14:58:38 -04002980 $iteration = $i;
2981
Steven Rostedta75fece2010-11-02 14:58:27 -04002982 my $makecmd = set_test_option("MAKE_CMD", $i);
2983
2984 $machine = set_test_option("MACHINE", $i);
Steven Rostedte48c5292010-11-02 14:35:37 -04002985 $ssh_user = set_test_option("SSH_USER", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002986 $tmpdir = set_test_option("TMP_DIR", $i);
2987 $outputdir = set_test_option("OUTPUT_DIR", $i);
2988 $builddir = set_test_option("BUILD_DIR", $i);
2989 $test_type = set_test_option("TEST_TYPE", $i);
2990 $build_type = set_test_option("BUILD_TYPE", $i);
2991 $build_options = set_test_option("BUILD_OPTIONS", $i);
Steven Rostedt0bd6c1a2011-06-14 20:39:31 -04002992 $pre_build = set_test_option("PRE_BUILD", $i);
2993 $post_build = set_test_option("POST_BUILD", $i);
2994 $pre_build_die = set_test_option("PRE_BUILD_DIE", $i);
2995 $post_build_die = set_test_option("POST_BUILD_DIE", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002996 $power_cycle = set_test_option("POWER_CYCLE", $i);
Steven Rostedte48c5292010-11-02 14:35:37 -04002997 $reboot = set_test_option("REBOOT", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002998 $noclean = set_test_option("BUILD_NOCLEAN", $i);
2999 $minconfig = set_test_option("MIN_CONFIG", $i);
Steven Rostedt4c4ab122011-07-15 21:16:17 -04003000 $output_minconfig = set_test_option("OUTPUT_MIN_CONFIG", $i);
3001 $start_minconfig = set_test_option("START_MIN_CONFIG", $i);
3002 $ignore_config = set_test_option("IGNORE_CONFIG", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04003003 $run_test = set_test_option("TEST", $i);
3004 $addconfig = set_test_option("ADD_CONFIG", $i);
3005 $reboot_type = set_test_option("REBOOT_TYPE", $i);
3006 $grub_menu = set_test_option("GRUB_MENU", $i);
Steven Rostedt8b37ca82010-11-02 14:58:33 -04003007 $post_install = set_test_option("POST_INSTALL", $i);
Steven Rostedte0a87422011-09-30 17:50:48 -04003008 $no_install = set_test_option("NO_INSTALL", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04003009 $reboot_script = set_test_option("REBOOT_SCRIPT", $i);
3010 $reboot_on_error = set_test_option("REBOOT_ON_ERROR", $i);
3011 $poweroff_on_error = set_test_option("POWEROFF_ON_ERROR", $i);
3012 $die_on_failure = set_test_option("DIE_ON_FAILURE", $i);
3013 $power_off = set_test_option("POWER_OFF", $i);
Steven Rostedt576f6272010-11-02 14:58:38 -04003014 $powercycle_after_reboot = set_test_option("POWERCYCLE_AFTER_REBOOT", $i);
3015 $poweroff_after_halt = set_test_option("POWEROFF_AFTER_HALT", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04003016 $sleep_time = set_test_option("SLEEP_TIME", $i);
3017 $bisect_sleep_time = set_test_option("BISECT_SLEEP_TIME", $i);
Steven Rostedt27d934b2011-05-20 09:18:18 -04003018 $patchcheck_sleep_time = set_test_option("PATCHCHECK_SLEEP_TIME", $i);
Steven Rostedt19902072011-06-14 20:46:25 -04003019 $ignore_warnings = set_test_option("IGNORE_WARNINGS", $i);
Steven Rostedtc960bb92011-03-08 09:22:39 -05003020 $bisect_manual = set_test_option("BISECT_MANUAL", $i);
Steven Rostedtc23dca72011-03-08 09:26:31 -05003021 $bisect_skip = set_test_option("BISECT_SKIP", $i);
Steven Rostedt30f75da2011-06-13 10:35:35 -04003022 $config_bisect_good = set_test_option("CONFIG_BISECT_GOOD", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04003023 $store_failures = set_test_option("STORE_FAILURES", $i);
Steven Rostedt9064af52011-06-13 10:38:48 -04003024 $test_name = set_test_option("TEST_NAME", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04003025 $timeout = set_test_option("TIMEOUT", $i);
3026 $booted_timeout = set_test_option("BOOTED_TIMEOUT", $i);
3027 $console = set_test_option("CONSOLE", $i);
Steven Rostedtf1a5b962011-06-13 10:30:00 -04003028 $detect_triplefault = set_test_option("DETECT_TRIPLE_FAULT", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04003029 $success_line = set_test_option("SUCCESS_LINE", $i);
Steven Rostedt2b803362011-09-30 18:00:23 -04003030 $reboot_success_line = set_test_option("REBOOT_SUCCESS_LINE", $i);
Steven Rostedt1c8a6172010-11-09 12:55:40 -05003031 $stop_after_success = set_test_option("STOP_AFTER_SUCCESS", $i);
3032 $stop_after_failure = set_test_option("STOP_AFTER_FAILURE", $i);
Steven Rostedt2d01b262011-03-08 09:47:54 -05003033 $stop_test_after = set_test_option("STOP_TEST_AFTER", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04003034 $build_target = set_test_option("BUILD_TARGET", $i);
Steven Rostedte48c5292010-11-02 14:35:37 -04003035 $ssh_exec = set_test_option("SSH_EXEC", $i);
3036 $scp_to_target = set_test_option("SCP_TO_TARGET", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04003037 $target_image = set_test_option("TARGET_IMAGE", $i);
3038 $localversion = set_test_option("LOCALVERSION", $i);
3039
Steven Rostedt35ce5952011-07-15 21:57:25 -04003040 $start_minconfig_defined = 1;
3041
Steven Rostedt4c4ab122011-07-15 21:16:17 -04003042 if (!defined($start_minconfig)) {
Steven Rostedt35ce5952011-07-15 21:57:25 -04003043 $start_minconfig_defined = 0;
Steven Rostedt4c4ab122011-07-15 21:16:17 -04003044 $start_minconfig = $minconfig;
3045 }
3046
Steven Rostedta75fece2010-11-02 14:58:27 -04003047 chdir $builddir || die "can't change directory to $builddir";
3048
Andrew Jonesa908a662011-08-12 15:32:03 +02003049 foreach my $dir ($tmpdir, $outputdir) {
3050 if (!-d $dir) {
3051 mkpath($dir) or
3052 die "can't create $dir";
3053 }
Steven Rostedta75fece2010-11-02 14:58:27 -04003054 }
3055
Steven Rostedte48c5292010-11-02 14:35:37 -04003056 $ENV{"SSH_USER"} = $ssh_user;
3057 $ENV{"MACHINE"} = $machine;
3058
Steven Rostedta75fece2010-11-02 14:58:27 -04003059 $target = "$ssh_user\@$machine";
3060
3061 $buildlog = "$tmpdir/buildlog-$machine";
3062 $dmesg = "$tmpdir/dmesg-$machine";
3063 $make = "$makecmd O=$outputdir";
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05003064 $output_config = "$outputdir/.config";
Steven Rostedta75fece2010-11-02 14:58:27 -04003065
3066 if ($reboot_type eq "grub") {
Steven Rostedt576f6272010-11-02 14:58:38 -04003067 dodie "GRUB_MENU not defined" if (!defined($grub_menu));
Steven Rostedta75fece2010-11-02 14:58:27 -04003068 } elsif (!defined($reboot_script)) {
Steven Rostedt576f6272010-11-02 14:58:38 -04003069 dodie "REBOOT_SCRIPT not defined"
Steven Rostedta75fece2010-11-02 14:58:27 -04003070 }
3071
3072 my $run_type = $build_type;
3073 if ($test_type eq "patchcheck") {
3074 $run_type = $opt{"PATCHCHECK_TYPE[$i]"};
3075 } elsif ($test_type eq "bisect") {
3076 $run_type = $opt{"BISECT_TYPE[$i]"};
Steven Rostedt0a05c762010-11-08 11:14:10 -05003077 } elsif ($test_type eq "config_bisect") {
3078 $run_type = $opt{"CONFIG_BISECT_TYPE[$i]"};
Steven Rostedta75fece2010-11-02 14:58:27 -04003079 }
3080
Steven Rostedt4c4ab122011-07-15 21:16:17 -04003081 if ($test_type eq "make_min_config") {
3082 $run_type = "";
3083 }
3084
Steven Rostedta75fece2010-11-02 14:58:27 -04003085 # mistake in config file?
3086 if (!defined($run_type)) {
3087 $run_type = "ERROR";
3088 }
Steven Rostedt2545eb62010-11-02 15:01:32 -04003089
Steven Rostedte0a87422011-09-30 17:50:48 -04003090 my $installme = "";
3091 $installme = " no_install" if ($no_install);
3092
Steven Rostedt2545eb62010-11-02 15:01:32 -04003093 doprint "\n\n";
Steven Rostedte0a87422011-09-30 17:50:48 -04003094 doprint "RUNNING TEST $i of $opt{NUM_TESTS} with option $test_type $run_type$installme\n\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -04003095
3096 unlink $dmesg;
3097 unlink $buildlog;
Steven Rostedt2545eb62010-11-02 15:01:32 -04003098
Steven Rostedt250bae82011-07-15 22:05:59 -04003099 if (defined($addconfig)) {
3100 my $min = $minconfig;
3101 if (!defined($minconfig)) {
3102 $min = "";
3103 }
3104 run_command "cat $addconfig $min > $tmpdir/add_config" or
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04003105 dodie "Failed to create temp config";
Steven Rostedt9be2e6b2010-11-09 12:20:21 -05003106 $minconfig = "$tmpdir/add_config";
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04003107 }
3108
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04003109 my $checkout = $opt{"CHECKOUT[$i]"};
3110 if (defined($checkout)) {
3111 run_command "git checkout $checkout" or
3112 die "failed to checkout $checkout";
3113 }
3114
Steven Rostedt4ab1cce2011-09-30 18:12:20 -04003115 $no_reboot = 0;
3116
3117
Steven Rostedta75fece2010-11-02 14:58:27 -04003118 if ($test_type eq "bisect") {
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04003119 bisect $i;
3120 next;
Steven Rostedt0a05c762010-11-08 11:14:10 -05003121 } elsif ($test_type eq "config_bisect") {
3122 config_bisect $i;
3123 next;
Steven Rostedta75fece2010-11-02 14:58:27 -04003124 } elsif ($test_type eq "patchcheck") {
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04003125 patchcheck $i;
3126 next;
Steven Rostedt4c4ab122011-07-15 21:16:17 -04003127 } elsif ($test_type eq "make_min_config") {
3128 make_min_config $i;
3129 next;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04003130 }
3131
Steven Rostedt7faafbd2010-11-02 14:58:22 -04003132 if ($build_type ne "nobuild") {
3133 build $build_type or next;
Steven Rostedt2545eb62010-11-02 15:01:32 -04003134 }
3135
Steven Rostedtcd8e3682011-08-18 16:35:44 -04003136 if ($test_type eq "install") {
3137 get_version;
3138 install;
3139 success $i;
3140 next;
3141 }
3142
Steven Rostedta75fece2010-11-02 14:58:27 -04003143 if ($test_type ne "build") {
Steven Rostedta75fece2010-11-02 14:58:27 -04003144 my $failed = 0;
Steven Rostedtddf607e2011-06-14 20:49:13 -04003145 start_monitor_and_boot or $failed = 1;
Steven Rostedta75fece2010-11-02 14:58:27 -04003146
3147 if (!$failed && $test_type ne "boot" && defined($run_test)) {
3148 do_run_test or $failed = 1;
3149 }
3150 end_monitor;
3151 next if ($failed);
Steven Rostedt5a391fb2010-11-02 14:57:43 -04003152 }
3153
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04003154 success $i;
Steven Rostedt2545eb62010-11-02 15:01:32 -04003155}
3156
Steven Rostedt5c42fc52010-11-02 14:57:01 -04003157if ($opt{"POWEROFF_ON_SUCCESS"}) {
Steven Rostedt75c3fda72010-11-02 14:57:21 -04003158 halt;
Steven Rostedt576f6272010-11-02 14:58:38 -04003159} elsif ($opt{"REBOOT_ON_SUCCESS"} && !do_not_reboot) {
Steven Rostedt75c3fda72010-11-02 14:57:21 -04003160 reboot;
Steven Rostedt5c42fc52010-11-02 14:57:01 -04003161}
Steven Rostedt75c3fda72010-11-02 14:57:21 -04003162
Steven Rostedte48c5292010-11-02 14:35:37 -04003163doprint "\n $successes of $opt{NUM_TESTS} tests were successful\n\n";
3164
Steven Rostedt2545eb62010-11-02 15:01:32 -04003165exit 0;