blob: ed20d6881ec9869f7cf0c000e0e718e6382507cd [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 Rostedt2545eb62010-11-02 15:01:32 -0400415sub read_config {
416 my ($config) = @_;
417
418 open(IN, $config) || die "can't read file $config";
419
Steven Rostedta57419b2010-11-02 15:13:54 -0400420 my $name = $config;
421 $name =~ s,.*/(.*),$1,;
422
423 my $test_num = 0;
424 my $default = 1;
425 my $repeat = 1;
426 my $num_tests_set = 0;
427 my $skip = 0;
428 my $rest;
Steven Rostedt0df213c2011-06-14 20:51:37 -0400429 my $test_case = 0;
Steven Rostedt45d73a52011-09-30 19:44:53 -0400430 my $if = 0;
431 my $if_set = 0;
Steven Rostedta57419b2010-11-02 15:13:54 -0400432
Steven Rostedt2545eb62010-11-02 15:01:32 -0400433 while (<IN>) {
434
435 # ignore blank lines and comments
436 next if (/^\s*$/ || /\s*\#/);
437
Steven Rostedta57419b2010-11-02 15:13:54 -0400438 if (/^\s*TEST_START(.*)/) {
439
440 $rest = $1;
441
442 if ($num_tests_set) {
443 die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
444 }
445
446 my $old_test_num = $test_num;
Steven Rostedte48c5292010-11-02 14:35:37 -0400447 my $old_repeat = $repeat;
Steven Rostedta57419b2010-11-02 15:13:54 -0400448
449 $test_num += $repeat;
450 $default = 0;
451 $repeat = 1;
452
Steven Rostedt45d73a52011-09-30 19:44:53 -0400453 if ($rest =~ /\s+SKIP\b(.*)/) {
Steven Rostedta57419b2010-11-02 15:13:54 -0400454 $rest = $1;
455 $skip = 1;
456 } else {
Steven Rostedt0df213c2011-06-14 20:51:37 -0400457 $test_case = 1;
Steven Rostedta57419b2010-11-02 15:13:54 -0400458 $skip = 0;
459 }
460
461 if ($rest =~ /\s+ITERATE\s+(\d+)(.*)$/) {
462 $repeat = $1;
463 $rest = $2;
464 $repeat_tests{"$test_num"} = $repeat;
465 }
466
Steven Rostedtab7a3f52011-09-30 20:24:07 -0400467 if ($rest =~ /\sIF\s+(.*)/) {
468 $rest = "";
Steven Rostedt45d73a52011-09-30 19:44:53 -0400469 if (process_if($name, $1)) {
470 $if_set = 1;
471 } else {
472 $skip = 1;
473 }
474 $if = 1;
475 } else {
476 $if = 0;
Steven Rostedta57419b2010-11-02 15:13:54 -0400477 }
478
479 if ($rest !~ /^\s*$/) {
480 die "$name: $.: Gargbage found after TEST_START\n$_";
481 }
482
483 if ($skip) {
484 $test_num = $old_test_num;
Steven Rostedte48c5292010-11-02 14:35:37 -0400485 $repeat = $old_repeat;
Steven Rostedta57419b2010-11-02 15:13:54 -0400486 }
487
488 } elsif (/^\s*DEFAULTS(.*)$/) {
489 $default = 1;
490
491 $rest = $1;
492
493 if ($rest =~ /\s+SKIP(.*)/) {
494 $rest = $1;
495 $skip = 1;
496 } else {
497 $skip = 0;
498 }
499
Steven Rostedtab7a3f52011-09-30 20:24:07 -0400500 if ($rest =~ /\sIF\s+(.*)/) {
Steven Rostedt45d73a52011-09-30 19:44:53 -0400501 $if = 1;
Steven Rostedt45d73a52011-09-30 19:44:53 -0400502 if (process_if($name, $1)) {
503 $if_set = 1;
504 } else {
505 $skip = 1;
506 }
Steven Rostedtab7a3f52011-09-30 20:24:07 -0400507 $rest = "";
Steven Rostedt45d73a52011-09-30 19:44:53 -0400508 } else {
509 $if = 0;
510 }
511
Steven Rostedta57419b2010-11-02 15:13:54 -0400512 if ($rest !~ /^\s*$/) {
513 die "$name: $.: Gargbage found after DEFAULTS\n$_";
514 }
515
Steven Rostedtab7a3f52011-09-30 20:24:07 -0400516 } elsif (/^\s*ELSE\b(.*)$/) {
Steven Rostedt45d73a52011-09-30 19:44:53 -0400517 if (!$if) {
518 die "$name: $.: ELSE found with out matching IF section\n$_";
519 }
520 $rest = $1;
521 if ($if_set) {
522 $skip = 1;
Steven Rostedtab7a3f52011-09-30 20:24:07 -0400523 $rest = "";
Steven Rostedt45d73a52011-09-30 19:44:53 -0400524 } else {
525 $skip = 0;
526
Steven Rostedtab7a3f52011-09-30 20:24:07 -0400527 if ($rest =~ /\sIF\s+(.*)/) {
Steven Rostedt45d73a52011-09-30 19:44:53 -0400528 # May be a ELSE IF section.
529 if (!process_if($name, $1)) {
530 $skip = 1;
531 }
Steven Rostedtab7a3f52011-09-30 20:24:07 -0400532 $rest = "";
Steven Rostedt45d73a52011-09-30 19:44:53 -0400533 } else {
534 $if = 0;
535 }
536 }
537
Steven Rostedtab7a3f52011-09-30 20:24:07 -0400538 if ($rest !~ /^\s*$/) {
539 die "$name: $.: Gargbage found after DEFAULTS\n$_";
540 }
541
Steven Rostedta57419b2010-11-02 15:13:54 -0400542 } elsif (/^\s*([A-Z_\[\]\d]+)\s*=\s*(.*?)\s*$/) {
543
544 next if ($skip);
545
Steven Rostedt2545eb62010-11-02 15:01:32 -0400546 my $lvalue = $1;
547 my $rvalue = $2;
548
Steven Rostedta57419b2010-11-02 15:13:54 -0400549 if (!$default &&
550 ($lvalue eq "NUM_TESTS" ||
551 $lvalue eq "LOG_FILE" ||
552 $lvalue eq "CLEAR_LOG")) {
553 die "$name: $.: $lvalue must be set in DEFAULTS section\n";
Steven Rostedta75fece2010-11-02 14:58:27 -0400554 }
Steven Rostedta57419b2010-11-02 15:13:54 -0400555
556 if ($lvalue eq "NUM_TESTS") {
557 if ($test_num) {
558 die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
559 }
560 if (!$default) {
561 die "$name: $.: NUM_TESTS must be set in default section\n";
562 }
563 $num_tests_set = 1;
564 }
565
566 if ($default || $lvalue =~ /\[\d+\]$/) {
567 set_value($lvalue, $rvalue);
568 } else {
569 my $val = "$lvalue\[$test_num\]";
570 set_value($val, $rvalue);
571
572 if ($repeat > 1) {
573 $repeats{$val} = $repeat;
574 }
575 }
Steven Rostedt77d942c2011-05-20 13:36:58 -0400576 } elsif (/^\s*([A-Z_\[\]\d]+)\s*:=\s*(.*?)\s*$/) {
577 next if ($skip);
578
579 my $lvalue = $1;
580 my $rvalue = $2;
581
582 # process config variables.
583 # Config variables are only active while reading the
584 # config and can be defined anywhere. They also ignore
585 # TEST_START and DEFAULTS, but are skipped if they are in
586 # on of these sections that have SKIP defined.
587 # The save variable can be
588 # defined multiple times and the new one simply overrides
589 # the prevous one.
590 set_variable($lvalue, $rvalue);
591
Steven Rostedta57419b2010-11-02 15:13:54 -0400592 } else {
593 die "$name: $.: Garbage found in config\n$_";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400594 }
595 }
596
597 close(IN);
Steven Rostedta75fece2010-11-02 14:58:27 -0400598
Steven Rostedta57419b2010-11-02 15:13:54 -0400599 if ($test_num) {
600 $test_num += $repeat - 1;
601 $opt{"NUM_TESTS"} = $test_num;
602 }
603
Steven Rostedt8d1491b2010-11-18 15:39:48 -0500604 # make sure we have all mandatory configs
605 get_ktest_configs;
606
Steven Rostedt0df213c2011-06-14 20:51:37 -0400607 # was a test specified?
608 if (!$test_case) {
609 print "No test case specified.\n";
610 print "What test case would you like to run?\n";
611 my $ans = <STDIN>;
612 chomp $ans;
613 $default{"TEST_TYPE"} = $ans;
614 }
615
Steven Rostedta75fece2010-11-02 14:58:27 -0400616 # set any defaults
617
618 foreach my $default (keys %default) {
619 if (!defined($opt{$default})) {
620 $opt{$default} = $default{$default};
621 }
622 }
Steven Rostedt2545eb62010-11-02 15:01:32 -0400623}
624
Steven Rostedt23715c3c2011-06-13 11:03:34 -0400625sub __eval_option {
626 my ($option, $i) = @_;
627
628 # Add space to evaluate the character before $
629 $option = " $option";
630 my $retval = "";
631
632 while ($option =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) {
633 my $start = $1;
634 my $var = $2;
635 my $end = $3;
636
637 # Append beginning of line
638 $retval = "$retval$start";
639
640 # If the iteration option OPT[$i] exists, then use that.
641 # otherwise see if the default OPT (without [$i]) exists.
642
643 my $o = "$var\[$i\]";
644
645 if (defined($opt{$o})) {
646 $o = $opt{$o};
647 $retval = "$retval$o";
648 } elsif (defined($opt{$var})) {
649 $o = $opt{$var};
650 $retval = "$retval$o";
651 } else {
652 $retval = "$retval\$\{$var\}";
653 }
654
655 $option = $end;
656 }
657
658 $retval = "$retval$option";
659
660 $retval =~ s/^ //;
661
662 return $retval;
663}
664
665sub eval_option {
666 my ($option, $i) = @_;
667
668 my $prev = "";
669
670 # Since an option can evaluate to another option,
671 # keep iterating until we do not evaluate any more
672 # options.
673 my $r = 0;
674 while ($prev ne $option) {
675 # Check for recursive evaluations.
676 # 100 deep should be more than enough.
677 if ($r++ > 100) {
678 die "Over 100 evaluations accurred with $option\n" .
679 "Check for recursive variables\n";
680 }
681 $prev = $option;
682 $option = __eval_option($option, $i);
683 }
684
685 return $option;
686}
687
Steven Rostedtd1e2f222010-11-08 16:39:57 -0500688sub _logit {
Steven Rostedt2545eb62010-11-02 15:01:32 -0400689 if (defined($opt{"LOG_FILE"})) {
690 open(OUT, ">> $opt{LOG_FILE}") or die "Can't write to $opt{LOG_FILE}";
691 print OUT @_;
692 close(OUT);
693 }
694}
695
Steven Rostedtd1e2f222010-11-08 16:39:57 -0500696sub logit {
697 if (defined($opt{"LOG_FILE"})) {
698 _logit @_;
699 } else {
700 print @_;
701 }
702}
703
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400704sub doprint {
705 print @_;
Steven Rostedtd1e2f222010-11-08 16:39:57 -0500706 _logit @_;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400707}
708
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400709sub run_command;
Andrew Jones2728be42011-08-12 15:32:05 +0200710sub start_monitor;
711sub end_monitor;
712sub wait_for_monitor;
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400713
714sub reboot {
Andrew Jones2728be42011-08-12 15:32:05 +0200715 my ($time) = @_;
716
Steven Rostedt2b803362011-09-30 18:00:23 -0400717 if (defined($time)) {
718 start_monitor;
719 # flush out current monitor
720 # May contain the reboot success line
721 wait_for_monitor 1;
722 }
723
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400724 # try to reboot normally
Steven Rostedte48c5292010-11-02 14:35:37 -0400725 if (run_command $reboot) {
Steven Rostedt576f6272010-11-02 14:58:38 -0400726 if (defined($powercycle_after_reboot)) {
727 sleep $powercycle_after_reboot;
728 run_command "$power_cycle";
729 }
730 } else {
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400731 # nope? power cycle it.
Steven Rostedta75fece2010-11-02 14:58:27 -0400732 run_command "$power_cycle";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400733 }
Andrew Jones2728be42011-08-12 15:32:05 +0200734
735 if (defined($time)) {
Steven Rostedt2b803362011-09-30 18:00:23 -0400736 wait_for_monitor($time, $reboot_success_line);
Andrew Jones2728be42011-08-12 15:32:05 +0200737 end_monitor;
738 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400739}
740
Steven Rostedt576f6272010-11-02 14:58:38 -0400741sub do_not_reboot {
742 my $i = $iteration;
743
Steven Rostedt4ab1cce2011-09-30 18:12:20 -0400744 return $test_type eq "build" || $no_reboot ||
Steven Rostedt576f6272010-11-02 14:58:38 -0400745 ($test_type eq "patchcheck" && $opt{"PATCHCHECK_TYPE[$i]"} eq "build") ||
746 ($test_type eq "bisect" && $opt{"BISECT_TYPE[$i]"} eq "build");
747}
748
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400749sub dodie {
Steven Rostedt5a391fb2010-11-02 14:57:43 -0400750 doprint "CRITICAL FAILURE... ", @_, "\n";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400751
Steven Rostedt576f6272010-11-02 14:58:38 -0400752 my $i = $iteration;
753
754 if ($reboot_on_error && !do_not_reboot) {
755
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400756 doprint "REBOOTING\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400757 reboot;
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400758
Steven Rostedta75fece2010-11-02 14:58:27 -0400759 } elsif ($poweroff_on_error && defined($power_off)) {
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400760 doprint "POWERING OFF\n";
Steven Rostedta75fece2010-11-02 14:58:27 -0400761 `$power_off`;
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400762 }
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400763
Steven Rostedtf80802c2011-03-07 13:18:47 -0500764 if (defined($opt{"LOG_FILE"})) {
765 print " See $opt{LOG_FILE} for more info.\n";
766 }
767
Steven Rostedt576f6272010-11-02 14:58:38 -0400768 die @_, "\n";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400769}
770
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400771sub open_console {
772 my ($fp) = @_;
773
774 my $flags;
775
Steven Rostedta75fece2010-11-02 14:58:27 -0400776 my $pid = open($fp, "$console|") or
777 dodie "Can't open console $console";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400778
779 $flags = fcntl($fp, F_GETFL, 0) or
Steven Rostedt576f6272010-11-02 14:58:38 -0400780 dodie "Can't get flags for the socket: $!";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400781 $flags = fcntl($fp, F_SETFL, $flags | O_NONBLOCK) or
Steven Rostedt576f6272010-11-02 14:58:38 -0400782 dodie "Can't set flags for the socket: $!";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400783
784 return $pid;
785}
786
787sub close_console {
788 my ($fp, $pid) = @_;
789
790 doprint "kill child process $pid\n";
791 kill 2, $pid;
792
793 print "closing!\n";
794 close($fp);
795}
796
797sub start_monitor {
798 if ($monitor_cnt++) {
799 return;
800 }
801 $monitor_fp = \*MONFD;
802 $monitor_pid = open_console $monitor_fp;
Steven Rostedta75fece2010-11-02 14:58:27 -0400803
804 return;
805
806 open(MONFD, "Stop perl from warning about single use of MONFD");
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400807}
808
809sub end_monitor {
810 if (--$monitor_cnt) {
811 return;
812 }
813 close_console($monitor_fp, $monitor_pid);
814}
815
816sub wait_for_monitor {
Steven Rostedt2b803362011-09-30 18:00:23 -0400817 my ($time, $stop) = @_;
818 my $full_line = "";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400819 my $line;
Steven Rostedt2b803362011-09-30 18:00:23 -0400820 my $booted = 0;
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400821
Steven Rostedta75fece2010-11-02 14:58:27 -0400822 doprint "** Wait for monitor to settle down **\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400823
824 # read the monitor and wait for the system to calm down
Steven Rostedt2b803362011-09-30 18:00:23 -0400825 while (!$booted) {
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400826 $line = wait_for_input($monitor_fp, $time);
Steven Rostedt2b803362011-09-30 18:00:23 -0400827 last if (!defined($line));
828 print "$line";
829 $full_line .= $line;
830
831 if (defined($stop) && $full_line =~ /$stop/) {
832 doprint "wait for monitor detected $stop\n";
833 $booted = 1;
834 }
835
836 if ($line =~ /\n/) {
837 $full_line = "";
838 }
839 }
Steven Rostedta75fece2010-11-02 14:58:27 -0400840 print "** Monitor flushed **\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400841}
842
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400843sub fail {
844
Steven Rostedta75fece2010-11-02 14:58:27 -0400845 if ($die_on_failure) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400846 dodie @_;
847 }
848
Steven Rostedta75fece2010-11-02 14:58:27 -0400849 doprint "FAILED\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400850
Steven Rostedt576f6272010-11-02 14:58:38 -0400851 my $i = $iteration;
852
Steven Rostedta75fece2010-11-02 14:58:27 -0400853 # no need to reboot for just building.
Steven Rostedt576f6272010-11-02 14:58:38 -0400854 if (!do_not_reboot) {
Steven Rostedta75fece2010-11-02 14:58:27 -0400855 doprint "REBOOTING\n";
Andrew Jones2728be42011-08-12 15:32:05 +0200856 reboot $sleep_time;
Steven Rostedta75fece2010-11-02 14:58:27 -0400857 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400858
Steven Rostedt9064af52011-06-13 10:38:48 -0400859 my $name = "";
860
861 if (defined($test_name)) {
862 $name = " ($test_name)";
863 }
864
Steven Rostedt576f6272010-11-02 14:58:38 -0400865 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
866 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
Steven Rostedt9064af52011-06-13 10:38:48 -0400867 doprint "KTEST RESULT: TEST $i$name Failed: ", @_, "\n";
Steven Rostedt576f6272010-11-02 14:58:38 -0400868 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
869 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
Steven Rostedta75fece2010-11-02 14:58:27 -0400870
871 return 1 if (!defined($store_failures));
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400872
873 my @t = localtime;
874 my $date = sprintf "%04d%02d%02d%02d%02d%02d",
875 1900+$t[5],$t[4],$t[3],$t[2],$t[1],$t[0];
876
Steven Rostedtcccae1a2010-11-09 12:21:32 -0500877 my $type = $build_type;
878 if ($type =~ /useconfig/) {
879 $type = "useconfig";
880 }
881
882 my $dir = "$machine-$test_type-$type-fail-$date";
Steven Rostedta75fece2010-11-02 14:58:27 -0400883 my $faildir = "$store_failures/$dir";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400884
885 if (!-d $faildir) {
886 mkpath($faildir) or
Steven Rostedta75fece2010-11-02 14:58:27 -0400887 die "can't create $faildir";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400888 }
Steven Rostedt51ad1dd2010-11-08 16:43:21 -0500889 if (-f "$output_config") {
890 cp "$output_config", "$faildir/config" or
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400891 die "failed to copy .config";
892 }
893 if (-f $buildlog) {
894 cp $buildlog, "$faildir/buildlog" or
895 die "failed to move $buildlog";
896 }
897 if (-f $dmesg) {
898 cp $dmesg, "$faildir/dmesg" or
899 die "failed to move $dmesg";
900 }
901
902 doprint "*** Saved info to $faildir ***\n";
903
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400904 return 1;
905}
906
Steven Rostedt2545eb62010-11-02 15:01:32 -0400907sub run_command {
908 my ($command) = @_;
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400909 my $dolog = 0;
910 my $dord = 0;
911 my $pid;
912
Steven Rostedte48c5292010-11-02 14:35:37 -0400913 $command =~ s/\$SSH_USER/$ssh_user/g;
914 $command =~ s/\$MACHINE/$machine/g;
915
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400916 doprint("$command ... ");
917
918 $pid = open(CMD, "$command 2>&1 |") or
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400919 (fail "unable to exec $command" and return 0);
Steven Rostedt2545eb62010-11-02 15:01:32 -0400920
921 if (defined($opt{"LOG_FILE"})) {
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400922 open(LOG, ">>$opt{LOG_FILE}") or
923 dodie "failed to write to log";
924 $dolog = 1;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -0400925 }
926
927 if (defined($redirect)) {
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400928 open (RD, ">$redirect") or
929 dodie "failed to write to redirect $redirect";
930 $dord = 1;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400931 }
932
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400933 while (<CMD>) {
934 print LOG if ($dolog);
935 print RD if ($dord);
936 }
Steven Rostedt2545eb62010-11-02 15:01:32 -0400937
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400938 waitpid($pid, 0);
Steven Rostedt2545eb62010-11-02 15:01:32 -0400939 my $failed = $?;
940
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400941 close(CMD);
942 close(LOG) if ($dolog);
943 close(RD) if ($dord);
944
Steven Rostedt2545eb62010-11-02 15:01:32 -0400945 if ($failed) {
946 doprint "FAILED!\n";
947 } else {
948 doprint "SUCCESS\n";
949 }
950
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400951 return !$failed;
952}
953
Steven Rostedte48c5292010-11-02 14:35:37 -0400954sub run_ssh {
955 my ($cmd) = @_;
956 my $cp_exec = $ssh_exec;
957
958 $cp_exec =~ s/\$SSH_COMMAND/$cmd/g;
959 return run_command "$cp_exec";
960}
961
962sub run_scp {
963 my ($src, $dst) = @_;
964 my $cp_scp = $scp_to_target;
965
966 $cp_scp =~ s/\$SRC_FILE/$src/g;
967 $cp_scp =~ s/\$DST_FILE/$dst/g;
968
969 return run_command "$cp_scp";
970}
971
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400972sub get_grub_index {
973
Steven Rostedta75fece2010-11-02 14:58:27 -0400974 if ($reboot_type ne "grub") {
975 return;
976 }
Steven Rostedt5a391fb2010-11-02 14:57:43 -0400977 return if (defined($grub_number));
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400978
979 doprint "Find grub menu ... ";
980 $grub_number = -1;
Steven Rostedte48c5292010-11-02 14:35:37 -0400981
982 my $ssh_grub = $ssh_exec;
983 $ssh_grub =~ s,\$SSH_COMMAND,cat /boot/grub/menu.lst,g;
984
985 open(IN, "$ssh_grub |")
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400986 or die "unable to get menu.lst";
Steven Rostedte48c5292010-11-02 14:35:37 -0400987
Steven Rostedteaa1fe22011-09-14 17:20:39 -0400988 my $found = 0;
989
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400990 while (<IN>) {
Steven Rostedta75fece2010-11-02 14:58:27 -0400991 if (/^\s*title\s+$grub_menu\s*$/) {
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400992 $grub_number++;
Steven Rostedteaa1fe22011-09-14 17:20:39 -0400993 $found = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400994 last;
995 } elsif (/^\s*title\s/) {
996 $grub_number++;
997 }
998 }
999 close(IN);
1000
Steven Rostedta75fece2010-11-02 14:58:27 -04001001 die "Could not find '$grub_menu' in /boot/grub/menu on $machine"
Steven Rostedteaa1fe22011-09-14 17:20:39 -04001002 if (!$found);
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001003 doprint "$grub_number\n";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001004}
1005
Steven Rostedt2545eb62010-11-02 15:01:32 -04001006sub wait_for_input
1007{
1008 my ($fp, $time) = @_;
1009 my $rin;
1010 my $ready;
1011 my $line;
1012 my $ch;
1013
1014 if (!defined($time)) {
1015 $time = $timeout;
1016 }
1017
1018 $rin = '';
1019 vec($rin, fileno($fp), 1) = 1;
1020 $ready = select($rin, undef, undef, $time);
1021
1022 $line = "";
1023
1024 # try to read one char at a time
1025 while (sysread $fp, $ch, 1) {
1026 $line .= $ch;
1027 last if ($ch eq "\n");
1028 }
1029
1030 if (!length($line)) {
1031 return undef;
1032 }
1033
1034 return $line;
1035}
1036
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001037sub reboot_to {
Steven Rostedta75fece2010-11-02 14:58:27 -04001038 if ($reboot_type eq "grub") {
Steven Rostedt4da46da2011-06-01 23:25:13 -04001039 run_ssh "'(echo \"savedefault --default=$grub_number --once\" | grub --batch && reboot)'";
Steven Rostedta75fece2010-11-02 14:58:27 -04001040 return;
1041 }
1042
1043 run_command "$reboot_script";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001044}
1045
Steven Rostedta57419b2010-11-02 15:13:54 -04001046sub get_sha1 {
1047 my ($commit) = @_;
1048
1049 doprint "git rev-list --max-count=1 $commit ... ";
1050 my $sha1 = `git rev-list --max-count=1 $commit`;
1051 my $ret = $?;
1052
1053 logit $sha1;
1054
1055 if ($ret) {
1056 doprint "FAILED\n";
1057 dodie "Failed to get git $commit";
1058 }
1059
1060 print "SUCCESS\n";
1061
1062 chomp $sha1;
1063
1064 return $sha1;
1065}
1066
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001067sub monitor {
Steven Rostedt2545eb62010-11-02 15:01:32 -04001068 my $booted = 0;
1069 my $bug = 0;
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001070 my $skip_call_trace = 0;
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001071 my $loops;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001072
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001073 wait_for_monitor 5;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001074
1075 my $line;
1076 my $full_line = "";
1077
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001078 open(DMESG, "> $dmesg") or
1079 die "unable to write to $dmesg";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001080
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001081 reboot_to;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001082
Steven Rostedt1c8a6172010-11-09 12:55:40 -05001083 my $success_start;
1084 my $failure_start;
Steven Rostedt2d01b262011-03-08 09:47:54 -05001085 my $monitor_start = time;
1086 my $done = 0;
Steven Rostedtf1a5b962011-06-13 10:30:00 -04001087 my $version_found = 0;
Steven Rostedt1c8a6172010-11-09 12:55:40 -05001088
Steven Rostedt2d01b262011-03-08 09:47:54 -05001089 while (!$done) {
Steven Rostedt2545eb62010-11-02 15:01:32 -04001090
Steven Rostedtecaf8e52011-06-13 10:48:10 -04001091 if ($bug && defined($stop_after_failure) &&
1092 $stop_after_failure >= 0) {
1093 my $time = $stop_after_failure - (time - $failure_start);
1094 $line = wait_for_input($monitor_fp, $time);
1095 if (!defined($line)) {
1096 doprint "bug timed out after $booted_timeout seconds\n";
1097 doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
1098 last;
1099 }
1100 } elsif ($booted) {
Steven Rostedta75fece2010-11-02 14:58:27 -04001101 $line = wait_for_input($monitor_fp, $booted_timeout);
Steven Rostedtcd4f1d52011-06-13 10:26:27 -04001102 if (!defined($line)) {
1103 my $s = $booted_timeout == 1 ? "" : "s";
1104 doprint "Successful boot found: break after $booted_timeout second$s\n";
1105 last;
1106 }
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001107 } else {
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001108 $line = wait_for_input($monitor_fp);
Steven Rostedtcd4f1d52011-06-13 10:26:27 -04001109 if (!defined($line)) {
1110 my $s = $timeout == 1 ? "" : "s";
1111 doprint "Timed out after $timeout second$s\n";
1112 last;
1113 }
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001114 }
Steven Rostedt2545eb62010-11-02 15:01:32 -04001115
Steven Rostedt2545eb62010-11-02 15:01:32 -04001116 doprint $line;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001117 print DMESG $line;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001118
1119 # we are not guaranteed to get a full line
1120 $full_line .= $line;
1121
Steven Rostedta75fece2010-11-02 14:58:27 -04001122 if ($full_line =~ /$success_line/) {
Steven Rostedt2545eb62010-11-02 15:01:32 -04001123 $booted = 1;
Steven Rostedt1c8a6172010-11-09 12:55:40 -05001124 $success_start = time;
1125 }
1126
1127 if ($booted && defined($stop_after_success) &&
1128 $stop_after_success >= 0) {
1129 my $now = time;
1130 if ($now - $success_start >= $stop_after_success) {
1131 doprint "Test forced to stop after $stop_after_success seconds after success\n";
1132 last;
1133 }
Steven Rostedt2545eb62010-11-02 15:01:32 -04001134 }
1135
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001136 if ($full_line =~ /\[ backtrace testing \]/) {
1137 $skip_call_trace = 1;
1138 }
1139
Steven Rostedt2545eb62010-11-02 15:01:32 -04001140 if ($full_line =~ /call trace:/i) {
Steven Rostedt46519202011-03-08 09:40:31 -05001141 if (!$bug && !$skip_call_trace) {
Steven Rostedt1c8a6172010-11-09 12:55:40 -05001142 $bug = 1;
1143 $failure_start = time;
1144 }
1145 }
1146
1147 if ($bug && defined($stop_after_failure) &&
1148 $stop_after_failure >= 0) {
1149 my $now = time;
1150 if ($now - $failure_start >= $stop_after_failure) {
1151 doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
1152 last;
1153 }
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001154 }
1155
1156 if ($full_line =~ /\[ end of backtrace testing \]/) {
1157 $skip_call_trace = 0;
1158 }
1159
1160 if ($full_line =~ /Kernel panic -/) {
Steven Rostedt10abf112011-03-07 13:21:00 -05001161 $failure_start = time;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001162 $bug = 1;
1163 }
1164
Steven Rostedtf1a5b962011-06-13 10:30:00 -04001165 # Detect triple faults by testing the banner
1166 if ($full_line =~ /\bLinux version (\S+).*\n/) {
1167 if ($1 eq $version) {
1168 $version_found = 1;
1169 } elsif ($version_found && $detect_triplefault) {
1170 # We already booted into the kernel we are testing,
1171 # but now we booted into another kernel?
1172 # Consider this a triple fault.
1173 doprint "Aleady booted in Linux kernel $version, but now\n";
1174 doprint "we booted into Linux kernel $1.\n";
1175 doprint "Assuming that this is a triple fault.\n";
1176 doprint "To disable this: set DETECT_TRIPLE_FAULT to 0\n";
1177 last;
1178 }
1179 }
1180
Steven Rostedt2545eb62010-11-02 15:01:32 -04001181 if ($line =~ /\n/) {
1182 $full_line = "";
1183 }
Steven Rostedt2d01b262011-03-08 09:47:54 -05001184
1185 if ($stop_test_after > 0 && !$booted && !$bug) {
1186 if (time - $monitor_start > $stop_test_after) {
Steven Rostedt4d62bf52011-05-20 09:14:35 -04001187 doprint "STOP_TEST_AFTER ($stop_test_after seconds) timed out\n";
Steven Rostedt2d01b262011-03-08 09:47:54 -05001188 $done = 1;
1189 }
1190 }
Steven Rostedt2545eb62010-11-02 15:01:32 -04001191 }
1192
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001193 close(DMESG);
Steven Rostedt2545eb62010-11-02 15:01:32 -04001194
Steven Rostedt2545eb62010-11-02 15:01:32 -04001195 if ($bug) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001196 return 0 if ($in_bisect);
Steven Rostedt576f6272010-11-02 14:58:38 -04001197 fail "failed - got a bug report" and return 0;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001198 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001199
Steven Rostedta75fece2010-11-02 14:58:27 -04001200 if (!$booted) {
1201 return 0 if ($in_bisect);
Steven Rostedt576f6272010-11-02 14:58:38 -04001202 fail "failed - never got a boot prompt." and return 0;
Steven Rostedta75fece2010-11-02 14:58:27 -04001203 }
1204
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001205 return 1;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001206}
1207
Steven Rostedtdb05cfe2011-06-13 11:09:22 -04001208sub do_post_install {
1209
1210 return if (!defined($post_install));
1211
1212 my $cp_post_install = $post_install;
1213 $cp_post_install =~ s/\$KERNEL_VERSION/$version/g;
1214 run_command "$cp_post_install" or
1215 dodie "Failed to run post install";
1216}
1217
Steven Rostedt2545eb62010-11-02 15:01:32 -04001218sub install {
1219
Steven Rostedte0a87422011-09-30 17:50:48 -04001220 return if ($no_install);
1221
Steven Rostedte48c5292010-11-02 14:35:37 -04001222 run_scp "$outputdir/$build_target", "$target_image" or
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001223 dodie "failed to copy image";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001224
1225 my $install_mods = 0;
1226
1227 # should we process modules?
1228 $install_mods = 0;
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05001229 open(IN, "$output_config") or dodie("Can't read config file");
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001230 while (<IN>) {
1231 if (/CONFIG_MODULES(=y)?/) {
1232 $install_mods = 1 if (defined($1));
1233 last;
1234 }
1235 }
1236 close(IN);
1237
1238 if (!$install_mods) {
Steven Rostedtdb05cfe2011-06-13 11:09:22 -04001239 do_post_install;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001240 doprint "No modules needed\n";
1241 return;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001242 }
1243
Steven Rostedta75fece2010-11-02 14:58:27 -04001244 run_command "$make INSTALL_MOD_PATH=$tmpdir modules_install" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001245 dodie "Failed to install modules";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001246
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001247 my $modlib = "/lib/modules/$version";
Steven Rostedta57419b2010-11-02 15:13:54 -04001248 my $modtar = "ktest-mods.tar.bz2";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001249
Steven Rostedte48c5292010-11-02 14:35:37 -04001250 run_ssh "rm -rf $modlib" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001251 dodie "failed to remove old mods: $modlib";
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001252
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001253 # would be nice if scp -r did not follow symbolic links
Steven Rostedta75fece2010-11-02 14:58:27 -04001254 run_command "cd $tmpdir && tar -cjf $modtar lib/modules/$version" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001255 dodie "making tarball";
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001256
Steven Rostedte48c5292010-11-02 14:35:37 -04001257 run_scp "$tmpdir/$modtar", "/tmp" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001258 dodie "failed to copy modules";
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001259
Steven Rostedta75fece2010-11-02 14:58:27 -04001260 unlink "$tmpdir/$modtar";
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001261
Steven Rostedte7b13442011-06-14 20:44:36 -04001262 run_ssh "'(cd / && tar xjf /tmp/$modtar)'" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001263 dodie "failed to tar modules";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001264
Steven Rostedte48c5292010-11-02 14:35:37 -04001265 run_ssh "rm -f /tmp/$modtar";
Steven Rostedt8b37ca82010-11-02 14:58:33 -04001266
Steven Rostedtdb05cfe2011-06-13 11:09:22 -04001267 do_post_install;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001268}
1269
Steven Rostedtddf607e2011-06-14 20:49:13 -04001270sub get_version {
1271 # get the release name
1272 doprint "$make kernelrelease ... ";
1273 $version = `$make kernelrelease | tail -1`;
1274 chomp($version);
1275 doprint "$version\n";
1276}
1277
1278sub start_monitor_and_boot {
1279 get_grub_index;
1280 get_version;
1281 install;
1282
1283 start_monitor;
1284 return monitor;
1285}
1286
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001287sub check_buildlog {
1288 my ($patch) = @_;
1289
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001290 my @files = `git show $patch | diffstat -l`;
1291
1292 open(IN, "git show $patch |") or
1293 dodie "failed to show $patch";
1294 while (<IN>) {
1295 if (m,^--- a/(.*),) {
1296 chomp $1;
1297 $files[$#files] = $1;
1298 }
1299 }
1300 close(IN);
1301
1302 open(IN, $buildlog) or dodie "Can't open $buildlog";
1303 while (<IN>) {
1304 if (/^\s*(.*?):.*(warning|error)/) {
1305 my $err = $1;
1306 foreach my $file (@files) {
Steven Rostedta75fece2010-11-02 14:58:27 -04001307 my $fullpath = "$builddir/$file";
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001308 if ($file eq $err || $fullpath eq $err) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001309 fail "$file built with warnings" and return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001310 }
1311 }
1312 }
1313 }
1314 close(IN);
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001315
1316 return 1;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001317}
1318
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001319sub apply_min_config {
1320 my $outconfig = "$output_config.new";
Steven Rostedt612b9e92011-03-07 13:27:43 -05001321
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001322 # Read the config file and remove anything that
1323 # is in the force_config hash (from minconfig and others)
1324 # then add the force config back.
1325
1326 doprint "Applying minimum configurations into $output_config.new\n";
1327
1328 open (OUT, ">$outconfig") or
1329 dodie "Can't create $outconfig";
1330
1331 if (-f $output_config) {
1332 open (IN, $output_config) or
1333 dodie "Failed to open $output_config";
1334 while (<IN>) {
1335 if (/^(# )?(CONFIG_[^\s=]*)/) {
1336 next if (defined($force_config{$2}));
1337 }
1338 print OUT;
1339 }
1340 close IN;
1341 }
1342 foreach my $config (keys %force_config) {
1343 print OUT "$force_config{$config}\n";
1344 }
1345 close OUT;
1346
1347 run_command "mv $outconfig $output_config";
1348}
1349
1350sub make_oldconfig {
1351
Steven Rostedt4c4ab122011-07-15 21:16:17 -04001352 my @force_list = keys %force_config;
1353
1354 if ($#force_list >= 0) {
1355 apply_min_config;
1356 }
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001357
1358 if (!run_command "$make oldnoconfig") {
Steven Rostedt612b9e92011-03-07 13:27:43 -05001359 # Perhaps oldnoconfig doesn't exist in this version of the kernel
1360 # try a yes '' | oldconfig
1361 doprint "oldnoconfig failed, trying yes '' | make oldconfig\n";
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001362 run_command "yes '' | $make oldconfig" or
Steven Rostedt612b9e92011-03-07 13:27:43 -05001363 dodie "failed make config oldconfig";
1364 }
1365}
1366
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001367# read a config file and use this to force new configs.
1368sub load_force_config {
1369 my ($config) = @_;
1370
1371 open(IN, $config) or
1372 dodie "failed to read $config";
1373 while (<IN>) {
1374 chomp;
1375 if (/^(CONFIG[^\s=]*)(\s*=.*)/) {
1376 $force_config{$1} = $_;
1377 } elsif (/^# (CONFIG_\S*) is not set/) {
1378 $force_config{$1} = $_;
1379 }
1380 }
1381 close IN;
1382}
1383
Steven Rostedt2545eb62010-11-02 15:01:32 -04001384sub build {
1385 my ($type) = @_;
1386
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001387 unlink $buildlog;
1388
Steven Rostedt4ab1cce2011-09-30 18:12:20 -04001389 # Failed builds should not reboot the target
1390 my $save_no_reboot = $no_reboot;
1391 $no_reboot = 1;
1392
Steven Rostedt0bd6c1a2011-06-14 20:39:31 -04001393 if (defined($pre_build)) {
1394 my $ret = run_command $pre_build;
1395 if (!$ret && defined($pre_build_die) &&
1396 $pre_build_die) {
1397 dodie "failed to pre_build\n";
1398 }
1399 }
1400
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001401 if ($type =~ /^useconfig:(.*)/) {
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05001402 run_command "cp $1 $output_config" or
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001403 dodie "could not copy $1 to .config";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001404
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001405 $type = "oldconfig";
1406 }
1407
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001408 # old config can ask questions
1409 if ($type eq "oldconfig") {
Steven Rostedt9386c6a2010-11-08 16:35:48 -05001410 $type = "oldnoconfig";
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001411
1412 # allow for empty configs
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05001413 run_command "touch $output_config";
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001414
Andrew Jones13488232011-08-12 15:32:04 +02001415 if (!$noclean) {
1416 run_command "mv $output_config $outputdir/config_temp" or
1417 dodie "moving .config";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001418
Andrew Jones13488232011-08-12 15:32:04 +02001419 run_command "$make mrproper" or dodie "make mrproper";
1420
1421 run_command "mv $outputdir/config_temp $output_config" or
1422 dodie "moving config_temp";
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001423 }
1424
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001425 } elsif (!$noclean) {
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05001426 unlink "$output_config";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001427 run_command "$make mrproper" or
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001428 dodie "make mrproper";
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001429 }
Steven Rostedt2545eb62010-11-02 15:01:32 -04001430
1431 # add something to distinguish this build
Steven Rostedta75fece2010-11-02 14:58:27 -04001432 open(OUT, "> $outputdir/localversion") or dodie("Can't make localversion file");
1433 print OUT "$localversion\n";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001434 close(OUT);
1435
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001436 if (defined($minconfig)) {
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001437 load_force_config($minconfig);
Steven Rostedt2545eb62010-11-02 15:01:32 -04001438 }
1439
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001440 if ($type ne "oldnoconfig") {
1441 run_command "$make $type" or
Steven Rostedt612b9e92011-03-07 13:27:43 -05001442 dodie "failed make config";
1443 }
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001444 # Run old config regardless, to enforce min configurations
1445 make_oldconfig;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001446
Steven Rostedta75fece2010-11-02 14:58:27 -04001447 $redirect = "$buildlog";
Steven Rostedt0bd6c1a2011-06-14 20:39:31 -04001448 my $build_ret = run_command "$make $build_options";
1449 undef $redirect;
1450
1451 if (defined($post_build)) {
1452 my $ret = run_command $post_build;
1453 if (!$ret && defined($post_build_die) &&
1454 $post_build_die) {
1455 dodie "failed to post_build\n";
1456 }
1457 }
1458
1459 if (!$build_ret) {
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001460 # bisect may need this to pass
Steven Rostedt4ab1cce2011-09-30 18:12:20 -04001461 if ($in_bisect) {
1462 $no_reboot = $save_no_reboot;
1463 return 0;
1464 }
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001465 fail "failed build" and return 0;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001466 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001467
Steven Rostedt4ab1cce2011-09-30 18:12:20 -04001468 $no_reboot = $save_no_reboot;
1469
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001470 return 1;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001471}
1472
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001473sub halt {
Steven Rostedte48c5292010-11-02 14:35:37 -04001474 if (!run_ssh "halt" or defined($power_off)) {
Steven Rostedt576f6272010-11-02 14:58:38 -04001475 if (defined($poweroff_after_halt)) {
1476 sleep $poweroff_after_halt;
1477 run_command "$power_off";
1478 }
1479 } else {
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001480 # nope? the zap it!
Steven Rostedta75fece2010-11-02 14:58:27 -04001481 run_command "$power_off";
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001482 }
1483}
1484
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001485sub success {
1486 my ($i) = @_;
1487
Steven Rostedte48c5292010-11-02 14:35:37 -04001488 $successes++;
1489
Steven Rostedt9064af52011-06-13 10:38:48 -04001490 my $name = "";
1491
1492 if (defined($test_name)) {
1493 $name = " ($test_name)";
1494 }
1495
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001496 doprint "\n\n*******************************************\n";
1497 doprint "*******************************************\n";
Steven Rostedt9064af52011-06-13 10:38:48 -04001498 doprint "KTEST RESULT: TEST $i$name SUCCESS!!!! **\n";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001499 doprint "*******************************************\n";
1500 doprint "*******************************************\n";
1501
Steven Rostedt576f6272010-11-02 14:58:38 -04001502 if ($i != $opt{"NUM_TESTS"} && !do_not_reboot) {
Steven Rostedta75fece2010-11-02 14:58:27 -04001503 doprint "Reboot and wait $sleep_time seconds\n";
Andrew Jones2728be42011-08-12 15:32:05 +02001504 reboot $sleep_time;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001505 }
1506}
1507
Steven Rostedtc960bb92011-03-08 09:22:39 -05001508sub answer_bisect {
1509 for (;;) {
1510 doprint "Pass or fail? [p/f]";
1511 my $ans = <STDIN>;
1512 chomp $ans;
1513 if ($ans eq "p" || $ans eq "P") {
1514 return 1;
1515 } elsif ($ans eq "f" || $ans eq "F") {
1516 return 0;
1517 } else {
1518 print "Please answer 'P' or 'F'\n";
1519 }
1520 }
1521}
1522
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001523sub child_run_test {
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001524 my $failed = 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001525
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001526 # child should have no power
Steven Rostedta75fece2010-11-02 14:58:27 -04001527 $reboot_on_error = 0;
1528 $poweroff_on_error = 0;
1529 $die_on_failure = 1;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001530
1531 run_command $run_test or $failed = 1;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001532 exit $failed;
1533}
1534
1535my $child_done;
1536
1537sub child_finished {
1538 $child_done = 1;
1539}
1540
1541sub do_run_test {
1542 my $child_pid;
1543 my $child_exit;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001544 my $line;
1545 my $full_line;
1546 my $bug = 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001547
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001548 wait_for_monitor 1;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001549
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001550 doprint "run test $run_test\n";
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001551
1552 $child_done = 0;
1553
1554 $SIG{CHLD} = qw(child_finished);
1555
1556 $child_pid = fork;
1557
1558 child_run_test if (!$child_pid);
1559
1560 $full_line = "";
1561
1562 do {
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001563 $line = wait_for_input($monitor_fp, 1);
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001564 if (defined($line)) {
1565
1566 # we are not guaranteed to get a full line
1567 $full_line .= $line;
Steven Rostedt8ea0e062011-03-08 09:44:35 -05001568 doprint $line;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001569
1570 if ($full_line =~ /call trace:/i) {
1571 $bug = 1;
1572 }
1573
1574 if ($full_line =~ /Kernel panic -/) {
1575 $bug = 1;
1576 }
1577
1578 if ($line =~ /\n/) {
1579 $full_line = "";
1580 }
1581 }
1582 } while (!$child_done && !$bug);
1583
1584 if ($bug) {
Steven Rostedt8ea0e062011-03-08 09:44:35 -05001585 my $failure_start = time;
1586 my $now;
1587 do {
1588 $line = wait_for_input($monitor_fp, 1);
1589 if (defined($line)) {
1590 doprint $line;
1591 }
1592 $now = time;
1593 if ($now - $failure_start >= $stop_after_failure) {
1594 last;
1595 }
1596 } while (defined($line));
1597
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001598 doprint "Detected kernel crash!\n";
1599 # kill the child with extreme prejudice
1600 kill 9, $child_pid;
1601 }
1602
1603 waitpid $child_pid, 0;
1604 $child_exit = $?;
1605
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001606 if ($bug || $child_exit) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001607 return 0 if $in_bisect;
1608 fail "test failed" and return 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001609 }
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001610 return 1;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001611}
1612
Steven Rostedta75fece2010-11-02 14:58:27 -04001613sub run_git_bisect {
1614 my ($command) = @_;
1615
1616 doprint "$command ... ";
1617
1618 my $output = `$command 2>&1`;
1619 my $ret = $?;
1620
1621 logit $output;
1622
1623 if ($ret) {
1624 doprint "FAILED\n";
1625 dodie "Failed to git bisect";
1626 }
1627
1628 doprint "SUCCESS\n";
1629 if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\))\s+\[([[:xdigit:]]+)\]/) {
1630 doprint "$1 [$2]\n";
1631 } elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) {
1632 $bisect_bad = $1;
1633 doprint "Found bad commit... $1\n";
1634 return 0;
1635 } else {
1636 # we already logged it, just print it now.
1637 print $output;
1638 }
1639
1640 return 1;
1641}
1642
Steven Rostedtc23dca72011-03-08 09:26:31 -05001643sub bisect_reboot {
1644 doprint "Reboot and sleep $bisect_sleep_time seconds\n";
Andrew Jones2728be42011-08-12 15:32:05 +02001645 reboot $bisect_sleep_time;
Steven Rostedtc23dca72011-03-08 09:26:31 -05001646}
1647
1648# returns 1 on success, 0 on failure, -1 on skip
Steven Rostedt0a05c762010-11-08 11:14:10 -05001649sub run_bisect_test {
1650 my ($type, $buildtype) = @_;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001651
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001652 my $failed = 0;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001653 my $result;
1654 my $output;
1655 my $ret;
1656
Steven Rostedt0a05c762010-11-08 11:14:10 -05001657 $in_bisect = 1;
1658
1659 build $buildtype or $failed = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001660
1661 if ($type ne "build") {
Steven Rostedtc23dca72011-03-08 09:26:31 -05001662 if ($failed && $bisect_skip) {
1663 $in_bisect = 0;
1664 return -1;
1665 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001666 dodie "Failed on build" if $failed;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001667
1668 # Now boot the box
Steven Rostedtddf607e2011-06-14 20:49:13 -04001669 start_monitor_and_boot or $failed = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001670
1671 if ($type ne "boot") {
Steven Rostedtc23dca72011-03-08 09:26:31 -05001672 if ($failed && $bisect_skip) {
1673 end_monitor;
1674 bisect_reboot;
1675 $in_bisect = 0;
1676 return -1;
1677 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001678 dodie "Failed on boot" if $failed;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001679
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001680 do_run_test or $failed = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001681 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001682 end_monitor;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001683 }
1684
1685 if ($failed) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001686 $result = 0;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001687 } else {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001688 $result = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001689 }
Steven Rostedt4025bc62011-05-20 09:16:29 -04001690
1691 # reboot the box to a kernel we can ssh to
1692 if ($type ne "build") {
1693 bisect_reboot;
1694 }
Steven Rostedt0a05c762010-11-08 11:14:10 -05001695 $in_bisect = 0;
1696
1697 return $result;
1698}
1699
1700sub run_bisect {
1701 my ($type) = @_;
1702 my $buildtype = "oldconfig";
1703
1704 # We should have a minconfig to use?
1705 if (defined($minconfig)) {
1706 $buildtype = "useconfig:$minconfig";
1707 }
1708
1709 my $ret = run_bisect_test $type, $buildtype;
1710
Steven Rostedtc960bb92011-03-08 09:22:39 -05001711 if ($bisect_manual) {
1712 $ret = answer_bisect;
1713 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001714
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04001715 # Are we looking for where it worked, not failed?
1716 if ($reverse_bisect) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001717 $ret = !$ret;
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04001718 }
1719
Steven Rostedtc23dca72011-03-08 09:26:31 -05001720 if ($ret > 0) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001721 return "good";
Steven Rostedtc23dca72011-03-08 09:26:31 -05001722 } elsif ($ret == 0) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001723 return "bad";
Steven Rostedtc23dca72011-03-08 09:26:31 -05001724 } elsif ($bisect_skip) {
1725 doprint "HIT A BAD COMMIT ... SKIPPING\n";
1726 return "skip";
Steven Rostedt0a05c762010-11-08 11:14:10 -05001727 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001728}
1729
1730sub bisect {
1731 my ($i) = @_;
1732
1733 my $result;
1734
1735 die "BISECT_GOOD[$i] not defined\n" if (!defined($opt{"BISECT_GOOD[$i]"}));
1736 die "BISECT_BAD[$i] not defined\n" if (!defined($opt{"BISECT_BAD[$i]"}));
1737 die "BISECT_TYPE[$i] not defined\n" if (!defined($opt{"BISECT_TYPE[$i]"}));
1738
1739 my $good = $opt{"BISECT_GOOD[$i]"};
1740 my $bad = $opt{"BISECT_BAD[$i]"};
1741 my $type = $opt{"BISECT_TYPE[$i]"};
Steven Rostedta75fece2010-11-02 14:58:27 -04001742 my $start = $opt{"BISECT_START[$i]"};
1743 my $replay = $opt{"BISECT_REPLAY[$i]"};
Steven Rostedt3410f6f2011-03-08 09:38:12 -05001744 my $start_files = $opt{"BISECT_FILES[$i]"};
1745
1746 if (defined($start_files)) {
1747 $start_files = " -- " . $start_files;
1748 } else {
1749 $start_files = "";
1750 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001751
Steven Rostedta57419b2010-11-02 15:13:54 -04001752 # convert to true sha1's
1753 $good = get_sha1($good);
1754 $bad = get_sha1($bad);
1755
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04001756 if (defined($opt{"BISECT_REVERSE[$i]"}) &&
1757 $opt{"BISECT_REVERSE[$i]"} == 1) {
1758 doprint "Performing a reverse bisect (bad is good, good is bad!)\n";
1759 $reverse_bisect = 1;
1760 } else {
1761 $reverse_bisect = 0;
1762 }
1763
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001764 # Can't have a test without having a test to run
1765 if ($type eq "test" && !defined($run_test)) {
1766 $type = "boot";
1767 }
1768
Steven Rostedta75fece2010-11-02 14:58:27 -04001769 my $check = $opt{"BISECT_CHECK[$i]"};
1770 if (defined($check) && $check ne "0") {
1771
1772 # get current HEAD
Steven Rostedta57419b2010-11-02 15:13:54 -04001773 my $head = get_sha1("HEAD");
Steven Rostedta75fece2010-11-02 14:58:27 -04001774
1775 if ($check ne "good") {
1776 doprint "TESTING BISECT BAD [$bad]\n";
1777 run_command "git checkout $bad" or
1778 die "Failed to checkout $bad";
1779
1780 $result = run_bisect $type;
1781
1782 if ($result ne "bad") {
1783 fail "Tested BISECT_BAD [$bad] and it succeeded" and return 0;
1784 }
1785 }
1786
1787 if ($check ne "bad") {
1788 doprint "TESTING BISECT GOOD [$good]\n";
1789 run_command "git checkout $good" or
1790 die "Failed to checkout $good";
1791
1792 $result = run_bisect $type;
1793
1794 if ($result ne "good") {
1795 fail "Tested BISECT_GOOD [$good] and it failed" and return 0;
1796 }
1797 }
1798
1799 # checkout where we started
1800 run_command "git checkout $head" or
1801 die "Failed to checkout $head";
1802 }
1803
Steven Rostedt3410f6f2011-03-08 09:38:12 -05001804 run_command "git bisect start$start_files" or
Steven Rostedta75fece2010-11-02 14:58:27 -04001805 dodie "could not start bisect";
1806
1807 run_command "git bisect good $good" or
1808 dodie "could not set bisect good to $good";
1809
1810 run_git_bisect "git bisect bad $bad" or
1811 dodie "could not set bisect bad to $bad";
1812
1813 if (defined($replay)) {
1814 run_command "git bisect replay $replay" or
1815 dodie "failed to run replay";
1816 }
1817
1818 if (defined($start)) {
1819 run_command "git checkout $start" or
1820 dodie "failed to checkout $start";
1821 }
1822
1823 my $test;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001824 do {
1825 $result = run_bisect $type;
Steven Rostedta75fece2010-11-02 14:58:27 -04001826 $test = run_git_bisect "git bisect $result";
1827 } while ($test);
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001828
1829 run_command "git bisect log" or
1830 dodie "could not capture git bisect log";
1831
1832 run_command "git bisect reset" or
1833 dodie "could not reset git bisect";
1834
1835 doprint "Bad commit was [$bisect_bad]\n";
1836
Steven Rostedt0a05c762010-11-08 11:14:10 -05001837 success $i;
1838}
1839
1840my %config_ignore;
1841my %config_set;
1842
1843my %config_list;
1844my %null_config;
1845
1846my %dependency;
1847
Steven Rostedt4c4ab122011-07-15 21:16:17 -04001848sub assign_configs {
1849 my ($hash, $config) = @_;
Steven Rostedt0a05c762010-11-08 11:14:10 -05001850
1851 open (IN, $config)
1852 or dodie "Failed to read $config";
1853
1854 while (<IN>) {
Steven Rostedt9bf71742011-06-01 23:27:19 -04001855 if (/^((CONFIG\S*)=.*)/) {
Steven Rostedt4c4ab122011-07-15 21:16:17 -04001856 ${$hash}{$2} = $1;
Steven Rostedt0a05c762010-11-08 11:14:10 -05001857 }
1858 }
1859
1860 close(IN);
1861}
1862
Steven Rostedt4c4ab122011-07-15 21:16:17 -04001863sub process_config_ignore {
1864 my ($config) = @_;
1865
1866 assign_configs \%config_ignore, $config;
1867}
1868
Steven Rostedt0a05c762010-11-08 11:14:10 -05001869sub read_current_config {
1870 my ($config_ref) = @_;
1871
1872 %{$config_ref} = ();
1873 undef %{$config_ref};
1874
1875 my @key = keys %{$config_ref};
1876 if ($#key >= 0) {
1877 print "did not delete!\n";
1878 exit;
1879 }
1880 open (IN, "$output_config");
1881
1882 while (<IN>) {
1883 if (/^(CONFIG\S+)=(.*)/) {
1884 ${$config_ref}{$1} = $2;
1885 }
1886 }
1887 close(IN);
1888}
1889
1890sub get_dependencies {
1891 my ($config) = @_;
1892
1893 my $arr = $dependency{$config};
1894 if (!defined($arr)) {
1895 return ();
1896 }
1897
1898 my @deps = @{$arr};
1899
1900 foreach my $dep (@{$arr}) {
1901 print "ADD DEP $dep\n";
1902 @deps = (@deps, get_dependencies $dep);
1903 }
1904
1905 return @deps;
1906}
1907
1908sub create_config {
1909 my @configs = @_;
1910
1911 open(OUT, ">$output_config") or dodie "Can not write to $output_config";
1912
1913 foreach my $config (@configs) {
1914 print OUT "$config_set{$config}\n";
1915 my @deps = get_dependencies $config;
1916 foreach my $dep (@deps) {
1917 print OUT "$config_set{$dep}\n";
1918 }
1919 }
1920
1921 foreach my $config (keys %config_ignore) {
1922 print OUT "$config_ignore{$config}\n";
1923 }
1924 close(OUT);
1925
1926# exit;
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001927 make_oldconfig;
Steven Rostedt0a05c762010-11-08 11:14:10 -05001928}
1929
1930sub compare_configs {
1931 my (%a, %b) = @_;
1932
1933 foreach my $item (keys %a) {
1934 if (!defined($b{$item})) {
1935 print "diff $item\n";
1936 return 1;
1937 }
1938 delete $b{$item};
1939 }
1940
1941 my @keys = keys %b;
1942 if ($#keys) {
1943 print "diff2 $keys[0]\n";
1944 }
1945 return -1 if ($#keys >= 0);
1946
1947 return 0;
1948}
1949
1950sub run_config_bisect_test {
1951 my ($type) = @_;
1952
1953 return run_bisect_test $type, "oldconfig";
1954}
1955
1956sub process_passed {
1957 my (%configs) = @_;
1958
1959 doprint "These configs had no failure: (Enabling them for further compiles)\n";
1960 # Passed! All these configs are part of a good compile.
1961 # Add them to the min options.
1962 foreach my $config (keys %configs) {
1963 if (defined($config_list{$config})) {
1964 doprint " removing $config\n";
1965 $config_ignore{$config} = $config_list{$config};
1966 delete $config_list{$config};
1967 }
1968 }
Steven Rostedtf1a27852010-11-11 11:34:38 -05001969 doprint "config copied to $outputdir/config_good\n";
1970 run_command "cp -f $output_config $outputdir/config_good";
Steven Rostedt0a05c762010-11-08 11:14:10 -05001971}
1972
1973sub process_failed {
1974 my ($config) = @_;
1975
1976 doprint "\n\n***************************************\n";
1977 doprint "Found bad config: $config\n";
1978 doprint "***************************************\n\n";
1979}
1980
1981sub run_config_bisect {
1982
1983 my @start_list = keys %config_list;
1984
1985 if ($#start_list < 0) {
1986 doprint "No more configs to test!!!\n";
1987 return -1;
1988 }
1989
1990 doprint "***** RUN TEST ***\n";
1991 my $type = $opt{"CONFIG_BISECT_TYPE[$iteration]"};
1992 my $ret;
1993 my %current_config;
1994
1995 my $count = $#start_list + 1;
1996 doprint " $count configs to test\n";
1997
1998 my $half = int($#start_list / 2);
1999
2000 do {
2001 my @tophalf = @start_list[0 .. $half];
2002
2003 create_config @tophalf;
2004 read_current_config \%current_config;
2005
2006 $count = $#tophalf + 1;
2007 doprint "Testing $count configs\n";
2008 my $found = 0;
2009 # make sure we test something
2010 foreach my $config (@tophalf) {
2011 if (defined($current_config{$config})) {
2012 logit " $config\n";
2013 $found = 1;
2014 }
2015 }
2016 if (!$found) {
2017 # try the other half
2018 doprint "Top half produced no set configs, trying bottom half\n";
Steven Rostedt4c8cc552011-06-01 23:22:30 -04002019 @tophalf = @start_list[$half + 1 .. $#start_list];
Steven Rostedt0a05c762010-11-08 11:14:10 -05002020 create_config @tophalf;
2021 read_current_config \%current_config;
2022 foreach my $config (@tophalf) {
2023 if (defined($current_config{$config})) {
2024 logit " $config\n";
2025 $found = 1;
2026 }
2027 }
2028 if (!$found) {
2029 doprint "Failed: Can't make new config with current configs\n";
2030 foreach my $config (@start_list) {
2031 doprint " CONFIG: $config\n";
2032 }
2033 return -1;
2034 }
2035 $count = $#tophalf + 1;
2036 doprint "Testing $count configs\n";
2037 }
2038
2039 $ret = run_config_bisect_test $type;
Steven Rostedtc960bb92011-03-08 09:22:39 -05002040 if ($bisect_manual) {
2041 $ret = answer_bisect;
2042 }
Steven Rostedt0a05c762010-11-08 11:14:10 -05002043 if ($ret) {
2044 process_passed %current_config;
2045 return 0;
2046 }
2047
2048 doprint "This config had a failure.\n";
2049 doprint "Removing these configs that were not set in this config:\n";
Steven Rostedtf1a27852010-11-11 11:34:38 -05002050 doprint "config copied to $outputdir/config_bad\n";
2051 run_command "cp -f $output_config $outputdir/config_bad";
Steven Rostedt0a05c762010-11-08 11:14:10 -05002052
2053 # A config exists in this group that was bad.
2054 foreach my $config (keys %config_list) {
2055 if (!defined($current_config{$config})) {
2056 doprint " removing $config\n";
2057 delete $config_list{$config};
2058 }
2059 }
2060
2061 @start_list = @tophalf;
2062
2063 if ($#start_list == 0) {
2064 process_failed $start_list[0];
2065 return 1;
2066 }
2067
2068 # remove half the configs we are looking at and see if
2069 # they are good.
2070 $half = int($#start_list / 2);
Steven Rostedt4c8cc552011-06-01 23:22:30 -04002071 } while ($#start_list > 0);
Steven Rostedt0a05c762010-11-08 11:14:10 -05002072
Steven Rostedtc960bb92011-03-08 09:22:39 -05002073 # we found a single config, try it again unless we are running manually
2074
2075 if ($bisect_manual) {
2076 process_failed $start_list[0];
2077 return 1;
2078 }
2079
Steven Rostedt0a05c762010-11-08 11:14:10 -05002080 my @tophalf = @start_list[0 .. 0];
2081
2082 $ret = run_config_bisect_test $type;
2083 if ($ret) {
2084 process_passed %current_config;
2085 return 0;
2086 }
2087
2088 process_failed $start_list[0];
2089 return 1;
2090}
2091
2092sub config_bisect {
2093 my ($i) = @_;
2094
2095 my $start_config = $opt{"CONFIG_BISECT[$i]"};
2096
2097 my $tmpconfig = "$tmpdir/use_config";
2098
Steven Rostedt30f75da2011-06-13 10:35:35 -04002099 if (defined($config_bisect_good)) {
2100 process_config_ignore $config_bisect_good;
2101 }
2102
Steven Rostedt0a05c762010-11-08 11:14:10 -05002103 # Make the file with the bad config and the min config
2104 if (defined($minconfig)) {
2105 # read the min config for things to ignore
2106 run_command "cp $minconfig $tmpconfig" or
2107 dodie "failed to copy $minconfig to $tmpconfig";
2108 } else {
2109 unlink $tmpconfig;
2110 }
2111
Steven Rostedt0a05c762010-11-08 11:14:10 -05002112 if (-f $tmpconfig) {
Steven Rostedtfcb3f162011-06-13 10:40:58 -04002113 load_force_config($tmpconfig);
Steven Rostedt0a05c762010-11-08 11:14:10 -05002114 process_config_ignore $tmpconfig;
2115 }
2116
2117 # now process the start config
2118 run_command "cp $start_config $output_config" or
2119 dodie "failed to copy $start_config to $output_config";
2120
2121 # read directly what we want to check
2122 my %config_check;
2123 open (IN, $output_config)
2124 or dodie "faied to open $output_config";
2125
2126 while (<IN>) {
2127 if (/^((CONFIG\S*)=.*)/) {
2128 $config_check{$2} = $1;
2129 }
2130 }
2131 close(IN);
2132
Steven Rostedt250bae82011-07-15 22:05:59 -04002133 # Now run oldconfig with the minconfig
Steven Rostedtfcb3f162011-06-13 10:40:58 -04002134 make_oldconfig;
Steven Rostedt0a05c762010-11-08 11:14:10 -05002135
2136 # check to see what we lost (or gained)
2137 open (IN, $output_config)
2138 or dodie "Failed to read $start_config";
2139
2140 my %removed_configs;
2141 my %added_configs;
2142
2143 while (<IN>) {
2144 if (/^((CONFIG\S*)=.*)/) {
2145 # save off all options
2146 $config_set{$2} = $1;
2147 if (defined($config_check{$2})) {
2148 if (defined($config_ignore{$2})) {
2149 $removed_configs{$2} = $1;
2150 } else {
2151 $config_list{$2} = $1;
2152 }
2153 } elsif (!defined($config_ignore{$2})) {
2154 $added_configs{$2} = $1;
2155 $config_list{$2} = $1;
2156 }
2157 }
2158 }
2159 close(IN);
2160
2161 my @confs = keys %removed_configs;
2162 if ($#confs >= 0) {
2163 doprint "Configs overridden by default configs and removed from check:\n";
2164 foreach my $config (@confs) {
2165 doprint " $config\n";
2166 }
2167 }
2168 @confs = keys %added_configs;
2169 if ($#confs >= 0) {
2170 doprint "Configs appearing in make oldconfig and added:\n";
2171 foreach my $config (@confs) {
2172 doprint " $config\n";
2173 }
2174 }
2175
2176 my %config_test;
2177 my $once = 0;
2178
2179 # Sometimes kconfig does weird things. We must make sure
2180 # that the config we autocreate has everything we need
2181 # to test, otherwise we may miss testing configs, or
2182 # may not be able to create a new config.
2183 # Here we create a config with everything set.
2184 create_config (keys %config_list);
2185 read_current_config \%config_test;
2186 foreach my $config (keys %config_list) {
2187 if (!defined($config_test{$config})) {
2188 if (!$once) {
2189 $once = 1;
2190 doprint "Configs not produced by kconfig (will not be checked):\n";
2191 }
2192 doprint " $config\n";
2193 delete $config_list{$config};
2194 }
2195 }
2196 my $ret;
2197 do {
2198 $ret = run_config_bisect;
2199 } while (!$ret);
2200
2201 return $ret if ($ret < 0);
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04002202
2203 success $i;
2204}
2205
Steven Rostedt27d934b2011-05-20 09:18:18 -04002206sub patchcheck_reboot {
2207 doprint "Reboot and sleep $patchcheck_sleep_time seconds\n";
Andrew Jones2728be42011-08-12 15:32:05 +02002208 reboot $patchcheck_sleep_time;
Steven Rostedt27d934b2011-05-20 09:18:18 -04002209}
2210
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002211sub patchcheck {
2212 my ($i) = @_;
2213
2214 die "PATCHCHECK_START[$i] not defined\n"
2215 if (!defined($opt{"PATCHCHECK_START[$i]"}));
2216 die "PATCHCHECK_TYPE[$i] not defined\n"
2217 if (!defined($opt{"PATCHCHECK_TYPE[$i]"}));
2218
2219 my $start = $opt{"PATCHCHECK_START[$i]"};
2220
2221 my $end = "HEAD";
2222 if (defined($opt{"PATCHCHECK_END[$i]"})) {
2223 $end = $opt{"PATCHCHECK_END[$i]"};
2224 }
2225
Steven Rostedta57419b2010-11-02 15:13:54 -04002226 # Get the true sha1's since we can use things like HEAD~3
2227 $start = get_sha1($start);
2228 $end = get_sha1($end);
2229
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002230 my $type = $opt{"PATCHCHECK_TYPE[$i]"};
2231
2232 # Can't have a test without having a test to run
2233 if ($type eq "test" && !defined($run_test)) {
2234 $type = "boot";
2235 }
2236
2237 open (IN, "git log --pretty=oneline $end|") or
2238 dodie "could not get git list";
2239
2240 my @list;
2241
2242 while (<IN>) {
2243 chomp;
2244 $list[$#list+1] = $_;
2245 last if (/^$start/);
2246 }
2247 close(IN);
2248
2249 if ($list[$#list] !~ /^$start/) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002250 fail "SHA1 $start not found";
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002251 }
2252
2253 # go backwards in the list
2254 @list = reverse @list;
2255
2256 my $save_clean = $noclean;
Steven Rostedt19902072011-06-14 20:46:25 -04002257 my %ignored_warnings;
2258
2259 if (defined($ignore_warnings)) {
2260 foreach my $sha1 (split /\s+/, $ignore_warnings) {
2261 $ignored_warnings{$sha1} = 1;
2262 }
2263 }
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002264
2265 $in_patchcheck = 1;
2266 foreach my $item (@list) {
2267 my $sha1 = $item;
2268 $sha1 =~ s/^([[:xdigit:]]+).*/$1/;
2269
2270 doprint "\nProcessing commit $item\n\n";
2271
2272 run_command "git checkout $sha1" or
2273 die "Failed to checkout $sha1";
2274
2275 # only clean on the first and last patch
2276 if ($item eq $list[0] ||
2277 $item eq $list[$#list]) {
2278 $noclean = $save_clean;
2279 } else {
2280 $noclean = 1;
2281 }
2282
2283 if (defined($minconfig)) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002284 build "useconfig:$minconfig" or return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002285 } else {
2286 # ?? no config to use?
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002287 build "oldconfig" or return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002288 }
2289
Steven Rostedt19902072011-06-14 20:46:25 -04002290
2291 if (!defined($ignored_warnings{$sha1})) {
2292 check_buildlog $sha1 or return 0;
2293 }
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002294
2295 next if ($type eq "build");
2296
Steven Rostedt7faafbd2010-11-02 14:58:22 -04002297 my $failed = 0;
2298
Steven Rostedtddf607e2011-06-14 20:49:13 -04002299 start_monitor_and_boot or $failed = 1;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04002300
2301 if (!$failed && $type ne "boot"){
2302 do_run_test or $failed = 1;
2303 }
2304 end_monitor;
2305 return 0 if ($failed);
2306
Steven Rostedt27d934b2011-05-20 09:18:18 -04002307 patchcheck_reboot;
2308
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002309 }
2310 $in_patchcheck = 0;
2311 success $i;
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002312
2313 return 1;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002314}
2315
Steven Rostedtb9066f62011-07-15 21:25:24 -04002316my %depends;
2317my $iflevel = 0;
2318my @ifdeps;
2319
2320# prevent recursion
2321my %read_kconfigs;
2322
2323# taken from streamline_config.pl
2324sub read_kconfig {
2325 my ($kconfig) = @_;
2326
2327 my $state = "NONE";
2328 my $config;
2329 my @kconfigs;
2330
2331 my $cont = 0;
2332 my $line;
2333
2334
2335 if (! -f $kconfig) {
2336 doprint "file $kconfig does not exist, skipping\n";
2337 return;
2338 }
2339
2340 open(KIN, "$kconfig")
2341 or die "Can't open $kconfig";
2342 while (<KIN>) {
2343 chomp;
2344
2345 # Make sure that lines ending with \ continue
2346 if ($cont) {
2347 $_ = $line . " " . $_;
2348 }
2349
2350 if (s/\\$//) {
2351 $cont = 1;
2352 $line = $_;
2353 next;
2354 }
2355
2356 $cont = 0;
2357
2358 # collect any Kconfig sources
2359 if (/^source\s*"(.*)"/) {
2360 $kconfigs[$#kconfigs+1] = $1;
2361 }
2362
2363 # configs found
2364 if (/^\s*(menu)?config\s+(\S+)\s*$/) {
2365 $state = "NEW";
2366 $config = $2;
2367
2368 for (my $i = 0; $i < $iflevel; $i++) {
2369 if ($i) {
2370 $depends{$config} .= " " . $ifdeps[$i];
2371 } else {
2372 $depends{$config} = $ifdeps[$i];
2373 }
2374 $state = "DEP";
2375 }
2376
2377 # collect the depends for the config
2378 } elsif ($state eq "NEW" && /^\s*depends\s+on\s+(.*)$/) {
2379
2380 if (defined($depends{$1})) {
2381 $depends{$config} .= " " . $1;
2382 } else {
2383 $depends{$config} = $1;
2384 }
2385
2386 # Get the configs that select this config
2387 } elsif ($state ne "NONE" && /^\s*select\s+(\S+)/) {
2388 if (defined($depends{$1})) {
2389 $depends{$1} .= " " . $config;
2390 } else {
2391 $depends{$1} = $config;
2392 }
2393
2394 # Check for if statements
2395 } elsif (/^if\s+(.*\S)\s*$/) {
2396 my $deps = $1;
2397 # remove beginning and ending non text
2398 $deps =~ s/^[^a-zA-Z0-9_]*//;
2399 $deps =~ s/[^a-zA-Z0-9_]*$//;
2400
2401 my @deps = split /[^a-zA-Z0-9_]+/, $deps;
2402
2403 $ifdeps[$iflevel++] = join ':', @deps;
2404
2405 } elsif (/^endif/) {
2406
2407 $iflevel-- if ($iflevel);
2408
2409 # stop on "help"
2410 } elsif (/^\s*help\s*$/) {
2411 $state = "NONE";
2412 }
2413 }
2414 close(KIN);
2415
2416 # read in any configs that were found.
2417 foreach $kconfig (@kconfigs) {
2418 if (!defined($read_kconfigs{$kconfig})) {
2419 $read_kconfigs{$kconfig} = 1;
2420 read_kconfig("$builddir/$kconfig");
2421 }
2422 }
2423}
2424
2425sub read_depends {
2426 # find out which arch this is by the kconfig file
2427 open (IN, $output_config)
2428 or dodie "Failed to read $output_config";
2429 my $arch;
2430 while (<IN>) {
2431 if (m,Linux/(\S+)\s+\S+\s+Kernel Configuration,) {
2432 $arch = $1;
2433 last;
2434 }
2435 }
2436 close IN;
2437
2438 if (!defined($arch)) {
2439 doprint "Could not find arch from config file\n";
2440 doprint "no dependencies used\n";
2441 return;
2442 }
2443
2444 # arch is really the subarch, we need to know
2445 # what directory to look at.
2446 if ($arch eq "i386" || $arch eq "x86_64") {
2447 $arch = "x86";
2448 } elsif ($arch =~ /^tile/) {
2449 $arch = "tile";
2450 }
2451
2452 my $kconfig = "$builddir/arch/$arch/Kconfig";
2453
2454 if (! -f $kconfig && $arch =~ /\d$/) {
2455 my $orig = $arch;
2456 # some subarchs have numbers, truncate them
2457 $arch =~ s/\d*$//;
2458 $kconfig = "$builddir/arch/$arch/Kconfig";
2459 if (! -f $kconfig) {
2460 doprint "No idea what arch dir $orig is for\n";
2461 doprint "no dependencies used\n";
2462 return;
2463 }
2464 }
2465
2466 read_kconfig($kconfig);
2467}
2468
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002469sub read_config_list {
2470 my ($config) = @_;
2471
2472 open (IN, $config)
2473 or dodie "Failed to read $config";
2474
2475 while (<IN>) {
2476 if (/^((CONFIG\S*)=.*)/) {
2477 if (!defined($config_ignore{$2})) {
2478 $config_list{$2} = $1;
2479 }
2480 }
2481 }
2482
2483 close(IN);
2484}
2485
2486sub read_output_config {
2487 my ($config) = @_;
2488
2489 assign_configs \%config_ignore, $config;
2490}
2491
2492sub make_new_config {
2493 my @configs = @_;
2494
2495 open (OUT, ">$output_config")
2496 or dodie "Failed to write $output_config";
2497
2498 foreach my $config (@configs) {
2499 print OUT "$config\n";
2500 }
2501 close OUT;
2502}
2503
Steven Rostedtb9066f62011-07-15 21:25:24 -04002504sub get_depends {
2505 my ($dep) = @_;
2506
2507 my $kconfig = $dep;
2508 $kconfig =~ s/CONFIG_//;
2509
2510 $dep = $depends{"$kconfig"};
2511
2512 # the dep string we have saves the dependencies as they
2513 # were found, including expressions like ! && ||. We
2514 # want to split this out into just an array of configs.
2515
2516 my $valid = "A-Za-z_0-9";
2517
2518 my @configs;
2519
2520 while ($dep =~ /[$valid]/) {
2521
2522 if ($dep =~ /^[^$valid]*([$valid]+)/) {
2523 my $conf = "CONFIG_" . $1;
2524
2525 $configs[$#configs + 1] = $conf;
2526
2527 $dep =~ s/^[^$valid]*[$valid]+//;
2528 } else {
2529 die "this should never happen";
2530 }
2531 }
2532
2533 return @configs;
2534}
2535
2536my %min_configs;
2537my %keep_configs;
Steven Rostedt43d1b652011-07-15 22:01:56 -04002538my %save_configs;
Steven Rostedtb9066f62011-07-15 21:25:24 -04002539my %processed_configs;
2540my %nochange_config;
2541
2542sub test_this_config {
2543 my ($config) = @_;
2544
2545 my $found;
2546
2547 # if we already processed this config, skip it
2548 if (defined($processed_configs{$config})) {
2549 return undef;
2550 }
2551 $processed_configs{$config} = 1;
2552
2553 # if this config failed during this round, skip it
2554 if (defined($nochange_config{$config})) {
2555 return undef;
2556 }
2557
2558 my $kconfig = $config;
2559 $kconfig =~ s/CONFIG_//;
2560
2561 # Test dependencies first
2562 if (defined($depends{"$kconfig"})) {
2563 my @parents = get_depends $config;
2564 foreach my $parent (@parents) {
2565 # if the parent is in the min config, check it first
2566 next if (!defined($min_configs{$parent}));
2567 $found = test_this_config($parent);
2568 if (defined($found)) {
2569 return $found;
2570 }
2571 }
2572 }
2573
2574 # Remove this config from the list of configs
2575 # do a make oldnoconfig and then read the resulting
2576 # .config to make sure it is missing the config that
2577 # we had before
2578 my %configs = %min_configs;
2579 delete $configs{$config};
2580 make_new_config ((values %configs), (values %keep_configs));
2581 make_oldconfig;
2582 undef %configs;
2583 assign_configs \%configs, $output_config;
2584
2585 return $config if (!defined($configs{$config}));
2586
2587 doprint "disabling config $config did not change .config\n";
2588
2589 $nochange_config{$config} = 1;
2590
2591 return undef;
2592}
2593
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002594sub make_min_config {
2595 my ($i) = @_;
2596
2597 if (!defined($output_minconfig)) {
2598 fail "OUTPUT_MIN_CONFIG not defined" and return;
2599 }
Steven Rostedt35ce5952011-07-15 21:57:25 -04002600
2601 # If output_minconfig exists, and the start_minconfig
2602 # came from min_config, than ask if we should use
2603 # that instead.
2604 if (-f $output_minconfig && !$start_minconfig_defined) {
2605 print "$output_minconfig exists\n";
2606 if (read_yn " Use it as minconfig?") {
2607 $start_minconfig = $output_minconfig;
2608 }
2609 }
2610
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002611 if (!defined($start_minconfig)) {
2612 fail "START_MIN_CONFIG or MIN_CONFIG not defined" and return;
2613 }
2614
Steven Rostedt35ce5952011-07-15 21:57:25 -04002615 my $temp_config = "$tmpdir/temp_config";
2616
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002617 # First things first. We build an allnoconfig to find
2618 # out what the defaults are that we can't touch.
2619 # Some are selections, but we really can't handle selections.
2620
2621 my $save_minconfig = $minconfig;
2622 undef $minconfig;
2623
2624 run_command "$make allnoconfig" or return 0;
2625
Steven Rostedtb9066f62011-07-15 21:25:24 -04002626 read_depends;
2627
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002628 process_config_ignore $output_config;
Steven Rostedtb9066f62011-07-15 21:25:24 -04002629
Steven Rostedt43d1b652011-07-15 22:01:56 -04002630 undef %save_configs;
Steven Rostedtb9066f62011-07-15 21:25:24 -04002631 undef %min_configs;
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002632
2633 if (defined($ignore_config)) {
2634 # make sure the file exists
2635 `touch $ignore_config`;
Steven Rostedt43d1b652011-07-15 22:01:56 -04002636 assign_configs \%save_configs, $ignore_config;
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002637 }
2638
Steven Rostedt43d1b652011-07-15 22:01:56 -04002639 %keep_configs = %save_configs;
2640
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002641 doprint "Load initial configs from $start_minconfig\n";
2642
2643 # Look at the current min configs, and save off all the
2644 # ones that were set via the allnoconfig
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002645 assign_configs \%min_configs, $start_minconfig;
2646
2647 my @config_keys = keys %min_configs;
2648
2649 # Remove anything that was set by the make allnoconfig
2650 # we shouldn't need them as they get set for us anyway.
2651 foreach my $config (@config_keys) {
2652 # Remove anything in the ignore_config
2653 if (defined($keep_configs{$config})) {
2654 my $file = $ignore_config;
2655 $file =~ s,.*/(.*?)$,$1,;
2656 doprint "$config set by $file ... ignored\n";
2657 delete $min_configs{$config};
2658 next;
2659 }
2660 # But make sure the settings are the same. If a min config
2661 # sets a selection, we do not want to get rid of it if
2662 # it is not the same as what we have. Just move it into
2663 # the keep configs.
2664 if (defined($config_ignore{$config})) {
2665 if ($config_ignore{$config} ne $min_configs{$config}) {
2666 doprint "$config is in allnoconfig as '$config_ignore{$config}'";
2667 doprint " but it is '$min_configs{$config}' in minconfig .. keeping\n";
2668 $keep_configs{$config} = $min_configs{$config};
2669 } else {
2670 doprint "$config set by allnoconfig ... ignored\n";
2671 }
2672 delete $min_configs{$config};
2673 }
2674 }
2675
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002676 my $done = 0;
Steven Rostedtb9066f62011-07-15 21:25:24 -04002677 my $take_two = 0;
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002678
2679 while (!$done) {
2680
2681 my $config;
2682 my $found;
2683
2684 # Now disable each config one by one and do a make oldconfig
2685 # till we find a config that changes our list.
2686
2687 # Put configs that did not modify the config at the end.
2688 my @test_configs = keys %min_configs;
2689 my $reset = 1;
2690 for (my $i = 0; $i < $#test_configs; $i++) {
2691 if (!defined($nochange_config{$test_configs[0]})) {
2692 $reset = 0;
2693 last;
2694 }
2695 # This config didn't change the .config last time.
2696 # Place it at the end
2697 my $config = shift @test_configs;
2698 push @test_configs, $config;
2699 }
2700
2701 # if every test config has failed to modify the .config file
2702 # in the past, then reset and start over.
2703 if ($reset) {
2704 undef %nochange_config;
2705 }
2706
Steven Rostedtb9066f62011-07-15 21:25:24 -04002707 undef %processed_configs;
2708
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002709 foreach my $config (@test_configs) {
2710
Steven Rostedtb9066f62011-07-15 21:25:24 -04002711 $found = test_this_config $config;
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002712
Steven Rostedtb9066f62011-07-15 21:25:24 -04002713 last if (defined($found));
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002714
2715 # oh well, try another config
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002716 }
2717
2718 if (!defined($found)) {
Steven Rostedtb9066f62011-07-15 21:25:24 -04002719 # we could have failed due to the nochange_config hash
2720 # reset and try again
2721 if (!$take_two) {
2722 undef %nochange_config;
2723 $take_two = 1;
2724 next;
2725 }
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002726 doprint "No more configs found that we can disable\n";
2727 $done = 1;
2728 last;
2729 }
Steven Rostedtb9066f62011-07-15 21:25:24 -04002730 $take_two = 0;
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002731
2732 $config = $found;
2733
2734 doprint "Test with $config disabled\n";
2735
2736 # set in_bisect to keep build and monitor from dieing
2737 $in_bisect = 1;
2738
2739 my $failed = 0;
2740 build "oldconfig";
2741 start_monitor_and_boot or $failed = 1;
2742 end_monitor;
2743
2744 $in_bisect = 0;
2745
2746 if ($failed) {
Steven Rostedtb9066f62011-07-15 21:25:24 -04002747 doprint "$min_configs{$config} is needed to boot the box... keeping\n";
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002748 # this config is needed, add it to the ignore list.
2749 $keep_configs{$config} = $min_configs{$config};
Steven Rostedt43d1b652011-07-15 22:01:56 -04002750 $save_configs{$config} = $min_configs{$config};
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002751 delete $min_configs{$config};
Steven Rostedt35ce5952011-07-15 21:57:25 -04002752
2753 # update new ignore configs
2754 if (defined($ignore_config)) {
2755 open (OUT, ">$temp_config")
2756 or die "Can't write to $temp_config";
Steven Rostedt43d1b652011-07-15 22:01:56 -04002757 foreach my $config (keys %save_configs) {
2758 print OUT "$save_configs{$config}\n";
Steven Rostedt35ce5952011-07-15 21:57:25 -04002759 }
2760 close OUT;
2761 run_command "mv $temp_config $ignore_config" or
2762 dodie "failed to copy update to $ignore_config";
2763 }
2764
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002765 } else {
2766 # We booted without this config, remove it from the minconfigs.
2767 doprint "$config is not needed, disabling\n";
2768
2769 delete $min_configs{$config};
2770
2771 # Also disable anything that is not enabled in this config
2772 my %configs;
2773 assign_configs \%configs, $output_config;
2774 my @config_keys = keys %min_configs;
2775 foreach my $config (@config_keys) {
2776 if (!defined($configs{$config})) {
2777 doprint "$config is not set, disabling\n";
2778 delete $min_configs{$config};
2779 }
2780 }
2781
2782 # Save off all the current mandidory configs
Steven Rostedt35ce5952011-07-15 21:57:25 -04002783 open (OUT, ">$temp_config")
2784 or die "Can't write to $temp_config";
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002785 foreach my $config (keys %keep_configs) {
2786 print OUT "$keep_configs{$config}\n";
2787 }
2788 foreach my $config (keys %min_configs) {
2789 print OUT "$min_configs{$config}\n";
2790 }
2791 close OUT;
Steven Rostedt35ce5952011-07-15 21:57:25 -04002792
2793 run_command "mv $temp_config $output_minconfig" or
2794 dodie "failed to copy update to $output_minconfig";
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002795 }
2796
2797 doprint "Reboot and wait $sleep_time seconds\n";
Andrew Jones2728be42011-08-12 15:32:05 +02002798 reboot $sleep_time;
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002799 }
2800
2801 success $i;
2802 return 1;
2803}
2804
Steven Rostedt8d1491b2010-11-18 15:39:48 -05002805$#ARGV < 1 or die "ktest.pl version: $VERSION\n usage: ktest.pl config-file\n";
Steven Rostedt2545eb62010-11-02 15:01:32 -04002806
Steven Rostedt8d1491b2010-11-18 15:39:48 -05002807if ($#ARGV == 0) {
2808 $ktest_config = $ARGV[0];
2809 if (! -f $ktest_config) {
2810 print "$ktest_config does not exist.\n";
Steven Rostedt35ce5952011-07-15 21:57:25 -04002811 if (!read_yn "Create it?") {
Steven Rostedt8d1491b2010-11-18 15:39:48 -05002812 exit 0;
2813 }
2814 }
2815} else {
2816 $ktest_config = "ktest.conf";
2817}
2818
2819if (! -f $ktest_config) {
2820 open(OUT, ">$ktest_config") or die "Can not create $ktest_config";
2821 print OUT << "EOF"
2822# Generated by ktest.pl
2823#
2824# Define each test with TEST_START
2825# The config options below it will override the defaults
2826TEST_START
2827
2828DEFAULTS
2829EOF
2830;
2831 close(OUT);
2832}
2833read_config $ktest_config;
2834
Steven Rostedt23715c3c2011-06-13 11:03:34 -04002835if (defined($opt{"LOG_FILE"})) {
2836 $opt{"LOG_FILE"} = eval_option($opt{"LOG_FILE"}, -1);
2837}
2838
Steven Rostedt8d1491b2010-11-18 15:39:48 -05002839# Append any configs entered in manually to the config file.
2840my @new_configs = keys %entered_configs;
2841if ($#new_configs >= 0) {
2842 print "\nAppending entered in configs to $ktest_config\n";
2843 open(OUT, ">>$ktest_config") or die "Can not append to $ktest_config";
2844 foreach my $config (@new_configs) {
2845 print OUT "$config = $entered_configs{$config}\n";
2846 $opt{$config} = $entered_configs{$config};
2847 }
2848}
Steven Rostedt2545eb62010-11-02 15:01:32 -04002849
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002850if ($opt{"CLEAR_LOG"} && defined($opt{"LOG_FILE"})) {
2851 unlink $opt{"LOG_FILE"};
2852}
Steven Rostedt2545eb62010-11-02 15:01:32 -04002853
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002854doprint "\n\nSTARTING AUTOMATED TESTS\n\n";
2855
Steven Rostedta57419b2010-11-02 15:13:54 -04002856for (my $i = 0, my $repeat = 1; $i <= $opt{"NUM_TESTS"}; $i += $repeat) {
2857
2858 if (!$i) {
2859 doprint "DEFAULT OPTIONS:\n";
2860 } else {
2861 doprint "\nTEST $i OPTIONS";
2862 if (defined($repeat_tests{$i})) {
2863 $repeat = $repeat_tests{$i};
2864 doprint " ITERATE $repeat";
2865 }
2866 doprint "\n";
2867 }
2868
2869 foreach my $option (sort keys %opt) {
2870
2871 if ($option =~ /\[(\d+)\]$/) {
2872 next if ($i != $1);
2873 } else {
2874 next if ($i);
2875 }
2876
2877 doprint "$option = $opt{$option}\n";
2878 }
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002879}
Steven Rostedt2545eb62010-11-02 15:01:32 -04002880
Steven Rostedt2a625122011-05-20 15:48:59 -04002881sub __set_test_option {
Steven Rostedt5a391fb2010-11-02 14:57:43 -04002882 my ($name, $i) = @_;
2883
2884 my $option = "$name\[$i\]";
2885
2886 if (defined($opt{$option})) {
2887 return $opt{$option};
2888 }
2889
Steven Rostedta57419b2010-11-02 15:13:54 -04002890 foreach my $test (keys %repeat_tests) {
2891 if ($i >= $test &&
2892 $i < $test + $repeat_tests{$test}) {
2893 $option = "$name\[$test\]";
2894 if (defined($opt{$option})) {
2895 return $opt{$option};
2896 }
2897 }
2898 }
2899
Steven Rostedt5a391fb2010-11-02 14:57:43 -04002900 if (defined($opt{$name})) {
2901 return $opt{$name};
2902 }
2903
2904 return undef;
2905}
2906
Steven Rostedt2a625122011-05-20 15:48:59 -04002907sub set_test_option {
2908 my ($name, $i) = @_;
2909
2910 my $option = __set_test_option($name, $i);
2911 return $option if (!defined($option));
2912
Steven Rostedt23715c3c2011-06-13 11:03:34 -04002913 return eval_option($option, $i);
Steven Rostedt2a625122011-05-20 15:48:59 -04002914}
2915
Steven Rostedt2545eb62010-11-02 15:01:32 -04002916# First we need to do is the builds
Steven Rostedta75fece2010-11-02 14:58:27 -04002917for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
Steven Rostedt2545eb62010-11-02 15:01:32 -04002918
Steven Rostedt4ab1cce2011-09-30 18:12:20 -04002919 # Do not reboot on failing test options
2920 $no_reboot = 1;
2921
Steven Rostedt576f6272010-11-02 14:58:38 -04002922 $iteration = $i;
2923
Steven Rostedta75fece2010-11-02 14:58:27 -04002924 my $makecmd = set_test_option("MAKE_CMD", $i);
2925
2926 $machine = set_test_option("MACHINE", $i);
Steven Rostedte48c5292010-11-02 14:35:37 -04002927 $ssh_user = set_test_option("SSH_USER", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002928 $tmpdir = set_test_option("TMP_DIR", $i);
2929 $outputdir = set_test_option("OUTPUT_DIR", $i);
2930 $builddir = set_test_option("BUILD_DIR", $i);
2931 $test_type = set_test_option("TEST_TYPE", $i);
2932 $build_type = set_test_option("BUILD_TYPE", $i);
2933 $build_options = set_test_option("BUILD_OPTIONS", $i);
Steven Rostedt0bd6c1a2011-06-14 20:39:31 -04002934 $pre_build = set_test_option("PRE_BUILD", $i);
2935 $post_build = set_test_option("POST_BUILD", $i);
2936 $pre_build_die = set_test_option("PRE_BUILD_DIE", $i);
2937 $post_build_die = set_test_option("POST_BUILD_DIE", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002938 $power_cycle = set_test_option("POWER_CYCLE", $i);
Steven Rostedte48c5292010-11-02 14:35:37 -04002939 $reboot = set_test_option("REBOOT", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002940 $noclean = set_test_option("BUILD_NOCLEAN", $i);
2941 $minconfig = set_test_option("MIN_CONFIG", $i);
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002942 $output_minconfig = set_test_option("OUTPUT_MIN_CONFIG", $i);
2943 $start_minconfig = set_test_option("START_MIN_CONFIG", $i);
2944 $ignore_config = set_test_option("IGNORE_CONFIG", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002945 $run_test = set_test_option("TEST", $i);
2946 $addconfig = set_test_option("ADD_CONFIG", $i);
2947 $reboot_type = set_test_option("REBOOT_TYPE", $i);
2948 $grub_menu = set_test_option("GRUB_MENU", $i);
Steven Rostedt8b37ca82010-11-02 14:58:33 -04002949 $post_install = set_test_option("POST_INSTALL", $i);
Steven Rostedte0a87422011-09-30 17:50:48 -04002950 $no_install = set_test_option("NO_INSTALL", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002951 $reboot_script = set_test_option("REBOOT_SCRIPT", $i);
2952 $reboot_on_error = set_test_option("REBOOT_ON_ERROR", $i);
2953 $poweroff_on_error = set_test_option("POWEROFF_ON_ERROR", $i);
2954 $die_on_failure = set_test_option("DIE_ON_FAILURE", $i);
2955 $power_off = set_test_option("POWER_OFF", $i);
Steven Rostedt576f6272010-11-02 14:58:38 -04002956 $powercycle_after_reboot = set_test_option("POWERCYCLE_AFTER_REBOOT", $i);
2957 $poweroff_after_halt = set_test_option("POWEROFF_AFTER_HALT", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002958 $sleep_time = set_test_option("SLEEP_TIME", $i);
2959 $bisect_sleep_time = set_test_option("BISECT_SLEEP_TIME", $i);
Steven Rostedt27d934b2011-05-20 09:18:18 -04002960 $patchcheck_sleep_time = set_test_option("PATCHCHECK_SLEEP_TIME", $i);
Steven Rostedt19902072011-06-14 20:46:25 -04002961 $ignore_warnings = set_test_option("IGNORE_WARNINGS", $i);
Steven Rostedtc960bb92011-03-08 09:22:39 -05002962 $bisect_manual = set_test_option("BISECT_MANUAL", $i);
Steven Rostedtc23dca72011-03-08 09:26:31 -05002963 $bisect_skip = set_test_option("BISECT_SKIP", $i);
Steven Rostedt30f75da2011-06-13 10:35:35 -04002964 $config_bisect_good = set_test_option("CONFIG_BISECT_GOOD", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002965 $store_failures = set_test_option("STORE_FAILURES", $i);
Steven Rostedt9064af52011-06-13 10:38:48 -04002966 $test_name = set_test_option("TEST_NAME", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002967 $timeout = set_test_option("TIMEOUT", $i);
2968 $booted_timeout = set_test_option("BOOTED_TIMEOUT", $i);
2969 $console = set_test_option("CONSOLE", $i);
Steven Rostedtf1a5b962011-06-13 10:30:00 -04002970 $detect_triplefault = set_test_option("DETECT_TRIPLE_FAULT", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002971 $success_line = set_test_option("SUCCESS_LINE", $i);
Steven Rostedt2b803362011-09-30 18:00:23 -04002972 $reboot_success_line = set_test_option("REBOOT_SUCCESS_LINE", $i);
Steven Rostedt1c8a6172010-11-09 12:55:40 -05002973 $stop_after_success = set_test_option("STOP_AFTER_SUCCESS", $i);
2974 $stop_after_failure = set_test_option("STOP_AFTER_FAILURE", $i);
Steven Rostedt2d01b262011-03-08 09:47:54 -05002975 $stop_test_after = set_test_option("STOP_TEST_AFTER", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002976 $build_target = set_test_option("BUILD_TARGET", $i);
Steven Rostedte48c5292010-11-02 14:35:37 -04002977 $ssh_exec = set_test_option("SSH_EXEC", $i);
2978 $scp_to_target = set_test_option("SCP_TO_TARGET", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002979 $target_image = set_test_option("TARGET_IMAGE", $i);
2980 $localversion = set_test_option("LOCALVERSION", $i);
2981
Steven Rostedt35ce5952011-07-15 21:57:25 -04002982 $start_minconfig_defined = 1;
2983
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002984 if (!defined($start_minconfig)) {
Steven Rostedt35ce5952011-07-15 21:57:25 -04002985 $start_minconfig_defined = 0;
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002986 $start_minconfig = $minconfig;
2987 }
2988
Steven Rostedta75fece2010-11-02 14:58:27 -04002989 chdir $builddir || die "can't change directory to $builddir";
2990
Andrew Jonesa908a662011-08-12 15:32:03 +02002991 foreach my $dir ($tmpdir, $outputdir) {
2992 if (!-d $dir) {
2993 mkpath($dir) or
2994 die "can't create $dir";
2995 }
Steven Rostedta75fece2010-11-02 14:58:27 -04002996 }
2997
Steven Rostedte48c5292010-11-02 14:35:37 -04002998 $ENV{"SSH_USER"} = $ssh_user;
2999 $ENV{"MACHINE"} = $machine;
3000
Steven Rostedta75fece2010-11-02 14:58:27 -04003001 $target = "$ssh_user\@$machine";
3002
3003 $buildlog = "$tmpdir/buildlog-$machine";
3004 $dmesg = "$tmpdir/dmesg-$machine";
3005 $make = "$makecmd O=$outputdir";
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05003006 $output_config = "$outputdir/.config";
Steven Rostedta75fece2010-11-02 14:58:27 -04003007
3008 if ($reboot_type eq "grub") {
Steven Rostedt576f6272010-11-02 14:58:38 -04003009 dodie "GRUB_MENU not defined" if (!defined($grub_menu));
Steven Rostedta75fece2010-11-02 14:58:27 -04003010 } elsif (!defined($reboot_script)) {
Steven Rostedt576f6272010-11-02 14:58:38 -04003011 dodie "REBOOT_SCRIPT not defined"
Steven Rostedta75fece2010-11-02 14:58:27 -04003012 }
3013
3014 my $run_type = $build_type;
3015 if ($test_type eq "patchcheck") {
3016 $run_type = $opt{"PATCHCHECK_TYPE[$i]"};
3017 } elsif ($test_type eq "bisect") {
3018 $run_type = $opt{"BISECT_TYPE[$i]"};
Steven Rostedt0a05c762010-11-08 11:14:10 -05003019 } elsif ($test_type eq "config_bisect") {
3020 $run_type = $opt{"CONFIG_BISECT_TYPE[$i]"};
Steven Rostedta75fece2010-11-02 14:58:27 -04003021 }
3022
Steven Rostedt4c4ab122011-07-15 21:16:17 -04003023 if ($test_type eq "make_min_config") {
3024 $run_type = "";
3025 }
3026
Steven Rostedta75fece2010-11-02 14:58:27 -04003027 # mistake in config file?
3028 if (!defined($run_type)) {
3029 $run_type = "ERROR";
3030 }
Steven Rostedt2545eb62010-11-02 15:01:32 -04003031
Steven Rostedte0a87422011-09-30 17:50:48 -04003032 my $installme = "";
3033 $installme = " no_install" if ($no_install);
3034
Steven Rostedt2545eb62010-11-02 15:01:32 -04003035 doprint "\n\n";
Steven Rostedte0a87422011-09-30 17:50:48 -04003036 doprint "RUNNING TEST $i of $opt{NUM_TESTS} with option $test_type $run_type$installme\n\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -04003037
3038 unlink $dmesg;
3039 unlink $buildlog;
Steven Rostedt2545eb62010-11-02 15:01:32 -04003040
Steven Rostedt250bae82011-07-15 22:05:59 -04003041 if (defined($addconfig)) {
3042 my $min = $minconfig;
3043 if (!defined($minconfig)) {
3044 $min = "";
3045 }
3046 run_command "cat $addconfig $min > $tmpdir/add_config" or
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04003047 dodie "Failed to create temp config";
Steven Rostedt9be2e6b2010-11-09 12:20:21 -05003048 $minconfig = "$tmpdir/add_config";
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04003049 }
3050
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04003051 my $checkout = $opt{"CHECKOUT[$i]"};
3052 if (defined($checkout)) {
3053 run_command "git checkout $checkout" or
3054 die "failed to checkout $checkout";
3055 }
3056
Steven Rostedt4ab1cce2011-09-30 18:12:20 -04003057 $no_reboot = 0;
3058
3059
Steven Rostedta75fece2010-11-02 14:58:27 -04003060 if ($test_type eq "bisect") {
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04003061 bisect $i;
3062 next;
Steven Rostedt0a05c762010-11-08 11:14:10 -05003063 } elsif ($test_type eq "config_bisect") {
3064 config_bisect $i;
3065 next;
Steven Rostedta75fece2010-11-02 14:58:27 -04003066 } elsif ($test_type eq "patchcheck") {
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04003067 patchcheck $i;
3068 next;
Steven Rostedt4c4ab122011-07-15 21:16:17 -04003069 } elsif ($test_type eq "make_min_config") {
3070 make_min_config $i;
3071 next;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04003072 }
3073
Steven Rostedt7faafbd2010-11-02 14:58:22 -04003074 if ($build_type ne "nobuild") {
3075 build $build_type or next;
Steven Rostedt2545eb62010-11-02 15:01:32 -04003076 }
3077
Steven Rostedtcd8e3682011-08-18 16:35:44 -04003078 if ($test_type eq "install") {
3079 get_version;
3080 install;
3081 success $i;
3082 next;
3083 }
3084
Steven Rostedta75fece2010-11-02 14:58:27 -04003085 if ($test_type ne "build") {
Steven Rostedta75fece2010-11-02 14:58:27 -04003086 my $failed = 0;
Steven Rostedtddf607e2011-06-14 20:49:13 -04003087 start_monitor_and_boot or $failed = 1;
Steven Rostedta75fece2010-11-02 14:58:27 -04003088
3089 if (!$failed && $test_type ne "boot" && defined($run_test)) {
3090 do_run_test or $failed = 1;
3091 }
3092 end_monitor;
3093 next if ($failed);
Steven Rostedt5a391fb2010-11-02 14:57:43 -04003094 }
3095
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04003096 success $i;
Steven Rostedt2545eb62010-11-02 15:01:32 -04003097}
3098
Steven Rostedt5c42fc52010-11-02 14:57:01 -04003099if ($opt{"POWEROFF_ON_SUCCESS"}) {
Steven Rostedt75c3fda72010-11-02 14:57:21 -04003100 halt;
Steven Rostedt576f6272010-11-02 14:58:38 -04003101} elsif ($opt{"REBOOT_ON_SUCCESS"} && !do_not_reboot) {
Steven Rostedt75c3fda72010-11-02 14:57:21 -04003102 reboot;
Steven Rostedt5c42fc52010-11-02 14:57:01 -04003103}
Steven Rostedt75c3fda72010-11-02 14:57:21 -04003104
Steven Rostedte48c5292010-11-02 14:35:37 -04003105doprint "\n $successes of $opt{NUM_TESTS} tests were successful\n\n";
3106
Steven Rostedt2545eb62010-11-02 15:01:32 -04003107exit 0;