blob: b4f32e73474539b4f99c6467ca2c80fa008e270e [file] [log] [blame]
Steven Rostedt2545eb62010-11-02 15:01:32 -04001#!/usr/bin/perl -w
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04002#
Uwe Kleine-Königcce1dac2011-01-24 21:12:01 +01003# Copyright 2010 - Steven Rostedt <srostedt@redhat.com>, Red Hat Inc.
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04004# Licensed under the terms of the GNU GPL License version 2
5#
Steven Rostedt2545eb62010-11-02 15:01:32 -04006
7use strict;
8use IPC::Open2;
9use Fcntl qw(F_GETFL F_SETFL O_NONBLOCK);
Steven Rostedt7faafbd2010-11-02 14:58:22 -040010use File::Path qw(mkpath);
11use File::Copy qw(cp);
Steven Rostedt2545eb62010-11-02 15:01:32 -040012use FileHandle;
13
Steven Rostedte48c5292010-11-02 14:35:37 -040014my $VERSION = "0.2";
15
Steven Rostedt2545eb62010-11-02 15:01:32 -040016$| = 1;
17
18my %opt;
Steven Rostedta57419b2010-11-02 15:13:54 -040019my %repeat_tests;
20my %repeats;
Steven Rostedta75fece2010-11-02 14:58:27 -040021my %default;
Steven Rostedt2545eb62010-11-02 15:01:32 -040022
23#default opts
Steven Rostedta57419b2010-11-02 15:13:54 -040024$default{"NUM_TESTS"} = 1;
Steven Rostedta75fece2010-11-02 14:58:27 -040025$default{"REBOOT_TYPE"} = "grub";
26$default{"TEST_TYPE"} = "test";
27$default{"BUILD_TYPE"} = "randconfig";
28$default{"MAKE_CMD"} = "make";
29$default{"TIMEOUT"} = 120;
Steven Rostedt48920632011-06-14 20:42:19 -040030$default{"TMP_DIR"} = "/tmp/ktest/\${MACHINE}";
Steven Rostedta75fece2010-11-02 14:58:27 -040031$default{"SLEEP_TIME"} = 60; # sleep time between tests
32$default{"BUILD_NOCLEAN"} = 0;
33$default{"REBOOT_ON_ERROR"} = 0;
34$default{"POWEROFF_ON_ERROR"} = 0;
35$default{"REBOOT_ON_SUCCESS"} = 1;
36$default{"POWEROFF_ON_SUCCESS"} = 0;
37$default{"BUILD_OPTIONS"} = "";
38$default{"BISECT_SLEEP_TIME"} = 60; # sleep time between bisects
Steven Rostedt27d934b2011-05-20 09:18:18 -040039$default{"PATCHCHECK_SLEEP_TIME"} = 60; # sleep time between patch checks
Steven Rostedta75fece2010-11-02 14:58:27 -040040$default{"CLEAR_LOG"} = 0;
Steven Rostedtc960bb92011-03-08 09:22:39 -050041$default{"BISECT_MANUAL"} = 0;
Steven Rostedtc23dca72011-03-08 09:26:31 -050042$default{"BISECT_SKIP"} = 1;
Steven Rostedta75fece2010-11-02 14:58:27 -040043$default{"SUCCESS_LINE"} = "login:";
Steven Rostedtf1a5b962011-06-13 10:30:00 -040044$default{"DETECT_TRIPLE_FAULT"} = 1;
Steven Rostedte0a87422011-09-30 17:50:48 -040045$default{"NO_INSTALL"} = 0;
Steven Rostedta75fece2010-11-02 14:58:27 -040046$default{"BOOTED_TIMEOUT"} = 1;
47$default{"DIE_ON_FAILURE"} = 1;
Steven Rostedte48c5292010-11-02 14:35:37 -040048$default{"SSH_EXEC"} = "ssh \$SSH_USER\@\$MACHINE \$SSH_COMMAND";
49$default{"SCP_TO_TARGET"} = "scp \$SRC_FILE \$SSH_USER\@\$MACHINE:\$DST_FILE";
50$default{"REBOOT"} = "ssh \$SSH_USER\@\$MACHINE reboot";
Steven Rostedt1c8a6172010-11-09 12:55:40 -050051$default{"STOP_AFTER_SUCCESS"} = 10;
52$default{"STOP_AFTER_FAILURE"} = 60;
Steven Rostedt2d01b262011-03-08 09:47:54 -050053$default{"STOP_TEST_AFTER"} = 600;
Steven Rostedt8d1491b2010-11-18 15:39:48 -050054$default{"LOCALVERSION"} = "-test";
Steven Rostedt2545eb62010-11-02 15:01:32 -040055
Steven Rostedt8d1491b2010-11-18 15:39:48 -050056my $ktest_config;
Steven Rostedt2545eb62010-11-02 15:01:32 -040057my $version;
Steven Rostedta75fece2010-11-02 14:58:27 -040058my $machine;
Steven Rostedte48c5292010-11-02 14:35:37 -040059my $ssh_user;
Steven Rostedta75fece2010-11-02 14:58:27 -040060my $tmpdir;
61my $builddir;
62my $outputdir;
Steven Rostedt51ad1dd2010-11-08 16:43:21 -050063my $output_config;
Steven Rostedta75fece2010-11-02 14:58:27 -040064my $test_type;
Steven Rostedt7faafbd2010-11-02 14:58:22 -040065my $build_type;
Steven Rostedta75fece2010-11-02 14:58:27 -040066my $build_options;
Steven Rostedt0bd6c1a2011-06-14 20:39:31 -040067my $pre_build;
68my $post_build;
69my $pre_build_die;
70my $post_build_die;
Steven Rostedta75fece2010-11-02 14:58:27 -040071my $reboot_type;
72my $reboot_script;
73my $power_cycle;
Steven Rostedte48c5292010-11-02 14:35:37 -040074my $reboot;
Steven Rostedta75fece2010-11-02 14:58:27 -040075my $reboot_on_error;
76my $poweroff_on_error;
77my $die_on_failure;
Steven Rostedt576f6272010-11-02 14:58:38 -040078my $powercycle_after_reboot;
79my $poweroff_after_halt;
Steven Rostedte48c5292010-11-02 14:35:37 -040080my $ssh_exec;
81my $scp_to_target;
Steven Rostedta75fece2010-11-02 14:58:27 -040082my $power_off;
83my $grub_menu;
Steven Rostedt2545eb62010-11-02 15:01:32 -040084my $grub_number;
85my $target;
86my $make;
Steven Rostedt8b37ca82010-11-02 14:58:33 -040087my $post_install;
Steven Rostedte0a87422011-09-30 17:50:48 -040088my $no_install;
Steven Rostedt5c42fc52010-11-02 14:57:01 -040089my $noclean;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -040090my $minconfig;
Steven Rostedt4c4ab122011-07-15 21:16:17 -040091my $start_minconfig;
Steven Rostedt35ce5952011-07-15 21:57:25 -040092my $start_minconfig_defined;
Steven Rostedt4c4ab122011-07-15 21:16:17 -040093my $output_minconfig;
94my $ignore_config;
Steven Rostedt2b7d9b22010-11-02 14:58:15 -040095my $addconfig;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -040096my $in_bisect = 0;
97my $bisect_bad = "";
Steven Rostedtd6ce2a02010-11-02 14:58:05 -040098my $reverse_bisect;
Steven Rostedtc960bb92011-03-08 09:22:39 -050099my $bisect_manual;
Steven Rostedtc23dca72011-03-08 09:26:31 -0500100my $bisect_skip;
Steven Rostedt30f75da2011-06-13 10:35:35 -0400101my $config_bisect_good;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -0400102my $in_patchcheck = 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -0400103my $run_test;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -0400104my $redirect;
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400105my $buildlog;
106my $dmesg;
107my $monitor_fp;
108my $monitor_pid;
109my $monitor_cnt = 0;
Steven Rostedta75fece2010-11-02 14:58:27 -0400110my $sleep_time;
111my $bisect_sleep_time;
Steven Rostedt27d934b2011-05-20 09:18:18 -0400112my $patchcheck_sleep_time;
Steven Rostedt19902072011-06-14 20:46:25 -0400113my $ignore_warnings;
Steven Rostedta75fece2010-11-02 14:58:27 -0400114my $store_failures;
Steven Rostedt9064af52011-06-13 10:38:48 -0400115my $test_name;
Steven Rostedta75fece2010-11-02 14:58:27 -0400116my $timeout;
117my $booted_timeout;
Steven Rostedtf1a5b962011-06-13 10:30:00 -0400118my $detect_triplefault;
Steven Rostedta75fece2010-11-02 14:58:27 -0400119my $console;
Steven Rostedt2b803362011-09-30 18:00:23 -0400120my $reboot_success_line;
Steven Rostedta75fece2010-11-02 14:58:27 -0400121my $success_line;
Steven Rostedt1c8a6172010-11-09 12:55:40 -0500122my $stop_after_success;
123my $stop_after_failure;
Steven Rostedt2d01b262011-03-08 09:47:54 -0500124my $stop_test_after;
Steven Rostedta75fece2010-11-02 14:58:27 -0400125my $build_target;
126my $target_image;
127my $localversion;
Steven Rostedt576f6272010-11-02 14:58:38 -0400128my $iteration = 0;
Steven Rostedte48c5292010-11-02 14:35:37 -0400129my $successes = 0;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400130
Steven Rostedt8d1491b2010-11-18 15:39:48 -0500131my %entered_configs;
132my %config_help;
Steven Rostedt77d942c2011-05-20 13:36:58 -0400133my %variable;
Steven Rostedtfcb3f162011-06-13 10:40:58 -0400134my %force_config;
Steven Rostedt8d1491b2010-11-18 15:39:48 -0500135
Steven Rostedt4ab1cce2011-09-30 18:12:20 -0400136# do not force reboots on config problems
137my $no_reboot = 1;
138
Steven Rostedt8d1491b2010-11-18 15:39:48 -0500139$config_help{"MACHINE"} = << "EOF"
140 The machine hostname that you will test.
141EOF
142 ;
143$config_help{"SSH_USER"} = << "EOF"
144 The box is expected to have ssh on normal bootup, provide the user
145 (most likely root, since you need privileged operations)
146EOF
147 ;
148$config_help{"BUILD_DIR"} = << "EOF"
149 The directory that contains the Linux source code (full path).
150EOF
151 ;
152$config_help{"OUTPUT_DIR"} = << "EOF"
153 The directory that the objects will be built (full path).
154 (can not be same as BUILD_DIR)
155EOF
156 ;
157$config_help{"BUILD_TARGET"} = << "EOF"
158 The location of the compiled file to copy to the target.
159 (relative to OUTPUT_DIR)
160EOF
161 ;
162$config_help{"TARGET_IMAGE"} = << "EOF"
163 The place to put your image on the test machine.
164EOF
165 ;
166$config_help{"POWER_CYCLE"} = << "EOF"
167 A script or command to reboot the box.
168
169 Here is a digital loggers power switch example
170 POWER_CYCLE = wget --no-proxy -O /dev/null -q --auth-no-challenge 'http://admin:admin\@power/outlet?5=CCL'
171
172 Here is an example to reboot a virtual box on the current host
173 with the name "Guest".
174 POWER_CYCLE = virsh destroy Guest; sleep 5; virsh start Guest
175EOF
176 ;
177$config_help{"CONSOLE"} = << "EOF"
178 The script or command that reads the console
179
180 If you use ttywatch server, something like the following would work.
181CONSOLE = nc -d localhost 3001
182
183 For a virtual machine with guest name "Guest".
184CONSOLE = virsh console Guest
185EOF
186 ;
187$config_help{"LOCALVERSION"} = << "EOF"
188 Required version ending to differentiate the test
189 from other linux builds on the system.
190EOF
191 ;
192$config_help{"REBOOT_TYPE"} = << "EOF"
193 Way to reboot the box to the test kernel.
194 Only valid options so far are "grub" and "script".
195
196 If you specify grub, it will assume grub version 1
197 and will search in /boot/grub/menu.lst for the title \$GRUB_MENU
198 and select that target to reboot to the kernel. If this is not
199 your setup, then specify "script" and have a command or script
200 specified in REBOOT_SCRIPT to boot to the target.
201
202 The entry in /boot/grub/menu.lst must be entered in manually.
203 The test will not modify that file.
204EOF
205 ;
206$config_help{"GRUB_MENU"} = << "EOF"
207 The grub title name for the test kernel to boot
208 (Only mandatory if REBOOT_TYPE = grub)
209
210 Note, ktest.pl will not update the grub menu.lst, you need to
211 manually add an option for the test. ktest.pl will search
212 the grub menu.lst for this option to find what kernel to
213 reboot into.
214
215 For example, if in the /boot/grub/menu.lst the test kernel title has:
216 title Test Kernel
217 kernel vmlinuz-test
218 GRUB_MENU = Test Kernel
219EOF
220 ;
221$config_help{"REBOOT_SCRIPT"} = << "EOF"
222 A script to reboot the target into the test kernel
223 (Only mandatory if REBOOT_TYPE = script)
224EOF
225 ;
226
Steven Rostedt35ce5952011-07-15 21:57:25 -0400227sub read_yn {
228 my ($prompt) = @_;
229
230 my $ans;
231
232 for (;;) {
233 print "$prompt [Y/n] ";
234 $ans = <STDIN>;
235 chomp $ans;
236 if ($ans =~ /^\s*$/) {
237 $ans = "y";
238 }
239 last if ($ans =~ /^y$/i || $ans =~ /^n$/i);
240 print "Please answer either 'y' or 'n'.\n";
241 }
242 if ($ans !~ /^y$/i) {
243 return 0;
244 }
245 return 1;
246}
Steven Rostedt8d1491b2010-11-18 15:39:48 -0500247
248sub get_ktest_config {
249 my ($config) = @_;
250
251 return if (defined($opt{$config}));
252
253 if (defined($config_help{$config})) {
254 print "\n";
255 print $config_help{$config};
256 }
257
258 for (;;) {
259 print "$config = ";
260 if (defined($default{$config})) {
261 print "\[$default{$config}\] ";
262 }
263 $entered_configs{$config} = <STDIN>;
264 $entered_configs{$config} =~ s/^\s*(.*\S)\s*$/$1/;
265 if ($entered_configs{$config} =~ /^\s*$/) {
266 if ($default{$config}) {
267 $entered_configs{$config} = $default{$config};
268 } else {
269 print "Your answer can not be blank\n";
270 next;
271 }
272 }
273 last;
274 }
275}
276
277sub get_ktest_configs {
278 get_ktest_config("MACHINE");
279 get_ktest_config("SSH_USER");
280 get_ktest_config("BUILD_DIR");
281 get_ktest_config("OUTPUT_DIR");
282 get_ktest_config("BUILD_TARGET");
283 get_ktest_config("TARGET_IMAGE");
284 get_ktest_config("POWER_CYCLE");
285 get_ktest_config("CONSOLE");
286 get_ktest_config("LOCALVERSION");
287
288 my $rtype = $opt{"REBOOT_TYPE"};
289
290 if (!defined($rtype)) {
291 if (!defined($opt{"GRUB_MENU"})) {
292 get_ktest_config("REBOOT_TYPE");
293 $rtype = $entered_configs{"REBOOT_TYPE"};
294 } else {
295 $rtype = "grub";
296 }
297 }
298
299 if ($rtype eq "grub") {
300 get_ktest_config("GRUB_MENU");
301 } else {
302 get_ktest_config("REBOOT_SCRIPT");
303 }
304}
305
Steven Rostedt77d942c2011-05-20 13:36:58 -0400306sub process_variables {
307 my ($value) = @_;
308 my $retval = "";
309
310 # We want to check for '\', and it is just easier
311 # to check the previous characet of '$' and not need
312 # to worry if '$' is the first character. By adding
313 # a space to $value, we can just check [^\\]\$ and
314 # it will still work.
315 $value = " $value";
316
317 while ($value =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) {
318 my $begin = $1;
319 my $var = $2;
320 my $end = $3;
321 # append beginning of value to retval
322 $retval = "$retval$begin";
323 if (defined($variable{$var})) {
324 $retval = "$retval$variable{$var}";
325 } else {
326 # put back the origin piece.
327 $retval = "$retval\$\{$var\}";
328 }
329 $value = $end;
330 }
331 $retval = "$retval$value";
332
333 # remove the space added in the beginning
334 $retval =~ s/ //;
335
336 return "$retval"
337}
338
Steven Rostedta57419b2010-11-02 15:13:54 -0400339sub set_value {
340 my ($lvalue, $rvalue) = @_;
341
342 if (defined($opt{$lvalue})) {
343 die "Error: Option $lvalue defined more than once!\n";
344 }
Steven Rostedt21a96792010-11-08 16:45:50 -0500345 if ($rvalue =~ /^\s*$/) {
346 delete $opt{$lvalue};
347 } else {
Steven Rostedt77d942c2011-05-20 13:36:58 -0400348 $rvalue = process_variables($rvalue);
Steven Rostedt21a96792010-11-08 16:45:50 -0500349 $opt{$lvalue} = $rvalue;
350 }
Steven Rostedta57419b2010-11-02 15:13:54 -0400351}
352
Steven Rostedt77d942c2011-05-20 13:36:58 -0400353sub set_variable {
354 my ($lvalue, $rvalue) = @_;
355
356 if ($rvalue =~ /^\s*$/) {
357 delete $variable{$lvalue};
358 } else {
359 $rvalue = process_variables($rvalue);
360 $variable{$lvalue} = $rvalue;
361 }
362}
363
Steven Rostedtab7a3f52011-09-30 20:24:07 -0400364sub process_compare {
365 my ($lval, $cmp, $rval) = @_;
366
367 # remove whitespace
368
369 $lval =~ s/^\s*//;
370 $lval =~ s/\s*$//;
371
372 $rval =~ s/^\s*//;
373 $rval =~ s/\s*$//;
374
375 if ($cmp eq "==") {
376 return $lval eq $rval;
377 } elsif ($cmp eq "!=") {
378 return $lval ne $rval;
379 }
380
381 my $statement = "$lval $cmp $rval";
382 my $ret = eval $statement;
383
384 # $@ stores error of eval
385 if ($@) {
386 return -1;
387 }
388
389 return $ret;
390}
391
Steven Rostedt45d73a52011-09-30 19:44:53 -0400392sub process_if {
393 my ($name, $value) = @_;
394
395 my $val = process_variables($value);
396
Steven Rostedtab7a3f52011-09-30 20:24:07 -0400397 if ($val =~ /(.*)(==|\!=|>=|<=|>|<)(.*)/) {
398 my $ret = process_compare($1, $2, $3);
399 if ($ret < 0) {
400 die "$name: $.: Unable to process comparison\n";
401 }
402 return $ret;
403 }
404
Steven Rostedt45d73a52011-09-30 19:44:53 -0400405 if ($val =~ /^\s*0\s*$/) {
406 return 0;
407 } elsif ($val =~ /^\s*\d+\s*$/) {
408 return 1;
409 }
410
411 die ("$name: $.: Undefined variable $val in if statement\n");
412 return 1;
413}
414
Steven Rostedt2ed3b162011-09-30 21:00:00 -0400415sub __read_config {
416 my ($config, $current_test_num) = @_;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400417
Steven Rostedt2ed3b162011-09-30 21:00:00 -0400418 my $in;
419 open($in, $config) || die "can't read file $config";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400420
Steven Rostedta57419b2010-11-02 15:13:54 -0400421 my $name = $config;
422 $name =~ s,.*/(.*),$1,;
423
Steven Rostedt2ed3b162011-09-30 21:00:00 -0400424 my $test_num = $$current_test_num;
Steven Rostedta57419b2010-11-02 15:13:54 -0400425 my $default = 1;
426 my $repeat = 1;
427 my $num_tests_set = 0;
428 my $skip = 0;
429 my $rest;
Steven Rostedt0df213c2011-06-14 20:51:37 -0400430 my $test_case = 0;
Steven Rostedt45d73a52011-09-30 19:44:53 -0400431 my $if = 0;
432 my $if_set = 0;
Steven Rostedta57419b2010-11-02 15:13:54 -0400433
Steven Rostedt2ed3b162011-09-30 21:00:00 -0400434 while (<$in>) {
Steven Rostedt2545eb62010-11-02 15:01:32 -0400435
436 # ignore blank lines and comments
437 next if (/^\s*$/ || /\s*\#/);
438
Steven Rostedt0050b6b2011-09-30 21:10:30 -0400439 if (/^\s*(TEST_START|DEFAULTS)\b(.*)/) {
Steven Rostedta57419b2010-11-02 15:13:54 -0400440
Steven Rostedt0050b6b2011-09-30 21:10:30 -0400441 my $type = $1;
442 $rest = $2;
Steven Rostedta57419b2010-11-02 15:13:54 -0400443
Steven Rostedt0050b6b2011-09-30 21:10:30 -0400444 my $old_test_num;
445 my $old_repeat;
446
447 if ($type eq "TEST_START") {
448
449 if ($num_tests_set) {
450 die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
451 }
452
453 $old_test_num = $test_num;
454 $old_repeat = $repeat;
455
456 $test_num += $repeat;
457 $default = 0;
458 $repeat = 1;
459 } else {
460 $default = 1;
Steven Rostedta57419b2010-11-02 15:13:54 -0400461 }
462
Steven Rostedt45d73a52011-09-30 19:44:53 -0400463 if ($rest =~ /\s+SKIP\b(.*)/) {
Steven Rostedta57419b2010-11-02 15:13:54 -0400464 $rest = $1;
465 $skip = 1;
466 } else {
Steven Rostedt0df213c2011-06-14 20:51:37 -0400467 $test_case = 1;
Steven Rostedta57419b2010-11-02 15:13:54 -0400468 $skip = 0;
469 }
470
471 if ($rest =~ /\s+ITERATE\s+(\d+)(.*)$/) {
472 $repeat = $1;
473 $rest = $2;
474 $repeat_tests{"$test_num"} = $repeat;
475 }
476
Steven Rostedtab7a3f52011-09-30 20:24:07 -0400477 if ($rest =~ /\sIF\s+(.*)/) {
478 $rest = "";
Steven Rostedt45d73a52011-09-30 19:44:53 -0400479 if (process_if($name, $1)) {
480 $if_set = 1;
481 } else {
482 $skip = 1;
483 }
484 $if = 1;
485 } else {
486 $if = 0;
Steven Rostedta57419b2010-11-02 15:13:54 -0400487 }
488
489 if ($rest !~ /^\s*$/) {
Steven Rostedt0050b6b2011-09-30 21:10:30 -0400490 die "$name: $.: Gargbage found after $type\n$_";
Steven Rostedta57419b2010-11-02 15:13:54 -0400491 }
492
Steven Rostedt0050b6b2011-09-30 21:10:30 -0400493 if ($skip && $type eq "TEST_START") {
Steven Rostedta57419b2010-11-02 15:13:54 -0400494 $test_num = $old_test_num;
Steven Rostedte48c5292010-11-02 14:35:37 -0400495 $repeat = $old_repeat;
Steven Rostedta57419b2010-11-02 15:13:54 -0400496 }
497
Steven Rostedtab7a3f52011-09-30 20:24:07 -0400498 } elsif (/^\s*ELSE\b(.*)$/) {
Steven Rostedt45d73a52011-09-30 19:44:53 -0400499 if (!$if) {
500 die "$name: $.: ELSE found with out matching IF section\n$_";
501 }
502 $rest = $1;
503 if ($if_set) {
504 $skip = 1;
Steven Rostedtab7a3f52011-09-30 20:24:07 -0400505 $rest = "";
Steven Rostedt45d73a52011-09-30 19:44:53 -0400506 } else {
507 $skip = 0;
508
Steven Rostedtab7a3f52011-09-30 20:24:07 -0400509 if ($rest =~ /\sIF\s+(.*)/) {
Steven Rostedt45d73a52011-09-30 19:44:53 -0400510 # May be a ELSE IF section.
511 if (!process_if($name, $1)) {
512 $skip = 1;
513 }
Steven Rostedtab7a3f52011-09-30 20:24:07 -0400514 $rest = "";
Steven Rostedt45d73a52011-09-30 19:44:53 -0400515 } else {
516 $if = 0;
517 }
518 }
519
Steven Rostedtab7a3f52011-09-30 20:24:07 -0400520 if ($rest !~ /^\s*$/) {
521 die "$name: $.: Gargbage found after DEFAULTS\n$_";
522 }
523
Steven Rostedt2ed3b162011-09-30 21:00:00 -0400524 } elsif (/^\s*INCLUDE\s+(\S+)/) {
525
526 next if ($skip);
527
528 if (!$default) {
529 die "$name: $.: INCLUDE can only be done in default sections\n$_";
530 }
531
532 my $file = process_variables($1);
533
534 if ($file !~ m,^/,) {
535 # check the path of the config file first
536 if ($config =~ m,(.*)/,) {
537 if (-f "$1/$file") {
538 $file = "$1/$file";
539 }
540 }
541 }
542
543 if ( ! -r $file ) {
544 die "$name: $.: Can't read file $file\n$_";
545 }
546
547 if (__read_config($file, \$test_num)) {
548 $test_case = 1;
549 }
550
Steven Rostedta57419b2010-11-02 15:13:54 -0400551 } elsif (/^\s*([A-Z_\[\]\d]+)\s*=\s*(.*?)\s*$/) {
552
553 next if ($skip);
554
Steven Rostedt2545eb62010-11-02 15:01:32 -0400555 my $lvalue = $1;
556 my $rvalue = $2;
557
Steven Rostedta57419b2010-11-02 15:13:54 -0400558 if (!$default &&
559 ($lvalue eq "NUM_TESTS" ||
560 $lvalue eq "LOG_FILE" ||
561 $lvalue eq "CLEAR_LOG")) {
562 die "$name: $.: $lvalue must be set in DEFAULTS section\n";
Steven Rostedta75fece2010-11-02 14:58:27 -0400563 }
Steven Rostedta57419b2010-11-02 15:13:54 -0400564
565 if ($lvalue eq "NUM_TESTS") {
566 if ($test_num) {
567 die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
568 }
569 if (!$default) {
570 die "$name: $.: NUM_TESTS must be set in default section\n";
571 }
572 $num_tests_set = 1;
573 }
574
575 if ($default || $lvalue =~ /\[\d+\]$/) {
576 set_value($lvalue, $rvalue);
577 } else {
578 my $val = "$lvalue\[$test_num\]";
579 set_value($val, $rvalue);
580
581 if ($repeat > 1) {
582 $repeats{$val} = $repeat;
583 }
584 }
Steven Rostedt77d942c2011-05-20 13:36:58 -0400585 } elsif (/^\s*([A-Z_\[\]\d]+)\s*:=\s*(.*?)\s*$/) {
586 next if ($skip);
587
588 my $lvalue = $1;
589 my $rvalue = $2;
590
591 # process config variables.
592 # Config variables are only active while reading the
593 # config and can be defined anywhere. They also ignore
594 # TEST_START and DEFAULTS, but are skipped if they are in
595 # on of these sections that have SKIP defined.
596 # The save variable can be
597 # defined multiple times and the new one simply overrides
598 # the prevous one.
599 set_variable($lvalue, $rvalue);
600
Steven Rostedta57419b2010-11-02 15:13:54 -0400601 } else {
602 die "$name: $.: Garbage found in config\n$_";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400603 }
604 }
605
Steven Rostedta57419b2010-11-02 15:13:54 -0400606 if ($test_num) {
607 $test_num += $repeat - 1;
608 $opt{"NUM_TESTS"} = $test_num;
609 }
610
Steven Rostedt2ed3b162011-09-30 21:00:00 -0400611 close($in);
612
613 $$current_test_num = $test_num;
614
615 return $test_case;
616}
617
618sub read_config {
619 my ($config) = @_;
620
621 my $test_case;
622 my $test_num = 0;
623
624 $test_case = __read_config $config, \$test_num;
625
Steven Rostedt8d1491b2010-11-18 15:39:48 -0500626 # make sure we have all mandatory configs
627 get_ktest_configs;
628
Steven Rostedt0df213c2011-06-14 20:51:37 -0400629 # was a test specified?
630 if (!$test_case) {
631 print "No test case specified.\n";
632 print "What test case would you like to run?\n";
633 my $ans = <STDIN>;
634 chomp $ans;
635 $default{"TEST_TYPE"} = $ans;
636 }
637
Steven Rostedta75fece2010-11-02 14:58:27 -0400638 # set any defaults
639
640 foreach my $default (keys %default) {
641 if (!defined($opt{$default})) {
642 $opt{$default} = $default{$default};
643 }
644 }
Steven Rostedt2545eb62010-11-02 15:01:32 -0400645}
646
Steven Rostedt23715c3c2011-06-13 11:03:34 -0400647sub __eval_option {
648 my ($option, $i) = @_;
649
650 # Add space to evaluate the character before $
651 $option = " $option";
652 my $retval = "";
653
654 while ($option =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) {
655 my $start = $1;
656 my $var = $2;
657 my $end = $3;
658
659 # Append beginning of line
660 $retval = "$retval$start";
661
662 # If the iteration option OPT[$i] exists, then use that.
663 # otherwise see if the default OPT (without [$i]) exists.
664
665 my $o = "$var\[$i\]";
666
667 if (defined($opt{$o})) {
668 $o = $opt{$o};
669 $retval = "$retval$o";
670 } elsif (defined($opt{$var})) {
671 $o = $opt{$var};
672 $retval = "$retval$o";
673 } else {
674 $retval = "$retval\$\{$var\}";
675 }
676
677 $option = $end;
678 }
679
680 $retval = "$retval$option";
681
682 $retval =~ s/^ //;
683
684 return $retval;
685}
686
687sub eval_option {
688 my ($option, $i) = @_;
689
690 my $prev = "";
691
692 # Since an option can evaluate to another option,
693 # keep iterating until we do not evaluate any more
694 # options.
695 my $r = 0;
696 while ($prev ne $option) {
697 # Check for recursive evaluations.
698 # 100 deep should be more than enough.
699 if ($r++ > 100) {
700 die "Over 100 evaluations accurred with $option\n" .
701 "Check for recursive variables\n";
702 }
703 $prev = $option;
704 $option = __eval_option($option, $i);
705 }
706
707 return $option;
708}
709
Steven Rostedtd1e2f222010-11-08 16:39:57 -0500710sub _logit {
Steven Rostedt2545eb62010-11-02 15:01:32 -0400711 if (defined($opt{"LOG_FILE"})) {
712 open(OUT, ">> $opt{LOG_FILE}") or die "Can't write to $opt{LOG_FILE}";
713 print OUT @_;
714 close(OUT);
715 }
716}
717
Steven Rostedtd1e2f222010-11-08 16:39:57 -0500718sub logit {
719 if (defined($opt{"LOG_FILE"})) {
720 _logit @_;
721 } else {
722 print @_;
723 }
724}
725
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400726sub doprint {
727 print @_;
Steven Rostedtd1e2f222010-11-08 16:39:57 -0500728 _logit @_;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400729}
730
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400731sub run_command;
Andrew Jones2728be42011-08-12 15:32:05 +0200732sub start_monitor;
733sub end_monitor;
734sub wait_for_monitor;
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400735
736sub reboot {
Andrew Jones2728be42011-08-12 15:32:05 +0200737 my ($time) = @_;
738
Steven Rostedt2b803362011-09-30 18:00:23 -0400739 if (defined($time)) {
740 start_monitor;
741 # flush out current monitor
742 # May contain the reboot success line
743 wait_for_monitor 1;
744 }
745
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400746 # try to reboot normally
Steven Rostedte48c5292010-11-02 14:35:37 -0400747 if (run_command $reboot) {
Steven Rostedt576f6272010-11-02 14:58:38 -0400748 if (defined($powercycle_after_reboot)) {
749 sleep $powercycle_after_reboot;
750 run_command "$power_cycle";
751 }
752 } else {
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400753 # nope? power cycle it.
Steven Rostedta75fece2010-11-02 14:58:27 -0400754 run_command "$power_cycle";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400755 }
Andrew Jones2728be42011-08-12 15:32:05 +0200756
757 if (defined($time)) {
Steven Rostedt2b803362011-09-30 18:00:23 -0400758 wait_for_monitor($time, $reboot_success_line);
Andrew Jones2728be42011-08-12 15:32:05 +0200759 end_monitor;
760 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400761}
762
Steven Rostedt576f6272010-11-02 14:58:38 -0400763sub do_not_reboot {
764 my $i = $iteration;
765
Steven Rostedt4ab1cce2011-09-30 18:12:20 -0400766 return $test_type eq "build" || $no_reboot ||
Steven Rostedt576f6272010-11-02 14:58:38 -0400767 ($test_type eq "patchcheck" && $opt{"PATCHCHECK_TYPE[$i]"} eq "build") ||
768 ($test_type eq "bisect" && $opt{"BISECT_TYPE[$i]"} eq "build");
769}
770
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400771sub dodie {
Steven Rostedt5a391fb2010-11-02 14:57:43 -0400772 doprint "CRITICAL FAILURE... ", @_, "\n";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400773
Steven Rostedt576f6272010-11-02 14:58:38 -0400774 my $i = $iteration;
775
776 if ($reboot_on_error && !do_not_reboot) {
777
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400778 doprint "REBOOTING\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400779 reboot;
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400780
Steven Rostedta75fece2010-11-02 14:58:27 -0400781 } elsif ($poweroff_on_error && defined($power_off)) {
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400782 doprint "POWERING OFF\n";
Steven Rostedta75fece2010-11-02 14:58:27 -0400783 `$power_off`;
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400784 }
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400785
Steven Rostedtf80802c2011-03-07 13:18:47 -0500786 if (defined($opt{"LOG_FILE"})) {
787 print " See $opt{LOG_FILE} for more info.\n";
788 }
789
Steven Rostedt576f6272010-11-02 14:58:38 -0400790 die @_, "\n";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400791}
792
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400793sub open_console {
794 my ($fp) = @_;
795
796 my $flags;
797
Steven Rostedta75fece2010-11-02 14:58:27 -0400798 my $pid = open($fp, "$console|") or
799 dodie "Can't open console $console";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400800
801 $flags = fcntl($fp, F_GETFL, 0) or
Steven Rostedt576f6272010-11-02 14:58:38 -0400802 dodie "Can't get flags for the socket: $!";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400803 $flags = fcntl($fp, F_SETFL, $flags | O_NONBLOCK) or
Steven Rostedt576f6272010-11-02 14:58:38 -0400804 dodie "Can't set flags for the socket: $!";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400805
806 return $pid;
807}
808
809sub close_console {
810 my ($fp, $pid) = @_;
811
812 doprint "kill child process $pid\n";
813 kill 2, $pid;
814
815 print "closing!\n";
816 close($fp);
817}
818
819sub start_monitor {
820 if ($monitor_cnt++) {
821 return;
822 }
823 $monitor_fp = \*MONFD;
824 $monitor_pid = open_console $monitor_fp;
Steven Rostedta75fece2010-11-02 14:58:27 -0400825
826 return;
827
828 open(MONFD, "Stop perl from warning about single use of MONFD");
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400829}
830
831sub end_monitor {
832 if (--$monitor_cnt) {
833 return;
834 }
835 close_console($monitor_fp, $monitor_pid);
836}
837
838sub wait_for_monitor {
Steven Rostedt2b803362011-09-30 18:00:23 -0400839 my ($time, $stop) = @_;
840 my $full_line = "";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400841 my $line;
Steven Rostedt2b803362011-09-30 18:00:23 -0400842 my $booted = 0;
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400843
Steven Rostedta75fece2010-11-02 14:58:27 -0400844 doprint "** Wait for monitor to settle down **\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400845
846 # read the monitor and wait for the system to calm down
Steven Rostedt2b803362011-09-30 18:00:23 -0400847 while (!$booted) {
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400848 $line = wait_for_input($monitor_fp, $time);
Steven Rostedt2b803362011-09-30 18:00:23 -0400849 last if (!defined($line));
850 print "$line";
851 $full_line .= $line;
852
853 if (defined($stop) && $full_line =~ /$stop/) {
854 doprint "wait for monitor detected $stop\n";
855 $booted = 1;
856 }
857
858 if ($line =~ /\n/) {
859 $full_line = "";
860 }
861 }
Steven Rostedta75fece2010-11-02 14:58:27 -0400862 print "** Monitor flushed **\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400863}
864
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400865sub fail {
866
Steven Rostedta75fece2010-11-02 14:58:27 -0400867 if ($die_on_failure) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400868 dodie @_;
869 }
870
Steven Rostedta75fece2010-11-02 14:58:27 -0400871 doprint "FAILED\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400872
Steven Rostedt576f6272010-11-02 14:58:38 -0400873 my $i = $iteration;
874
Steven Rostedta75fece2010-11-02 14:58:27 -0400875 # no need to reboot for just building.
Steven Rostedt576f6272010-11-02 14:58:38 -0400876 if (!do_not_reboot) {
Steven Rostedta75fece2010-11-02 14:58:27 -0400877 doprint "REBOOTING\n";
Andrew Jones2728be42011-08-12 15:32:05 +0200878 reboot $sleep_time;
Steven Rostedta75fece2010-11-02 14:58:27 -0400879 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400880
Steven Rostedt9064af52011-06-13 10:38:48 -0400881 my $name = "";
882
883 if (defined($test_name)) {
884 $name = " ($test_name)";
885 }
886
Steven Rostedt576f6272010-11-02 14:58:38 -0400887 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
888 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
Steven Rostedt9064af52011-06-13 10:38:48 -0400889 doprint "KTEST RESULT: TEST $i$name Failed: ", @_, "\n";
Steven Rostedt576f6272010-11-02 14:58:38 -0400890 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
891 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
Steven Rostedta75fece2010-11-02 14:58:27 -0400892
893 return 1 if (!defined($store_failures));
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400894
895 my @t = localtime;
896 my $date = sprintf "%04d%02d%02d%02d%02d%02d",
897 1900+$t[5],$t[4],$t[3],$t[2],$t[1],$t[0];
898
Steven Rostedtcccae1a2010-11-09 12:21:32 -0500899 my $type = $build_type;
900 if ($type =~ /useconfig/) {
901 $type = "useconfig";
902 }
903
904 my $dir = "$machine-$test_type-$type-fail-$date";
Steven Rostedta75fece2010-11-02 14:58:27 -0400905 my $faildir = "$store_failures/$dir";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400906
907 if (!-d $faildir) {
908 mkpath($faildir) or
Steven Rostedta75fece2010-11-02 14:58:27 -0400909 die "can't create $faildir";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400910 }
Steven Rostedt51ad1dd2010-11-08 16:43:21 -0500911 if (-f "$output_config") {
912 cp "$output_config", "$faildir/config" or
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400913 die "failed to copy .config";
914 }
915 if (-f $buildlog) {
916 cp $buildlog, "$faildir/buildlog" or
917 die "failed to move $buildlog";
918 }
919 if (-f $dmesg) {
920 cp $dmesg, "$faildir/dmesg" or
921 die "failed to move $dmesg";
922 }
923
924 doprint "*** Saved info to $faildir ***\n";
925
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400926 return 1;
927}
928
Steven Rostedt2545eb62010-11-02 15:01:32 -0400929sub run_command {
930 my ($command) = @_;
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400931 my $dolog = 0;
932 my $dord = 0;
933 my $pid;
934
Steven Rostedte48c5292010-11-02 14:35:37 -0400935 $command =~ s/\$SSH_USER/$ssh_user/g;
936 $command =~ s/\$MACHINE/$machine/g;
937
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400938 doprint("$command ... ");
939
940 $pid = open(CMD, "$command 2>&1 |") or
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400941 (fail "unable to exec $command" and return 0);
Steven Rostedt2545eb62010-11-02 15:01:32 -0400942
943 if (defined($opt{"LOG_FILE"})) {
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400944 open(LOG, ">>$opt{LOG_FILE}") or
945 dodie "failed to write to log";
946 $dolog = 1;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -0400947 }
948
949 if (defined($redirect)) {
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400950 open (RD, ">$redirect") or
951 dodie "failed to write to redirect $redirect";
952 $dord = 1;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400953 }
954
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400955 while (<CMD>) {
956 print LOG if ($dolog);
957 print RD if ($dord);
958 }
Steven Rostedt2545eb62010-11-02 15:01:32 -0400959
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400960 waitpid($pid, 0);
Steven Rostedt2545eb62010-11-02 15:01:32 -0400961 my $failed = $?;
962
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400963 close(CMD);
964 close(LOG) if ($dolog);
965 close(RD) if ($dord);
966
Steven Rostedt2545eb62010-11-02 15:01:32 -0400967 if ($failed) {
968 doprint "FAILED!\n";
969 } else {
970 doprint "SUCCESS\n";
971 }
972
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400973 return !$failed;
974}
975
Steven Rostedte48c5292010-11-02 14:35:37 -0400976sub run_ssh {
977 my ($cmd) = @_;
978 my $cp_exec = $ssh_exec;
979
980 $cp_exec =~ s/\$SSH_COMMAND/$cmd/g;
981 return run_command "$cp_exec";
982}
983
984sub run_scp {
985 my ($src, $dst) = @_;
986 my $cp_scp = $scp_to_target;
987
988 $cp_scp =~ s/\$SRC_FILE/$src/g;
989 $cp_scp =~ s/\$DST_FILE/$dst/g;
990
991 return run_command "$cp_scp";
992}
993
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400994sub get_grub_index {
995
Steven Rostedta75fece2010-11-02 14:58:27 -0400996 if ($reboot_type ne "grub") {
997 return;
998 }
Steven Rostedt5a391fb2010-11-02 14:57:43 -0400999 return if (defined($grub_number));
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001000
1001 doprint "Find grub menu ... ";
1002 $grub_number = -1;
Steven Rostedte48c5292010-11-02 14:35:37 -04001003
1004 my $ssh_grub = $ssh_exec;
1005 $ssh_grub =~ s,\$SSH_COMMAND,cat /boot/grub/menu.lst,g;
1006
1007 open(IN, "$ssh_grub |")
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001008 or die "unable to get menu.lst";
Steven Rostedte48c5292010-11-02 14:35:37 -04001009
Steven Rostedteaa1fe22011-09-14 17:20:39 -04001010 my $found = 0;
1011
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001012 while (<IN>) {
Steven Rostedta75fece2010-11-02 14:58:27 -04001013 if (/^\s*title\s+$grub_menu\s*$/) {
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001014 $grub_number++;
Steven Rostedteaa1fe22011-09-14 17:20:39 -04001015 $found = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001016 last;
1017 } elsif (/^\s*title\s/) {
1018 $grub_number++;
1019 }
1020 }
1021 close(IN);
1022
Steven Rostedta75fece2010-11-02 14:58:27 -04001023 die "Could not find '$grub_menu' in /boot/grub/menu on $machine"
Steven Rostedteaa1fe22011-09-14 17:20:39 -04001024 if (!$found);
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001025 doprint "$grub_number\n";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001026}
1027
Steven Rostedt2545eb62010-11-02 15:01:32 -04001028sub wait_for_input
1029{
1030 my ($fp, $time) = @_;
1031 my $rin;
1032 my $ready;
1033 my $line;
1034 my $ch;
1035
1036 if (!defined($time)) {
1037 $time = $timeout;
1038 }
1039
1040 $rin = '';
1041 vec($rin, fileno($fp), 1) = 1;
1042 $ready = select($rin, undef, undef, $time);
1043
1044 $line = "";
1045
1046 # try to read one char at a time
1047 while (sysread $fp, $ch, 1) {
1048 $line .= $ch;
1049 last if ($ch eq "\n");
1050 }
1051
1052 if (!length($line)) {
1053 return undef;
1054 }
1055
1056 return $line;
1057}
1058
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001059sub reboot_to {
Steven Rostedta75fece2010-11-02 14:58:27 -04001060 if ($reboot_type eq "grub") {
Steven Rostedt4da46da2011-06-01 23:25:13 -04001061 run_ssh "'(echo \"savedefault --default=$grub_number --once\" | grub --batch && reboot)'";
Steven Rostedta75fece2010-11-02 14:58:27 -04001062 return;
1063 }
1064
1065 run_command "$reboot_script";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001066}
1067
Steven Rostedta57419b2010-11-02 15:13:54 -04001068sub get_sha1 {
1069 my ($commit) = @_;
1070
1071 doprint "git rev-list --max-count=1 $commit ... ";
1072 my $sha1 = `git rev-list --max-count=1 $commit`;
1073 my $ret = $?;
1074
1075 logit $sha1;
1076
1077 if ($ret) {
1078 doprint "FAILED\n";
1079 dodie "Failed to get git $commit";
1080 }
1081
1082 print "SUCCESS\n";
1083
1084 chomp $sha1;
1085
1086 return $sha1;
1087}
1088
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001089sub monitor {
Steven Rostedt2545eb62010-11-02 15:01:32 -04001090 my $booted = 0;
1091 my $bug = 0;
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001092 my $skip_call_trace = 0;
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001093 my $loops;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001094
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001095 wait_for_monitor 5;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001096
1097 my $line;
1098 my $full_line = "";
1099
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001100 open(DMESG, "> $dmesg") or
1101 die "unable to write to $dmesg";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001102
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001103 reboot_to;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001104
Steven Rostedt1c8a6172010-11-09 12:55:40 -05001105 my $success_start;
1106 my $failure_start;
Steven Rostedt2d01b262011-03-08 09:47:54 -05001107 my $monitor_start = time;
1108 my $done = 0;
Steven Rostedtf1a5b962011-06-13 10:30:00 -04001109 my $version_found = 0;
Steven Rostedt1c8a6172010-11-09 12:55:40 -05001110
Steven Rostedt2d01b262011-03-08 09:47:54 -05001111 while (!$done) {
Steven Rostedt2545eb62010-11-02 15:01:32 -04001112
Steven Rostedtecaf8e52011-06-13 10:48:10 -04001113 if ($bug && defined($stop_after_failure) &&
1114 $stop_after_failure >= 0) {
1115 my $time = $stop_after_failure - (time - $failure_start);
1116 $line = wait_for_input($monitor_fp, $time);
1117 if (!defined($line)) {
1118 doprint "bug timed out after $booted_timeout seconds\n";
1119 doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
1120 last;
1121 }
1122 } elsif ($booted) {
Steven Rostedta75fece2010-11-02 14:58:27 -04001123 $line = wait_for_input($monitor_fp, $booted_timeout);
Steven Rostedtcd4f1d52011-06-13 10:26:27 -04001124 if (!defined($line)) {
1125 my $s = $booted_timeout == 1 ? "" : "s";
1126 doprint "Successful boot found: break after $booted_timeout second$s\n";
1127 last;
1128 }
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001129 } else {
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001130 $line = wait_for_input($monitor_fp);
Steven Rostedtcd4f1d52011-06-13 10:26:27 -04001131 if (!defined($line)) {
1132 my $s = $timeout == 1 ? "" : "s";
1133 doprint "Timed out after $timeout second$s\n";
1134 last;
1135 }
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001136 }
Steven Rostedt2545eb62010-11-02 15:01:32 -04001137
Steven Rostedt2545eb62010-11-02 15:01:32 -04001138 doprint $line;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001139 print DMESG $line;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001140
1141 # we are not guaranteed to get a full line
1142 $full_line .= $line;
1143
Steven Rostedta75fece2010-11-02 14:58:27 -04001144 if ($full_line =~ /$success_line/) {
Steven Rostedt2545eb62010-11-02 15:01:32 -04001145 $booted = 1;
Steven Rostedt1c8a6172010-11-09 12:55:40 -05001146 $success_start = time;
1147 }
1148
1149 if ($booted && defined($stop_after_success) &&
1150 $stop_after_success >= 0) {
1151 my $now = time;
1152 if ($now - $success_start >= $stop_after_success) {
1153 doprint "Test forced to stop after $stop_after_success seconds after success\n";
1154 last;
1155 }
Steven Rostedt2545eb62010-11-02 15:01:32 -04001156 }
1157
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001158 if ($full_line =~ /\[ backtrace testing \]/) {
1159 $skip_call_trace = 1;
1160 }
1161
Steven Rostedt2545eb62010-11-02 15:01:32 -04001162 if ($full_line =~ /call trace:/i) {
Steven Rostedt46519202011-03-08 09:40:31 -05001163 if (!$bug && !$skip_call_trace) {
Steven Rostedt1c8a6172010-11-09 12:55:40 -05001164 $bug = 1;
1165 $failure_start = time;
1166 }
1167 }
1168
1169 if ($bug && defined($stop_after_failure) &&
1170 $stop_after_failure >= 0) {
1171 my $now = time;
1172 if ($now - $failure_start >= $stop_after_failure) {
1173 doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
1174 last;
1175 }
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001176 }
1177
1178 if ($full_line =~ /\[ end of backtrace testing \]/) {
1179 $skip_call_trace = 0;
1180 }
1181
1182 if ($full_line =~ /Kernel panic -/) {
Steven Rostedt10abf112011-03-07 13:21:00 -05001183 $failure_start = time;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001184 $bug = 1;
1185 }
1186
Steven Rostedtf1a5b962011-06-13 10:30:00 -04001187 # Detect triple faults by testing the banner
1188 if ($full_line =~ /\bLinux version (\S+).*\n/) {
1189 if ($1 eq $version) {
1190 $version_found = 1;
1191 } elsif ($version_found && $detect_triplefault) {
1192 # We already booted into the kernel we are testing,
1193 # but now we booted into another kernel?
1194 # Consider this a triple fault.
1195 doprint "Aleady booted in Linux kernel $version, but now\n";
1196 doprint "we booted into Linux kernel $1.\n";
1197 doprint "Assuming that this is a triple fault.\n";
1198 doprint "To disable this: set DETECT_TRIPLE_FAULT to 0\n";
1199 last;
1200 }
1201 }
1202
Steven Rostedt2545eb62010-11-02 15:01:32 -04001203 if ($line =~ /\n/) {
1204 $full_line = "";
1205 }
Steven Rostedt2d01b262011-03-08 09:47:54 -05001206
1207 if ($stop_test_after > 0 && !$booted && !$bug) {
1208 if (time - $monitor_start > $stop_test_after) {
Steven Rostedt4d62bf52011-05-20 09:14:35 -04001209 doprint "STOP_TEST_AFTER ($stop_test_after seconds) timed out\n";
Steven Rostedt2d01b262011-03-08 09:47:54 -05001210 $done = 1;
1211 }
1212 }
Steven Rostedt2545eb62010-11-02 15:01:32 -04001213 }
1214
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001215 close(DMESG);
Steven Rostedt2545eb62010-11-02 15:01:32 -04001216
Steven Rostedt2545eb62010-11-02 15:01:32 -04001217 if ($bug) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001218 return 0 if ($in_bisect);
Steven Rostedt576f6272010-11-02 14:58:38 -04001219 fail "failed - got a bug report" and return 0;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001220 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001221
Steven Rostedta75fece2010-11-02 14:58:27 -04001222 if (!$booted) {
1223 return 0 if ($in_bisect);
Steven Rostedt576f6272010-11-02 14:58:38 -04001224 fail "failed - never got a boot prompt." and return 0;
Steven Rostedta75fece2010-11-02 14:58:27 -04001225 }
1226
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001227 return 1;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001228}
1229
Steven Rostedtdb05cfe2011-06-13 11:09:22 -04001230sub do_post_install {
1231
1232 return if (!defined($post_install));
1233
1234 my $cp_post_install = $post_install;
1235 $cp_post_install =~ s/\$KERNEL_VERSION/$version/g;
1236 run_command "$cp_post_install" or
1237 dodie "Failed to run post install";
1238}
1239
Steven Rostedt2545eb62010-11-02 15:01:32 -04001240sub install {
1241
Steven Rostedte0a87422011-09-30 17:50:48 -04001242 return if ($no_install);
1243
Steven Rostedte48c5292010-11-02 14:35:37 -04001244 run_scp "$outputdir/$build_target", "$target_image" or
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001245 dodie "failed to copy image";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001246
1247 my $install_mods = 0;
1248
1249 # should we process modules?
1250 $install_mods = 0;
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05001251 open(IN, "$output_config") or dodie("Can't read config file");
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001252 while (<IN>) {
1253 if (/CONFIG_MODULES(=y)?/) {
1254 $install_mods = 1 if (defined($1));
1255 last;
1256 }
1257 }
1258 close(IN);
1259
1260 if (!$install_mods) {
Steven Rostedtdb05cfe2011-06-13 11:09:22 -04001261 do_post_install;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001262 doprint "No modules needed\n";
1263 return;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001264 }
1265
Steven Rostedta75fece2010-11-02 14:58:27 -04001266 run_command "$make INSTALL_MOD_PATH=$tmpdir modules_install" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001267 dodie "Failed to install modules";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001268
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001269 my $modlib = "/lib/modules/$version";
Steven Rostedta57419b2010-11-02 15:13:54 -04001270 my $modtar = "ktest-mods.tar.bz2";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001271
Steven Rostedte48c5292010-11-02 14:35:37 -04001272 run_ssh "rm -rf $modlib" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001273 dodie "failed to remove old mods: $modlib";
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001274
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001275 # would be nice if scp -r did not follow symbolic links
Steven Rostedta75fece2010-11-02 14:58:27 -04001276 run_command "cd $tmpdir && tar -cjf $modtar lib/modules/$version" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001277 dodie "making tarball";
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001278
Steven Rostedte48c5292010-11-02 14:35:37 -04001279 run_scp "$tmpdir/$modtar", "/tmp" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001280 dodie "failed to copy modules";
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001281
Steven Rostedta75fece2010-11-02 14:58:27 -04001282 unlink "$tmpdir/$modtar";
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001283
Steven Rostedte7b13442011-06-14 20:44:36 -04001284 run_ssh "'(cd / && tar xjf /tmp/$modtar)'" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001285 dodie "failed to tar modules";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001286
Steven Rostedte48c5292010-11-02 14:35:37 -04001287 run_ssh "rm -f /tmp/$modtar";
Steven Rostedt8b37ca82010-11-02 14:58:33 -04001288
Steven Rostedtdb05cfe2011-06-13 11:09:22 -04001289 do_post_install;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001290}
1291
Steven Rostedtddf607e2011-06-14 20:49:13 -04001292sub get_version {
1293 # get the release name
1294 doprint "$make kernelrelease ... ";
1295 $version = `$make kernelrelease | tail -1`;
1296 chomp($version);
1297 doprint "$version\n";
1298}
1299
1300sub start_monitor_and_boot {
1301 get_grub_index;
1302 get_version;
1303 install;
1304
1305 start_monitor;
1306 return monitor;
1307}
1308
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001309sub check_buildlog {
1310 my ($patch) = @_;
1311
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001312 my @files = `git show $patch | diffstat -l`;
1313
1314 open(IN, "git show $patch |") or
1315 dodie "failed to show $patch";
1316 while (<IN>) {
1317 if (m,^--- a/(.*),) {
1318 chomp $1;
1319 $files[$#files] = $1;
1320 }
1321 }
1322 close(IN);
1323
1324 open(IN, $buildlog) or dodie "Can't open $buildlog";
1325 while (<IN>) {
1326 if (/^\s*(.*?):.*(warning|error)/) {
1327 my $err = $1;
1328 foreach my $file (@files) {
Steven Rostedta75fece2010-11-02 14:58:27 -04001329 my $fullpath = "$builddir/$file";
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001330 if ($file eq $err || $fullpath eq $err) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001331 fail "$file built with warnings" and return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001332 }
1333 }
1334 }
1335 }
1336 close(IN);
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001337
1338 return 1;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001339}
1340
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001341sub apply_min_config {
1342 my $outconfig = "$output_config.new";
Steven Rostedt612b9e92011-03-07 13:27:43 -05001343
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001344 # Read the config file and remove anything that
1345 # is in the force_config hash (from minconfig and others)
1346 # then add the force config back.
1347
1348 doprint "Applying minimum configurations into $output_config.new\n";
1349
1350 open (OUT, ">$outconfig") or
1351 dodie "Can't create $outconfig";
1352
1353 if (-f $output_config) {
1354 open (IN, $output_config) or
1355 dodie "Failed to open $output_config";
1356 while (<IN>) {
1357 if (/^(# )?(CONFIG_[^\s=]*)/) {
1358 next if (defined($force_config{$2}));
1359 }
1360 print OUT;
1361 }
1362 close IN;
1363 }
1364 foreach my $config (keys %force_config) {
1365 print OUT "$force_config{$config}\n";
1366 }
1367 close OUT;
1368
1369 run_command "mv $outconfig $output_config";
1370}
1371
1372sub make_oldconfig {
1373
Steven Rostedt4c4ab122011-07-15 21:16:17 -04001374 my @force_list = keys %force_config;
1375
1376 if ($#force_list >= 0) {
1377 apply_min_config;
1378 }
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001379
1380 if (!run_command "$make oldnoconfig") {
Steven Rostedt612b9e92011-03-07 13:27:43 -05001381 # Perhaps oldnoconfig doesn't exist in this version of the kernel
1382 # try a yes '' | oldconfig
1383 doprint "oldnoconfig failed, trying yes '' | make oldconfig\n";
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001384 run_command "yes '' | $make oldconfig" or
Steven Rostedt612b9e92011-03-07 13:27:43 -05001385 dodie "failed make config oldconfig";
1386 }
1387}
1388
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001389# read a config file and use this to force new configs.
1390sub load_force_config {
1391 my ($config) = @_;
1392
1393 open(IN, $config) or
1394 dodie "failed to read $config";
1395 while (<IN>) {
1396 chomp;
1397 if (/^(CONFIG[^\s=]*)(\s*=.*)/) {
1398 $force_config{$1} = $_;
1399 } elsif (/^# (CONFIG_\S*) is not set/) {
1400 $force_config{$1} = $_;
1401 }
1402 }
1403 close IN;
1404}
1405
Steven Rostedt2545eb62010-11-02 15:01:32 -04001406sub build {
1407 my ($type) = @_;
1408
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001409 unlink $buildlog;
1410
Steven Rostedt4ab1cce2011-09-30 18:12:20 -04001411 # Failed builds should not reboot the target
1412 my $save_no_reboot = $no_reboot;
1413 $no_reboot = 1;
1414
Steven Rostedt0bd6c1a2011-06-14 20:39:31 -04001415 if (defined($pre_build)) {
1416 my $ret = run_command $pre_build;
1417 if (!$ret && defined($pre_build_die) &&
1418 $pre_build_die) {
1419 dodie "failed to pre_build\n";
1420 }
1421 }
1422
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001423 if ($type =~ /^useconfig:(.*)/) {
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05001424 run_command "cp $1 $output_config" or
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001425 dodie "could not copy $1 to .config";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001426
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001427 $type = "oldconfig";
1428 }
1429
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001430 # old config can ask questions
1431 if ($type eq "oldconfig") {
Steven Rostedt9386c6a2010-11-08 16:35:48 -05001432 $type = "oldnoconfig";
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001433
1434 # allow for empty configs
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05001435 run_command "touch $output_config";
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001436
Andrew Jones13488232011-08-12 15:32:04 +02001437 if (!$noclean) {
1438 run_command "mv $output_config $outputdir/config_temp" or
1439 dodie "moving .config";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001440
Andrew Jones13488232011-08-12 15:32:04 +02001441 run_command "$make mrproper" or dodie "make mrproper";
1442
1443 run_command "mv $outputdir/config_temp $output_config" or
1444 dodie "moving config_temp";
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001445 }
1446
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001447 } elsif (!$noclean) {
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05001448 unlink "$output_config";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001449 run_command "$make mrproper" or
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001450 dodie "make mrproper";
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001451 }
Steven Rostedt2545eb62010-11-02 15:01:32 -04001452
1453 # add something to distinguish this build
Steven Rostedta75fece2010-11-02 14:58:27 -04001454 open(OUT, "> $outputdir/localversion") or dodie("Can't make localversion file");
1455 print OUT "$localversion\n";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001456 close(OUT);
1457
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001458 if (defined($minconfig)) {
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001459 load_force_config($minconfig);
Steven Rostedt2545eb62010-11-02 15:01:32 -04001460 }
1461
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001462 if ($type ne "oldnoconfig") {
1463 run_command "$make $type" or
Steven Rostedt612b9e92011-03-07 13:27:43 -05001464 dodie "failed make config";
1465 }
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001466 # Run old config regardless, to enforce min configurations
1467 make_oldconfig;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001468
Steven Rostedta75fece2010-11-02 14:58:27 -04001469 $redirect = "$buildlog";
Steven Rostedt0bd6c1a2011-06-14 20:39:31 -04001470 my $build_ret = run_command "$make $build_options";
1471 undef $redirect;
1472
1473 if (defined($post_build)) {
1474 my $ret = run_command $post_build;
1475 if (!$ret && defined($post_build_die) &&
1476 $post_build_die) {
1477 dodie "failed to post_build\n";
1478 }
1479 }
1480
1481 if (!$build_ret) {
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001482 # bisect may need this to pass
Steven Rostedt4ab1cce2011-09-30 18:12:20 -04001483 if ($in_bisect) {
1484 $no_reboot = $save_no_reboot;
1485 return 0;
1486 }
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001487 fail "failed build" and return 0;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001488 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001489
Steven Rostedt4ab1cce2011-09-30 18:12:20 -04001490 $no_reboot = $save_no_reboot;
1491
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001492 return 1;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001493}
1494
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001495sub halt {
Steven Rostedte48c5292010-11-02 14:35:37 -04001496 if (!run_ssh "halt" or defined($power_off)) {
Steven Rostedt576f6272010-11-02 14:58:38 -04001497 if (defined($poweroff_after_halt)) {
1498 sleep $poweroff_after_halt;
1499 run_command "$power_off";
1500 }
1501 } else {
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001502 # nope? the zap it!
Steven Rostedta75fece2010-11-02 14:58:27 -04001503 run_command "$power_off";
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001504 }
1505}
1506
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001507sub success {
1508 my ($i) = @_;
1509
Steven Rostedte48c5292010-11-02 14:35:37 -04001510 $successes++;
1511
Steven Rostedt9064af52011-06-13 10:38:48 -04001512 my $name = "";
1513
1514 if (defined($test_name)) {
1515 $name = " ($test_name)";
1516 }
1517
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001518 doprint "\n\n*******************************************\n";
1519 doprint "*******************************************\n";
Steven Rostedt9064af52011-06-13 10:38:48 -04001520 doprint "KTEST RESULT: TEST $i$name SUCCESS!!!! **\n";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001521 doprint "*******************************************\n";
1522 doprint "*******************************************\n";
1523
Steven Rostedt576f6272010-11-02 14:58:38 -04001524 if ($i != $opt{"NUM_TESTS"} && !do_not_reboot) {
Steven Rostedta75fece2010-11-02 14:58:27 -04001525 doprint "Reboot and wait $sleep_time seconds\n";
Andrew Jones2728be42011-08-12 15:32:05 +02001526 reboot $sleep_time;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001527 }
1528}
1529
Steven Rostedtc960bb92011-03-08 09:22:39 -05001530sub answer_bisect {
1531 for (;;) {
1532 doprint "Pass or fail? [p/f]";
1533 my $ans = <STDIN>;
1534 chomp $ans;
1535 if ($ans eq "p" || $ans eq "P") {
1536 return 1;
1537 } elsif ($ans eq "f" || $ans eq "F") {
1538 return 0;
1539 } else {
1540 print "Please answer 'P' or 'F'\n";
1541 }
1542 }
1543}
1544
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001545sub child_run_test {
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001546 my $failed = 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001547
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001548 # child should have no power
Steven Rostedta75fece2010-11-02 14:58:27 -04001549 $reboot_on_error = 0;
1550 $poweroff_on_error = 0;
1551 $die_on_failure = 1;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001552
1553 run_command $run_test or $failed = 1;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001554 exit $failed;
1555}
1556
1557my $child_done;
1558
1559sub child_finished {
1560 $child_done = 1;
1561}
1562
1563sub do_run_test {
1564 my $child_pid;
1565 my $child_exit;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001566 my $line;
1567 my $full_line;
1568 my $bug = 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001569
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001570 wait_for_monitor 1;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001571
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001572 doprint "run test $run_test\n";
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001573
1574 $child_done = 0;
1575
1576 $SIG{CHLD} = qw(child_finished);
1577
1578 $child_pid = fork;
1579
1580 child_run_test if (!$child_pid);
1581
1582 $full_line = "";
1583
1584 do {
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001585 $line = wait_for_input($monitor_fp, 1);
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001586 if (defined($line)) {
1587
1588 # we are not guaranteed to get a full line
1589 $full_line .= $line;
Steven Rostedt8ea0e062011-03-08 09:44:35 -05001590 doprint $line;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001591
1592 if ($full_line =~ /call trace:/i) {
1593 $bug = 1;
1594 }
1595
1596 if ($full_line =~ /Kernel panic -/) {
1597 $bug = 1;
1598 }
1599
1600 if ($line =~ /\n/) {
1601 $full_line = "";
1602 }
1603 }
1604 } while (!$child_done && !$bug);
1605
1606 if ($bug) {
Steven Rostedt8ea0e062011-03-08 09:44:35 -05001607 my $failure_start = time;
1608 my $now;
1609 do {
1610 $line = wait_for_input($monitor_fp, 1);
1611 if (defined($line)) {
1612 doprint $line;
1613 }
1614 $now = time;
1615 if ($now - $failure_start >= $stop_after_failure) {
1616 last;
1617 }
1618 } while (defined($line));
1619
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001620 doprint "Detected kernel crash!\n";
1621 # kill the child with extreme prejudice
1622 kill 9, $child_pid;
1623 }
1624
1625 waitpid $child_pid, 0;
1626 $child_exit = $?;
1627
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001628 if ($bug || $child_exit) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001629 return 0 if $in_bisect;
1630 fail "test failed" and return 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001631 }
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001632 return 1;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001633}
1634
Steven Rostedta75fece2010-11-02 14:58:27 -04001635sub run_git_bisect {
1636 my ($command) = @_;
1637
1638 doprint "$command ... ";
1639
1640 my $output = `$command 2>&1`;
1641 my $ret = $?;
1642
1643 logit $output;
1644
1645 if ($ret) {
1646 doprint "FAILED\n";
1647 dodie "Failed to git bisect";
1648 }
1649
1650 doprint "SUCCESS\n";
1651 if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\))\s+\[([[:xdigit:]]+)\]/) {
1652 doprint "$1 [$2]\n";
1653 } elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) {
1654 $bisect_bad = $1;
1655 doprint "Found bad commit... $1\n";
1656 return 0;
1657 } else {
1658 # we already logged it, just print it now.
1659 print $output;
1660 }
1661
1662 return 1;
1663}
1664
Steven Rostedtc23dca72011-03-08 09:26:31 -05001665sub bisect_reboot {
1666 doprint "Reboot and sleep $bisect_sleep_time seconds\n";
Andrew Jones2728be42011-08-12 15:32:05 +02001667 reboot $bisect_sleep_time;
Steven Rostedtc23dca72011-03-08 09:26:31 -05001668}
1669
1670# returns 1 on success, 0 on failure, -1 on skip
Steven Rostedt0a05c762010-11-08 11:14:10 -05001671sub run_bisect_test {
1672 my ($type, $buildtype) = @_;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001673
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001674 my $failed = 0;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001675 my $result;
1676 my $output;
1677 my $ret;
1678
Steven Rostedt0a05c762010-11-08 11:14:10 -05001679 $in_bisect = 1;
1680
1681 build $buildtype or $failed = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001682
1683 if ($type ne "build") {
Steven Rostedtc23dca72011-03-08 09:26:31 -05001684 if ($failed && $bisect_skip) {
1685 $in_bisect = 0;
1686 return -1;
1687 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001688 dodie "Failed on build" if $failed;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001689
1690 # Now boot the box
Steven Rostedtddf607e2011-06-14 20:49:13 -04001691 start_monitor_and_boot or $failed = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001692
1693 if ($type ne "boot") {
Steven Rostedtc23dca72011-03-08 09:26:31 -05001694 if ($failed && $bisect_skip) {
1695 end_monitor;
1696 bisect_reboot;
1697 $in_bisect = 0;
1698 return -1;
1699 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001700 dodie "Failed on boot" if $failed;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001701
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001702 do_run_test or $failed = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001703 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001704 end_monitor;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001705 }
1706
1707 if ($failed) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001708 $result = 0;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001709 } else {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001710 $result = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001711 }
Steven Rostedt4025bc62011-05-20 09:16:29 -04001712
1713 # reboot the box to a kernel we can ssh to
1714 if ($type ne "build") {
1715 bisect_reboot;
1716 }
Steven Rostedt0a05c762010-11-08 11:14:10 -05001717 $in_bisect = 0;
1718
1719 return $result;
1720}
1721
1722sub run_bisect {
1723 my ($type) = @_;
1724 my $buildtype = "oldconfig";
1725
1726 # We should have a minconfig to use?
1727 if (defined($minconfig)) {
1728 $buildtype = "useconfig:$minconfig";
1729 }
1730
1731 my $ret = run_bisect_test $type, $buildtype;
1732
Steven Rostedtc960bb92011-03-08 09:22:39 -05001733 if ($bisect_manual) {
1734 $ret = answer_bisect;
1735 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001736
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04001737 # Are we looking for where it worked, not failed?
1738 if ($reverse_bisect) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001739 $ret = !$ret;
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04001740 }
1741
Steven Rostedtc23dca72011-03-08 09:26:31 -05001742 if ($ret > 0) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001743 return "good";
Steven Rostedtc23dca72011-03-08 09:26:31 -05001744 } elsif ($ret == 0) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001745 return "bad";
Steven Rostedtc23dca72011-03-08 09:26:31 -05001746 } elsif ($bisect_skip) {
1747 doprint "HIT A BAD COMMIT ... SKIPPING\n";
1748 return "skip";
Steven Rostedt0a05c762010-11-08 11:14:10 -05001749 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001750}
1751
1752sub bisect {
1753 my ($i) = @_;
1754
1755 my $result;
1756
1757 die "BISECT_GOOD[$i] not defined\n" if (!defined($opt{"BISECT_GOOD[$i]"}));
1758 die "BISECT_BAD[$i] not defined\n" if (!defined($opt{"BISECT_BAD[$i]"}));
1759 die "BISECT_TYPE[$i] not defined\n" if (!defined($opt{"BISECT_TYPE[$i]"}));
1760
1761 my $good = $opt{"BISECT_GOOD[$i]"};
1762 my $bad = $opt{"BISECT_BAD[$i]"};
1763 my $type = $opt{"BISECT_TYPE[$i]"};
Steven Rostedta75fece2010-11-02 14:58:27 -04001764 my $start = $opt{"BISECT_START[$i]"};
1765 my $replay = $opt{"BISECT_REPLAY[$i]"};
Steven Rostedt3410f6f2011-03-08 09:38:12 -05001766 my $start_files = $opt{"BISECT_FILES[$i]"};
1767
1768 if (defined($start_files)) {
1769 $start_files = " -- " . $start_files;
1770 } else {
1771 $start_files = "";
1772 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001773
Steven Rostedta57419b2010-11-02 15:13:54 -04001774 # convert to true sha1's
1775 $good = get_sha1($good);
1776 $bad = get_sha1($bad);
1777
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04001778 if (defined($opt{"BISECT_REVERSE[$i]"}) &&
1779 $opt{"BISECT_REVERSE[$i]"} == 1) {
1780 doprint "Performing a reverse bisect (bad is good, good is bad!)\n";
1781 $reverse_bisect = 1;
1782 } else {
1783 $reverse_bisect = 0;
1784 }
1785
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001786 # Can't have a test without having a test to run
1787 if ($type eq "test" && !defined($run_test)) {
1788 $type = "boot";
1789 }
1790
Steven Rostedta75fece2010-11-02 14:58:27 -04001791 my $check = $opt{"BISECT_CHECK[$i]"};
1792 if (defined($check) && $check ne "0") {
1793
1794 # get current HEAD
Steven Rostedta57419b2010-11-02 15:13:54 -04001795 my $head = get_sha1("HEAD");
Steven Rostedta75fece2010-11-02 14:58:27 -04001796
1797 if ($check ne "good") {
1798 doprint "TESTING BISECT BAD [$bad]\n";
1799 run_command "git checkout $bad" or
1800 die "Failed to checkout $bad";
1801
1802 $result = run_bisect $type;
1803
1804 if ($result ne "bad") {
1805 fail "Tested BISECT_BAD [$bad] and it succeeded" and return 0;
1806 }
1807 }
1808
1809 if ($check ne "bad") {
1810 doprint "TESTING BISECT GOOD [$good]\n";
1811 run_command "git checkout $good" or
1812 die "Failed to checkout $good";
1813
1814 $result = run_bisect $type;
1815
1816 if ($result ne "good") {
1817 fail "Tested BISECT_GOOD [$good] and it failed" and return 0;
1818 }
1819 }
1820
1821 # checkout where we started
1822 run_command "git checkout $head" or
1823 die "Failed to checkout $head";
1824 }
1825
Steven Rostedt3410f6f2011-03-08 09:38:12 -05001826 run_command "git bisect start$start_files" or
Steven Rostedta75fece2010-11-02 14:58:27 -04001827 dodie "could not start bisect";
1828
1829 run_command "git bisect good $good" or
1830 dodie "could not set bisect good to $good";
1831
1832 run_git_bisect "git bisect bad $bad" or
1833 dodie "could not set bisect bad to $bad";
1834
1835 if (defined($replay)) {
1836 run_command "git bisect replay $replay" or
1837 dodie "failed to run replay";
1838 }
1839
1840 if (defined($start)) {
1841 run_command "git checkout $start" or
1842 dodie "failed to checkout $start";
1843 }
1844
1845 my $test;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001846 do {
1847 $result = run_bisect $type;
Steven Rostedta75fece2010-11-02 14:58:27 -04001848 $test = run_git_bisect "git bisect $result";
1849 } while ($test);
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001850
1851 run_command "git bisect log" or
1852 dodie "could not capture git bisect log";
1853
1854 run_command "git bisect reset" or
1855 dodie "could not reset git bisect";
1856
1857 doprint "Bad commit was [$bisect_bad]\n";
1858
Steven Rostedt0a05c762010-11-08 11:14:10 -05001859 success $i;
1860}
1861
1862my %config_ignore;
1863my %config_set;
1864
1865my %config_list;
1866my %null_config;
1867
1868my %dependency;
1869
Steven Rostedt4c4ab122011-07-15 21:16:17 -04001870sub assign_configs {
1871 my ($hash, $config) = @_;
Steven Rostedt0a05c762010-11-08 11:14:10 -05001872
1873 open (IN, $config)
1874 or dodie "Failed to read $config";
1875
1876 while (<IN>) {
Steven Rostedt9bf71742011-06-01 23:27:19 -04001877 if (/^((CONFIG\S*)=.*)/) {
Steven Rostedt4c4ab122011-07-15 21:16:17 -04001878 ${$hash}{$2} = $1;
Steven Rostedt0a05c762010-11-08 11:14:10 -05001879 }
1880 }
1881
1882 close(IN);
1883}
1884
Steven Rostedt4c4ab122011-07-15 21:16:17 -04001885sub process_config_ignore {
1886 my ($config) = @_;
1887
1888 assign_configs \%config_ignore, $config;
1889}
1890
Steven Rostedt0a05c762010-11-08 11:14:10 -05001891sub read_current_config {
1892 my ($config_ref) = @_;
1893
1894 %{$config_ref} = ();
1895 undef %{$config_ref};
1896
1897 my @key = keys %{$config_ref};
1898 if ($#key >= 0) {
1899 print "did not delete!\n";
1900 exit;
1901 }
1902 open (IN, "$output_config");
1903
1904 while (<IN>) {
1905 if (/^(CONFIG\S+)=(.*)/) {
1906 ${$config_ref}{$1} = $2;
1907 }
1908 }
1909 close(IN);
1910}
1911
1912sub get_dependencies {
1913 my ($config) = @_;
1914
1915 my $arr = $dependency{$config};
1916 if (!defined($arr)) {
1917 return ();
1918 }
1919
1920 my @deps = @{$arr};
1921
1922 foreach my $dep (@{$arr}) {
1923 print "ADD DEP $dep\n";
1924 @deps = (@deps, get_dependencies $dep);
1925 }
1926
1927 return @deps;
1928}
1929
1930sub create_config {
1931 my @configs = @_;
1932
1933 open(OUT, ">$output_config") or dodie "Can not write to $output_config";
1934
1935 foreach my $config (@configs) {
1936 print OUT "$config_set{$config}\n";
1937 my @deps = get_dependencies $config;
1938 foreach my $dep (@deps) {
1939 print OUT "$config_set{$dep}\n";
1940 }
1941 }
1942
1943 foreach my $config (keys %config_ignore) {
1944 print OUT "$config_ignore{$config}\n";
1945 }
1946 close(OUT);
1947
1948# exit;
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001949 make_oldconfig;
Steven Rostedt0a05c762010-11-08 11:14:10 -05001950}
1951
1952sub compare_configs {
1953 my (%a, %b) = @_;
1954
1955 foreach my $item (keys %a) {
1956 if (!defined($b{$item})) {
1957 print "diff $item\n";
1958 return 1;
1959 }
1960 delete $b{$item};
1961 }
1962
1963 my @keys = keys %b;
1964 if ($#keys) {
1965 print "diff2 $keys[0]\n";
1966 }
1967 return -1 if ($#keys >= 0);
1968
1969 return 0;
1970}
1971
1972sub run_config_bisect_test {
1973 my ($type) = @_;
1974
1975 return run_bisect_test $type, "oldconfig";
1976}
1977
1978sub process_passed {
1979 my (%configs) = @_;
1980
1981 doprint "These configs had no failure: (Enabling them for further compiles)\n";
1982 # Passed! All these configs are part of a good compile.
1983 # Add them to the min options.
1984 foreach my $config (keys %configs) {
1985 if (defined($config_list{$config})) {
1986 doprint " removing $config\n";
1987 $config_ignore{$config} = $config_list{$config};
1988 delete $config_list{$config};
1989 }
1990 }
Steven Rostedtf1a27852010-11-11 11:34:38 -05001991 doprint "config copied to $outputdir/config_good\n";
1992 run_command "cp -f $output_config $outputdir/config_good";
Steven Rostedt0a05c762010-11-08 11:14:10 -05001993}
1994
1995sub process_failed {
1996 my ($config) = @_;
1997
1998 doprint "\n\n***************************************\n";
1999 doprint "Found bad config: $config\n";
2000 doprint "***************************************\n\n";
2001}
2002
2003sub run_config_bisect {
2004
2005 my @start_list = keys %config_list;
2006
2007 if ($#start_list < 0) {
2008 doprint "No more configs to test!!!\n";
2009 return -1;
2010 }
2011
2012 doprint "***** RUN TEST ***\n";
2013 my $type = $opt{"CONFIG_BISECT_TYPE[$iteration]"};
2014 my $ret;
2015 my %current_config;
2016
2017 my $count = $#start_list + 1;
2018 doprint " $count configs to test\n";
2019
2020 my $half = int($#start_list / 2);
2021
2022 do {
2023 my @tophalf = @start_list[0 .. $half];
2024
2025 create_config @tophalf;
2026 read_current_config \%current_config;
2027
2028 $count = $#tophalf + 1;
2029 doprint "Testing $count configs\n";
2030 my $found = 0;
2031 # make sure we test something
2032 foreach my $config (@tophalf) {
2033 if (defined($current_config{$config})) {
2034 logit " $config\n";
2035 $found = 1;
2036 }
2037 }
2038 if (!$found) {
2039 # try the other half
2040 doprint "Top half produced no set configs, trying bottom half\n";
Steven Rostedt4c8cc552011-06-01 23:22:30 -04002041 @tophalf = @start_list[$half + 1 .. $#start_list];
Steven Rostedt0a05c762010-11-08 11:14:10 -05002042 create_config @tophalf;
2043 read_current_config \%current_config;
2044 foreach my $config (@tophalf) {
2045 if (defined($current_config{$config})) {
2046 logit " $config\n";
2047 $found = 1;
2048 }
2049 }
2050 if (!$found) {
2051 doprint "Failed: Can't make new config with current configs\n";
2052 foreach my $config (@start_list) {
2053 doprint " CONFIG: $config\n";
2054 }
2055 return -1;
2056 }
2057 $count = $#tophalf + 1;
2058 doprint "Testing $count configs\n";
2059 }
2060
2061 $ret = run_config_bisect_test $type;
Steven Rostedtc960bb92011-03-08 09:22:39 -05002062 if ($bisect_manual) {
2063 $ret = answer_bisect;
2064 }
Steven Rostedt0a05c762010-11-08 11:14:10 -05002065 if ($ret) {
2066 process_passed %current_config;
2067 return 0;
2068 }
2069
2070 doprint "This config had a failure.\n";
2071 doprint "Removing these configs that were not set in this config:\n";
Steven Rostedtf1a27852010-11-11 11:34:38 -05002072 doprint "config copied to $outputdir/config_bad\n";
2073 run_command "cp -f $output_config $outputdir/config_bad";
Steven Rostedt0a05c762010-11-08 11:14:10 -05002074
2075 # A config exists in this group that was bad.
2076 foreach my $config (keys %config_list) {
2077 if (!defined($current_config{$config})) {
2078 doprint " removing $config\n";
2079 delete $config_list{$config};
2080 }
2081 }
2082
2083 @start_list = @tophalf;
2084
2085 if ($#start_list == 0) {
2086 process_failed $start_list[0];
2087 return 1;
2088 }
2089
2090 # remove half the configs we are looking at and see if
2091 # they are good.
2092 $half = int($#start_list / 2);
Steven Rostedt4c8cc552011-06-01 23:22:30 -04002093 } while ($#start_list > 0);
Steven Rostedt0a05c762010-11-08 11:14:10 -05002094
Steven Rostedtc960bb92011-03-08 09:22:39 -05002095 # we found a single config, try it again unless we are running manually
2096
2097 if ($bisect_manual) {
2098 process_failed $start_list[0];
2099 return 1;
2100 }
2101
Steven Rostedt0a05c762010-11-08 11:14:10 -05002102 my @tophalf = @start_list[0 .. 0];
2103
2104 $ret = run_config_bisect_test $type;
2105 if ($ret) {
2106 process_passed %current_config;
2107 return 0;
2108 }
2109
2110 process_failed $start_list[0];
2111 return 1;
2112}
2113
2114sub config_bisect {
2115 my ($i) = @_;
2116
2117 my $start_config = $opt{"CONFIG_BISECT[$i]"};
2118
2119 my $tmpconfig = "$tmpdir/use_config";
2120
Steven Rostedt30f75da2011-06-13 10:35:35 -04002121 if (defined($config_bisect_good)) {
2122 process_config_ignore $config_bisect_good;
2123 }
2124
Steven Rostedt0a05c762010-11-08 11:14:10 -05002125 # Make the file with the bad config and the min config
2126 if (defined($minconfig)) {
2127 # read the min config for things to ignore
2128 run_command "cp $minconfig $tmpconfig" or
2129 dodie "failed to copy $minconfig to $tmpconfig";
2130 } else {
2131 unlink $tmpconfig;
2132 }
2133
Steven Rostedt0a05c762010-11-08 11:14:10 -05002134 if (-f $tmpconfig) {
Steven Rostedtfcb3f162011-06-13 10:40:58 -04002135 load_force_config($tmpconfig);
Steven Rostedt0a05c762010-11-08 11:14:10 -05002136 process_config_ignore $tmpconfig;
2137 }
2138
2139 # now process the start config
2140 run_command "cp $start_config $output_config" or
2141 dodie "failed to copy $start_config to $output_config";
2142
2143 # read directly what we want to check
2144 my %config_check;
2145 open (IN, $output_config)
2146 or dodie "faied to open $output_config";
2147
2148 while (<IN>) {
2149 if (/^((CONFIG\S*)=.*)/) {
2150 $config_check{$2} = $1;
2151 }
2152 }
2153 close(IN);
2154
Steven Rostedt250bae82011-07-15 22:05:59 -04002155 # Now run oldconfig with the minconfig
Steven Rostedtfcb3f162011-06-13 10:40:58 -04002156 make_oldconfig;
Steven Rostedt0a05c762010-11-08 11:14:10 -05002157
2158 # check to see what we lost (or gained)
2159 open (IN, $output_config)
2160 or dodie "Failed to read $start_config";
2161
2162 my %removed_configs;
2163 my %added_configs;
2164
2165 while (<IN>) {
2166 if (/^((CONFIG\S*)=.*)/) {
2167 # save off all options
2168 $config_set{$2} = $1;
2169 if (defined($config_check{$2})) {
2170 if (defined($config_ignore{$2})) {
2171 $removed_configs{$2} = $1;
2172 } else {
2173 $config_list{$2} = $1;
2174 }
2175 } elsif (!defined($config_ignore{$2})) {
2176 $added_configs{$2} = $1;
2177 $config_list{$2} = $1;
2178 }
2179 }
2180 }
2181 close(IN);
2182
2183 my @confs = keys %removed_configs;
2184 if ($#confs >= 0) {
2185 doprint "Configs overridden by default configs and removed from check:\n";
2186 foreach my $config (@confs) {
2187 doprint " $config\n";
2188 }
2189 }
2190 @confs = keys %added_configs;
2191 if ($#confs >= 0) {
2192 doprint "Configs appearing in make oldconfig and added:\n";
2193 foreach my $config (@confs) {
2194 doprint " $config\n";
2195 }
2196 }
2197
2198 my %config_test;
2199 my $once = 0;
2200
2201 # Sometimes kconfig does weird things. We must make sure
2202 # that the config we autocreate has everything we need
2203 # to test, otherwise we may miss testing configs, or
2204 # may not be able to create a new config.
2205 # Here we create a config with everything set.
2206 create_config (keys %config_list);
2207 read_current_config \%config_test;
2208 foreach my $config (keys %config_list) {
2209 if (!defined($config_test{$config})) {
2210 if (!$once) {
2211 $once = 1;
2212 doprint "Configs not produced by kconfig (will not be checked):\n";
2213 }
2214 doprint " $config\n";
2215 delete $config_list{$config};
2216 }
2217 }
2218 my $ret;
2219 do {
2220 $ret = run_config_bisect;
2221 } while (!$ret);
2222
2223 return $ret if ($ret < 0);
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04002224
2225 success $i;
2226}
2227
Steven Rostedt27d934b2011-05-20 09:18:18 -04002228sub patchcheck_reboot {
2229 doprint "Reboot and sleep $patchcheck_sleep_time seconds\n";
Andrew Jones2728be42011-08-12 15:32:05 +02002230 reboot $patchcheck_sleep_time;
Steven Rostedt27d934b2011-05-20 09:18:18 -04002231}
2232
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002233sub patchcheck {
2234 my ($i) = @_;
2235
2236 die "PATCHCHECK_START[$i] not defined\n"
2237 if (!defined($opt{"PATCHCHECK_START[$i]"}));
2238 die "PATCHCHECK_TYPE[$i] not defined\n"
2239 if (!defined($opt{"PATCHCHECK_TYPE[$i]"}));
2240
2241 my $start = $opt{"PATCHCHECK_START[$i]"};
2242
2243 my $end = "HEAD";
2244 if (defined($opt{"PATCHCHECK_END[$i]"})) {
2245 $end = $opt{"PATCHCHECK_END[$i]"};
2246 }
2247
Steven Rostedta57419b2010-11-02 15:13:54 -04002248 # Get the true sha1's since we can use things like HEAD~3
2249 $start = get_sha1($start);
2250 $end = get_sha1($end);
2251
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002252 my $type = $opt{"PATCHCHECK_TYPE[$i]"};
2253
2254 # Can't have a test without having a test to run
2255 if ($type eq "test" && !defined($run_test)) {
2256 $type = "boot";
2257 }
2258
2259 open (IN, "git log --pretty=oneline $end|") or
2260 dodie "could not get git list";
2261
2262 my @list;
2263
2264 while (<IN>) {
2265 chomp;
2266 $list[$#list+1] = $_;
2267 last if (/^$start/);
2268 }
2269 close(IN);
2270
2271 if ($list[$#list] !~ /^$start/) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002272 fail "SHA1 $start not found";
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002273 }
2274
2275 # go backwards in the list
2276 @list = reverse @list;
2277
2278 my $save_clean = $noclean;
Steven Rostedt19902072011-06-14 20:46:25 -04002279 my %ignored_warnings;
2280
2281 if (defined($ignore_warnings)) {
2282 foreach my $sha1 (split /\s+/, $ignore_warnings) {
2283 $ignored_warnings{$sha1} = 1;
2284 }
2285 }
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002286
2287 $in_patchcheck = 1;
2288 foreach my $item (@list) {
2289 my $sha1 = $item;
2290 $sha1 =~ s/^([[:xdigit:]]+).*/$1/;
2291
2292 doprint "\nProcessing commit $item\n\n";
2293
2294 run_command "git checkout $sha1" or
2295 die "Failed to checkout $sha1";
2296
2297 # only clean on the first and last patch
2298 if ($item eq $list[0] ||
2299 $item eq $list[$#list]) {
2300 $noclean = $save_clean;
2301 } else {
2302 $noclean = 1;
2303 }
2304
2305 if (defined($minconfig)) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002306 build "useconfig:$minconfig" or return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002307 } else {
2308 # ?? no config to use?
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002309 build "oldconfig" or return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002310 }
2311
Steven Rostedt19902072011-06-14 20:46:25 -04002312
2313 if (!defined($ignored_warnings{$sha1})) {
2314 check_buildlog $sha1 or return 0;
2315 }
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002316
2317 next if ($type eq "build");
2318
Steven Rostedt7faafbd2010-11-02 14:58:22 -04002319 my $failed = 0;
2320
Steven Rostedtddf607e2011-06-14 20:49:13 -04002321 start_monitor_and_boot or $failed = 1;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04002322
2323 if (!$failed && $type ne "boot"){
2324 do_run_test or $failed = 1;
2325 }
2326 end_monitor;
2327 return 0 if ($failed);
2328
Steven Rostedt27d934b2011-05-20 09:18:18 -04002329 patchcheck_reboot;
2330
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002331 }
2332 $in_patchcheck = 0;
2333 success $i;
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002334
2335 return 1;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002336}
2337
Steven Rostedtb9066f62011-07-15 21:25:24 -04002338my %depends;
2339my $iflevel = 0;
2340my @ifdeps;
2341
2342# prevent recursion
2343my %read_kconfigs;
2344
2345# taken from streamline_config.pl
2346sub read_kconfig {
2347 my ($kconfig) = @_;
2348
2349 my $state = "NONE";
2350 my $config;
2351 my @kconfigs;
2352
2353 my $cont = 0;
2354 my $line;
2355
2356
2357 if (! -f $kconfig) {
2358 doprint "file $kconfig does not exist, skipping\n";
2359 return;
2360 }
2361
2362 open(KIN, "$kconfig")
2363 or die "Can't open $kconfig";
2364 while (<KIN>) {
2365 chomp;
2366
2367 # Make sure that lines ending with \ continue
2368 if ($cont) {
2369 $_ = $line . " " . $_;
2370 }
2371
2372 if (s/\\$//) {
2373 $cont = 1;
2374 $line = $_;
2375 next;
2376 }
2377
2378 $cont = 0;
2379
2380 # collect any Kconfig sources
2381 if (/^source\s*"(.*)"/) {
2382 $kconfigs[$#kconfigs+1] = $1;
2383 }
2384
2385 # configs found
2386 if (/^\s*(menu)?config\s+(\S+)\s*$/) {
2387 $state = "NEW";
2388 $config = $2;
2389
2390 for (my $i = 0; $i < $iflevel; $i++) {
2391 if ($i) {
2392 $depends{$config} .= " " . $ifdeps[$i];
2393 } else {
2394 $depends{$config} = $ifdeps[$i];
2395 }
2396 $state = "DEP";
2397 }
2398
2399 # collect the depends for the config
2400 } elsif ($state eq "NEW" && /^\s*depends\s+on\s+(.*)$/) {
2401
2402 if (defined($depends{$1})) {
2403 $depends{$config} .= " " . $1;
2404 } else {
2405 $depends{$config} = $1;
2406 }
2407
2408 # Get the configs that select this config
2409 } elsif ($state ne "NONE" && /^\s*select\s+(\S+)/) {
2410 if (defined($depends{$1})) {
2411 $depends{$1} .= " " . $config;
2412 } else {
2413 $depends{$1} = $config;
2414 }
2415
2416 # Check for if statements
2417 } elsif (/^if\s+(.*\S)\s*$/) {
2418 my $deps = $1;
2419 # remove beginning and ending non text
2420 $deps =~ s/^[^a-zA-Z0-9_]*//;
2421 $deps =~ s/[^a-zA-Z0-9_]*$//;
2422
2423 my @deps = split /[^a-zA-Z0-9_]+/, $deps;
2424
2425 $ifdeps[$iflevel++] = join ':', @deps;
2426
2427 } elsif (/^endif/) {
2428
2429 $iflevel-- if ($iflevel);
2430
2431 # stop on "help"
2432 } elsif (/^\s*help\s*$/) {
2433 $state = "NONE";
2434 }
2435 }
2436 close(KIN);
2437
2438 # read in any configs that were found.
2439 foreach $kconfig (@kconfigs) {
2440 if (!defined($read_kconfigs{$kconfig})) {
2441 $read_kconfigs{$kconfig} = 1;
2442 read_kconfig("$builddir/$kconfig");
2443 }
2444 }
2445}
2446
2447sub read_depends {
2448 # find out which arch this is by the kconfig file
2449 open (IN, $output_config)
2450 or dodie "Failed to read $output_config";
2451 my $arch;
2452 while (<IN>) {
2453 if (m,Linux/(\S+)\s+\S+\s+Kernel Configuration,) {
2454 $arch = $1;
2455 last;
2456 }
2457 }
2458 close IN;
2459
2460 if (!defined($arch)) {
2461 doprint "Could not find arch from config file\n";
2462 doprint "no dependencies used\n";
2463 return;
2464 }
2465
2466 # arch is really the subarch, we need to know
2467 # what directory to look at.
2468 if ($arch eq "i386" || $arch eq "x86_64") {
2469 $arch = "x86";
2470 } elsif ($arch =~ /^tile/) {
2471 $arch = "tile";
2472 }
2473
2474 my $kconfig = "$builddir/arch/$arch/Kconfig";
2475
2476 if (! -f $kconfig && $arch =~ /\d$/) {
2477 my $orig = $arch;
2478 # some subarchs have numbers, truncate them
2479 $arch =~ s/\d*$//;
2480 $kconfig = "$builddir/arch/$arch/Kconfig";
2481 if (! -f $kconfig) {
2482 doprint "No idea what arch dir $orig is for\n";
2483 doprint "no dependencies used\n";
2484 return;
2485 }
2486 }
2487
2488 read_kconfig($kconfig);
2489}
2490
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002491sub read_config_list {
2492 my ($config) = @_;
2493
2494 open (IN, $config)
2495 or dodie "Failed to read $config";
2496
2497 while (<IN>) {
2498 if (/^((CONFIG\S*)=.*)/) {
2499 if (!defined($config_ignore{$2})) {
2500 $config_list{$2} = $1;
2501 }
2502 }
2503 }
2504
2505 close(IN);
2506}
2507
2508sub read_output_config {
2509 my ($config) = @_;
2510
2511 assign_configs \%config_ignore, $config;
2512}
2513
2514sub make_new_config {
2515 my @configs = @_;
2516
2517 open (OUT, ">$output_config")
2518 or dodie "Failed to write $output_config";
2519
2520 foreach my $config (@configs) {
2521 print OUT "$config\n";
2522 }
2523 close OUT;
2524}
2525
Steven Rostedtb9066f62011-07-15 21:25:24 -04002526sub get_depends {
2527 my ($dep) = @_;
2528
2529 my $kconfig = $dep;
2530 $kconfig =~ s/CONFIG_//;
2531
2532 $dep = $depends{"$kconfig"};
2533
2534 # the dep string we have saves the dependencies as they
2535 # were found, including expressions like ! && ||. We
2536 # want to split this out into just an array of configs.
2537
2538 my $valid = "A-Za-z_0-9";
2539
2540 my @configs;
2541
2542 while ($dep =~ /[$valid]/) {
2543
2544 if ($dep =~ /^[^$valid]*([$valid]+)/) {
2545 my $conf = "CONFIG_" . $1;
2546
2547 $configs[$#configs + 1] = $conf;
2548
2549 $dep =~ s/^[^$valid]*[$valid]+//;
2550 } else {
2551 die "this should never happen";
2552 }
2553 }
2554
2555 return @configs;
2556}
2557
2558my %min_configs;
2559my %keep_configs;
Steven Rostedt43d1b652011-07-15 22:01:56 -04002560my %save_configs;
Steven Rostedtb9066f62011-07-15 21:25:24 -04002561my %processed_configs;
2562my %nochange_config;
2563
2564sub test_this_config {
2565 my ($config) = @_;
2566
2567 my $found;
2568
2569 # if we already processed this config, skip it
2570 if (defined($processed_configs{$config})) {
2571 return undef;
2572 }
2573 $processed_configs{$config} = 1;
2574
2575 # if this config failed during this round, skip it
2576 if (defined($nochange_config{$config})) {
2577 return undef;
2578 }
2579
2580 my $kconfig = $config;
2581 $kconfig =~ s/CONFIG_//;
2582
2583 # Test dependencies first
2584 if (defined($depends{"$kconfig"})) {
2585 my @parents = get_depends $config;
2586 foreach my $parent (@parents) {
2587 # if the parent is in the min config, check it first
2588 next if (!defined($min_configs{$parent}));
2589 $found = test_this_config($parent);
2590 if (defined($found)) {
2591 return $found;
2592 }
2593 }
2594 }
2595
2596 # Remove this config from the list of configs
2597 # do a make oldnoconfig and then read the resulting
2598 # .config to make sure it is missing the config that
2599 # we had before
2600 my %configs = %min_configs;
2601 delete $configs{$config};
2602 make_new_config ((values %configs), (values %keep_configs));
2603 make_oldconfig;
2604 undef %configs;
2605 assign_configs \%configs, $output_config;
2606
2607 return $config if (!defined($configs{$config}));
2608
2609 doprint "disabling config $config did not change .config\n";
2610
2611 $nochange_config{$config} = 1;
2612
2613 return undef;
2614}
2615
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002616sub make_min_config {
2617 my ($i) = @_;
2618
2619 if (!defined($output_minconfig)) {
2620 fail "OUTPUT_MIN_CONFIG not defined" and return;
2621 }
Steven Rostedt35ce5952011-07-15 21:57:25 -04002622
2623 # If output_minconfig exists, and the start_minconfig
2624 # came from min_config, than ask if we should use
2625 # that instead.
2626 if (-f $output_minconfig && !$start_minconfig_defined) {
2627 print "$output_minconfig exists\n";
2628 if (read_yn " Use it as minconfig?") {
2629 $start_minconfig = $output_minconfig;
2630 }
2631 }
2632
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002633 if (!defined($start_minconfig)) {
2634 fail "START_MIN_CONFIG or MIN_CONFIG not defined" and return;
2635 }
2636
Steven Rostedt35ce5952011-07-15 21:57:25 -04002637 my $temp_config = "$tmpdir/temp_config";
2638
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002639 # First things first. We build an allnoconfig to find
2640 # out what the defaults are that we can't touch.
2641 # Some are selections, but we really can't handle selections.
2642
2643 my $save_minconfig = $minconfig;
2644 undef $minconfig;
2645
2646 run_command "$make allnoconfig" or return 0;
2647
Steven Rostedtb9066f62011-07-15 21:25:24 -04002648 read_depends;
2649
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002650 process_config_ignore $output_config;
Steven Rostedtb9066f62011-07-15 21:25:24 -04002651
Steven Rostedt43d1b652011-07-15 22:01:56 -04002652 undef %save_configs;
Steven Rostedtb9066f62011-07-15 21:25:24 -04002653 undef %min_configs;
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002654
2655 if (defined($ignore_config)) {
2656 # make sure the file exists
2657 `touch $ignore_config`;
Steven Rostedt43d1b652011-07-15 22:01:56 -04002658 assign_configs \%save_configs, $ignore_config;
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002659 }
2660
Steven Rostedt43d1b652011-07-15 22:01:56 -04002661 %keep_configs = %save_configs;
2662
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002663 doprint "Load initial configs from $start_minconfig\n";
2664
2665 # Look at the current min configs, and save off all the
2666 # ones that were set via the allnoconfig
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002667 assign_configs \%min_configs, $start_minconfig;
2668
2669 my @config_keys = keys %min_configs;
2670
2671 # Remove anything that was set by the make allnoconfig
2672 # we shouldn't need them as they get set for us anyway.
2673 foreach my $config (@config_keys) {
2674 # Remove anything in the ignore_config
2675 if (defined($keep_configs{$config})) {
2676 my $file = $ignore_config;
2677 $file =~ s,.*/(.*?)$,$1,;
2678 doprint "$config set by $file ... ignored\n";
2679 delete $min_configs{$config};
2680 next;
2681 }
2682 # But make sure the settings are the same. If a min config
2683 # sets a selection, we do not want to get rid of it if
2684 # it is not the same as what we have. Just move it into
2685 # the keep configs.
2686 if (defined($config_ignore{$config})) {
2687 if ($config_ignore{$config} ne $min_configs{$config}) {
2688 doprint "$config is in allnoconfig as '$config_ignore{$config}'";
2689 doprint " but it is '$min_configs{$config}' in minconfig .. keeping\n";
2690 $keep_configs{$config} = $min_configs{$config};
2691 } else {
2692 doprint "$config set by allnoconfig ... ignored\n";
2693 }
2694 delete $min_configs{$config};
2695 }
2696 }
2697
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002698 my $done = 0;
Steven Rostedtb9066f62011-07-15 21:25:24 -04002699 my $take_two = 0;
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002700
2701 while (!$done) {
2702
2703 my $config;
2704 my $found;
2705
2706 # Now disable each config one by one and do a make oldconfig
2707 # till we find a config that changes our list.
2708
2709 # Put configs that did not modify the config at the end.
2710 my @test_configs = keys %min_configs;
2711 my $reset = 1;
2712 for (my $i = 0; $i < $#test_configs; $i++) {
2713 if (!defined($nochange_config{$test_configs[0]})) {
2714 $reset = 0;
2715 last;
2716 }
2717 # This config didn't change the .config last time.
2718 # Place it at the end
2719 my $config = shift @test_configs;
2720 push @test_configs, $config;
2721 }
2722
2723 # if every test config has failed to modify the .config file
2724 # in the past, then reset and start over.
2725 if ($reset) {
2726 undef %nochange_config;
2727 }
2728
Steven Rostedtb9066f62011-07-15 21:25:24 -04002729 undef %processed_configs;
2730
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002731 foreach my $config (@test_configs) {
2732
Steven Rostedtb9066f62011-07-15 21:25:24 -04002733 $found = test_this_config $config;
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002734
Steven Rostedtb9066f62011-07-15 21:25:24 -04002735 last if (defined($found));
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002736
2737 # oh well, try another config
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002738 }
2739
2740 if (!defined($found)) {
Steven Rostedtb9066f62011-07-15 21:25:24 -04002741 # we could have failed due to the nochange_config hash
2742 # reset and try again
2743 if (!$take_two) {
2744 undef %nochange_config;
2745 $take_two = 1;
2746 next;
2747 }
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002748 doprint "No more configs found that we can disable\n";
2749 $done = 1;
2750 last;
2751 }
Steven Rostedtb9066f62011-07-15 21:25:24 -04002752 $take_two = 0;
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002753
2754 $config = $found;
2755
2756 doprint "Test with $config disabled\n";
2757
2758 # set in_bisect to keep build and monitor from dieing
2759 $in_bisect = 1;
2760
2761 my $failed = 0;
2762 build "oldconfig";
2763 start_monitor_and_boot or $failed = 1;
2764 end_monitor;
2765
2766 $in_bisect = 0;
2767
2768 if ($failed) {
Steven Rostedtb9066f62011-07-15 21:25:24 -04002769 doprint "$min_configs{$config} is needed to boot the box... keeping\n";
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002770 # this config is needed, add it to the ignore list.
2771 $keep_configs{$config} = $min_configs{$config};
Steven Rostedt43d1b652011-07-15 22:01:56 -04002772 $save_configs{$config} = $min_configs{$config};
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002773 delete $min_configs{$config};
Steven Rostedt35ce5952011-07-15 21:57:25 -04002774
2775 # update new ignore configs
2776 if (defined($ignore_config)) {
2777 open (OUT, ">$temp_config")
2778 or die "Can't write to $temp_config";
Steven Rostedt43d1b652011-07-15 22:01:56 -04002779 foreach my $config (keys %save_configs) {
2780 print OUT "$save_configs{$config}\n";
Steven Rostedt35ce5952011-07-15 21:57:25 -04002781 }
2782 close OUT;
2783 run_command "mv $temp_config $ignore_config" or
2784 dodie "failed to copy update to $ignore_config";
2785 }
2786
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002787 } else {
2788 # We booted without this config, remove it from the minconfigs.
2789 doprint "$config is not needed, disabling\n";
2790
2791 delete $min_configs{$config};
2792
2793 # Also disable anything that is not enabled in this config
2794 my %configs;
2795 assign_configs \%configs, $output_config;
2796 my @config_keys = keys %min_configs;
2797 foreach my $config (@config_keys) {
2798 if (!defined($configs{$config})) {
2799 doprint "$config is not set, disabling\n";
2800 delete $min_configs{$config};
2801 }
2802 }
2803
2804 # Save off all the current mandidory configs
Steven Rostedt35ce5952011-07-15 21:57:25 -04002805 open (OUT, ">$temp_config")
2806 or die "Can't write to $temp_config";
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002807 foreach my $config (keys %keep_configs) {
2808 print OUT "$keep_configs{$config}\n";
2809 }
2810 foreach my $config (keys %min_configs) {
2811 print OUT "$min_configs{$config}\n";
2812 }
2813 close OUT;
Steven Rostedt35ce5952011-07-15 21:57:25 -04002814
2815 run_command "mv $temp_config $output_minconfig" or
2816 dodie "failed to copy update to $output_minconfig";
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002817 }
2818
2819 doprint "Reboot and wait $sleep_time seconds\n";
Andrew Jones2728be42011-08-12 15:32:05 +02002820 reboot $sleep_time;
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002821 }
2822
2823 success $i;
2824 return 1;
2825}
2826
Steven Rostedt8d1491b2010-11-18 15:39:48 -05002827$#ARGV < 1 or die "ktest.pl version: $VERSION\n usage: ktest.pl config-file\n";
Steven Rostedt2545eb62010-11-02 15:01:32 -04002828
Steven Rostedt8d1491b2010-11-18 15:39:48 -05002829if ($#ARGV == 0) {
2830 $ktest_config = $ARGV[0];
2831 if (! -f $ktest_config) {
2832 print "$ktest_config does not exist.\n";
Steven Rostedt35ce5952011-07-15 21:57:25 -04002833 if (!read_yn "Create it?") {
Steven Rostedt8d1491b2010-11-18 15:39:48 -05002834 exit 0;
2835 }
2836 }
2837} else {
2838 $ktest_config = "ktest.conf";
2839}
2840
2841if (! -f $ktest_config) {
2842 open(OUT, ">$ktest_config") or die "Can not create $ktest_config";
2843 print OUT << "EOF"
2844# Generated by ktest.pl
2845#
2846# Define each test with TEST_START
2847# The config options below it will override the defaults
2848TEST_START
2849
2850DEFAULTS
2851EOF
2852;
2853 close(OUT);
2854}
2855read_config $ktest_config;
2856
Steven Rostedt23715c3c2011-06-13 11:03:34 -04002857if (defined($opt{"LOG_FILE"})) {
2858 $opt{"LOG_FILE"} = eval_option($opt{"LOG_FILE"}, -1);
2859}
2860
Steven Rostedt8d1491b2010-11-18 15:39:48 -05002861# Append any configs entered in manually to the config file.
2862my @new_configs = keys %entered_configs;
2863if ($#new_configs >= 0) {
2864 print "\nAppending entered in configs to $ktest_config\n";
2865 open(OUT, ">>$ktest_config") or die "Can not append to $ktest_config";
2866 foreach my $config (@new_configs) {
2867 print OUT "$config = $entered_configs{$config}\n";
2868 $opt{$config} = $entered_configs{$config};
2869 }
2870}
Steven Rostedt2545eb62010-11-02 15:01:32 -04002871
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002872if ($opt{"CLEAR_LOG"} && defined($opt{"LOG_FILE"})) {
2873 unlink $opt{"LOG_FILE"};
2874}
Steven Rostedt2545eb62010-11-02 15:01:32 -04002875
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002876doprint "\n\nSTARTING AUTOMATED TESTS\n\n";
2877
Steven Rostedta57419b2010-11-02 15:13:54 -04002878for (my $i = 0, my $repeat = 1; $i <= $opt{"NUM_TESTS"}; $i += $repeat) {
2879
2880 if (!$i) {
2881 doprint "DEFAULT OPTIONS:\n";
2882 } else {
2883 doprint "\nTEST $i OPTIONS";
2884 if (defined($repeat_tests{$i})) {
2885 $repeat = $repeat_tests{$i};
2886 doprint " ITERATE $repeat";
2887 }
2888 doprint "\n";
2889 }
2890
2891 foreach my $option (sort keys %opt) {
2892
2893 if ($option =~ /\[(\d+)\]$/) {
2894 next if ($i != $1);
2895 } else {
2896 next if ($i);
2897 }
2898
2899 doprint "$option = $opt{$option}\n";
2900 }
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002901}
Steven Rostedt2545eb62010-11-02 15:01:32 -04002902
Steven Rostedt2a625122011-05-20 15:48:59 -04002903sub __set_test_option {
Steven Rostedt5a391fb2010-11-02 14:57:43 -04002904 my ($name, $i) = @_;
2905
2906 my $option = "$name\[$i\]";
2907
2908 if (defined($opt{$option})) {
2909 return $opt{$option};
2910 }
2911
Steven Rostedta57419b2010-11-02 15:13:54 -04002912 foreach my $test (keys %repeat_tests) {
2913 if ($i >= $test &&
2914 $i < $test + $repeat_tests{$test}) {
2915 $option = "$name\[$test\]";
2916 if (defined($opt{$option})) {
2917 return $opt{$option};
2918 }
2919 }
2920 }
2921
Steven Rostedt5a391fb2010-11-02 14:57:43 -04002922 if (defined($opt{$name})) {
2923 return $opt{$name};
2924 }
2925
2926 return undef;
2927}
2928
Steven Rostedt2a625122011-05-20 15:48:59 -04002929sub set_test_option {
2930 my ($name, $i) = @_;
2931
2932 my $option = __set_test_option($name, $i);
2933 return $option if (!defined($option));
2934
Steven Rostedt23715c3c2011-06-13 11:03:34 -04002935 return eval_option($option, $i);
Steven Rostedt2a625122011-05-20 15:48:59 -04002936}
2937
Steven Rostedt2545eb62010-11-02 15:01:32 -04002938# First we need to do is the builds
Steven Rostedta75fece2010-11-02 14:58:27 -04002939for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
Steven Rostedt2545eb62010-11-02 15:01:32 -04002940
Steven Rostedt4ab1cce2011-09-30 18:12:20 -04002941 # Do not reboot on failing test options
2942 $no_reboot = 1;
2943
Steven Rostedt576f6272010-11-02 14:58:38 -04002944 $iteration = $i;
2945
Steven Rostedta75fece2010-11-02 14:58:27 -04002946 my $makecmd = set_test_option("MAKE_CMD", $i);
2947
2948 $machine = set_test_option("MACHINE", $i);
Steven Rostedte48c5292010-11-02 14:35:37 -04002949 $ssh_user = set_test_option("SSH_USER", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002950 $tmpdir = set_test_option("TMP_DIR", $i);
2951 $outputdir = set_test_option("OUTPUT_DIR", $i);
2952 $builddir = set_test_option("BUILD_DIR", $i);
2953 $test_type = set_test_option("TEST_TYPE", $i);
2954 $build_type = set_test_option("BUILD_TYPE", $i);
2955 $build_options = set_test_option("BUILD_OPTIONS", $i);
Steven Rostedt0bd6c1a2011-06-14 20:39:31 -04002956 $pre_build = set_test_option("PRE_BUILD", $i);
2957 $post_build = set_test_option("POST_BUILD", $i);
2958 $pre_build_die = set_test_option("PRE_BUILD_DIE", $i);
2959 $post_build_die = set_test_option("POST_BUILD_DIE", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002960 $power_cycle = set_test_option("POWER_CYCLE", $i);
Steven Rostedte48c5292010-11-02 14:35:37 -04002961 $reboot = set_test_option("REBOOT", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002962 $noclean = set_test_option("BUILD_NOCLEAN", $i);
2963 $minconfig = set_test_option("MIN_CONFIG", $i);
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002964 $output_minconfig = set_test_option("OUTPUT_MIN_CONFIG", $i);
2965 $start_minconfig = set_test_option("START_MIN_CONFIG", $i);
2966 $ignore_config = set_test_option("IGNORE_CONFIG", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002967 $run_test = set_test_option("TEST", $i);
2968 $addconfig = set_test_option("ADD_CONFIG", $i);
2969 $reboot_type = set_test_option("REBOOT_TYPE", $i);
2970 $grub_menu = set_test_option("GRUB_MENU", $i);
Steven Rostedt8b37ca82010-11-02 14:58:33 -04002971 $post_install = set_test_option("POST_INSTALL", $i);
Steven Rostedte0a87422011-09-30 17:50:48 -04002972 $no_install = set_test_option("NO_INSTALL", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002973 $reboot_script = set_test_option("REBOOT_SCRIPT", $i);
2974 $reboot_on_error = set_test_option("REBOOT_ON_ERROR", $i);
2975 $poweroff_on_error = set_test_option("POWEROFF_ON_ERROR", $i);
2976 $die_on_failure = set_test_option("DIE_ON_FAILURE", $i);
2977 $power_off = set_test_option("POWER_OFF", $i);
Steven Rostedt576f6272010-11-02 14:58:38 -04002978 $powercycle_after_reboot = set_test_option("POWERCYCLE_AFTER_REBOOT", $i);
2979 $poweroff_after_halt = set_test_option("POWEROFF_AFTER_HALT", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002980 $sleep_time = set_test_option("SLEEP_TIME", $i);
2981 $bisect_sleep_time = set_test_option("BISECT_SLEEP_TIME", $i);
Steven Rostedt27d934b2011-05-20 09:18:18 -04002982 $patchcheck_sleep_time = set_test_option("PATCHCHECK_SLEEP_TIME", $i);
Steven Rostedt19902072011-06-14 20:46:25 -04002983 $ignore_warnings = set_test_option("IGNORE_WARNINGS", $i);
Steven Rostedtc960bb92011-03-08 09:22:39 -05002984 $bisect_manual = set_test_option("BISECT_MANUAL", $i);
Steven Rostedtc23dca72011-03-08 09:26:31 -05002985 $bisect_skip = set_test_option("BISECT_SKIP", $i);
Steven Rostedt30f75da2011-06-13 10:35:35 -04002986 $config_bisect_good = set_test_option("CONFIG_BISECT_GOOD", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002987 $store_failures = set_test_option("STORE_FAILURES", $i);
Steven Rostedt9064af52011-06-13 10:38:48 -04002988 $test_name = set_test_option("TEST_NAME", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002989 $timeout = set_test_option("TIMEOUT", $i);
2990 $booted_timeout = set_test_option("BOOTED_TIMEOUT", $i);
2991 $console = set_test_option("CONSOLE", $i);
Steven Rostedtf1a5b962011-06-13 10:30:00 -04002992 $detect_triplefault = set_test_option("DETECT_TRIPLE_FAULT", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002993 $success_line = set_test_option("SUCCESS_LINE", $i);
Steven Rostedt2b803362011-09-30 18:00:23 -04002994 $reboot_success_line = set_test_option("REBOOT_SUCCESS_LINE", $i);
Steven Rostedt1c8a6172010-11-09 12:55:40 -05002995 $stop_after_success = set_test_option("STOP_AFTER_SUCCESS", $i);
2996 $stop_after_failure = set_test_option("STOP_AFTER_FAILURE", $i);
Steven Rostedt2d01b262011-03-08 09:47:54 -05002997 $stop_test_after = set_test_option("STOP_TEST_AFTER", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002998 $build_target = set_test_option("BUILD_TARGET", $i);
Steven Rostedte48c5292010-11-02 14:35:37 -04002999 $ssh_exec = set_test_option("SSH_EXEC", $i);
3000 $scp_to_target = set_test_option("SCP_TO_TARGET", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04003001 $target_image = set_test_option("TARGET_IMAGE", $i);
3002 $localversion = set_test_option("LOCALVERSION", $i);
3003
Steven Rostedt35ce5952011-07-15 21:57:25 -04003004 $start_minconfig_defined = 1;
3005
Steven Rostedt4c4ab122011-07-15 21:16:17 -04003006 if (!defined($start_minconfig)) {
Steven Rostedt35ce5952011-07-15 21:57:25 -04003007 $start_minconfig_defined = 0;
Steven Rostedt4c4ab122011-07-15 21:16:17 -04003008 $start_minconfig = $minconfig;
3009 }
3010
Steven Rostedta75fece2010-11-02 14:58:27 -04003011 chdir $builddir || die "can't change directory to $builddir";
3012
Andrew Jonesa908a662011-08-12 15:32:03 +02003013 foreach my $dir ($tmpdir, $outputdir) {
3014 if (!-d $dir) {
3015 mkpath($dir) or
3016 die "can't create $dir";
3017 }
Steven Rostedta75fece2010-11-02 14:58:27 -04003018 }
3019
Steven Rostedte48c5292010-11-02 14:35:37 -04003020 $ENV{"SSH_USER"} = $ssh_user;
3021 $ENV{"MACHINE"} = $machine;
3022
Steven Rostedta75fece2010-11-02 14:58:27 -04003023 $target = "$ssh_user\@$machine";
3024
3025 $buildlog = "$tmpdir/buildlog-$machine";
3026 $dmesg = "$tmpdir/dmesg-$machine";
3027 $make = "$makecmd O=$outputdir";
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05003028 $output_config = "$outputdir/.config";
Steven Rostedta75fece2010-11-02 14:58:27 -04003029
3030 if ($reboot_type eq "grub") {
Steven Rostedt576f6272010-11-02 14:58:38 -04003031 dodie "GRUB_MENU not defined" if (!defined($grub_menu));
Steven Rostedta75fece2010-11-02 14:58:27 -04003032 } elsif (!defined($reboot_script)) {
Steven Rostedt576f6272010-11-02 14:58:38 -04003033 dodie "REBOOT_SCRIPT not defined"
Steven Rostedta75fece2010-11-02 14:58:27 -04003034 }
3035
3036 my $run_type = $build_type;
3037 if ($test_type eq "patchcheck") {
3038 $run_type = $opt{"PATCHCHECK_TYPE[$i]"};
3039 } elsif ($test_type eq "bisect") {
3040 $run_type = $opt{"BISECT_TYPE[$i]"};
Steven Rostedt0a05c762010-11-08 11:14:10 -05003041 } elsif ($test_type eq "config_bisect") {
3042 $run_type = $opt{"CONFIG_BISECT_TYPE[$i]"};
Steven Rostedta75fece2010-11-02 14:58:27 -04003043 }
3044
Steven Rostedt4c4ab122011-07-15 21:16:17 -04003045 if ($test_type eq "make_min_config") {
3046 $run_type = "";
3047 }
3048
Steven Rostedta75fece2010-11-02 14:58:27 -04003049 # mistake in config file?
3050 if (!defined($run_type)) {
3051 $run_type = "ERROR";
3052 }
Steven Rostedt2545eb62010-11-02 15:01:32 -04003053
Steven Rostedte0a87422011-09-30 17:50:48 -04003054 my $installme = "";
3055 $installme = " no_install" if ($no_install);
3056
Steven Rostedt2545eb62010-11-02 15:01:32 -04003057 doprint "\n\n";
Steven Rostedte0a87422011-09-30 17:50:48 -04003058 doprint "RUNNING TEST $i of $opt{NUM_TESTS} with option $test_type $run_type$installme\n\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -04003059
3060 unlink $dmesg;
3061 unlink $buildlog;
Steven Rostedt2545eb62010-11-02 15:01:32 -04003062
Steven Rostedt250bae82011-07-15 22:05:59 -04003063 if (defined($addconfig)) {
3064 my $min = $minconfig;
3065 if (!defined($minconfig)) {
3066 $min = "";
3067 }
3068 run_command "cat $addconfig $min > $tmpdir/add_config" or
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04003069 dodie "Failed to create temp config";
Steven Rostedt9be2e6b2010-11-09 12:20:21 -05003070 $minconfig = "$tmpdir/add_config";
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04003071 }
3072
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04003073 my $checkout = $opt{"CHECKOUT[$i]"};
3074 if (defined($checkout)) {
3075 run_command "git checkout $checkout" or
3076 die "failed to checkout $checkout";
3077 }
3078
Steven Rostedt4ab1cce2011-09-30 18:12:20 -04003079 $no_reboot = 0;
3080
3081
Steven Rostedta75fece2010-11-02 14:58:27 -04003082 if ($test_type eq "bisect") {
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04003083 bisect $i;
3084 next;
Steven Rostedt0a05c762010-11-08 11:14:10 -05003085 } elsif ($test_type eq "config_bisect") {
3086 config_bisect $i;
3087 next;
Steven Rostedta75fece2010-11-02 14:58:27 -04003088 } elsif ($test_type eq "patchcheck") {
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04003089 patchcheck $i;
3090 next;
Steven Rostedt4c4ab122011-07-15 21:16:17 -04003091 } elsif ($test_type eq "make_min_config") {
3092 make_min_config $i;
3093 next;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04003094 }
3095
Steven Rostedt7faafbd2010-11-02 14:58:22 -04003096 if ($build_type ne "nobuild") {
3097 build $build_type or next;
Steven Rostedt2545eb62010-11-02 15:01:32 -04003098 }
3099
Steven Rostedtcd8e3682011-08-18 16:35:44 -04003100 if ($test_type eq "install") {
3101 get_version;
3102 install;
3103 success $i;
3104 next;
3105 }
3106
Steven Rostedta75fece2010-11-02 14:58:27 -04003107 if ($test_type ne "build") {
Steven Rostedta75fece2010-11-02 14:58:27 -04003108 my $failed = 0;
Steven Rostedtddf607e2011-06-14 20:49:13 -04003109 start_monitor_and_boot or $failed = 1;
Steven Rostedta75fece2010-11-02 14:58:27 -04003110
3111 if (!$failed && $test_type ne "boot" && defined($run_test)) {
3112 do_run_test or $failed = 1;
3113 }
3114 end_monitor;
3115 next if ($failed);
Steven Rostedt5a391fb2010-11-02 14:57:43 -04003116 }
3117
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04003118 success $i;
Steven Rostedt2545eb62010-11-02 15:01:32 -04003119}
3120
Steven Rostedt5c42fc52010-11-02 14:57:01 -04003121if ($opt{"POWEROFF_ON_SUCCESS"}) {
Steven Rostedt75c3fda72010-11-02 14:57:21 -04003122 halt;
Steven Rostedt576f6272010-11-02 14:58:38 -04003123} elsif ($opt{"REBOOT_ON_SUCCESS"} && !do_not_reboot) {
Steven Rostedt75c3fda72010-11-02 14:57:21 -04003124 reboot;
Steven Rostedt5c42fc52010-11-02 14:57:01 -04003125}
Steven Rostedt75c3fda72010-11-02 14:57:21 -04003126
Steven Rostedte48c5292010-11-02 14:35:37 -04003127doprint "\n $successes of $opt{NUM_TESTS} tests were successful\n\n";
3128
Steven Rostedt2545eb62010-11-02 15:01:32 -04003129exit 0;