blob: 62de47de2b04ce673900f3e8b8b6b73cb2f883cc [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 {
340 my ($lvalue, $rvalue) = @_;
341
342 if (defined($opt{$lvalue})) {
343 die "Error: Option $lvalue defined more than once!\n";
344 }
Steven Rostedt21a96792010-11-08 16:45:50 -0500345 if ($rvalue =~ /^\s*$/) {
346 delete $opt{$lvalue};
347 } else {
Steven Rostedt77d942c2011-05-20 13:36:58 -0400348 $rvalue = process_variables($rvalue);
Steven Rostedt21a96792010-11-08 16:45:50 -0500349 $opt{$lvalue} = $rvalue;
350 }
Steven Rostedta57419b2010-11-02 15:13:54 -0400351}
352
Steven Rostedt77d942c2011-05-20 13:36:58 -0400353sub set_variable {
354 my ($lvalue, $rvalue) = @_;
355
356 if ($rvalue =~ /^\s*$/) {
357 delete $variable{$lvalue};
358 } else {
359 $rvalue = process_variables($rvalue);
360 $variable{$lvalue} = $rvalue;
361 }
362}
363
Steven Rostedtab7a3f52011-09-30 20:24:07 -0400364sub process_compare {
365 my ($lval, $cmp, $rval) = @_;
366
367 # remove whitespace
368
369 $lval =~ s/^\s*//;
370 $lval =~ s/\s*$//;
371
372 $rval =~ s/^\s*//;
373 $rval =~ s/\s*$//;
374
375 if ($cmp eq "==") {
376 return $lval eq $rval;
377 } elsif ($cmp eq "!=") {
378 return $lval ne $rval;
379 }
380
381 my $statement = "$lval $cmp $rval";
382 my $ret = eval $statement;
383
384 # $@ stores error of eval
385 if ($@) {
386 return -1;
387 }
388
389 return $ret;
390}
391
Steven Rostedt45d73a52011-09-30 19:44:53 -0400392sub process_if {
393 my ($name, $value) = @_;
394
395 my $val = process_variables($value);
396
Steven Rostedtab7a3f52011-09-30 20:24:07 -0400397 if ($val =~ /(.*)(==|\!=|>=|<=|>|<)(.*)/) {
398 my $ret = process_compare($1, $2, $3);
399 if ($ret < 0) {
400 die "$name: $.: Unable to process comparison\n";
401 }
402 return $ret;
403 }
404
Steven Rostedt45d73a52011-09-30 19:44:53 -0400405 if ($val =~ /^\s*0\s*$/) {
406 return 0;
407 } elsif ($val =~ /^\s*\d+\s*$/) {
408 return 1;
409 }
410
411 die ("$name: $.: Undefined variable $val in if statement\n");
412 return 1;
413}
414
Steven Rostedt2ed3b162011-09-30 21:00:00 -0400415sub __read_config {
416 my ($config, $current_test_num) = @_;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400417
Steven Rostedt2ed3b162011-09-30 21:00:00 -0400418 my $in;
419 open($in, $config) || die "can't read file $config";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400420
Steven Rostedta57419b2010-11-02 15:13:54 -0400421 my $name = $config;
422 $name =~ s,.*/(.*),$1,;
423
Steven Rostedt2ed3b162011-09-30 21:00:00 -0400424 my $test_num = $$current_test_num;
Steven Rostedta57419b2010-11-02 15:13:54 -0400425 my $default = 1;
426 my $repeat = 1;
427 my $num_tests_set = 0;
428 my $skip = 0;
429 my $rest;
Steven Rostedt0df213c2011-06-14 20:51:37 -0400430 my $test_case = 0;
Steven Rostedt45d73a52011-09-30 19:44:53 -0400431 my $if = 0;
432 my $if_set = 0;
Steven Rostedta57419b2010-11-02 15:13:54 -0400433
Steven Rostedt2ed3b162011-09-30 21:00:00 -0400434 while (<$in>) {
Steven Rostedt2545eb62010-11-02 15:01:32 -0400435
436 # ignore blank lines and comments
437 next if (/^\s*$/ || /\s*\#/);
438
Steven Rostedta57419b2010-11-02 15:13:54 -0400439 if (/^\s*TEST_START(.*)/) {
440
441 $rest = $1;
442
443 if ($num_tests_set) {
444 die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
445 }
446
447 my $old_test_num = $test_num;
Steven Rostedte48c5292010-11-02 14:35:37 -0400448 my $old_repeat = $repeat;
Steven Rostedta57419b2010-11-02 15:13:54 -0400449
450 $test_num += $repeat;
451 $default = 0;
452 $repeat = 1;
453
Steven Rostedt45d73a52011-09-30 19:44:53 -0400454 if ($rest =~ /\s+SKIP\b(.*)/) {
Steven Rostedta57419b2010-11-02 15:13:54 -0400455 $rest = $1;
456 $skip = 1;
457 } else {
Steven Rostedt0df213c2011-06-14 20:51:37 -0400458 $test_case = 1;
Steven Rostedta57419b2010-11-02 15:13:54 -0400459 $skip = 0;
460 }
461
462 if ($rest =~ /\s+ITERATE\s+(\d+)(.*)$/) {
463 $repeat = $1;
464 $rest = $2;
465 $repeat_tests{"$test_num"} = $repeat;
466 }
467
Steven Rostedtab7a3f52011-09-30 20:24:07 -0400468 if ($rest =~ /\sIF\s+(.*)/) {
469 $rest = "";
Steven Rostedt45d73a52011-09-30 19:44:53 -0400470 if (process_if($name, $1)) {
471 $if_set = 1;
472 } else {
473 $skip = 1;
474 }
475 $if = 1;
476 } else {
477 $if = 0;
Steven Rostedta57419b2010-11-02 15:13:54 -0400478 }
479
480 if ($rest !~ /^\s*$/) {
481 die "$name: $.: Gargbage found after TEST_START\n$_";
482 }
483
484 if ($skip) {
485 $test_num = $old_test_num;
Steven Rostedte48c5292010-11-02 14:35:37 -0400486 $repeat = $old_repeat;
Steven Rostedta57419b2010-11-02 15:13:54 -0400487 }
488
489 } elsif (/^\s*DEFAULTS(.*)$/) {
490 $default = 1;
491
492 $rest = $1;
493
494 if ($rest =~ /\s+SKIP(.*)/) {
495 $rest = $1;
496 $skip = 1;
497 } else {
498 $skip = 0;
499 }
500
Steven Rostedtab7a3f52011-09-30 20:24:07 -0400501 if ($rest =~ /\sIF\s+(.*)/) {
Steven Rostedt45d73a52011-09-30 19:44:53 -0400502 $if = 1;
Steven Rostedt45d73a52011-09-30 19:44:53 -0400503 if (process_if($name, $1)) {
504 $if_set = 1;
505 } else {
506 $skip = 1;
507 }
Steven Rostedtab7a3f52011-09-30 20:24:07 -0400508 $rest = "";
Steven Rostedt45d73a52011-09-30 19:44:53 -0400509 } else {
510 $if = 0;
511 }
512
Steven Rostedta57419b2010-11-02 15:13:54 -0400513 if ($rest !~ /^\s*$/) {
514 die "$name: $.: Gargbage found after DEFAULTS\n$_";
515 }
516
Steven Rostedtab7a3f52011-09-30 20:24:07 -0400517 } elsif (/^\s*ELSE\b(.*)$/) {
Steven Rostedt45d73a52011-09-30 19:44:53 -0400518 if (!$if) {
519 die "$name: $.: ELSE found with out matching IF section\n$_";
520 }
521 $rest = $1;
522 if ($if_set) {
523 $skip = 1;
Steven Rostedtab7a3f52011-09-30 20:24:07 -0400524 $rest = "";
Steven Rostedt45d73a52011-09-30 19:44:53 -0400525 } else {
526 $skip = 0;
527
Steven Rostedtab7a3f52011-09-30 20:24:07 -0400528 if ($rest =~ /\sIF\s+(.*)/) {
Steven Rostedt45d73a52011-09-30 19:44:53 -0400529 # May be a ELSE IF section.
530 if (!process_if($name, $1)) {
531 $skip = 1;
532 }
Steven Rostedtab7a3f52011-09-30 20:24:07 -0400533 $rest = "";
Steven Rostedt45d73a52011-09-30 19:44:53 -0400534 } else {
535 $if = 0;
536 }
537 }
538
Steven Rostedtab7a3f52011-09-30 20:24:07 -0400539 if ($rest !~ /^\s*$/) {
540 die "$name: $.: Gargbage found after DEFAULTS\n$_";
541 }
542
Steven Rostedt2ed3b162011-09-30 21:00:00 -0400543 } elsif (/^\s*INCLUDE\s+(\S+)/) {
544
545 next if ($skip);
546
547 if (!$default) {
548 die "$name: $.: INCLUDE can only be done in default sections\n$_";
549 }
550
551 my $file = process_variables($1);
552
553 if ($file !~ m,^/,) {
554 # check the path of the config file first
555 if ($config =~ m,(.*)/,) {
556 if (-f "$1/$file") {
557 $file = "$1/$file";
558 }
559 }
560 }
561
562 if ( ! -r $file ) {
563 die "$name: $.: Can't read file $file\n$_";
564 }
565
566 if (__read_config($file, \$test_num)) {
567 $test_case = 1;
568 }
569
Steven Rostedta57419b2010-11-02 15:13:54 -0400570 } elsif (/^\s*([A-Z_\[\]\d]+)\s*=\s*(.*?)\s*$/) {
571
572 next if ($skip);
573
Steven Rostedt2545eb62010-11-02 15:01:32 -0400574 my $lvalue = $1;
575 my $rvalue = $2;
576
Steven Rostedta57419b2010-11-02 15:13:54 -0400577 if (!$default &&
578 ($lvalue eq "NUM_TESTS" ||
579 $lvalue eq "LOG_FILE" ||
580 $lvalue eq "CLEAR_LOG")) {
581 die "$name: $.: $lvalue must be set in DEFAULTS section\n";
Steven Rostedta75fece2010-11-02 14:58:27 -0400582 }
Steven Rostedta57419b2010-11-02 15:13:54 -0400583
584 if ($lvalue eq "NUM_TESTS") {
585 if ($test_num) {
586 die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
587 }
588 if (!$default) {
589 die "$name: $.: NUM_TESTS must be set in default section\n";
590 }
591 $num_tests_set = 1;
592 }
593
594 if ($default || $lvalue =~ /\[\d+\]$/) {
595 set_value($lvalue, $rvalue);
596 } else {
597 my $val = "$lvalue\[$test_num\]";
598 set_value($val, $rvalue);
599
600 if ($repeat > 1) {
601 $repeats{$val} = $repeat;
602 }
603 }
Steven Rostedt77d942c2011-05-20 13:36:58 -0400604 } elsif (/^\s*([A-Z_\[\]\d]+)\s*:=\s*(.*?)\s*$/) {
605 next if ($skip);
606
607 my $lvalue = $1;
608 my $rvalue = $2;
609
610 # process config variables.
611 # Config variables are only active while reading the
612 # config and can be defined anywhere. They also ignore
613 # TEST_START and DEFAULTS, but are skipped if they are in
614 # on of these sections that have SKIP defined.
615 # The save variable can be
616 # defined multiple times and the new one simply overrides
617 # the prevous one.
618 set_variable($lvalue, $rvalue);
619
Steven Rostedta57419b2010-11-02 15:13:54 -0400620 } else {
621 die "$name: $.: Garbage found in config\n$_";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400622 }
623 }
624
Steven Rostedta57419b2010-11-02 15:13:54 -0400625 if ($test_num) {
626 $test_num += $repeat - 1;
627 $opt{"NUM_TESTS"} = $test_num;
628 }
629
Steven Rostedt2ed3b162011-09-30 21:00:00 -0400630 close($in);
631
632 $$current_test_num = $test_num;
633
634 return $test_case;
635}
636
637sub read_config {
638 my ($config) = @_;
639
640 my $test_case;
641 my $test_num = 0;
642
643 $test_case = __read_config $config, \$test_num;
644
Steven Rostedt8d1491b2010-11-18 15:39:48 -0500645 # make sure we have all mandatory configs
646 get_ktest_configs;
647
Steven Rostedt0df213c2011-06-14 20:51:37 -0400648 # was a test specified?
649 if (!$test_case) {
650 print "No test case specified.\n";
651 print "What test case would you like to run?\n";
652 my $ans = <STDIN>;
653 chomp $ans;
654 $default{"TEST_TYPE"} = $ans;
655 }
656
Steven Rostedta75fece2010-11-02 14:58:27 -0400657 # set any defaults
658
659 foreach my $default (keys %default) {
660 if (!defined($opt{$default})) {
661 $opt{$default} = $default{$default};
662 }
663 }
Steven Rostedt2545eb62010-11-02 15:01:32 -0400664}
665
Steven Rostedt23715c3c2011-06-13 11:03:34 -0400666sub __eval_option {
667 my ($option, $i) = @_;
668
669 # Add space to evaluate the character before $
670 $option = " $option";
671 my $retval = "";
672
673 while ($option =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) {
674 my $start = $1;
675 my $var = $2;
676 my $end = $3;
677
678 # Append beginning of line
679 $retval = "$retval$start";
680
681 # If the iteration option OPT[$i] exists, then use that.
682 # otherwise see if the default OPT (without [$i]) exists.
683
684 my $o = "$var\[$i\]";
685
686 if (defined($opt{$o})) {
687 $o = $opt{$o};
688 $retval = "$retval$o";
689 } elsif (defined($opt{$var})) {
690 $o = $opt{$var};
691 $retval = "$retval$o";
692 } else {
693 $retval = "$retval\$\{$var\}";
694 }
695
696 $option = $end;
697 }
698
699 $retval = "$retval$option";
700
701 $retval =~ s/^ //;
702
703 return $retval;
704}
705
706sub eval_option {
707 my ($option, $i) = @_;
708
709 my $prev = "";
710
711 # Since an option can evaluate to another option,
712 # keep iterating until we do not evaluate any more
713 # options.
714 my $r = 0;
715 while ($prev ne $option) {
716 # Check for recursive evaluations.
717 # 100 deep should be more than enough.
718 if ($r++ > 100) {
719 die "Over 100 evaluations accurred with $option\n" .
720 "Check for recursive variables\n";
721 }
722 $prev = $option;
723 $option = __eval_option($option, $i);
724 }
725
726 return $option;
727}
728
Steven Rostedtd1e2f222010-11-08 16:39:57 -0500729sub _logit {
Steven Rostedt2545eb62010-11-02 15:01:32 -0400730 if (defined($opt{"LOG_FILE"})) {
731 open(OUT, ">> $opt{LOG_FILE}") or die "Can't write to $opt{LOG_FILE}";
732 print OUT @_;
733 close(OUT);
734 }
735}
736
Steven Rostedtd1e2f222010-11-08 16:39:57 -0500737sub logit {
738 if (defined($opt{"LOG_FILE"})) {
739 _logit @_;
740 } else {
741 print @_;
742 }
743}
744
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400745sub doprint {
746 print @_;
Steven Rostedtd1e2f222010-11-08 16:39:57 -0500747 _logit @_;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400748}
749
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400750sub run_command;
Andrew Jones2728be42011-08-12 15:32:05 +0200751sub start_monitor;
752sub end_monitor;
753sub wait_for_monitor;
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400754
755sub reboot {
Andrew Jones2728be42011-08-12 15:32:05 +0200756 my ($time) = @_;
757
Steven Rostedt2b803362011-09-30 18:00:23 -0400758 if (defined($time)) {
759 start_monitor;
760 # flush out current monitor
761 # May contain the reboot success line
762 wait_for_monitor 1;
763 }
764
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400765 # try to reboot normally
Steven Rostedte48c5292010-11-02 14:35:37 -0400766 if (run_command $reboot) {
Steven Rostedt576f6272010-11-02 14:58:38 -0400767 if (defined($powercycle_after_reboot)) {
768 sleep $powercycle_after_reboot;
769 run_command "$power_cycle";
770 }
771 } else {
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400772 # nope? power cycle it.
Steven Rostedta75fece2010-11-02 14:58:27 -0400773 run_command "$power_cycle";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400774 }
Andrew Jones2728be42011-08-12 15:32:05 +0200775
776 if (defined($time)) {
Steven Rostedt2b803362011-09-30 18:00:23 -0400777 wait_for_monitor($time, $reboot_success_line);
Andrew Jones2728be42011-08-12 15:32:05 +0200778 end_monitor;
779 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400780}
781
Steven Rostedt576f6272010-11-02 14:58:38 -0400782sub do_not_reboot {
783 my $i = $iteration;
784
Steven Rostedt4ab1cce2011-09-30 18:12:20 -0400785 return $test_type eq "build" || $no_reboot ||
Steven Rostedt576f6272010-11-02 14:58:38 -0400786 ($test_type eq "patchcheck" && $opt{"PATCHCHECK_TYPE[$i]"} eq "build") ||
787 ($test_type eq "bisect" && $opt{"BISECT_TYPE[$i]"} eq "build");
788}
789
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400790sub dodie {
Steven Rostedt5a391fb2010-11-02 14:57:43 -0400791 doprint "CRITICAL FAILURE... ", @_, "\n";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400792
Steven Rostedt576f6272010-11-02 14:58:38 -0400793 my $i = $iteration;
794
795 if ($reboot_on_error && !do_not_reboot) {
796
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400797 doprint "REBOOTING\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400798 reboot;
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400799
Steven Rostedta75fece2010-11-02 14:58:27 -0400800 } elsif ($poweroff_on_error && defined($power_off)) {
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400801 doprint "POWERING OFF\n";
Steven Rostedta75fece2010-11-02 14:58:27 -0400802 `$power_off`;
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400803 }
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400804
Steven Rostedtf80802c2011-03-07 13:18:47 -0500805 if (defined($opt{"LOG_FILE"})) {
806 print " See $opt{LOG_FILE} for more info.\n";
807 }
808
Steven Rostedt576f6272010-11-02 14:58:38 -0400809 die @_, "\n";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400810}
811
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400812sub open_console {
813 my ($fp) = @_;
814
815 my $flags;
816
Steven Rostedta75fece2010-11-02 14:58:27 -0400817 my $pid = open($fp, "$console|") or
818 dodie "Can't open console $console";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400819
820 $flags = fcntl($fp, F_GETFL, 0) or
Steven Rostedt576f6272010-11-02 14:58:38 -0400821 dodie "Can't get flags for the socket: $!";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400822 $flags = fcntl($fp, F_SETFL, $flags | O_NONBLOCK) or
Steven Rostedt576f6272010-11-02 14:58:38 -0400823 dodie "Can't set flags for the socket: $!";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400824
825 return $pid;
826}
827
828sub close_console {
829 my ($fp, $pid) = @_;
830
831 doprint "kill child process $pid\n";
832 kill 2, $pid;
833
834 print "closing!\n";
835 close($fp);
836}
837
838sub start_monitor {
839 if ($monitor_cnt++) {
840 return;
841 }
842 $monitor_fp = \*MONFD;
843 $monitor_pid = open_console $monitor_fp;
Steven Rostedta75fece2010-11-02 14:58:27 -0400844
845 return;
846
847 open(MONFD, "Stop perl from warning about single use of MONFD");
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400848}
849
850sub end_monitor {
851 if (--$monitor_cnt) {
852 return;
853 }
854 close_console($monitor_fp, $monitor_pid);
855}
856
857sub wait_for_monitor {
Steven Rostedt2b803362011-09-30 18:00:23 -0400858 my ($time, $stop) = @_;
859 my $full_line = "";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400860 my $line;
Steven Rostedt2b803362011-09-30 18:00:23 -0400861 my $booted = 0;
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400862
Steven Rostedta75fece2010-11-02 14:58:27 -0400863 doprint "** Wait for monitor to settle down **\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400864
865 # read the monitor and wait for the system to calm down
Steven Rostedt2b803362011-09-30 18:00:23 -0400866 while (!$booted) {
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400867 $line = wait_for_input($monitor_fp, $time);
Steven Rostedt2b803362011-09-30 18:00:23 -0400868 last if (!defined($line));
869 print "$line";
870 $full_line .= $line;
871
872 if (defined($stop) && $full_line =~ /$stop/) {
873 doprint "wait for monitor detected $stop\n";
874 $booted = 1;
875 }
876
877 if ($line =~ /\n/) {
878 $full_line = "";
879 }
880 }
Steven Rostedta75fece2010-11-02 14:58:27 -0400881 print "** Monitor flushed **\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400882}
883
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400884sub fail {
885
Steven Rostedta75fece2010-11-02 14:58:27 -0400886 if ($die_on_failure) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400887 dodie @_;
888 }
889
Steven Rostedta75fece2010-11-02 14:58:27 -0400890 doprint "FAILED\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400891
Steven Rostedt576f6272010-11-02 14:58:38 -0400892 my $i = $iteration;
893
Steven Rostedta75fece2010-11-02 14:58:27 -0400894 # no need to reboot for just building.
Steven Rostedt576f6272010-11-02 14:58:38 -0400895 if (!do_not_reboot) {
Steven Rostedta75fece2010-11-02 14:58:27 -0400896 doprint "REBOOTING\n";
Andrew Jones2728be42011-08-12 15:32:05 +0200897 reboot $sleep_time;
Steven Rostedta75fece2010-11-02 14:58:27 -0400898 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400899
Steven Rostedt9064af52011-06-13 10:38:48 -0400900 my $name = "";
901
902 if (defined($test_name)) {
903 $name = " ($test_name)";
904 }
905
Steven Rostedt576f6272010-11-02 14:58:38 -0400906 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
907 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
Steven Rostedt9064af52011-06-13 10:38:48 -0400908 doprint "KTEST RESULT: TEST $i$name Failed: ", @_, "\n";
Steven Rostedt576f6272010-11-02 14:58:38 -0400909 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
910 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
Steven Rostedta75fece2010-11-02 14:58:27 -0400911
912 return 1 if (!defined($store_failures));
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400913
914 my @t = localtime;
915 my $date = sprintf "%04d%02d%02d%02d%02d%02d",
916 1900+$t[5],$t[4],$t[3],$t[2],$t[1],$t[0];
917
Steven Rostedtcccae1a2010-11-09 12:21:32 -0500918 my $type = $build_type;
919 if ($type =~ /useconfig/) {
920 $type = "useconfig";
921 }
922
923 my $dir = "$machine-$test_type-$type-fail-$date";
Steven Rostedta75fece2010-11-02 14:58:27 -0400924 my $faildir = "$store_failures/$dir";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400925
926 if (!-d $faildir) {
927 mkpath($faildir) or
Steven Rostedta75fece2010-11-02 14:58:27 -0400928 die "can't create $faildir";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400929 }
Steven Rostedt51ad1dd2010-11-08 16:43:21 -0500930 if (-f "$output_config") {
931 cp "$output_config", "$faildir/config" or
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400932 die "failed to copy .config";
933 }
934 if (-f $buildlog) {
935 cp $buildlog, "$faildir/buildlog" or
936 die "failed to move $buildlog";
937 }
938 if (-f $dmesg) {
939 cp $dmesg, "$faildir/dmesg" or
940 die "failed to move $dmesg";
941 }
942
943 doprint "*** Saved info to $faildir ***\n";
944
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400945 return 1;
946}
947
Steven Rostedt2545eb62010-11-02 15:01:32 -0400948sub run_command {
949 my ($command) = @_;
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400950 my $dolog = 0;
951 my $dord = 0;
952 my $pid;
953
Steven Rostedte48c5292010-11-02 14:35:37 -0400954 $command =~ s/\$SSH_USER/$ssh_user/g;
955 $command =~ s/\$MACHINE/$machine/g;
956
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400957 doprint("$command ... ");
958
959 $pid = open(CMD, "$command 2>&1 |") or
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400960 (fail "unable to exec $command" and return 0);
Steven Rostedt2545eb62010-11-02 15:01:32 -0400961
962 if (defined($opt{"LOG_FILE"})) {
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400963 open(LOG, ">>$opt{LOG_FILE}") or
964 dodie "failed to write to log";
965 $dolog = 1;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -0400966 }
967
968 if (defined($redirect)) {
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400969 open (RD, ">$redirect") or
970 dodie "failed to write to redirect $redirect";
971 $dord = 1;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400972 }
973
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400974 while (<CMD>) {
975 print LOG if ($dolog);
976 print RD if ($dord);
977 }
Steven Rostedt2545eb62010-11-02 15:01:32 -0400978
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400979 waitpid($pid, 0);
Steven Rostedt2545eb62010-11-02 15:01:32 -0400980 my $failed = $?;
981
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400982 close(CMD);
983 close(LOG) if ($dolog);
984 close(RD) if ($dord);
985
Steven Rostedt2545eb62010-11-02 15:01:32 -0400986 if ($failed) {
987 doprint "FAILED!\n";
988 } else {
989 doprint "SUCCESS\n";
990 }
991
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400992 return !$failed;
993}
994
Steven Rostedte48c5292010-11-02 14:35:37 -0400995sub run_ssh {
996 my ($cmd) = @_;
997 my $cp_exec = $ssh_exec;
998
999 $cp_exec =~ s/\$SSH_COMMAND/$cmd/g;
1000 return run_command "$cp_exec";
1001}
1002
1003sub run_scp {
1004 my ($src, $dst) = @_;
1005 my $cp_scp = $scp_to_target;
1006
1007 $cp_scp =~ s/\$SRC_FILE/$src/g;
1008 $cp_scp =~ s/\$DST_FILE/$dst/g;
1009
1010 return run_command "$cp_scp";
1011}
1012
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001013sub get_grub_index {
1014
Steven Rostedta75fece2010-11-02 14:58:27 -04001015 if ($reboot_type ne "grub") {
1016 return;
1017 }
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001018 return if (defined($grub_number));
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001019
1020 doprint "Find grub menu ... ";
1021 $grub_number = -1;
Steven Rostedte48c5292010-11-02 14:35:37 -04001022
1023 my $ssh_grub = $ssh_exec;
1024 $ssh_grub =~ s,\$SSH_COMMAND,cat /boot/grub/menu.lst,g;
1025
1026 open(IN, "$ssh_grub |")
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001027 or die "unable to get menu.lst";
Steven Rostedte48c5292010-11-02 14:35:37 -04001028
Steven Rostedteaa1fe22011-09-14 17:20:39 -04001029 my $found = 0;
1030
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001031 while (<IN>) {
Steven Rostedta75fece2010-11-02 14:58:27 -04001032 if (/^\s*title\s+$grub_menu\s*$/) {
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001033 $grub_number++;
Steven Rostedteaa1fe22011-09-14 17:20:39 -04001034 $found = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001035 last;
1036 } elsif (/^\s*title\s/) {
1037 $grub_number++;
1038 }
1039 }
1040 close(IN);
1041
Steven Rostedta75fece2010-11-02 14:58:27 -04001042 die "Could not find '$grub_menu' in /boot/grub/menu on $machine"
Steven Rostedteaa1fe22011-09-14 17:20:39 -04001043 if (!$found);
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001044 doprint "$grub_number\n";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001045}
1046
Steven Rostedt2545eb62010-11-02 15:01:32 -04001047sub wait_for_input
1048{
1049 my ($fp, $time) = @_;
1050 my $rin;
1051 my $ready;
1052 my $line;
1053 my $ch;
1054
1055 if (!defined($time)) {
1056 $time = $timeout;
1057 }
1058
1059 $rin = '';
1060 vec($rin, fileno($fp), 1) = 1;
1061 $ready = select($rin, undef, undef, $time);
1062
1063 $line = "";
1064
1065 # try to read one char at a time
1066 while (sysread $fp, $ch, 1) {
1067 $line .= $ch;
1068 last if ($ch eq "\n");
1069 }
1070
1071 if (!length($line)) {
1072 return undef;
1073 }
1074
1075 return $line;
1076}
1077
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001078sub reboot_to {
Steven Rostedta75fece2010-11-02 14:58:27 -04001079 if ($reboot_type eq "grub") {
Steven Rostedt4da46da2011-06-01 23:25:13 -04001080 run_ssh "'(echo \"savedefault --default=$grub_number --once\" | grub --batch && reboot)'";
Steven Rostedta75fece2010-11-02 14:58:27 -04001081 return;
1082 }
1083
1084 run_command "$reboot_script";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001085}
1086
Steven Rostedta57419b2010-11-02 15:13:54 -04001087sub get_sha1 {
1088 my ($commit) = @_;
1089
1090 doprint "git rev-list --max-count=1 $commit ... ";
1091 my $sha1 = `git rev-list --max-count=1 $commit`;
1092 my $ret = $?;
1093
1094 logit $sha1;
1095
1096 if ($ret) {
1097 doprint "FAILED\n";
1098 dodie "Failed to get git $commit";
1099 }
1100
1101 print "SUCCESS\n";
1102
1103 chomp $sha1;
1104
1105 return $sha1;
1106}
1107
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001108sub monitor {
Steven Rostedt2545eb62010-11-02 15:01:32 -04001109 my $booted = 0;
1110 my $bug = 0;
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001111 my $skip_call_trace = 0;
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001112 my $loops;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001113
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001114 wait_for_monitor 5;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001115
1116 my $line;
1117 my $full_line = "";
1118
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001119 open(DMESG, "> $dmesg") or
1120 die "unable to write to $dmesg";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001121
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001122 reboot_to;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001123
Steven Rostedt1c8a6172010-11-09 12:55:40 -05001124 my $success_start;
1125 my $failure_start;
Steven Rostedt2d01b262011-03-08 09:47:54 -05001126 my $monitor_start = time;
1127 my $done = 0;
Steven Rostedtf1a5b962011-06-13 10:30:00 -04001128 my $version_found = 0;
Steven Rostedt1c8a6172010-11-09 12:55:40 -05001129
Steven Rostedt2d01b262011-03-08 09:47:54 -05001130 while (!$done) {
Steven Rostedt2545eb62010-11-02 15:01:32 -04001131
Steven Rostedtecaf8e52011-06-13 10:48:10 -04001132 if ($bug && defined($stop_after_failure) &&
1133 $stop_after_failure >= 0) {
1134 my $time = $stop_after_failure - (time - $failure_start);
1135 $line = wait_for_input($monitor_fp, $time);
1136 if (!defined($line)) {
1137 doprint "bug timed out after $booted_timeout seconds\n";
1138 doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
1139 last;
1140 }
1141 } elsif ($booted) {
Steven Rostedta75fece2010-11-02 14:58:27 -04001142 $line = wait_for_input($monitor_fp, $booted_timeout);
Steven Rostedtcd4f1d52011-06-13 10:26:27 -04001143 if (!defined($line)) {
1144 my $s = $booted_timeout == 1 ? "" : "s";
1145 doprint "Successful boot found: break after $booted_timeout second$s\n";
1146 last;
1147 }
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001148 } else {
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001149 $line = wait_for_input($monitor_fp);
Steven Rostedtcd4f1d52011-06-13 10:26:27 -04001150 if (!defined($line)) {
1151 my $s = $timeout == 1 ? "" : "s";
1152 doprint "Timed out after $timeout second$s\n";
1153 last;
1154 }
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001155 }
Steven Rostedt2545eb62010-11-02 15:01:32 -04001156
Steven Rostedt2545eb62010-11-02 15:01:32 -04001157 doprint $line;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001158 print DMESG $line;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001159
1160 # we are not guaranteed to get a full line
1161 $full_line .= $line;
1162
Steven Rostedta75fece2010-11-02 14:58:27 -04001163 if ($full_line =~ /$success_line/) {
Steven Rostedt2545eb62010-11-02 15:01:32 -04001164 $booted = 1;
Steven Rostedt1c8a6172010-11-09 12:55:40 -05001165 $success_start = time;
1166 }
1167
1168 if ($booted && defined($stop_after_success) &&
1169 $stop_after_success >= 0) {
1170 my $now = time;
1171 if ($now - $success_start >= $stop_after_success) {
1172 doprint "Test forced to stop after $stop_after_success seconds after success\n";
1173 last;
1174 }
Steven Rostedt2545eb62010-11-02 15:01:32 -04001175 }
1176
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001177 if ($full_line =~ /\[ backtrace testing \]/) {
1178 $skip_call_trace = 1;
1179 }
1180
Steven Rostedt2545eb62010-11-02 15:01:32 -04001181 if ($full_line =~ /call trace:/i) {
Steven Rostedt46519202011-03-08 09:40:31 -05001182 if (!$bug && !$skip_call_trace) {
Steven Rostedt1c8a6172010-11-09 12:55:40 -05001183 $bug = 1;
1184 $failure_start = time;
1185 }
1186 }
1187
1188 if ($bug && defined($stop_after_failure) &&
1189 $stop_after_failure >= 0) {
1190 my $now = time;
1191 if ($now - $failure_start >= $stop_after_failure) {
1192 doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
1193 last;
1194 }
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001195 }
1196
1197 if ($full_line =~ /\[ end of backtrace testing \]/) {
1198 $skip_call_trace = 0;
1199 }
1200
1201 if ($full_line =~ /Kernel panic -/) {
Steven Rostedt10abf112011-03-07 13:21:00 -05001202 $failure_start = time;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001203 $bug = 1;
1204 }
1205
Steven Rostedtf1a5b962011-06-13 10:30:00 -04001206 # Detect triple faults by testing the banner
1207 if ($full_line =~ /\bLinux version (\S+).*\n/) {
1208 if ($1 eq $version) {
1209 $version_found = 1;
1210 } elsif ($version_found && $detect_triplefault) {
1211 # We already booted into the kernel we are testing,
1212 # but now we booted into another kernel?
1213 # Consider this a triple fault.
1214 doprint "Aleady booted in Linux kernel $version, but now\n";
1215 doprint "we booted into Linux kernel $1.\n";
1216 doprint "Assuming that this is a triple fault.\n";
1217 doprint "To disable this: set DETECT_TRIPLE_FAULT to 0\n";
1218 last;
1219 }
1220 }
1221
Steven Rostedt2545eb62010-11-02 15:01:32 -04001222 if ($line =~ /\n/) {
1223 $full_line = "";
1224 }
Steven Rostedt2d01b262011-03-08 09:47:54 -05001225
1226 if ($stop_test_after > 0 && !$booted && !$bug) {
1227 if (time - $monitor_start > $stop_test_after) {
Steven Rostedt4d62bf52011-05-20 09:14:35 -04001228 doprint "STOP_TEST_AFTER ($stop_test_after seconds) timed out\n";
Steven Rostedt2d01b262011-03-08 09:47:54 -05001229 $done = 1;
1230 }
1231 }
Steven Rostedt2545eb62010-11-02 15:01:32 -04001232 }
1233
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001234 close(DMESG);
Steven Rostedt2545eb62010-11-02 15:01:32 -04001235
Steven Rostedt2545eb62010-11-02 15:01:32 -04001236 if ($bug) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001237 return 0 if ($in_bisect);
Steven Rostedt576f6272010-11-02 14:58:38 -04001238 fail "failed - got a bug report" and return 0;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001239 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001240
Steven Rostedta75fece2010-11-02 14:58:27 -04001241 if (!$booted) {
1242 return 0 if ($in_bisect);
Steven Rostedt576f6272010-11-02 14:58:38 -04001243 fail "failed - never got a boot prompt." and return 0;
Steven Rostedta75fece2010-11-02 14:58:27 -04001244 }
1245
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001246 return 1;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001247}
1248
Steven Rostedtdb05cfe2011-06-13 11:09:22 -04001249sub do_post_install {
1250
1251 return if (!defined($post_install));
1252
1253 my $cp_post_install = $post_install;
1254 $cp_post_install =~ s/\$KERNEL_VERSION/$version/g;
1255 run_command "$cp_post_install" or
1256 dodie "Failed to run post install";
1257}
1258
Steven Rostedt2545eb62010-11-02 15:01:32 -04001259sub install {
1260
Steven Rostedte0a87422011-09-30 17:50:48 -04001261 return if ($no_install);
1262
Steven Rostedte48c5292010-11-02 14:35:37 -04001263 run_scp "$outputdir/$build_target", "$target_image" or
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001264 dodie "failed to copy image";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001265
1266 my $install_mods = 0;
1267
1268 # should we process modules?
1269 $install_mods = 0;
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05001270 open(IN, "$output_config") or dodie("Can't read config file");
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001271 while (<IN>) {
1272 if (/CONFIG_MODULES(=y)?/) {
1273 $install_mods = 1 if (defined($1));
1274 last;
1275 }
1276 }
1277 close(IN);
1278
1279 if (!$install_mods) {
Steven Rostedtdb05cfe2011-06-13 11:09:22 -04001280 do_post_install;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001281 doprint "No modules needed\n";
1282 return;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001283 }
1284
Steven Rostedta75fece2010-11-02 14:58:27 -04001285 run_command "$make INSTALL_MOD_PATH=$tmpdir modules_install" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001286 dodie "Failed to install modules";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001287
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001288 my $modlib = "/lib/modules/$version";
Steven Rostedta57419b2010-11-02 15:13:54 -04001289 my $modtar = "ktest-mods.tar.bz2";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001290
Steven Rostedte48c5292010-11-02 14:35:37 -04001291 run_ssh "rm -rf $modlib" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001292 dodie "failed to remove old mods: $modlib";
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001293
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001294 # would be nice if scp -r did not follow symbolic links
Steven Rostedta75fece2010-11-02 14:58:27 -04001295 run_command "cd $tmpdir && tar -cjf $modtar lib/modules/$version" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001296 dodie "making tarball";
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001297
Steven Rostedte48c5292010-11-02 14:35:37 -04001298 run_scp "$tmpdir/$modtar", "/tmp" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001299 dodie "failed to copy modules";
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001300
Steven Rostedta75fece2010-11-02 14:58:27 -04001301 unlink "$tmpdir/$modtar";
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001302
Steven Rostedte7b13442011-06-14 20:44:36 -04001303 run_ssh "'(cd / && tar xjf /tmp/$modtar)'" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001304 dodie "failed to tar modules";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001305
Steven Rostedte48c5292010-11-02 14:35:37 -04001306 run_ssh "rm -f /tmp/$modtar";
Steven Rostedt8b37ca82010-11-02 14:58:33 -04001307
Steven Rostedtdb05cfe2011-06-13 11:09:22 -04001308 do_post_install;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001309}
1310
Steven Rostedtddf607e2011-06-14 20:49:13 -04001311sub get_version {
1312 # get the release name
1313 doprint "$make kernelrelease ... ";
1314 $version = `$make kernelrelease | tail -1`;
1315 chomp($version);
1316 doprint "$version\n";
1317}
1318
1319sub start_monitor_and_boot {
1320 get_grub_index;
1321 get_version;
1322 install;
1323
1324 start_monitor;
1325 return monitor;
1326}
1327
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001328sub check_buildlog {
1329 my ($patch) = @_;
1330
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001331 my @files = `git show $patch | diffstat -l`;
1332
1333 open(IN, "git show $patch |") or
1334 dodie "failed to show $patch";
1335 while (<IN>) {
1336 if (m,^--- a/(.*),) {
1337 chomp $1;
1338 $files[$#files] = $1;
1339 }
1340 }
1341 close(IN);
1342
1343 open(IN, $buildlog) or dodie "Can't open $buildlog";
1344 while (<IN>) {
1345 if (/^\s*(.*?):.*(warning|error)/) {
1346 my $err = $1;
1347 foreach my $file (@files) {
Steven Rostedta75fece2010-11-02 14:58:27 -04001348 my $fullpath = "$builddir/$file";
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001349 if ($file eq $err || $fullpath eq $err) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001350 fail "$file built with warnings" and return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001351 }
1352 }
1353 }
1354 }
1355 close(IN);
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001356
1357 return 1;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001358}
1359
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001360sub apply_min_config {
1361 my $outconfig = "$output_config.new";
Steven Rostedt612b9e92011-03-07 13:27:43 -05001362
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001363 # Read the config file and remove anything that
1364 # is in the force_config hash (from minconfig and others)
1365 # then add the force config back.
1366
1367 doprint "Applying minimum configurations into $output_config.new\n";
1368
1369 open (OUT, ">$outconfig") or
1370 dodie "Can't create $outconfig";
1371
1372 if (-f $output_config) {
1373 open (IN, $output_config) or
1374 dodie "Failed to open $output_config";
1375 while (<IN>) {
1376 if (/^(# )?(CONFIG_[^\s=]*)/) {
1377 next if (defined($force_config{$2}));
1378 }
1379 print OUT;
1380 }
1381 close IN;
1382 }
1383 foreach my $config (keys %force_config) {
1384 print OUT "$force_config{$config}\n";
1385 }
1386 close OUT;
1387
1388 run_command "mv $outconfig $output_config";
1389}
1390
1391sub make_oldconfig {
1392
Steven Rostedt4c4ab122011-07-15 21:16:17 -04001393 my @force_list = keys %force_config;
1394
1395 if ($#force_list >= 0) {
1396 apply_min_config;
1397 }
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001398
1399 if (!run_command "$make oldnoconfig") {
Steven Rostedt612b9e92011-03-07 13:27:43 -05001400 # Perhaps oldnoconfig doesn't exist in this version of the kernel
1401 # try a yes '' | oldconfig
1402 doprint "oldnoconfig failed, trying yes '' | make oldconfig\n";
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001403 run_command "yes '' | $make oldconfig" or
Steven Rostedt612b9e92011-03-07 13:27:43 -05001404 dodie "failed make config oldconfig";
1405 }
1406}
1407
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001408# read a config file and use this to force new configs.
1409sub load_force_config {
1410 my ($config) = @_;
1411
1412 open(IN, $config) or
1413 dodie "failed to read $config";
1414 while (<IN>) {
1415 chomp;
1416 if (/^(CONFIG[^\s=]*)(\s*=.*)/) {
1417 $force_config{$1} = $_;
1418 } elsif (/^# (CONFIG_\S*) is not set/) {
1419 $force_config{$1} = $_;
1420 }
1421 }
1422 close IN;
1423}
1424
Steven Rostedt2545eb62010-11-02 15:01:32 -04001425sub build {
1426 my ($type) = @_;
1427
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001428 unlink $buildlog;
1429
Steven Rostedt4ab1cce2011-09-30 18:12:20 -04001430 # Failed builds should not reboot the target
1431 my $save_no_reboot = $no_reboot;
1432 $no_reboot = 1;
1433
Steven Rostedt0bd6c1a2011-06-14 20:39:31 -04001434 if (defined($pre_build)) {
1435 my $ret = run_command $pre_build;
1436 if (!$ret && defined($pre_build_die) &&
1437 $pre_build_die) {
1438 dodie "failed to pre_build\n";
1439 }
1440 }
1441
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001442 if ($type =~ /^useconfig:(.*)/) {
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05001443 run_command "cp $1 $output_config" or
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001444 dodie "could not copy $1 to .config";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001445
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001446 $type = "oldconfig";
1447 }
1448
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001449 # old config can ask questions
1450 if ($type eq "oldconfig") {
Steven Rostedt9386c6a2010-11-08 16:35:48 -05001451 $type = "oldnoconfig";
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001452
1453 # allow for empty configs
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05001454 run_command "touch $output_config";
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001455
Andrew Jones13488232011-08-12 15:32:04 +02001456 if (!$noclean) {
1457 run_command "mv $output_config $outputdir/config_temp" or
1458 dodie "moving .config";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001459
Andrew Jones13488232011-08-12 15:32:04 +02001460 run_command "$make mrproper" or dodie "make mrproper";
1461
1462 run_command "mv $outputdir/config_temp $output_config" or
1463 dodie "moving config_temp";
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001464 }
1465
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001466 } elsif (!$noclean) {
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05001467 unlink "$output_config";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001468 run_command "$make mrproper" or
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001469 dodie "make mrproper";
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001470 }
Steven Rostedt2545eb62010-11-02 15:01:32 -04001471
1472 # add something to distinguish this build
Steven Rostedta75fece2010-11-02 14:58:27 -04001473 open(OUT, "> $outputdir/localversion") or dodie("Can't make localversion file");
1474 print OUT "$localversion\n";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001475 close(OUT);
1476
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001477 if (defined($minconfig)) {
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001478 load_force_config($minconfig);
Steven Rostedt2545eb62010-11-02 15:01:32 -04001479 }
1480
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001481 if ($type ne "oldnoconfig") {
1482 run_command "$make $type" or
Steven Rostedt612b9e92011-03-07 13:27:43 -05001483 dodie "failed make config";
1484 }
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001485 # Run old config regardless, to enforce min configurations
1486 make_oldconfig;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001487
Steven Rostedta75fece2010-11-02 14:58:27 -04001488 $redirect = "$buildlog";
Steven Rostedt0bd6c1a2011-06-14 20:39:31 -04001489 my $build_ret = run_command "$make $build_options";
1490 undef $redirect;
1491
1492 if (defined($post_build)) {
1493 my $ret = run_command $post_build;
1494 if (!$ret && defined($post_build_die) &&
1495 $post_build_die) {
1496 dodie "failed to post_build\n";
1497 }
1498 }
1499
1500 if (!$build_ret) {
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001501 # bisect may need this to pass
Steven Rostedt4ab1cce2011-09-30 18:12:20 -04001502 if ($in_bisect) {
1503 $no_reboot = $save_no_reboot;
1504 return 0;
1505 }
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001506 fail "failed build" and return 0;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001507 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001508
Steven Rostedt4ab1cce2011-09-30 18:12:20 -04001509 $no_reboot = $save_no_reboot;
1510
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001511 return 1;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001512}
1513
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001514sub halt {
Steven Rostedte48c5292010-11-02 14:35:37 -04001515 if (!run_ssh "halt" or defined($power_off)) {
Steven Rostedt576f6272010-11-02 14:58:38 -04001516 if (defined($poweroff_after_halt)) {
1517 sleep $poweroff_after_halt;
1518 run_command "$power_off";
1519 }
1520 } else {
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001521 # nope? the zap it!
Steven Rostedta75fece2010-11-02 14:58:27 -04001522 run_command "$power_off";
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001523 }
1524}
1525
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001526sub success {
1527 my ($i) = @_;
1528
Steven Rostedte48c5292010-11-02 14:35:37 -04001529 $successes++;
1530
Steven Rostedt9064af52011-06-13 10:38:48 -04001531 my $name = "";
1532
1533 if (defined($test_name)) {
1534 $name = " ($test_name)";
1535 }
1536
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001537 doprint "\n\n*******************************************\n";
1538 doprint "*******************************************\n";
Steven Rostedt9064af52011-06-13 10:38:48 -04001539 doprint "KTEST RESULT: TEST $i$name SUCCESS!!!! **\n";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001540 doprint "*******************************************\n";
1541 doprint "*******************************************\n";
1542
Steven Rostedt576f6272010-11-02 14:58:38 -04001543 if ($i != $opt{"NUM_TESTS"} && !do_not_reboot) {
Steven Rostedta75fece2010-11-02 14:58:27 -04001544 doprint "Reboot and wait $sleep_time seconds\n";
Andrew Jones2728be42011-08-12 15:32:05 +02001545 reboot $sleep_time;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001546 }
1547}
1548
Steven Rostedtc960bb92011-03-08 09:22:39 -05001549sub answer_bisect {
1550 for (;;) {
1551 doprint "Pass or fail? [p/f]";
1552 my $ans = <STDIN>;
1553 chomp $ans;
1554 if ($ans eq "p" || $ans eq "P") {
1555 return 1;
1556 } elsif ($ans eq "f" || $ans eq "F") {
1557 return 0;
1558 } else {
1559 print "Please answer 'P' or 'F'\n";
1560 }
1561 }
1562}
1563
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001564sub child_run_test {
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001565 my $failed = 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001566
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001567 # child should have no power
Steven Rostedta75fece2010-11-02 14:58:27 -04001568 $reboot_on_error = 0;
1569 $poweroff_on_error = 0;
1570 $die_on_failure = 1;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001571
1572 run_command $run_test or $failed = 1;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001573 exit $failed;
1574}
1575
1576my $child_done;
1577
1578sub child_finished {
1579 $child_done = 1;
1580}
1581
1582sub do_run_test {
1583 my $child_pid;
1584 my $child_exit;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001585 my $line;
1586 my $full_line;
1587 my $bug = 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001588
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001589 wait_for_monitor 1;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001590
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001591 doprint "run test $run_test\n";
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001592
1593 $child_done = 0;
1594
1595 $SIG{CHLD} = qw(child_finished);
1596
1597 $child_pid = fork;
1598
1599 child_run_test if (!$child_pid);
1600
1601 $full_line = "";
1602
1603 do {
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001604 $line = wait_for_input($monitor_fp, 1);
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001605 if (defined($line)) {
1606
1607 # we are not guaranteed to get a full line
1608 $full_line .= $line;
Steven Rostedt8ea0e062011-03-08 09:44:35 -05001609 doprint $line;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001610
1611 if ($full_line =~ /call trace:/i) {
1612 $bug = 1;
1613 }
1614
1615 if ($full_line =~ /Kernel panic -/) {
1616 $bug = 1;
1617 }
1618
1619 if ($line =~ /\n/) {
1620 $full_line = "";
1621 }
1622 }
1623 } while (!$child_done && !$bug);
1624
1625 if ($bug) {
Steven Rostedt8ea0e062011-03-08 09:44:35 -05001626 my $failure_start = time;
1627 my $now;
1628 do {
1629 $line = wait_for_input($monitor_fp, 1);
1630 if (defined($line)) {
1631 doprint $line;
1632 }
1633 $now = time;
1634 if ($now - $failure_start >= $stop_after_failure) {
1635 last;
1636 }
1637 } while (defined($line));
1638
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001639 doprint "Detected kernel crash!\n";
1640 # kill the child with extreme prejudice
1641 kill 9, $child_pid;
1642 }
1643
1644 waitpid $child_pid, 0;
1645 $child_exit = $?;
1646
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001647 if ($bug || $child_exit) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001648 return 0 if $in_bisect;
1649 fail "test failed" and return 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001650 }
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001651 return 1;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001652}
1653
Steven Rostedta75fece2010-11-02 14:58:27 -04001654sub run_git_bisect {
1655 my ($command) = @_;
1656
1657 doprint "$command ... ";
1658
1659 my $output = `$command 2>&1`;
1660 my $ret = $?;
1661
1662 logit $output;
1663
1664 if ($ret) {
1665 doprint "FAILED\n";
1666 dodie "Failed to git bisect";
1667 }
1668
1669 doprint "SUCCESS\n";
1670 if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\))\s+\[([[:xdigit:]]+)\]/) {
1671 doprint "$1 [$2]\n";
1672 } elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) {
1673 $bisect_bad = $1;
1674 doprint "Found bad commit... $1\n";
1675 return 0;
1676 } else {
1677 # we already logged it, just print it now.
1678 print $output;
1679 }
1680
1681 return 1;
1682}
1683
Steven Rostedtc23dca72011-03-08 09:26:31 -05001684sub bisect_reboot {
1685 doprint "Reboot and sleep $bisect_sleep_time seconds\n";
Andrew Jones2728be42011-08-12 15:32:05 +02001686 reboot $bisect_sleep_time;
Steven Rostedtc23dca72011-03-08 09:26:31 -05001687}
1688
1689# returns 1 on success, 0 on failure, -1 on skip
Steven Rostedt0a05c762010-11-08 11:14:10 -05001690sub run_bisect_test {
1691 my ($type, $buildtype) = @_;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001692
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001693 my $failed = 0;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001694 my $result;
1695 my $output;
1696 my $ret;
1697
Steven Rostedt0a05c762010-11-08 11:14:10 -05001698 $in_bisect = 1;
1699
1700 build $buildtype or $failed = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001701
1702 if ($type ne "build") {
Steven Rostedtc23dca72011-03-08 09:26:31 -05001703 if ($failed && $bisect_skip) {
1704 $in_bisect = 0;
1705 return -1;
1706 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001707 dodie "Failed on build" if $failed;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001708
1709 # Now boot the box
Steven Rostedtddf607e2011-06-14 20:49:13 -04001710 start_monitor_and_boot or $failed = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001711
1712 if ($type ne "boot") {
Steven Rostedtc23dca72011-03-08 09:26:31 -05001713 if ($failed && $bisect_skip) {
1714 end_monitor;
1715 bisect_reboot;
1716 $in_bisect = 0;
1717 return -1;
1718 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001719 dodie "Failed on boot" if $failed;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001720
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001721 do_run_test or $failed = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001722 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001723 end_monitor;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001724 }
1725
1726 if ($failed) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001727 $result = 0;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001728 } else {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001729 $result = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001730 }
Steven Rostedt4025bc62011-05-20 09:16:29 -04001731
1732 # reboot the box to a kernel we can ssh to
1733 if ($type ne "build") {
1734 bisect_reboot;
1735 }
Steven Rostedt0a05c762010-11-08 11:14:10 -05001736 $in_bisect = 0;
1737
1738 return $result;
1739}
1740
1741sub run_bisect {
1742 my ($type) = @_;
1743 my $buildtype = "oldconfig";
1744
1745 # We should have a minconfig to use?
1746 if (defined($minconfig)) {
1747 $buildtype = "useconfig:$minconfig";
1748 }
1749
1750 my $ret = run_bisect_test $type, $buildtype;
1751
Steven Rostedtc960bb92011-03-08 09:22:39 -05001752 if ($bisect_manual) {
1753 $ret = answer_bisect;
1754 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001755
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04001756 # Are we looking for where it worked, not failed?
1757 if ($reverse_bisect) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001758 $ret = !$ret;
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04001759 }
1760
Steven Rostedtc23dca72011-03-08 09:26:31 -05001761 if ($ret > 0) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001762 return "good";
Steven Rostedtc23dca72011-03-08 09:26:31 -05001763 } elsif ($ret == 0) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001764 return "bad";
Steven Rostedtc23dca72011-03-08 09:26:31 -05001765 } elsif ($bisect_skip) {
1766 doprint "HIT A BAD COMMIT ... SKIPPING\n";
1767 return "skip";
Steven Rostedt0a05c762010-11-08 11:14:10 -05001768 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001769}
1770
1771sub bisect {
1772 my ($i) = @_;
1773
1774 my $result;
1775
1776 die "BISECT_GOOD[$i] not defined\n" if (!defined($opt{"BISECT_GOOD[$i]"}));
1777 die "BISECT_BAD[$i] not defined\n" if (!defined($opt{"BISECT_BAD[$i]"}));
1778 die "BISECT_TYPE[$i] not defined\n" if (!defined($opt{"BISECT_TYPE[$i]"}));
1779
1780 my $good = $opt{"BISECT_GOOD[$i]"};
1781 my $bad = $opt{"BISECT_BAD[$i]"};
1782 my $type = $opt{"BISECT_TYPE[$i]"};
Steven Rostedta75fece2010-11-02 14:58:27 -04001783 my $start = $opt{"BISECT_START[$i]"};
1784 my $replay = $opt{"BISECT_REPLAY[$i]"};
Steven Rostedt3410f6f2011-03-08 09:38:12 -05001785 my $start_files = $opt{"BISECT_FILES[$i]"};
1786
1787 if (defined($start_files)) {
1788 $start_files = " -- " . $start_files;
1789 } else {
1790 $start_files = "";
1791 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001792
Steven Rostedta57419b2010-11-02 15:13:54 -04001793 # convert to true sha1's
1794 $good = get_sha1($good);
1795 $bad = get_sha1($bad);
1796
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04001797 if (defined($opt{"BISECT_REVERSE[$i]"}) &&
1798 $opt{"BISECT_REVERSE[$i]"} == 1) {
1799 doprint "Performing a reverse bisect (bad is good, good is bad!)\n";
1800 $reverse_bisect = 1;
1801 } else {
1802 $reverse_bisect = 0;
1803 }
1804
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001805 # Can't have a test without having a test to run
1806 if ($type eq "test" && !defined($run_test)) {
1807 $type = "boot";
1808 }
1809
Steven Rostedta75fece2010-11-02 14:58:27 -04001810 my $check = $opt{"BISECT_CHECK[$i]"};
1811 if (defined($check) && $check ne "0") {
1812
1813 # get current HEAD
Steven Rostedta57419b2010-11-02 15:13:54 -04001814 my $head = get_sha1("HEAD");
Steven Rostedta75fece2010-11-02 14:58:27 -04001815
1816 if ($check ne "good") {
1817 doprint "TESTING BISECT BAD [$bad]\n";
1818 run_command "git checkout $bad" or
1819 die "Failed to checkout $bad";
1820
1821 $result = run_bisect $type;
1822
1823 if ($result ne "bad") {
1824 fail "Tested BISECT_BAD [$bad] and it succeeded" and return 0;
1825 }
1826 }
1827
1828 if ($check ne "bad") {
1829 doprint "TESTING BISECT GOOD [$good]\n";
1830 run_command "git checkout $good" or
1831 die "Failed to checkout $good";
1832
1833 $result = run_bisect $type;
1834
1835 if ($result ne "good") {
1836 fail "Tested BISECT_GOOD [$good] and it failed" and return 0;
1837 }
1838 }
1839
1840 # checkout where we started
1841 run_command "git checkout $head" or
1842 die "Failed to checkout $head";
1843 }
1844
Steven Rostedt3410f6f2011-03-08 09:38:12 -05001845 run_command "git bisect start$start_files" or
Steven Rostedta75fece2010-11-02 14:58:27 -04001846 dodie "could not start bisect";
1847
1848 run_command "git bisect good $good" or
1849 dodie "could not set bisect good to $good";
1850
1851 run_git_bisect "git bisect bad $bad" or
1852 dodie "could not set bisect bad to $bad";
1853
1854 if (defined($replay)) {
1855 run_command "git bisect replay $replay" or
1856 dodie "failed to run replay";
1857 }
1858
1859 if (defined($start)) {
1860 run_command "git checkout $start" or
1861 dodie "failed to checkout $start";
1862 }
1863
1864 my $test;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001865 do {
1866 $result = run_bisect $type;
Steven Rostedta75fece2010-11-02 14:58:27 -04001867 $test = run_git_bisect "git bisect $result";
1868 } while ($test);
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001869
1870 run_command "git bisect log" or
1871 dodie "could not capture git bisect log";
1872
1873 run_command "git bisect reset" or
1874 dodie "could not reset git bisect";
1875
1876 doprint "Bad commit was [$bisect_bad]\n";
1877
Steven Rostedt0a05c762010-11-08 11:14:10 -05001878 success $i;
1879}
1880
1881my %config_ignore;
1882my %config_set;
1883
1884my %config_list;
1885my %null_config;
1886
1887my %dependency;
1888
Steven Rostedt4c4ab122011-07-15 21:16:17 -04001889sub assign_configs {
1890 my ($hash, $config) = @_;
Steven Rostedt0a05c762010-11-08 11:14:10 -05001891
1892 open (IN, $config)
1893 or dodie "Failed to read $config";
1894
1895 while (<IN>) {
Steven Rostedt9bf71742011-06-01 23:27:19 -04001896 if (/^((CONFIG\S*)=.*)/) {
Steven Rostedt4c4ab122011-07-15 21:16:17 -04001897 ${$hash}{$2} = $1;
Steven Rostedt0a05c762010-11-08 11:14:10 -05001898 }
1899 }
1900
1901 close(IN);
1902}
1903
Steven Rostedt4c4ab122011-07-15 21:16:17 -04001904sub process_config_ignore {
1905 my ($config) = @_;
1906
1907 assign_configs \%config_ignore, $config;
1908}
1909
Steven Rostedt0a05c762010-11-08 11:14:10 -05001910sub read_current_config {
1911 my ($config_ref) = @_;
1912
1913 %{$config_ref} = ();
1914 undef %{$config_ref};
1915
1916 my @key = keys %{$config_ref};
1917 if ($#key >= 0) {
1918 print "did not delete!\n";
1919 exit;
1920 }
1921 open (IN, "$output_config");
1922
1923 while (<IN>) {
1924 if (/^(CONFIG\S+)=(.*)/) {
1925 ${$config_ref}{$1} = $2;
1926 }
1927 }
1928 close(IN);
1929}
1930
1931sub get_dependencies {
1932 my ($config) = @_;
1933
1934 my $arr = $dependency{$config};
1935 if (!defined($arr)) {
1936 return ();
1937 }
1938
1939 my @deps = @{$arr};
1940
1941 foreach my $dep (@{$arr}) {
1942 print "ADD DEP $dep\n";
1943 @deps = (@deps, get_dependencies $dep);
1944 }
1945
1946 return @deps;
1947}
1948
1949sub create_config {
1950 my @configs = @_;
1951
1952 open(OUT, ">$output_config") or dodie "Can not write to $output_config";
1953
1954 foreach my $config (@configs) {
1955 print OUT "$config_set{$config}\n";
1956 my @deps = get_dependencies $config;
1957 foreach my $dep (@deps) {
1958 print OUT "$config_set{$dep}\n";
1959 }
1960 }
1961
1962 foreach my $config (keys %config_ignore) {
1963 print OUT "$config_ignore{$config}\n";
1964 }
1965 close(OUT);
1966
1967# exit;
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001968 make_oldconfig;
Steven Rostedt0a05c762010-11-08 11:14:10 -05001969}
1970
1971sub compare_configs {
1972 my (%a, %b) = @_;
1973
1974 foreach my $item (keys %a) {
1975 if (!defined($b{$item})) {
1976 print "diff $item\n";
1977 return 1;
1978 }
1979 delete $b{$item};
1980 }
1981
1982 my @keys = keys %b;
1983 if ($#keys) {
1984 print "diff2 $keys[0]\n";
1985 }
1986 return -1 if ($#keys >= 0);
1987
1988 return 0;
1989}
1990
1991sub run_config_bisect_test {
1992 my ($type) = @_;
1993
1994 return run_bisect_test $type, "oldconfig";
1995}
1996
1997sub process_passed {
1998 my (%configs) = @_;
1999
2000 doprint "These configs had no failure: (Enabling them for further compiles)\n";
2001 # Passed! All these configs are part of a good compile.
2002 # Add them to the min options.
2003 foreach my $config (keys %configs) {
2004 if (defined($config_list{$config})) {
2005 doprint " removing $config\n";
2006 $config_ignore{$config} = $config_list{$config};
2007 delete $config_list{$config};
2008 }
2009 }
Steven Rostedtf1a27852010-11-11 11:34:38 -05002010 doprint "config copied to $outputdir/config_good\n";
2011 run_command "cp -f $output_config $outputdir/config_good";
Steven Rostedt0a05c762010-11-08 11:14:10 -05002012}
2013
2014sub process_failed {
2015 my ($config) = @_;
2016
2017 doprint "\n\n***************************************\n";
2018 doprint "Found bad config: $config\n";
2019 doprint "***************************************\n\n";
2020}
2021
2022sub run_config_bisect {
2023
2024 my @start_list = keys %config_list;
2025
2026 if ($#start_list < 0) {
2027 doprint "No more configs to test!!!\n";
2028 return -1;
2029 }
2030
2031 doprint "***** RUN TEST ***\n";
2032 my $type = $opt{"CONFIG_BISECT_TYPE[$iteration]"};
2033 my $ret;
2034 my %current_config;
2035
2036 my $count = $#start_list + 1;
2037 doprint " $count configs to test\n";
2038
2039 my $half = int($#start_list / 2);
2040
2041 do {
2042 my @tophalf = @start_list[0 .. $half];
2043
2044 create_config @tophalf;
2045 read_current_config \%current_config;
2046
2047 $count = $#tophalf + 1;
2048 doprint "Testing $count configs\n";
2049 my $found = 0;
2050 # make sure we test something
2051 foreach my $config (@tophalf) {
2052 if (defined($current_config{$config})) {
2053 logit " $config\n";
2054 $found = 1;
2055 }
2056 }
2057 if (!$found) {
2058 # try the other half
2059 doprint "Top half produced no set configs, trying bottom half\n";
Steven Rostedt4c8cc552011-06-01 23:22:30 -04002060 @tophalf = @start_list[$half + 1 .. $#start_list];
Steven Rostedt0a05c762010-11-08 11:14:10 -05002061 create_config @tophalf;
2062 read_current_config \%current_config;
2063 foreach my $config (@tophalf) {
2064 if (defined($current_config{$config})) {
2065 logit " $config\n";
2066 $found = 1;
2067 }
2068 }
2069 if (!$found) {
2070 doprint "Failed: Can't make new config with current configs\n";
2071 foreach my $config (@start_list) {
2072 doprint " CONFIG: $config\n";
2073 }
2074 return -1;
2075 }
2076 $count = $#tophalf + 1;
2077 doprint "Testing $count configs\n";
2078 }
2079
2080 $ret = run_config_bisect_test $type;
Steven Rostedtc960bb92011-03-08 09:22:39 -05002081 if ($bisect_manual) {
2082 $ret = answer_bisect;
2083 }
Steven Rostedt0a05c762010-11-08 11:14:10 -05002084 if ($ret) {
2085 process_passed %current_config;
2086 return 0;
2087 }
2088
2089 doprint "This config had a failure.\n";
2090 doprint "Removing these configs that were not set in this config:\n";
Steven Rostedtf1a27852010-11-11 11:34:38 -05002091 doprint "config copied to $outputdir/config_bad\n";
2092 run_command "cp -f $output_config $outputdir/config_bad";
Steven Rostedt0a05c762010-11-08 11:14:10 -05002093
2094 # A config exists in this group that was bad.
2095 foreach my $config (keys %config_list) {
2096 if (!defined($current_config{$config})) {
2097 doprint " removing $config\n";
2098 delete $config_list{$config};
2099 }
2100 }
2101
2102 @start_list = @tophalf;
2103
2104 if ($#start_list == 0) {
2105 process_failed $start_list[0];
2106 return 1;
2107 }
2108
2109 # remove half the configs we are looking at and see if
2110 # they are good.
2111 $half = int($#start_list / 2);
Steven Rostedt4c8cc552011-06-01 23:22:30 -04002112 } while ($#start_list > 0);
Steven Rostedt0a05c762010-11-08 11:14:10 -05002113
Steven Rostedtc960bb92011-03-08 09:22:39 -05002114 # we found a single config, try it again unless we are running manually
2115
2116 if ($bisect_manual) {
2117 process_failed $start_list[0];
2118 return 1;
2119 }
2120
Steven Rostedt0a05c762010-11-08 11:14:10 -05002121 my @tophalf = @start_list[0 .. 0];
2122
2123 $ret = run_config_bisect_test $type;
2124 if ($ret) {
2125 process_passed %current_config;
2126 return 0;
2127 }
2128
2129 process_failed $start_list[0];
2130 return 1;
2131}
2132
2133sub config_bisect {
2134 my ($i) = @_;
2135
2136 my $start_config = $opt{"CONFIG_BISECT[$i]"};
2137
2138 my $tmpconfig = "$tmpdir/use_config";
2139
Steven Rostedt30f75da2011-06-13 10:35:35 -04002140 if (defined($config_bisect_good)) {
2141 process_config_ignore $config_bisect_good;
2142 }
2143
Steven Rostedt0a05c762010-11-08 11:14:10 -05002144 # Make the file with the bad config and the min config
2145 if (defined($minconfig)) {
2146 # read the min config for things to ignore
2147 run_command "cp $minconfig $tmpconfig" or
2148 dodie "failed to copy $minconfig to $tmpconfig";
2149 } else {
2150 unlink $tmpconfig;
2151 }
2152
Steven Rostedt0a05c762010-11-08 11:14:10 -05002153 if (-f $tmpconfig) {
Steven Rostedtfcb3f162011-06-13 10:40:58 -04002154 load_force_config($tmpconfig);
Steven Rostedt0a05c762010-11-08 11:14:10 -05002155 process_config_ignore $tmpconfig;
2156 }
2157
2158 # now process the start config
2159 run_command "cp $start_config $output_config" or
2160 dodie "failed to copy $start_config to $output_config";
2161
2162 # read directly what we want to check
2163 my %config_check;
2164 open (IN, $output_config)
2165 or dodie "faied to open $output_config";
2166
2167 while (<IN>) {
2168 if (/^((CONFIG\S*)=.*)/) {
2169 $config_check{$2} = $1;
2170 }
2171 }
2172 close(IN);
2173
Steven Rostedt250bae82011-07-15 22:05:59 -04002174 # Now run oldconfig with the minconfig
Steven Rostedtfcb3f162011-06-13 10:40:58 -04002175 make_oldconfig;
Steven Rostedt0a05c762010-11-08 11:14:10 -05002176
2177 # check to see what we lost (or gained)
2178 open (IN, $output_config)
2179 or dodie "Failed to read $start_config";
2180
2181 my %removed_configs;
2182 my %added_configs;
2183
2184 while (<IN>) {
2185 if (/^((CONFIG\S*)=.*)/) {
2186 # save off all options
2187 $config_set{$2} = $1;
2188 if (defined($config_check{$2})) {
2189 if (defined($config_ignore{$2})) {
2190 $removed_configs{$2} = $1;
2191 } else {
2192 $config_list{$2} = $1;
2193 }
2194 } elsif (!defined($config_ignore{$2})) {
2195 $added_configs{$2} = $1;
2196 $config_list{$2} = $1;
2197 }
2198 }
2199 }
2200 close(IN);
2201
2202 my @confs = keys %removed_configs;
2203 if ($#confs >= 0) {
2204 doprint "Configs overridden by default configs and removed from check:\n";
2205 foreach my $config (@confs) {
2206 doprint " $config\n";
2207 }
2208 }
2209 @confs = keys %added_configs;
2210 if ($#confs >= 0) {
2211 doprint "Configs appearing in make oldconfig and added:\n";
2212 foreach my $config (@confs) {
2213 doprint " $config\n";
2214 }
2215 }
2216
2217 my %config_test;
2218 my $once = 0;
2219
2220 # Sometimes kconfig does weird things. We must make sure
2221 # that the config we autocreate has everything we need
2222 # to test, otherwise we may miss testing configs, or
2223 # may not be able to create a new config.
2224 # Here we create a config with everything set.
2225 create_config (keys %config_list);
2226 read_current_config \%config_test;
2227 foreach my $config (keys %config_list) {
2228 if (!defined($config_test{$config})) {
2229 if (!$once) {
2230 $once = 1;
2231 doprint "Configs not produced by kconfig (will not be checked):\n";
2232 }
2233 doprint " $config\n";
2234 delete $config_list{$config};
2235 }
2236 }
2237 my $ret;
2238 do {
2239 $ret = run_config_bisect;
2240 } while (!$ret);
2241
2242 return $ret if ($ret < 0);
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04002243
2244 success $i;
2245}
2246
Steven Rostedt27d934b2011-05-20 09:18:18 -04002247sub patchcheck_reboot {
2248 doprint "Reboot and sleep $patchcheck_sleep_time seconds\n";
Andrew Jones2728be42011-08-12 15:32:05 +02002249 reboot $patchcheck_sleep_time;
Steven Rostedt27d934b2011-05-20 09:18:18 -04002250}
2251
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002252sub patchcheck {
2253 my ($i) = @_;
2254
2255 die "PATCHCHECK_START[$i] not defined\n"
2256 if (!defined($opt{"PATCHCHECK_START[$i]"}));
2257 die "PATCHCHECK_TYPE[$i] not defined\n"
2258 if (!defined($opt{"PATCHCHECK_TYPE[$i]"}));
2259
2260 my $start = $opt{"PATCHCHECK_START[$i]"};
2261
2262 my $end = "HEAD";
2263 if (defined($opt{"PATCHCHECK_END[$i]"})) {
2264 $end = $opt{"PATCHCHECK_END[$i]"};
2265 }
2266
Steven Rostedta57419b2010-11-02 15:13:54 -04002267 # Get the true sha1's since we can use things like HEAD~3
2268 $start = get_sha1($start);
2269 $end = get_sha1($end);
2270
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002271 my $type = $opt{"PATCHCHECK_TYPE[$i]"};
2272
2273 # Can't have a test without having a test to run
2274 if ($type eq "test" && !defined($run_test)) {
2275 $type = "boot";
2276 }
2277
2278 open (IN, "git log --pretty=oneline $end|") or
2279 dodie "could not get git list";
2280
2281 my @list;
2282
2283 while (<IN>) {
2284 chomp;
2285 $list[$#list+1] = $_;
2286 last if (/^$start/);
2287 }
2288 close(IN);
2289
2290 if ($list[$#list] !~ /^$start/) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002291 fail "SHA1 $start not found";
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002292 }
2293
2294 # go backwards in the list
2295 @list = reverse @list;
2296
2297 my $save_clean = $noclean;
Steven Rostedt19902072011-06-14 20:46:25 -04002298 my %ignored_warnings;
2299
2300 if (defined($ignore_warnings)) {
2301 foreach my $sha1 (split /\s+/, $ignore_warnings) {
2302 $ignored_warnings{$sha1} = 1;
2303 }
2304 }
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002305
2306 $in_patchcheck = 1;
2307 foreach my $item (@list) {
2308 my $sha1 = $item;
2309 $sha1 =~ s/^([[:xdigit:]]+).*/$1/;
2310
2311 doprint "\nProcessing commit $item\n\n";
2312
2313 run_command "git checkout $sha1" or
2314 die "Failed to checkout $sha1";
2315
2316 # only clean on the first and last patch
2317 if ($item eq $list[0] ||
2318 $item eq $list[$#list]) {
2319 $noclean = $save_clean;
2320 } else {
2321 $noclean = 1;
2322 }
2323
2324 if (defined($minconfig)) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002325 build "useconfig:$minconfig" or return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002326 } else {
2327 # ?? no config to use?
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002328 build "oldconfig" or return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002329 }
2330
Steven Rostedt19902072011-06-14 20:46:25 -04002331
2332 if (!defined($ignored_warnings{$sha1})) {
2333 check_buildlog $sha1 or return 0;
2334 }
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002335
2336 next if ($type eq "build");
2337
Steven Rostedt7faafbd2010-11-02 14:58:22 -04002338 my $failed = 0;
2339
Steven Rostedtddf607e2011-06-14 20:49:13 -04002340 start_monitor_and_boot or $failed = 1;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04002341
2342 if (!$failed && $type ne "boot"){
2343 do_run_test or $failed = 1;
2344 }
2345 end_monitor;
2346 return 0 if ($failed);
2347
Steven Rostedt27d934b2011-05-20 09:18:18 -04002348 patchcheck_reboot;
2349
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002350 }
2351 $in_patchcheck = 0;
2352 success $i;
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002353
2354 return 1;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002355}
2356
Steven Rostedtb9066f62011-07-15 21:25:24 -04002357my %depends;
2358my $iflevel = 0;
2359my @ifdeps;
2360
2361# prevent recursion
2362my %read_kconfigs;
2363
2364# taken from streamline_config.pl
2365sub read_kconfig {
2366 my ($kconfig) = @_;
2367
2368 my $state = "NONE";
2369 my $config;
2370 my @kconfigs;
2371
2372 my $cont = 0;
2373 my $line;
2374
2375
2376 if (! -f $kconfig) {
2377 doprint "file $kconfig does not exist, skipping\n";
2378 return;
2379 }
2380
2381 open(KIN, "$kconfig")
2382 or die "Can't open $kconfig";
2383 while (<KIN>) {
2384 chomp;
2385
2386 # Make sure that lines ending with \ continue
2387 if ($cont) {
2388 $_ = $line . " " . $_;
2389 }
2390
2391 if (s/\\$//) {
2392 $cont = 1;
2393 $line = $_;
2394 next;
2395 }
2396
2397 $cont = 0;
2398
2399 # collect any Kconfig sources
2400 if (/^source\s*"(.*)"/) {
2401 $kconfigs[$#kconfigs+1] = $1;
2402 }
2403
2404 # configs found
2405 if (/^\s*(menu)?config\s+(\S+)\s*$/) {
2406 $state = "NEW";
2407 $config = $2;
2408
2409 for (my $i = 0; $i < $iflevel; $i++) {
2410 if ($i) {
2411 $depends{$config} .= " " . $ifdeps[$i];
2412 } else {
2413 $depends{$config} = $ifdeps[$i];
2414 }
2415 $state = "DEP";
2416 }
2417
2418 # collect the depends for the config
2419 } elsif ($state eq "NEW" && /^\s*depends\s+on\s+(.*)$/) {
2420
2421 if (defined($depends{$1})) {
2422 $depends{$config} .= " " . $1;
2423 } else {
2424 $depends{$config} = $1;
2425 }
2426
2427 # Get the configs that select this config
2428 } elsif ($state ne "NONE" && /^\s*select\s+(\S+)/) {
2429 if (defined($depends{$1})) {
2430 $depends{$1} .= " " . $config;
2431 } else {
2432 $depends{$1} = $config;
2433 }
2434
2435 # Check for if statements
2436 } elsif (/^if\s+(.*\S)\s*$/) {
2437 my $deps = $1;
2438 # remove beginning and ending non text
2439 $deps =~ s/^[^a-zA-Z0-9_]*//;
2440 $deps =~ s/[^a-zA-Z0-9_]*$//;
2441
2442 my @deps = split /[^a-zA-Z0-9_]+/, $deps;
2443
2444 $ifdeps[$iflevel++] = join ':', @deps;
2445
2446 } elsif (/^endif/) {
2447
2448 $iflevel-- if ($iflevel);
2449
2450 # stop on "help"
2451 } elsif (/^\s*help\s*$/) {
2452 $state = "NONE";
2453 }
2454 }
2455 close(KIN);
2456
2457 # read in any configs that were found.
2458 foreach $kconfig (@kconfigs) {
2459 if (!defined($read_kconfigs{$kconfig})) {
2460 $read_kconfigs{$kconfig} = 1;
2461 read_kconfig("$builddir/$kconfig");
2462 }
2463 }
2464}
2465
2466sub read_depends {
2467 # find out which arch this is by the kconfig file
2468 open (IN, $output_config)
2469 or dodie "Failed to read $output_config";
2470 my $arch;
2471 while (<IN>) {
2472 if (m,Linux/(\S+)\s+\S+\s+Kernel Configuration,) {
2473 $arch = $1;
2474 last;
2475 }
2476 }
2477 close IN;
2478
2479 if (!defined($arch)) {
2480 doprint "Could not find arch from config file\n";
2481 doprint "no dependencies used\n";
2482 return;
2483 }
2484
2485 # arch is really the subarch, we need to know
2486 # what directory to look at.
2487 if ($arch eq "i386" || $arch eq "x86_64") {
2488 $arch = "x86";
2489 } elsif ($arch =~ /^tile/) {
2490 $arch = "tile";
2491 }
2492
2493 my $kconfig = "$builddir/arch/$arch/Kconfig";
2494
2495 if (! -f $kconfig && $arch =~ /\d$/) {
2496 my $orig = $arch;
2497 # some subarchs have numbers, truncate them
2498 $arch =~ s/\d*$//;
2499 $kconfig = "$builddir/arch/$arch/Kconfig";
2500 if (! -f $kconfig) {
2501 doprint "No idea what arch dir $orig is for\n";
2502 doprint "no dependencies used\n";
2503 return;
2504 }
2505 }
2506
2507 read_kconfig($kconfig);
2508}
2509
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002510sub read_config_list {
2511 my ($config) = @_;
2512
2513 open (IN, $config)
2514 or dodie "Failed to read $config";
2515
2516 while (<IN>) {
2517 if (/^((CONFIG\S*)=.*)/) {
2518 if (!defined($config_ignore{$2})) {
2519 $config_list{$2} = $1;
2520 }
2521 }
2522 }
2523
2524 close(IN);
2525}
2526
2527sub read_output_config {
2528 my ($config) = @_;
2529
2530 assign_configs \%config_ignore, $config;
2531}
2532
2533sub make_new_config {
2534 my @configs = @_;
2535
2536 open (OUT, ">$output_config")
2537 or dodie "Failed to write $output_config";
2538
2539 foreach my $config (@configs) {
2540 print OUT "$config\n";
2541 }
2542 close OUT;
2543}
2544
Steven Rostedtb9066f62011-07-15 21:25:24 -04002545sub get_depends {
2546 my ($dep) = @_;
2547
2548 my $kconfig = $dep;
2549 $kconfig =~ s/CONFIG_//;
2550
2551 $dep = $depends{"$kconfig"};
2552
2553 # the dep string we have saves the dependencies as they
2554 # were found, including expressions like ! && ||. We
2555 # want to split this out into just an array of configs.
2556
2557 my $valid = "A-Za-z_0-9";
2558
2559 my @configs;
2560
2561 while ($dep =~ /[$valid]/) {
2562
2563 if ($dep =~ /^[^$valid]*([$valid]+)/) {
2564 my $conf = "CONFIG_" . $1;
2565
2566 $configs[$#configs + 1] = $conf;
2567
2568 $dep =~ s/^[^$valid]*[$valid]+//;
2569 } else {
2570 die "this should never happen";
2571 }
2572 }
2573
2574 return @configs;
2575}
2576
2577my %min_configs;
2578my %keep_configs;
Steven Rostedt43d1b652011-07-15 22:01:56 -04002579my %save_configs;
Steven Rostedtb9066f62011-07-15 21:25:24 -04002580my %processed_configs;
2581my %nochange_config;
2582
2583sub test_this_config {
2584 my ($config) = @_;
2585
2586 my $found;
2587
2588 # if we already processed this config, skip it
2589 if (defined($processed_configs{$config})) {
2590 return undef;
2591 }
2592 $processed_configs{$config} = 1;
2593
2594 # if this config failed during this round, skip it
2595 if (defined($nochange_config{$config})) {
2596 return undef;
2597 }
2598
2599 my $kconfig = $config;
2600 $kconfig =~ s/CONFIG_//;
2601
2602 # Test dependencies first
2603 if (defined($depends{"$kconfig"})) {
2604 my @parents = get_depends $config;
2605 foreach my $parent (@parents) {
2606 # if the parent is in the min config, check it first
2607 next if (!defined($min_configs{$parent}));
2608 $found = test_this_config($parent);
2609 if (defined($found)) {
2610 return $found;
2611 }
2612 }
2613 }
2614
2615 # Remove this config from the list of configs
2616 # do a make oldnoconfig and then read the resulting
2617 # .config to make sure it is missing the config that
2618 # we had before
2619 my %configs = %min_configs;
2620 delete $configs{$config};
2621 make_new_config ((values %configs), (values %keep_configs));
2622 make_oldconfig;
2623 undef %configs;
2624 assign_configs \%configs, $output_config;
2625
2626 return $config if (!defined($configs{$config}));
2627
2628 doprint "disabling config $config did not change .config\n";
2629
2630 $nochange_config{$config} = 1;
2631
2632 return undef;
2633}
2634
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002635sub make_min_config {
2636 my ($i) = @_;
2637
2638 if (!defined($output_minconfig)) {
2639 fail "OUTPUT_MIN_CONFIG not defined" and return;
2640 }
Steven Rostedt35ce5952011-07-15 21:57:25 -04002641
2642 # If output_minconfig exists, and the start_minconfig
2643 # came from min_config, than ask if we should use
2644 # that instead.
2645 if (-f $output_minconfig && !$start_minconfig_defined) {
2646 print "$output_minconfig exists\n";
2647 if (read_yn " Use it as minconfig?") {
2648 $start_minconfig = $output_minconfig;
2649 }
2650 }
2651
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002652 if (!defined($start_minconfig)) {
2653 fail "START_MIN_CONFIG or MIN_CONFIG not defined" and return;
2654 }
2655
Steven Rostedt35ce5952011-07-15 21:57:25 -04002656 my $temp_config = "$tmpdir/temp_config";
2657
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002658 # First things first. We build an allnoconfig to find
2659 # out what the defaults are that we can't touch.
2660 # Some are selections, but we really can't handle selections.
2661
2662 my $save_minconfig = $minconfig;
2663 undef $minconfig;
2664
2665 run_command "$make allnoconfig" or return 0;
2666
Steven Rostedtb9066f62011-07-15 21:25:24 -04002667 read_depends;
2668
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002669 process_config_ignore $output_config;
Steven Rostedtb9066f62011-07-15 21:25:24 -04002670
Steven Rostedt43d1b652011-07-15 22:01:56 -04002671 undef %save_configs;
Steven Rostedtb9066f62011-07-15 21:25:24 -04002672 undef %min_configs;
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002673
2674 if (defined($ignore_config)) {
2675 # make sure the file exists
2676 `touch $ignore_config`;
Steven Rostedt43d1b652011-07-15 22:01:56 -04002677 assign_configs \%save_configs, $ignore_config;
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002678 }
2679
Steven Rostedt43d1b652011-07-15 22:01:56 -04002680 %keep_configs = %save_configs;
2681
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002682 doprint "Load initial configs from $start_minconfig\n";
2683
2684 # Look at the current min configs, and save off all the
2685 # ones that were set via the allnoconfig
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002686 assign_configs \%min_configs, $start_minconfig;
2687
2688 my @config_keys = keys %min_configs;
2689
2690 # Remove anything that was set by the make allnoconfig
2691 # we shouldn't need them as they get set for us anyway.
2692 foreach my $config (@config_keys) {
2693 # Remove anything in the ignore_config
2694 if (defined($keep_configs{$config})) {
2695 my $file = $ignore_config;
2696 $file =~ s,.*/(.*?)$,$1,;
2697 doprint "$config set by $file ... ignored\n";
2698 delete $min_configs{$config};
2699 next;
2700 }
2701 # But make sure the settings are the same. If a min config
2702 # sets a selection, we do not want to get rid of it if
2703 # it is not the same as what we have. Just move it into
2704 # the keep configs.
2705 if (defined($config_ignore{$config})) {
2706 if ($config_ignore{$config} ne $min_configs{$config}) {
2707 doprint "$config is in allnoconfig as '$config_ignore{$config}'";
2708 doprint " but it is '$min_configs{$config}' in minconfig .. keeping\n";
2709 $keep_configs{$config} = $min_configs{$config};
2710 } else {
2711 doprint "$config set by allnoconfig ... ignored\n";
2712 }
2713 delete $min_configs{$config};
2714 }
2715 }
2716
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002717 my $done = 0;
Steven Rostedtb9066f62011-07-15 21:25:24 -04002718 my $take_two = 0;
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002719
2720 while (!$done) {
2721
2722 my $config;
2723 my $found;
2724
2725 # Now disable each config one by one and do a make oldconfig
2726 # till we find a config that changes our list.
2727
2728 # Put configs that did not modify the config at the end.
2729 my @test_configs = keys %min_configs;
2730 my $reset = 1;
2731 for (my $i = 0; $i < $#test_configs; $i++) {
2732 if (!defined($nochange_config{$test_configs[0]})) {
2733 $reset = 0;
2734 last;
2735 }
2736 # This config didn't change the .config last time.
2737 # Place it at the end
2738 my $config = shift @test_configs;
2739 push @test_configs, $config;
2740 }
2741
2742 # if every test config has failed to modify the .config file
2743 # in the past, then reset and start over.
2744 if ($reset) {
2745 undef %nochange_config;
2746 }
2747
Steven Rostedtb9066f62011-07-15 21:25:24 -04002748 undef %processed_configs;
2749
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002750 foreach my $config (@test_configs) {
2751
Steven Rostedtb9066f62011-07-15 21:25:24 -04002752 $found = test_this_config $config;
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002753
Steven Rostedtb9066f62011-07-15 21:25:24 -04002754 last if (defined($found));
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002755
2756 # oh well, try another config
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002757 }
2758
2759 if (!defined($found)) {
Steven Rostedtb9066f62011-07-15 21:25:24 -04002760 # we could have failed due to the nochange_config hash
2761 # reset and try again
2762 if (!$take_two) {
2763 undef %nochange_config;
2764 $take_two = 1;
2765 next;
2766 }
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002767 doprint "No more configs found that we can disable\n";
2768 $done = 1;
2769 last;
2770 }
Steven Rostedtb9066f62011-07-15 21:25:24 -04002771 $take_two = 0;
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002772
2773 $config = $found;
2774
2775 doprint "Test with $config disabled\n";
2776
2777 # set in_bisect to keep build and monitor from dieing
2778 $in_bisect = 1;
2779
2780 my $failed = 0;
2781 build "oldconfig";
2782 start_monitor_and_boot or $failed = 1;
2783 end_monitor;
2784
2785 $in_bisect = 0;
2786
2787 if ($failed) {
Steven Rostedtb9066f62011-07-15 21:25:24 -04002788 doprint "$min_configs{$config} is needed to boot the box... keeping\n";
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002789 # this config is needed, add it to the ignore list.
2790 $keep_configs{$config} = $min_configs{$config};
Steven Rostedt43d1b652011-07-15 22:01:56 -04002791 $save_configs{$config} = $min_configs{$config};
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002792 delete $min_configs{$config};
Steven Rostedt35ce5952011-07-15 21:57:25 -04002793
2794 # update new ignore configs
2795 if (defined($ignore_config)) {
2796 open (OUT, ">$temp_config")
2797 or die "Can't write to $temp_config";
Steven Rostedt43d1b652011-07-15 22:01:56 -04002798 foreach my $config (keys %save_configs) {
2799 print OUT "$save_configs{$config}\n";
Steven Rostedt35ce5952011-07-15 21:57:25 -04002800 }
2801 close OUT;
2802 run_command "mv $temp_config $ignore_config" or
2803 dodie "failed to copy update to $ignore_config";
2804 }
2805
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002806 } else {
2807 # We booted without this config, remove it from the minconfigs.
2808 doprint "$config is not needed, disabling\n";
2809
2810 delete $min_configs{$config};
2811
2812 # Also disable anything that is not enabled in this config
2813 my %configs;
2814 assign_configs \%configs, $output_config;
2815 my @config_keys = keys %min_configs;
2816 foreach my $config (@config_keys) {
2817 if (!defined($configs{$config})) {
2818 doprint "$config is not set, disabling\n";
2819 delete $min_configs{$config};
2820 }
2821 }
2822
2823 # Save off all the current mandidory configs
Steven Rostedt35ce5952011-07-15 21:57:25 -04002824 open (OUT, ">$temp_config")
2825 or die "Can't write to $temp_config";
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002826 foreach my $config (keys %keep_configs) {
2827 print OUT "$keep_configs{$config}\n";
2828 }
2829 foreach my $config (keys %min_configs) {
2830 print OUT "$min_configs{$config}\n";
2831 }
2832 close OUT;
Steven Rostedt35ce5952011-07-15 21:57:25 -04002833
2834 run_command "mv $temp_config $output_minconfig" or
2835 dodie "failed to copy update to $output_minconfig";
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002836 }
2837
2838 doprint "Reboot and wait $sleep_time seconds\n";
Andrew Jones2728be42011-08-12 15:32:05 +02002839 reboot $sleep_time;
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002840 }
2841
2842 success $i;
2843 return 1;
2844}
2845
Steven Rostedt8d1491b2010-11-18 15:39:48 -05002846$#ARGV < 1 or die "ktest.pl version: $VERSION\n usage: ktest.pl config-file\n";
Steven Rostedt2545eb62010-11-02 15:01:32 -04002847
Steven Rostedt8d1491b2010-11-18 15:39:48 -05002848if ($#ARGV == 0) {
2849 $ktest_config = $ARGV[0];
2850 if (! -f $ktest_config) {
2851 print "$ktest_config does not exist.\n";
Steven Rostedt35ce5952011-07-15 21:57:25 -04002852 if (!read_yn "Create it?") {
Steven Rostedt8d1491b2010-11-18 15:39:48 -05002853 exit 0;
2854 }
2855 }
2856} else {
2857 $ktest_config = "ktest.conf";
2858}
2859
2860if (! -f $ktest_config) {
2861 open(OUT, ">$ktest_config") or die "Can not create $ktest_config";
2862 print OUT << "EOF"
2863# Generated by ktest.pl
2864#
2865# Define each test with TEST_START
2866# The config options below it will override the defaults
2867TEST_START
2868
2869DEFAULTS
2870EOF
2871;
2872 close(OUT);
2873}
2874read_config $ktest_config;
2875
Steven Rostedt23715c3c2011-06-13 11:03:34 -04002876if (defined($opt{"LOG_FILE"})) {
2877 $opt{"LOG_FILE"} = eval_option($opt{"LOG_FILE"}, -1);
2878}
2879
Steven Rostedt8d1491b2010-11-18 15:39:48 -05002880# Append any configs entered in manually to the config file.
2881my @new_configs = keys %entered_configs;
2882if ($#new_configs >= 0) {
2883 print "\nAppending entered in configs to $ktest_config\n";
2884 open(OUT, ">>$ktest_config") or die "Can not append to $ktest_config";
2885 foreach my $config (@new_configs) {
2886 print OUT "$config = $entered_configs{$config}\n";
2887 $opt{$config} = $entered_configs{$config};
2888 }
2889}
Steven Rostedt2545eb62010-11-02 15:01:32 -04002890
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002891if ($opt{"CLEAR_LOG"} && defined($opt{"LOG_FILE"})) {
2892 unlink $opt{"LOG_FILE"};
2893}
Steven Rostedt2545eb62010-11-02 15:01:32 -04002894
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002895doprint "\n\nSTARTING AUTOMATED TESTS\n\n";
2896
Steven Rostedta57419b2010-11-02 15:13:54 -04002897for (my $i = 0, my $repeat = 1; $i <= $opt{"NUM_TESTS"}; $i += $repeat) {
2898
2899 if (!$i) {
2900 doprint "DEFAULT OPTIONS:\n";
2901 } else {
2902 doprint "\nTEST $i OPTIONS";
2903 if (defined($repeat_tests{$i})) {
2904 $repeat = $repeat_tests{$i};
2905 doprint " ITERATE $repeat";
2906 }
2907 doprint "\n";
2908 }
2909
2910 foreach my $option (sort keys %opt) {
2911
2912 if ($option =~ /\[(\d+)\]$/) {
2913 next if ($i != $1);
2914 } else {
2915 next if ($i);
2916 }
2917
2918 doprint "$option = $opt{$option}\n";
2919 }
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002920}
Steven Rostedt2545eb62010-11-02 15:01:32 -04002921
Steven Rostedt2a625122011-05-20 15:48:59 -04002922sub __set_test_option {
Steven Rostedt5a391fb2010-11-02 14:57:43 -04002923 my ($name, $i) = @_;
2924
2925 my $option = "$name\[$i\]";
2926
2927 if (defined($opt{$option})) {
2928 return $opt{$option};
2929 }
2930
Steven Rostedta57419b2010-11-02 15:13:54 -04002931 foreach my $test (keys %repeat_tests) {
2932 if ($i >= $test &&
2933 $i < $test + $repeat_tests{$test}) {
2934 $option = "$name\[$test\]";
2935 if (defined($opt{$option})) {
2936 return $opt{$option};
2937 }
2938 }
2939 }
2940
Steven Rostedt5a391fb2010-11-02 14:57:43 -04002941 if (defined($opt{$name})) {
2942 return $opt{$name};
2943 }
2944
2945 return undef;
2946}
2947
Steven Rostedt2a625122011-05-20 15:48:59 -04002948sub set_test_option {
2949 my ($name, $i) = @_;
2950
2951 my $option = __set_test_option($name, $i);
2952 return $option if (!defined($option));
2953
Steven Rostedt23715c3c2011-06-13 11:03:34 -04002954 return eval_option($option, $i);
Steven Rostedt2a625122011-05-20 15:48:59 -04002955}
2956
Steven Rostedt2545eb62010-11-02 15:01:32 -04002957# First we need to do is the builds
Steven Rostedta75fece2010-11-02 14:58:27 -04002958for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
Steven Rostedt2545eb62010-11-02 15:01:32 -04002959
Steven Rostedt4ab1cce2011-09-30 18:12:20 -04002960 # Do not reboot on failing test options
2961 $no_reboot = 1;
2962
Steven Rostedt576f6272010-11-02 14:58:38 -04002963 $iteration = $i;
2964
Steven Rostedta75fece2010-11-02 14:58:27 -04002965 my $makecmd = set_test_option("MAKE_CMD", $i);
2966
2967 $machine = set_test_option("MACHINE", $i);
Steven Rostedte48c5292010-11-02 14:35:37 -04002968 $ssh_user = set_test_option("SSH_USER", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002969 $tmpdir = set_test_option("TMP_DIR", $i);
2970 $outputdir = set_test_option("OUTPUT_DIR", $i);
2971 $builddir = set_test_option("BUILD_DIR", $i);
2972 $test_type = set_test_option("TEST_TYPE", $i);
2973 $build_type = set_test_option("BUILD_TYPE", $i);
2974 $build_options = set_test_option("BUILD_OPTIONS", $i);
Steven Rostedt0bd6c1a2011-06-14 20:39:31 -04002975 $pre_build = set_test_option("PRE_BUILD", $i);
2976 $post_build = set_test_option("POST_BUILD", $i);
2977 $pre_build_die = set_test_option("PRE_BUILD_DIE", $i);
2978 $post_build_die = set_test_option("POST_BUILD_DIE", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002979 $power_cycle = set_test_option("POWER_CYCLE", $i);
Steven Rostedte48c5292010-11-02 14:35:37 -04002980 $reboot = set_test_option("REBOOT", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002981 $noclean = set_test_option("BUILD_NOCLEAN", $i);
2982 $minconfig = set_test_option("MIN_CONFIG", $i);
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002983 $output_minconfig = set_test_option("OUTPUT_MIN_CONFIG", $i);
2984 $start_minconfig = set_test_option("START_MIN_CONFIG", $i);
2985 $ignore_config = set_test_option("IGNORE_CONFIG", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002986 $run_test = set_test_option("TEST", $i);
2987 $addconfig = set_test_option("ADD_CONFIG", $i);
2988 $reboot_type = set_test_option("REBOOT_TYPE", $i);
2989 $grub_menu = set_test_option("GRUB_MENU", $i);
Steven Rostedt8b37ca82010-11-02 14:58:33 -04002990 $post_install = set_test_option("POST_INSTALL", $i);
Steven Rostedte0a87422011-09-30 17:50:48 -04002991 $no_install = set_test_option("NO_INSTALL", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002992 $reboot_script = set_test_option("REBOOT_SCRIPT", $i);
2993 $reboot_on_error = set_test_option("REBOOT_ON_ERROR", $i);
2994 $poweroff_on_error = set_test_option("POWEROFF_ON_ERROR", $i);
2995 $die_on_failure = set_test_option("DIE_ON_FAILURE", $i);
2996 $power_off = set_test_option("POWER_OFF", $i);
Steven Rostedt576f6272010-11-02 14:58:38 -04002997 $powercycle_after_reboot = set_test_option("POWERCYCLE_AFTER_REBOOT", $i);
2998 $poweroff_after_halt = set_test_option("POWEROFF_AFTER_HALT", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002999 $sleep_time = set_test_option("SLEEP_TIME", $i);
3000 $bisect_sleep_time = set_test_option("BISECT_SLEEP_TIME", $i);
Steven Rostedt27d934b2011-05-20 09:18:18 -04003001 $patchcheck_sleep_time = set_test_option("PATCHCHECK_SLEEP_TIME", $i);
Steven Rostedt19902072011-06-14 20:46:25 -04003002 $ignore_warnings = set_test_option("IGNORE_WARNINGS", $i);
Steven Rostedtc960bb92011-03-08 09:22:39 -05003003 $bisect_manual = set_test_option("BISECT_MANUAL", $i);
Steven Rostedtc23dca72011-03-08 09:26:31 -05003004 $bisect_skip = set_test_option("BISECT_SKIP", $i);
Steven Rostedt30f75da2011-06-13 10:35:35 -04003005 $config_bisect_good = set_test_option("CONFIG_BISECT_GOOD", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04003006 $store_failures = set_test_option("STORE_FAILURES", $i);
Steven Rostedt9064af52011-06-13 10:38:48 -04003007 $test_name = set_test_option("TEST_NAME", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04003008 $timeout = set_test_option("TIMEOUT", $i);
3009 $booted_timeout = set_test_option("BOOTED_TIMEOUT", $i);
3010 $console = set_test_option("CONSOLE", $i);
Steven Rostedtf1a5b962011-06-13 10:30:00 -04003011 $detect_triplefault = set_test_option("DETECT_TRIPLE_FAULT", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04003012 $success_line = set_test_option("SUCCESS_LINE", $i);
Steven Rostedt2b803362011-09-30 18:00:23 -04003013 $reboot_success_line = set_test_option("REBOOT_SUCCESS_LINE", $i);
Steven Rostedt1c8a6172010-11-09 12:55:40 -05003014 $stop_after_success = set_test_option("STOP_AFTER_SUCCESS", $i);
3015 $stop_after_failure = set_test_option("STOP_AFTER_FAILURE", $i);
Steven Rostedt2d01b262011-03-08 09:47:54 -05003016 $stop_test_after = set_test_option("STOP_TEST_AFTER", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04003017 $build_target = set_test_option("BUILD_TARGET", $i);
Steven Rostedte48c5292010-11-02 14:35:37 -04003018 $ssh_exec = set_test_option("SSH_EXEC", $i);
3019 $scp_to_target = set_test_option("SCP_TO_TARGET", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04003020 $target_image = set_test_option("TARGET_IMAGE", $i);
3021 $localversion = set_test_option("LOCALVERSION", $i);
3022
Steven Rostedt35ce5952011-07-15 21:57:25 -04003023 $start_minconfig_defined = 1;
3024
Steven Rostedt4c4ab122011-07-15 21:16:17 -04003025 if (!defined($start_minconfig)) {
Steven Rostedt35ce5952011-07-15 21:57:25 -04003026 $start_minconfig_defined = 0;
Steven Rostedt4c4ab122011-07-15 21:16:17 -04003027 $start_minconfig = $minconfig;
3028 }
3029
Steven Rostedta75fece2010-11-02 14:58:27 -04003030 chdir $builddir || die "can't change directory to $builddir";
3031
Andrew Jonesa908a662011-08-12 15:32:03 +02003032 foreach my $dir ($tmpdir, $outputdir) {
3033 if (!-d $dir) {
3034 mkpath($dir) or
3035 die "can't create $dir";
3036 }
Steven Rostedta75fece2010-11-02 14:58:27 -04003037 }
3038
Steven Rostedte48c5292010-11-02 14:35:37 -04003039 $ENV{"SSH_USER"} = $ssh_user;
3040 $ENV{"MACHINE"} = $machine;
3041
Steven Rostedta75fece2010-11-02 14:58:27 -04003042 $target = "$ssh_user\@$machine";
3043
3044 $buildlog = "$tmpdir/buildlog-$machine";
3045 $dmesg = "$tmpdir/dmesg-$machine";
3046 $make = "$makecmd O=$outputdir";
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05003047 $output_config = "$outputdir/.config";
Steven Rostedta75fece2010-11-02 14:58:27 -04003048
3049 if ($reboot_type eq "grub") {
Steven Rostedt576f6272010-11-02 14:58:38 -04003050 dodie "GRUB_MENU not defined" if (!defined($grub_menu));
Steven Rostedta75fece2010-11-02 14:58:27 -04003051 } elsif (!defined($reboot_script)) {
Steven Rostedt576f6272010-11-02 14:58:38 -04003052 dodie "REBOOT_SCRIPT not defined"
Steven Rostedta75fece2010-11-02 14:58:27 -04003053 }
3054
3055 my $run_type = $build_type;
3056 if ($test_type eq "patchcheck") {
3057 $run_type = $opt{"PATCHCHECK_TYPE[$i]"};
3058 } elsif ($test_type eq "bisect") {
3059 $run_type = $opt{"BISECT_TYPE[$i]"};
Steven Rostedt0a05c762010-11-08 11:14:10 -05003060 } elsif ($test_type eq "config_bisect") {
3061 $run_type = $opt{"CONFIG_BISECT_TYPE[$i]"};
Steven Rostedta75fece2010-11-02 14:58:27 -04003062 }
3063
Steven Rostedt4c4ab122011-07-15 21:16:17 -04003064 if ($test_type eq "make_min_config") {
3065 $run_type = "";
3066 }
3067
Steven Rostedta75fece2010-11-02 14:58:27 -04003068 # mistake in config file?
3069 if (!defined($run_type)) {
3070 $run_type = "ERROR";
3071 }
Steven Rostedt2545eb62010-11-02 15:01:32 -04003072
Steven Rostedte0a87422011-09-30 17:50:48 -04003073 my $installme = "";
3074 $installme = " no_install" if ($no_install);
3075
Steven Rostedt2545eb62010-11-02 15:01:32 -04003076 doprint "\n\n";
Steven Rostedte0a87422011-09-30 17:50:48 -04003077 doprint "RUNNING TEST $i of $opt{NUM_TESTS} with option $test_type $run_type$installme\n\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -04003078
3079 unlink $dmesg;
3080 unlink $buildlog;
Steven Rostedt2545eb62010-11-02 15:01:32 -04003081
Steven Rostedt250bae82011-07-15 22:05:59 -04003082 if (defined($addconfig)) {
3083 my $min = $minconfig;
3084 if (!defined($minconfig)) {
3085 $min = "";
3086 }
3087 run_command "cat $addconfig $min > $tmpdir/add_config" or
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04003088 dodie "Failed to create temp config";
Steven Rostedt9be2e6b2010-11-09 12:20:21 -05003089 $minconfig = "$tmpdir/add_config";
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04003090 }
3091
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04003092 my $checkout = $opt{"CHECKOUT[$i]"};
3093 if (defined($checkout)) {
3094 run_command "git checkout $checkout" or
3095 die "failed to checkout $checkout";
3096 }
3097
Steven Rostedt4ab1cce2011-09-30 18:12:20 -04003098 $no_reboot = 0;
3099
3100
Steven Rostedta75fece2010-11-02 14:58:27 -04003101 if ($test_type eq "bisect") {
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04003102 bisect $i;
3103 next;
Steven Rostedt0a05c762010-11-08 11:14:10 -05003104 } elsif ($test_type eq "config_bisect") {
3105 config_bisect $i;
3106 next;
Steven Rostedta75fece2010-11-02 14:58:27 -04003107 } elsif ($test_type eq "patchcheck") {
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04003108 patchcheck $i;
3109 next;
Steven Rostedt4c4ab122011-07-15 21:16:17 -04003110 } elsif ($test_type eq "make_min_config") {
3111 make_min_config $i;
3112 next;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04003113 }
3114
Steven Rostedt7faafbd2010-11-02 14:58:22 -04003115 if ($build_type ne "nobuild") {
3116 build $build_type or next;
Steven Rostedt2545eb62010-11-02 15:01:32 -04003117 }
3118
Steven Rostedtcd8e3682011-08-18 16:35:44 -04003119 if ($test_type eq "install") {
3120 get_version;
3121 install;
3122 success $i;
3123 next;
3124 }
3125
Steven Rostedta75fece2010-11-02 14:58:27 -04003126 if ($test_type ne "build") {
Steven Rostedta75fece2010-11-02 14:58:27 -04003127 my $failed = 0;
Steven Rostedtddf607e2011-06-14 20:49:13 -04003128 start_monitor_and_boot or $failed = 1;
Steven Rostedta75fece2010-11-02 14:58:27 -04003129
3130 if (!$failed && $test_type ne "boot" && defined($run_test)) {
3131 do_run_test or $failed = 1;
3132 }
3133 end_monitor;
3134 next if ($failed);
Steven Rostedt5a391fb2010-11-02 14:57:43 -04003135 }
3136
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04003137 success $i;
Steven Rostedt2545eb62010-11-02 15:01:32 -04003138}
3139
Steven Rostedt5c42fc52010-11-02 14:57:01 -04003140if ($opt{"POWEROFF_ON_SUCCESS"}) {
Steven Rostedt75c3fda72010-11-02 14:57:21 -04003141 halt;
Steven Rostedt576f6272010-11-02 14:58:38 -04003142} elsif ($opt{"REBOOT_ON_SUCCESS"} && !do_not_reboot) {
Steven Rostedt75c3fda72010-11-02 14:57:21 -04003143 reboot;
Steven Rostedt5c42fc52010-11-02 14:57:01 -04003144}
Steven Rostedt75c3fda72010-11-02 14:57:21 -04003145
Steven Rostedte48c5292010-11-02 14:35:37 -04003146doprint "\n $successes of $opt{NUM_TESTS} tests were successful\n\n";
3147
Steven Rostedt2545eb62010-11-02 15:01:32 -04003148exit 0;