blob: 8bbfceedfdb29ad3f77e177087fd9dbcddd79150 [file] [log] [blame]
Steven Rostedt2545eb62010-11-02 15:01:32 -04001#!/usr/bin/perl -w
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04002#
3# Copywrite 2010 - Steven Rostedt <srostedt@redhat.com>, Red Hat Inc.
4# 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 Rostedta57419b2010-11-02 15:13:54 -040030$default{"TMP_DIR"} = "/tmp/ktest";
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
39$default{"CLEAR_LOG"} = 0;
Steven Rostedtc960bb92011-03-08 09:22:39 -050040$default{"BISECT_MANUAL"} = 0;
Steven Rostedtc23dca72011-03-08 09:26:31 -050041$default{"BISECT_SKIP"} = 1;
Steven Rostedta75fece2010-11-02 14:58:27 -040042$default{"SUCCESS_LINE"} = "login:";
43$default{"BOOTED_TIMEOUT"} = 1;
44$default{"DIE_ON_FAILURE"} = 1;
Steven Rostedte48c5292010-11-02 14:35:37 -040045$default{"SSH_EXEC"} = "ssh \$SSH_USER\@\$MACHINE \$SSH_COMMAND";
46$default{"SCP_TO_TARGET"} = "scp \$SRC_FILE \$SSH_USER\@\$MACHINE:\$DST_FILE";
47$default{"REBOOT"} = "ssh \$SSH_USER\@\$MACHINE reboot";
Steven Rostedt1c8a6172010-11-09 12:55:40 -050048$default{"STOP_AFTER_SUCCESS"} = 10;
49$default{"STOP_AFTER_FAILURE"} = 60;
Steven Rostedt8d1491b2010-11-18 15:39:48 -050050$default{"LOCALVERSION"} = "-test";
Steven Rostedt2545eb62010-11-02 15:01:32 -040051
Steven Rostedt8d1491b2010-11-18 15:39:48 -050052my $ktest_config;
Steven Rostedt2545eb62010-11-02 15:01:32 -040053my $version;
Steven Rostedta75fece2010-11-02 14:58:27 -040054my $machine;
Steven Rostedte48c5292010-11-02 14:35:37 -040055my $ssh_user;
Steven Rostedta75fece2010-11-02 14:58:27 -040056my $tmpdir;
57my $builddir;
58my $outputdir;
Steven Rostedt51ad1dd2010-11-08 16:43:21 -050059my $output_config;
Steven Rostedta75fece2010-11-02 14:58:27 -040060my $test_type;
Steven Rostedt7faafbd2010-11-02 14:58:22 -040061my $build_type;
Steven Rostedta75fece2010-11-02 14:58:27 -040062my $build_options;
63my $reboot_type;
64my $reboot_script;
65my $power_cycle;
Steven Rostedte48c5292010-11-02 14:35:37 -040066my $reboot;
Steven Rostedta75fece2010-11-02 14:58:27 -040067my $reboot_on_error;
68my $poweroff_on_error;
69my $die_on_failure;
Steven Rostedt576f6272010-11-02 14:58:38 -040070my $powercycle_after_reboot;
71my $poweroff_after_halt;
Steven Rostedte48c5292010-11-02 14:35:37 -040072my $ssh_exec;
73my $scp_to_target;
Steven Rostedta75fece2010-11-02 14:58:27 -040074my $power_off;
75my $grub_menu;
Steven Rostedt2545eb62010-11-02 15:01:32 -040076my $grub_number;
77my $target;
78my $make;
Steven Rostedt8b37ca82010-11-02 14:58:33 -040079my $post_install;
Steven Rostedt5c42fc52010-11-02 14:57:01 -040080my $noclean;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -040081my $minconfig;
Steven Rostedt2b7d9b22010-11-02 14:58:15 -040082my $addconfig;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -040083my $in_bisect = 0;
84my $bisect_bad = "";
Steven Rostedtd6ce2a02010-11-02 14:58:05 -040085my $reverse_bisect;
Steven Rostedtc960bb92011-03-08 09:22:39 -050086my $bisect_manual;
Steven Rostedtc23dca72011-03-08 09:26:31 -050087my $bisect_skip;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -040088my $in_patchcheck = 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -040089my $run_test;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -040090my $redirect;
Steven Rostedt7faafbd2010-11-02 14:58:22 -040091my $buildlog;
92my $dmesg;
93my $monitor_fp;
94my $monitor_pid;
95my $monitor_cnt = 0;
Steven Rostedta75fece2010-11-02 14:58:27 -040096my $sleep_time;
97my $bisect_sleep_time;
98my $store_failures;
99my $timeout;
100my $booted_timeout;
101my $console;
102my $success_line;
Steven Rostedt1c8a6172010-11-09 12:55:40 -0500103my $stop_after_success;
104my $stop_after_failure;
Steven Rostedta75fece2010-11-02 14:58:27 -0400105my $build_target;
106my $target_image;
107my $localversion;
Steven Rostedt576f6272010-11-02 14:58:38 -0400108my $iteration = 0;
Steven Rostedte48c5292010-11-02 14:35:37 -0400109my $successes = 0;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400110
Steven Rostedt8d1491b2010-11-18 15:39:48 -0500111my %entered_configs;
112my %config_help;
113
114$config_help{"MACHINE"} = << "EOF"
115 The machine hostname that you will test.
116EOF
117 ;
118$config_help{"SSH_USER"} = << "EOF"
119 The box is expected to have ssh on normal bootup, provide the user
120 (most likely root, since you need privileged operations)
121EOF
122 ;
123$config_help{"BUILD_DIR"} = << "EOF"
124 The directory that contains the Linux source code (full path).
125EOF
126 ;
127$config_help{"OUTPUT_DIR"} = << "EOF"
128 The directory that the objects will be built (full path).
129 (can not be same as BUILD_DIR)
130EOF
131 ;
132$config_help{"BUILD_TARGET"} = << "EOF"
133 The location of the compiled file to copy to the target.
134 (relative to OUTPUT_DIR)
135EOF
136 ;
137$config_help{"TARGET_IMAGE"} = << "EOF"
138 The place to put your image on the test machine.
139EOF
140 ;
141$config_help{"POWER_CYCLE"} = << "EOF"
142 A script or command to reboot the box.
143
144 Here is a digital loggers power switch example
145 POWER_CYCLE = wget --no-proxy -O /dev/null -q --auth-no-challenge 'http://admin:admin\@power/outlet?5=CCL'
146
147 Here is an example to reboot a virtual box on the current host
148 with the name "Guest".
149 POWER_CYCLE = virsh destroy Guest; sleep 5; virsh start Guest
150EOF
151 ;
152$config_help{"CONSOLE"} = << "EOF"
153 The script or command that reads the console
154
155 If you use ttywatch server, something like the following would work.
156CONSOLE = nc -d localhost 3001
157
158 For a virtual machine with guest name "Guest".
159CONSOLE = virsh console Guest
160EOF
161 ;
162$config_help{"LOCALVERSION"} = << "EOF"
163 Required version ending to differentiate the test
164 from other linux builds on the system.
165EOF
166 ;
167$config_help{"REBOOT_TYPE"} = << "EOF"
168 Way to reboot the box to the test kernel.
169 Only valid options so far are "grub" and "script".
170
171 If you specify grub, it will assume grub version 1
172 and will search in /boot/grub/menu.lst for the title \$GRUB_MENU
173 and select that target to reboot to the kernel. If this is not
174 your setup, then specify "script" and have a command or script
175 specified in REBOOT_SCRIPT to boot to the target.
176
177 The entry in /boot/grub/menu.lst must be entered in manually.
178 The test will not modify that file.
179EOF
180 ;
181$config_help{"GRUB_MENU"} = << "EOF"
182 The grub title name for the test kernel to boot
183 (Only mandatory if REBOOT_TYPE = grub)
184
185 Note, ktest.pl will not update the grub menu.lst, you need to
186 manually add an option for the test. ktest.pl will search
187 the grub menu.lst for this option to find what kernel to
188 reboot into.
189
190 For example, if in the /boot/grub/menu.lst the test kernel title has:
191 title Test Kernel
192 kernel vmlinuz-test
193 GRUB_MENU = Test Kernel
194EOF
195 ;
196$config_help{"REBOOT_SCRIPT"} = << "EOF"
197 A script to reboot the target into the test kernel
198 (Only mandatory if REBOOT_TYPE = script)
199EOF
200 ;
201
202
203sub get_ktest_config {
204 my ($config) = @_;
205
206 return if (defined($opt{$config}));
207
208 if (defined($config_help{$config})) {
209 print "\n";
210 print $config_help{$config};
211 }
212
213 for (;;) {
214 print "$config = ";
215 if (defined($default{$config})) {
216 print "\[$default{$config}\] ";
217 }
218 $entered_configs{$config} = <STDIN>;
219 $entered_configs{$config} =~ s/^\s*(.*\S)\s*$/$1/;
220 if ($entered_configs{$config} =~ /^\s*$/) {
221 if ($default{$config}) {
222 $entered_configs{$config} = $default{$config};
223 } else {
224 print "Your answer can not be blank\n";
225 next;
226 }
227 }
228 last;
229 }
230}
231
232sub get_ktest_configs {
233 get_ktest_config("MACHINE");
234 get_ktest_config("SSH_USER");
235 get_ktest_config("BUILD_DIR");
236 get_ktest_config("OUTPUT_DIR");
237 get_ktest_config("BUILD_TARGET");
238 get_ktest_config("TARGET_IMAGE");
239 get_ktest_config("POWER_CYCLE");
240 get_ktest_config("CONSOLE");
241 get_ktest_config("LOCALVERSION");
242
243 my $rtype = $opt{"REBOOT_TYPE"};
244
245 if (!defined($rtype)) {
246 if (!defined($opt{"GRUB_MENU"})) {
247 get_ktest_config("REBOOT_TYPE");
248 $rtype = $entered_configs{"REBOOT_TYPE"};
249 } else {
250 $rtype = "grub";
251 }
252 }
253
254 if ($rtype eq "grub") {
255 get_ktest_config("GRUB_MENU");
256 } else {
257 get_ktest_config("REBOOT_SCRIPT");
258 }
259}
260
Steven Rostedta57419b2010-11-02 15:13:54 -0400261sub set_value {
262 my ($lvalue, $rvalue) = @_;
263
264 if (defined($opt{$lvalue})) {
265 die "Error: Option $lvalue defined more than once!\n";
266 }
Steven Rostedt21a96792010-11-08 16:45:50 -0500267 if ($rvalue =~ /^\s*$/) {
268 delete $opt{$lvalue};
269 } else {
270 $opt{$lvalue} = $rvalue;
271 }
Steven Rostedta57419b2010-11-02 15:13:54 -0400272}
273
Steven Rostedt2545eb62010-11-02 15:01:32 -0400274sub read_config {
275 my ($config) = @_;
276
277 open(IN, $config) || die "can't read file $config";
278
Steven Rostedta57419b2010-11-02 15:13:54 -0400279 my $name = $config;
280 $name =~ s,.*/(.*),$1,;
281
282 my $test_num = 0;
283 my $default = 1;
284 my $repeat = 1;
285 my $num_tests_set = 0;
286 my $skip = 0;
287 my $rest;
288
Steven Rostedt2545eb62010-11-02 15:01:32 -0400289 while (<IN>) {
290
291 # ignore blank lines and comments
292 next if (/^\s*$/ || /\s*\#/);
293
Steven Rostedta57419b2010-11-02 15:13:54 -0400294 if (/^\s*TEST_START(.*)/) {
295
296 $rest = $1;
297
298 if ($num_tests_set) {
299 die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
300 }
301
302 my $old_test_num = $test_num;
Steven Rostedte48c5292010-11-02 14:35:37 -0400303 my $old_repeat = $repeat;
Steven Rostedta57419b2010-11-02 15:13:54 -0400304
305 $test_num += $repeat;
306 $default = 0;
307 $repeat = 1;
308
309 if ($rest =~ /\s+SKIP(.*)/) {
310 $rest = $1;
311 $skip = 1;
312 } else {
313 $skip = 0;
314 }
315
316 if ($rest =~ /\s+ITERATE\s+(\d+)(.*)$/) {
317 $repeat = $1;
318 $rest = $2;
319 $repeat_tests{"$test_num"} = $repeat;
320 }
321
322 if ($rest =~ /\s+SKIP(.*)/) {
323 $rest = $1;
324 $skip = 1;
325 }
326
327 if ($rest !~ /^\s*$/) {
328 die "$name: $.: Gargbage found after TEST_START\n$_";
329 }
330
331 if ($skip) {
332 $test_num = $old_test_num;
Steven Rostedte48c5292010-11-02 14:35:37 -0400333 $repeat = $old_repeat;
Steven Rostedta57419b2010-11-02 15:13:54 -0400334 }
335
336 } elsif (/^\s*DEFAULTS(.*)$/) {
337 $default = 1;
338
339 $rest = $1;
340
341 if ($rest =~ /\s+SKIP(.*)/) {
342 $rest = $1;
343 $skip = 1;
344 } else {
345 $skip = 0;
346 }
347
348 if ($rest !~ /^\s*$/) {
349 die "$name: $.: Gargbage found after DEFAULTS\n$_";
350 }
351
352 } elsif (/^\s*([A-Z_\[\]\d]+)\s*=\s*(.*?)\s*$/) {
353
354 next if ($skip);
355
Steven Rostedt2545eb62010-11-02 15:01:32 -0400356 my $lvalue = $1;
357 my $rvalue = $2;
358
Steven Rostedta57419b2010-11-02 15:13:54 -0400359 if (!$default &&
360 ($lvalue eq "NUM_TESTS" ||
361 $lvalue eq "LOG_FILE" ||
362 $lvalue eq "CLEAR_LOG")) {
363 die "$name: $.: $lvalue must be set in DEFAULTS section\n";
Steven Rostedta75fece2010-11-02 14:58:27 -0400364 }
Steven Rostedta57419b2010-11-02 15:13:54 -0400365
366 if ($lvalue eq "NUM_TESTS") {
367 if ($test_num) {
368 die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
369 }
370 if (!$default) {
371 die "$name: $.: NUM_TESTS must be set in default section\n";
372 }
373 $num_tests_set = 1;
374 }
375
376 if ($default || $lvalue =~ /\[\d+\]$/) {
377 set_value($lvalue, $rvalue);
378 } else {
379 my $val = "$lvalue\[$test_num\]";
380 set_value($val, $rvalue);
381
382 if ($repeat > 1) {
383 $repeats{$val} = $repeat;
384 }
385 }
386 } else {
387 die "$name: $.: Garbage found in config\n$_";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400388 }
389 }
390
391 close(IN);
Steven Rostedta75fece2010-11-02 14:58:27 -0400392
Steven Rostedta57419b2010-11-02 15:13:54 -0400393 if ($test_num) {
394 $test_num += $repeat - 1;
395 $opt{"NUM_TESTS"} = $test_num;
396 }
397
Steven Rostedt8d1491b2010-11-18 15:39:48 -0500398 # make sure we have all mandatory configs
399 get_ktest_configs;
400
Steven Rostedta75fece2010-11-02 14:58:27 -0400401 # set any defaults
402
403 foreach my $default (keys %default) {
404 if (!defined($opt{$default})) {
405 $opt{$default} = $default{$default};
406 }
407 }
Steven Rostedt2545eb62010-11-02 15:01:32 -0400408}
409
Steven Rostedtd1e2f222010-11-08 16:39:57 -0500410sub _logit {
Steven Rostedt2545eb62010-11-02 15:01:32 -0400411 if (defined($opt{"LOG_FILE"})) {
412 open(OUT, ">> $opt{LOG_FILE}") or die "Can't write to $opt{LOG_FILE}";
413 print OUT @_;
414 close(OUT);
415 }
416}
417
Steven Rostedtd1e2f222010-11-08 16:39:57 -0500418sub logit {
419 if (defined($opt{"LOG_FILE"})) {
420 _logit @_;
421 } else {
422 print @_;
423 }
424}
425
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400426sub doprint {
427 print @_;
Steven Rostedtd1e2f222010-11-08 16:39:57 -0500428 _logit @_;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400429}
430
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400431sub run_command;
432
433sub reboot {
434 # try to reboot normally
Steven Rostedte48c5292010-11-02 14:35:37 -0400435 if (run_command $reboot) {
Steven Rostedt576f6272010-11-02 14:58:38 -0400436 if (defined($powercycle_after_reboot)) {
437 sleep $powercycle_after_reboot;
438 run_command "$power_cycle";
439 }
440 } else {
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400441 # nope? power cycle it.
Steven Rostedta75fece2010-11-02 14:58:27 -0400442 run_command "$power_cycle";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400443 }
444}
445
Steven Rostedt576f6272010-11-02 14:58:38 -0400446sub do_not_reboot {
447 my $i = $iteration;
448
449 return $test_type eq "build" ||
450 ($test_type eq "patchcheck" && $opt{"PATCHCHECK_TYPE[$i]"} eq "build") ||
451 ($test_type eq "bisect" && $opt{"BISECT_TYPE[$i]"} eq "build");
452}
453
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400454sub dodie {
Steven Rostedt5a391fb2010-11-02 14:57:43 -0400455 doprint "CRITICAL FAILURE... ", @_, "\n";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400456
Steven Rostedt576f6272010-11-02 14:58:38 -0400457 my $i = $iteration;
458
459 if ($reboot_on_error && !do_not_reboot) {
460
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400461 doprint "REBOOTING\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400462 reboot;
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400463
Steven Rostedta75fece2010-11-02 14:58:27 -0400464 } elsif ($poweroff_on_error && defined($power_off)) {
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400465 doprint "POWERING OFF\n";
Steven Rostedta75fece2010-11-02 14:58:27 -0400466 `$power_off`;
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400467 }
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400468
Steven Rostedtf80802c2011-03-07 13:18:47 -0500469 if (defined($opt{"LOG_FILE"})) {
470 print " See $opt{LOG_FILE} for more info.\n";
471 }
472
Steven Rostedt576f6272010-11-02 14:58:38 -0400473 die @_, "\n";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400474}
475
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400476sub open_console {
477 my ($fp) = @_;
478
479 my $flags;
480
Steven Rostedta75fece2010-11-02 14:58:27 -0400481 my $pid = open($fp, "$console|") or
482 dodie "Can't open console $console";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400483
484 $flags = fcntl($fp, F_GETFL, 0) or
Steven Rostedt576f6272010-11-02 14:58:38 -0400485 dodie "Can't get flags for the socket: $!";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400486 $flags = fcntl($fp, F_SETFL, $flags | O_NONBLOCK) or
Steven Rostedt576f6272010-11-02 14:58:38 -0400487 dodie "Can't set flags for the socket: $!";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400488
489 return $pid;
490}
491
492sub close_console {
493 my ($fp, $pid) = @_;
494
495 doprint "kill child process $pid\n";
496 kill 2, $pid;
497
498 print "closing!\n";
499 close($fp);
500}
501
502sub start_monitor {
503 if ($monitor_cnt++) {
504 return;
505 }
506 $monitor_fp = \*MONFD;
507 $monitor_pid = open_console $monitor_fp;
Steven Rostedta75fece2010-11-02 14:58:27 -0400508
509 return;
510
511 open(MONFD, "Stop perl from warning about single use of MONFD");
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400512}
513
514sub end_monitor {
515 if (--$monitor_cnt) {
516 return;
517 }
518 close_console($monitor_fp, $monitor_pid);
519}
520
521sub wait_for_monitor {
522 my ($time) = @_;
523 my $line;
524
Steven Rostedta75fece2010-11-02 14:58:27 -0400525 doprint "** Wait for monitor to settle down **\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400526
527 # read the monitor and wait for the system to calm down
528 do {
529 $line = wait_for_input($monitor_fp, $time);
Steven Rostedta75fece2010-11-02 14:58:27 -0400530 print "$line" if (defined($line));
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400531 } while (defined($line));
Steven Rostedta75fece2010-11-02 14:58:27 -0400532 print "** Monitor flushed **\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400533}
534
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400535sub fail {
536
Steven Rostedta75fece2010-11-02 14:58:27 -0400537 if ($die_on_failure) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400538 dodie @_;
539 }
540
Steven Rostedta75fece2010-11-02 14:58:27 -0400541 doprint "FAILED\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400542
Steven Rostedt576f6272010-11-02 14:58:38 -0400543 my $i = $iteration;
544
Steven Rostedta75fece2010-11-02 14:58:27 -0400545 # no need to reboot for just building.
Steven Rostedt576f6272010-11-02 14:58:38 -0400546 if (!do_not_reboot) {
Steven Rostedta75fece2010-11-02 14:58:27 -0400547 doprint "REBOOTING\n";
548 reboot;
549 start_monitor;
550 wait_for_monitor $sleep_time;
551 end_monitor;
552 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400553
Steven Rostedt576f6272010-11-02 14:58:38 -0400554 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
555 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
Steven Rostedt7a849cd2010-11-08 16:49:25 -0500556 doprint "KTEST RESULT: TEST $i Failed: ", @_, "\n";
Steven Rostedt576f6272010-11-02 14:58:38 -0400557 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
558 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
Steven Rostedta75fece2010-11-02 14:58:27 -0400559
560 return 1 if (!defined($store_failures));
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400561
562 my @t = localtime;
563 my $date = sprintf "%04d%02d%02d%02d%02d%02d",
564 1900+$t[5],$t[4],$t[3],$t[2],$t[1],$t[0];
565
Steven Rostedtcccae1a2010-11-09 12:21:32 -0500566 my $type = $build_type;
567 if ($type =~ /useconfig/) {
568 $type = "useconfig";
569 }
570
571 my $dir = "$machine-$test_type-$type-fail-$date";
Steven Rostedta75fece2010-11-02 14:58:27 -0400572 my $faildir = "$store_failures/$dir";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400573
574 if (!-d $faildir) {
575 mkpath($faildir) or
Steven Rostedta75fece2010-11-02 14:58:27 -0400576 die "can't create $faildir";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400577 }
Steven Rostedt51ad1dd2010-11-08 16:43:21 -0500578 if (-f "$output_config") {
579 cp "$output_config", "$faildir/config" or
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400580 die "failed to copy .config";
581 }
582 if (-f $buildlog) {
583 cp $buildlog, "$faildir/buildlog" or
584 die "failed to move $buildlog";
585 }
586 if (-f $dmesg) {
587 cp $dmesg, "$faildir/dmesg" or
588 die "failed to move $dmesg";
589 }
590
591 doprint "*** Saved info to $faildir ***\n";
592
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400593 return 1;
594}
595
Steven Rostedt2545eb62010-11-02 15:01:32 -0400596sub run_command {
597 my ($command) = @_;
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400598 my $dolog = 0;
599 my $dord = 0;
600 my $pid;
601
Steven Rostedte48c5292010-11-02 14:35:37 -0400602 $command =~ s/\$SSH_USER/$ssh_user/g;
603 $command =~ s/\$MACHINE/$machine/g;
604
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400605 doprint("$command ... ");
606
607 $pid = open(CMD, "$command 2>&1 |") or
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400608 (fail "unable to exec $command" and return 0);
Steven Rostedt2545eb62010-11-02 15:01:32 -0400609
610 if (defined($opt{"LOG_FILE"})) {
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400611 open(LOG, ">>$opt{LOG_FILE}") or
612 dodie "failed to write to log";
613 $dolog = 1;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -0400614 }
615
616 if (defined($redirect)) {
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400617 open (RD, ">$redirect") or
618 dodie "failed to write to redirect $redirect";
619 $dord = 1;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400620 }
621
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400622 while (<CMD>) {
623 print LOG if ($dolog);
624 print RD if ($dord);
625 }
Steven Rostedt2545eb62010-11-02 15:01:32 -0400626
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400627 waitpid($pid, 0);
Steven Rostedt2545eb62010-11-02 15:01:32 -0400628 my $failed = $?;
629
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400630 close(CMD);
631 close(LOG) if ($dolog);
632 close(RD) if ($dord);
633
Steven Rostedt2545eb62010-11-02 15:01:32 -0400634 if ($failed) {
635 doprint "FAILED!\n";
636 } else {
637 doprint "SUCCESS\n";
638 }
639
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400640 return !$failed;
641}
642
Steven Rostedte48c5292010-11-02 14:35:37 -0400643sub run_ssh {
644 my ($cmd) = @_;
645 my $cp_exec = $ssh_exec;
646
647 $cp_exec =~ s/\$SSH_COMMAND/$cmd/g;
648 return run_command "$cp_exec";
649}
650
651sub run_scp {
652 my ($src, $dst) = @_;
653 my $cp_scp = $scp_to_target;
654
655 $cp_scp =~ s/\$SRC_FILE/$src/g;
656 $cp_scp =~ s/\$DST_FILE/$dst/g;
657
658 return run_command "$cp_scp";
659}
660
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400661sub get_grub_index {
662
Steven Rostedta75fece2010-11-02 14:58:27 -0400663 if ($reboot_type ne "grub") {
664 return;
665 }
Steven Rostedt5a391fb2010-11-02 14:57:43 -0400666 return if (defined($grub_number));
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400667
668 doprint "Find grub menu ... ";
669 $grub_number = -1;
Steven Rostedte48c5292010-11-02 14:35:37 -0400670
671 my $ssh_grub = $ssh_exec;
672 $ssh_grub =~ s,\$SSH_COMMAND,cat /boot/grub/menu.lst,g;
673
674 open(IN, "$ssh_grub |")
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400675 or die "unable to get menu.lst";
Steven Rostedte48c5292010-11-02 14:35:37 -0400676
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400677 while (<IN>) {
Steven Rostedta75fece2010-11-02 14:58:27 -0400678 if (/^\s*title\s+$grub_menu\s*$/) {
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400679 $grub_number++;
680 last;
681 } elsif (/^\s*title\s/) {
682 $grub_number++;
683 }
684 }
685 close(IN);
686
Steven Rostedta75fece2010-11-02 14:58:27 -0400687 die "Could not find '$grub_menu' in /boot/grub/menu on $machine"
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400688 if ($grub_number < 0);
689 doprint "$grub_number\n";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400690}
691
Steven Rostedt2545eb62010-11-02 15:01:32 -0400692sub wait_for_input
693{
694 my ($fp, $time) = @_;
695 my $rin;
696 my $ready;
697 my $line;
698 my $ch;
699
700 if (!defined($time)) {
701 $time = $timeout;
702 }
703
704 $rin = '';
705 vec($rin, fileno($fp), 1) = 1;
706 $ready = select($rin, undef, undef, $time);
707
708 $line = "";
709
710 # try to read one char at a time
711 while (sysread $fp, $ch, 1) {
712 $line .= $ch;
713 last if ($ch eq "\n");
714 }
715
716 if (!length($line)) {
717 return undef;
718 }
719
720 return $line;
721}
722
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400723sub reboot_to {
Steven Rostedta75fece2010-11-02 14:58:27 -0400724 if ($reboot_type eq "grub") {
Steven Rostedteec56462010-11-10 09:08:20 -0500725 run_ssh "'(echo \"savedefault --default=$grub_number --once\" | grub --batch; reboot)'";
Steven Rostedta75fece2010-11-02 14:58:27 -0400726 return;
727 }
728
729 run_command "$reboot_script";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400730}
731
Steven Rostedta57419b2010-11-02 15:13:54 -0400732sub get_sha1 {
733 my ($commit) = @_;
734
735 doprint "git rev-list --max-count=1 $commit ... ";
736 my $sha1 = `git rev-list --max-count=1 $commit`;
737 my $ret = $?;
738
739 logit $sha1;
740
741 if ($ret) {
742 doprint "FAILED\n";
743 dodie "Failed to get git $commit";
744 }
745
746 print "SUCCESS\n";
747
748 chomp $sha1;
749
750 return $sha1;
751}
752
Steven Rostedt5a391fb2010-11-02 14:57:43 -0400753sub monitor {
Steven Rostedt2545eb62010-11-02 15:01:32 -0400754 my $booted = 0;
755 my $bug = 0;
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400756 my $skip_call_trace = 0;
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400757 my $loops;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400758
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400759 wait_for_monitor 5;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400760
761 my $line;
762 my $full_line = "";
763
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400764 open(DMESG, "> $dmesg") or
765 die "unable to write to $dmesg";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400766
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400767 reboot_to;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400768
Steven Rostedt1c8a6172010-11-09 12:55:40 -0500769 my $success_start;
770 my $failure_start;
771
Steven Rostedt2545eb62010-11-02 15:01:32 -0400772 for (;;) {
773
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400774 if ($booted) {
Steven Rostedta75fece2010-11-02 14:58:27 -0400775 $line = wait_for_input($monitor_fp, $booted_timeout);
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400776 } else {
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400777 $line = wait_for_input($monitor_fp);
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400778 }
Steven Rostedt2545eb62010-11-02 15:01:32 -0400779
780 last if (!defined($line));
781
782 doprint $line;
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400783 print DMESG $line;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400784
785 # we are not guaranteed to get a full line
786 $full_line .= $line;
787
Steven Rostedta75fece2010-11-02 14:58:27 -0400788 if ($full_line =~ /$success_line/) {
Steven Rostedt2545eb62010-11-02 15:01:32 -0400789 $booted = 1;
Steven Rostedt1c8a6172010-11-09 12:55:40 -0500790 $success_start = time;
791 }
792
793 if ($booted && defined($stop_after_success) &&
794 $stop_after_success >= 0) {
795 my $now = time;
796 if ($now - $success_start >= $stop_after_success) {
797 doprint "Test forced to stop after $stop_after_success seconds after success\n";
798 last;
799 }
Steven Rostedt2545eb62010-11-02 15:01:32 -0400800 }
801
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400802 if ($full_line =~ /\[ backtrace testing \]/) {
803 $skip_call_trace = 1;
804 }
805
Steven Rostedt2545eb62010-11-02 15:01:32 -0400806 if ($full_line =~ /call trace:/i) {
Steven Rostedt46519202011-03-08 09:40:31 -0500807 if (!$bug && !$skip_call_trace) {
Steven Rostedt1c8a6172010-11-09 12:55:40 -0500808 $bug = 1;
809 $failure_start = time;
810 }
811 }
812
813 if ($bug && defined($stop_after_failure) &&
814 $stop_after_failure >= 0) {
815 my $now = time;
816 if ($now - $failure_start >= $stop_after_failure) {
817 doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
818 last;
819 }
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400820 }
821
822 if ($full_line =~ /\[ end of backtrace testing \]/) {
823 $skip_call_trace = 0;
824 }
825
826 if ($full_line =~ /Kernel panic -/) {
Steven Rostedt10abf112011-03-07 13:21:00 -0500827 $failure_start = time;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400828 $bug = 1;
829 }
830
831 if ($line =~ /\n/) {
832 $full_line = "";
833 }
834 }
835
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400836 close(DMESG);
Steven Rostedt2545eb62010-11-02 15:01:32 -0400837
Steven Rostedt2545eb62010-11-02 15:01:32 -0400838 if ($bug) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400839 return 0 if ($in_bisect);
Steven Rostedt576f6272010-11-02 14:58:38 -0400840 fail "failed - got a bug report" and return 0;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400841 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400842
Steven Rostedta75fece2010-11-02 14:58:27 -0400843 if (!$booted) {
844 return 0 if ($in_bisect);
Steven Rostedt576f6272010-11-02 14:58:38 -0400845 fail "failed - never got a boot prompt." and return 0;
Steven Rostedta75fece2010-11-02 14:58:27 -0400846 }
847
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400848 return 1;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400849}
850
851sub install {
852
Steven Rostedte48c5292010-11-02 14:35:37 -0400853 run_scp "$outputdir/$build_target", "$target_image" or
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400854 dodie "failed to copy image";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400855
856 my $install_mods = 0;
857
858 # should we process modules?
859 $install_mods = 0;
Steven Rostedt51ad1dd2010-11-08 16:43:21 -0500860 open(IN, "$output_config") or dodie("Can't read config file");
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400861 while (<IN>) {
862 if (/CONFIG_MODULES(=y)?/) {
863 $install_mods = 1 if (defined($1));
864 last;
865 }
866 }
867 close(IN);
868
869 if (!$install_mods) {
870 doprint "No modules needed\n";
871 return;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400872 }
873
Steven Rostedta75fece2010-11-02 14:58:27 -0400874 run_command "$make INSTALL_MOD_PATH=$tmpdir modules_install" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400875 dodie "Failed to install modules";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400876
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400877 my $modlib = "/lib/modules/$version";
Steven Rostedta57419b2010-11-02 15:13:54 -0400878 my $modtar = "ktest-mods.tar.bz2";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400879
Steven Rostedte48c5292010-11-02 14:35:37 -0400880 run_ssh "rm -rf $modlib" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400881 dodie "failed to remove old mods: $modlib";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400882
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400883 # would be nice if scp -r did not follow symbolic links
Steven Rostedta75fece2010-11-02 14:58:27 -0400884 run_command "cd $tmpdir && tar -cjf $modtar lib/modules/$version" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400885 dodie "making tarball";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400886
Steven Rostedte48c5292010-11-02 14:35:37 -0400887 run_scp "$tmpdir/$modtar", "/tmp" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400888 dodie "failed to copy modules";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400889
Steven Rostedta75fece2010-11-02 14:58:27 -0400890 unlink "$tmpdir/$modtar";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400891
Steven Rostedte48c5292010-11-02 14:35:37 -0400892 run_ssh "'(cd / && tar xf /tmp/$modtar)'" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400893 dodie "failed to tar modules";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400894
Steven Rostedte48c5292010-11-02 14:35:37 -0400895 run_ssh "rm -f /tmp/$modtar";
Steven Rostedt8b37ca82010-11-02 14:58:33 -0400896
897 return if (!defined($post_install));
898
Steven Rostedte48c5292010-11-02 14:35:37 -0400899 my $cp_post_install = $post_install;
900 $cp_post_install = s/\$KERNEL_VERSION/$version/g;
901 run_command "$cp_post_install" or
Steven Rostedt576f6272010-11-02 14:58:38 -0400902 dodie "Failed to run post install";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400903}
904
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -0400905sub check_buildlog {
906 my ($patch) = @_;
907
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -0400908 my @files = `git show $patch | diffstat -l`;
909
910 open(IN, "git show $patch |") or
911 dodie "failed to show $patch";
912 while (<IN>) {
913 if (m,^--- a/(.*),) {
914 chomp $1;
915 $files[$#files] = $1;
916 }
917 }
918 close(IN);
919
920 open(IN, $buildlog) or dodie "Can't open $buildlog";
921 while (<IN>) {
922 if (/^\s*(.*?):.*(warning|error)/) {
923 my $err = $1;
924 foreach my $file (@files) {
Steven Rostedta75fece2010-11-02 14:58:27 -0400925 my $fullpath = "$builddir/$file";
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -0400926 if ($file eq $err || $fullpath eq $err) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400927 fail "$file built with warnings" and return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -0400928 }
929 }
930 }
931 }
932 close(IN);
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400933
934 return 1;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -0400935}
936
Steven Rostedt612b9e92011-03-07 13:27:43 -0500937sub make_oldconfig {
938 my ($defconfig) = @_;
939
940 if (!run_command "$defconfig $make oldnoconfig") {
941 # Perhaps oldnoconfig doesn't exist in this version of the kernel
942 # try a yes '' | oldconfig
943 doprint "oldnoconfig failed, trying yes '' | make oldconfig\n";
944 run_command "yes '' | $defconfig $make oldconfig" or
945 dodie "failed make config oldconfig";
946 }
947}
948
Steven Rostedt2545eb62010-11-02 15:01:32 -0400949sub build {
950 my ($type) = @_;
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400951 my $defconfig = "";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400952
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400953 unlink $buildlog;
954
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400955 if ($type =~ /^useconfig:(.*)/) {
Steven Rostedt51ad1dd2010-11-08 16:43:21 -0500956 run_command "cp $1 $output_config" or
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400957 dodie "could not copy $1 to .config";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400958
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400959 $type = "oldconfig";
960 }
961
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400962 # old config can ask questions
963 if ($type eq "oldconfig") {
Steven Rostedt9386c6a2010-11-08 16:35:48 -0500964 $type = "oldnoconfig";
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400965
966 # allow for empty configs
Steven Rostedt51ad1dd2010-11-08 16:43:21 -0500967 run_command "touch $output_config";
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400968
Steven Rostedt51ad1dd2010-11-08 16:43:21 -0500969 run_command "mv $output_config $outputdir/config_temp" or
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400970 dodie "moving .config";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400971
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400972 if (!$noclean && !run_command "$make mrproper") {
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400973 dodie "make mrproper";
974 }
975
Steven Rostedt51ad1dd2010-11-08 16:43:21 -0500976 run_command "mv $outputdir/config_temp $output_config" or
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400977 dodie "moving config_temp";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400978
979 } elsif (!$noclean) {
Steven Rostedt51ad1dd2010-11-08 16:43:21 -0500980 unlink "$output_config";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400981 run_command "$make mrproper" or
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400982 dodie "make mrproper";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400983 }
Steven Rostedt2545eb62010-11-02 15:01:32 -0400984
985 # add something to distinguish this build
Steven Rostedta75fece2010-11-02 14:58:27 -0400986 open(OUT, "> $outputdir/localversion") or dodie("Can't make localversion file");
987 print OUT "$localversion\n";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400988 close(OUT);
989
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400990 if (defined($minconfig)) {
991 $defconfig = "KCONFIG_ALLCONFIG=$minconfig";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400992 }
993
Steven Rostedt612b9e92011-03-07 13:27:43 -0500994 if ($type eq "oldnoconfig") {
995 make_oldconfig $defconfig;
996 } else {
997 run_command "$defconfig $make $type" or
998 dodie "failed make config";
999 }
Steven Rostedt2545eb62010-11-02 15:01:32 -04001000
Steven Rostedta75fece2010-11-02 14:58:27 -04001001 $redirect = "$buildlog";
1002 if (!run_command "$make $build_options") {
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001003 undef $redirect;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001004 # bisect may need this to pass
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001005 return 0 if ($in_bisect);
1006 fail "failed build" and return 0;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001007 }
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001008 undef $redirect;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001009
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001010 return 1;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001011}
1012
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001013sub halt {
Steven Rostedte48c5292010-11-02 14:35:37 -04001014 if (!run_ssh "halt" or defined($power_off)) {
Steven Rostedt576f6272010-11-02 14:58:38 -04001015 if (defined($poweroff_after_halt)) {
1016 sleep $poweroff_after_halt;
1017 run_command "$power_off";
1018 }
1019 } else {
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001020 # nope? the zap it!
Steven Rostedta75fece2010-11-02 14:58:27 -04001021 run_command "$power_off";
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001022 }
1023}
1024
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001025sub success {
1026 my ($i) = @_;
1027
Steven Rostedte48c5292010-11-02 14:35:37 -04001028 $successes++;
1029
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001030 doprint "\n\n*******************************************\n";
1031 doprint "*******************************************\n";
Steven Rostedt7a849cd2010-11-08 16:49:25 -05001032 doprint "KTEST RESULT: TEST $i SUCCESS!!!! **\n";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001033 doprint "*******************************************\n";
1034 doprint "*******************************************\n";
1035
Steven Rostedt576f6272010-11-02 14:58:38 -04001036 if ($i != $opt{"NUM_TESTS"} && !do_not_reboot) {
Steven Rostedta75fece2010-11-02 14:58:27 -04001037 doprint "Reboot and wait $sleep_time seconds\n";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001038 reboot;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001039 start_monitor;
Steven Rostedta75fece2010-11-02 14:58:27 -04001040 wait_for_monitor $sleep_time;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001041 end_monitor;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001042 }
1043}
1044
1045sub get_version {
1046 # get the release name
1047 doprint "$make kernelrelease ... ";
1048 $version = `$make kernelrelease | tail -1`;
1049 chomp($version);
1050 doprint "$version\n";
1051}
1052
Steven Rostedtc960bb92011-03-08 09:22:39 -05001053sub answer_bisect {
1054 for (;;) {
1055 doprint "Pass or fail? [p/f]";
1056 my $ans = <STDIN>;
1057 chomp $ans;
1058 if ($ans eq "p" || $ans eq "P") {
1059 return 1;
1060 } elsif ($ans eq "f" || $ans eq "F") {
1061 return 0;
1062 } else {
1063 print "Please answer 'P' or 'F'\n";
1064 }
1065 }
1066}
1067
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001068sub child_run_test {
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001069 my $failed = 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001070
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001071 # child should have no power
Steven Rostedta75fece2010-11-02 14:58:27 -04001072 $reboot_on_error = 0;
1073 $poweroff_on_error = 0;
1074 $die_on_failure = 1;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001075
1076 run_command $run_test or $failed = 1;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001077 exit $failed;
1078}
1079
1080my $child_done;
1081
1082sub child_finished {
1083 $child_done = 1;
1084}
1085
1086sub do_run_test {
1087 my $child_pid;
1088 my $child_exit;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001089 my $line;
1090 my $full_line;
1091 my $bug = 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001092
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001093 wait_for_monitor 1;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001094
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001095 doprint "run test $run_test\n";
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001096
1097 $child_done = 0;
1098
1099 $SIG{CHLD} = qw(child_finished);
1100
1101 $child_pid = fork;
1102
1103 child_run_test if (!$child_pid);
1104
1105 $full_line = "";
1106
1107 do {
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001108 $line = wait_for_input($monitor_fp, 1);
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001109 if (defined($line)) {
1110
1111 # we are not guaranteed to get a full line
1112 $full_line .= $line;
Steven Rostedt8ea0e062011-03-08 09:44:35 -05001113 doprint $line;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001114
1115 if ($full_line =~ /call trace:/i) {
1116 $bug = 1;
1117 }
1118
1119 if ($full_line =~ /Kernel panic -/) {
1120 $bug = 1;
1121 }
1122
1123 if ($line =~ /\n/) {
1124 $full_line = "";
1125 }
1126 }
1127 } while (!$child_done && !$bug);
1128
1129 if ($bug) {
Steven Rostedt8ea0e062011-03-08 09:44:35 -05001130 my $failure_start = time;
1131 my $now;
1132 do {
1133 $line = wait_for_input($monitor_fp, 1);
1134 if (defined($line)) {
1135 doprint $line;
1136 }
1137 $now = time;
1138 if ($now - $failure_start >= $stop_after_failure) {
1139 last;
1140 }
1141 } while (defined($line));
1142
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001143 doprint "Detected kernel crash!\n";
1144 # kill the child with extreme prejudice
1145 kill 9, $child_pid;
1146 }
1147
1148 waitpid $child_pid, 0;
1149 $child_exit = $?;
1150
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001151 if ($bug || $child_exit) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001152 return 0 if $in_bisect;
1153 fail "test failed" and return 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001154 }
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001155 return 1;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001156}
1157
Steven Rostedta75fece2010-11-02 14:58:27 -04001158sub run_git_bisect {
1159 my ($command) = @_;
1160
1161 doprint "$command ... ";
1162
1163 my $output = `$command 2>&1`;
1164 my $ret = $?;
1165
1166 logit $output;
1167
1168 if ($ret) {
1169 doprint "FAILED\n";
1170 dodie "Failed to git bisect";
1171 }
1172
1173 doprint "SUCCESS\n";
1174 if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\))\s+\[([[:xdigit:]]+)\]/) {
1175 doprint "$1 [$2]\n";
1176 } elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) {
1177 $bisect_bad = $1;
1178 doprint "Found bad commit... $1\n";
1179 return 0;
1180 } else {
1181 # we already logged it, just print it now.
1182 print $output;
1183 }
1184
1185 return 1;
1186}
1187
Steven Rostedtc23dca72011-03-08 09:26:31 -05001188sub bisect_reboot {
1189 doprint "Reboot and sleep $bisect_sleep_time seconds\n";
1190 reboot;
1191 start_monitor;
1192 wait_for_monitor $bisect_sleep_time;
1193 end_monitor;
1194}
1195
1196# returns 1 on success, 0 on failure, -1 on skip
Steven Rostedt0a05c762010-11-08 11:14:10 -05001197sub run_bisect_test {
1198 my ($type, $buildtype) = @_;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001199
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001200 my $failed = 0;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001201 my $result;
1202 my $output;
1203 my $ret;
1204
Steven Rostedt0a05c762010-11-08 11:14:10 -05001205 $in_bisect = 1;
1206
1207 build $buildtype or $failed = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001208
1209 if ($type ne "build") {
Steven Rostedtc23dca72011-03-08 09:26:31 -05001210 if ($failed && $bisect_skip) {
1211 $in_bisect = 0;
1212 return -1;
1213 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001214 dodie "Failed on build" if $failed;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001215
1216 # Now boot the box
1217 get_grub_index;
1218 get_version;
1219 install;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001220
1221 start_monitor;
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001222 monitor or $failed = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001223
1224 if ($type ne "boot") {
Steven Rostedtc23dca72011-03-08 09:26:31 -05001225 if ($failed && $bisect_skip) {
1226 end_monitor;
1227 bisect_reboot;
1228 $in_bisect = 0;
1229 return -1;
1230 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001231 dodie "Failed on boot" if $failed;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001232
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001233 do_run_test or $failed = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001234 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001235 end_monitor;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001236 }
1237
1238 if ($failed) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001239 $result = 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001240
1241 # reboot the box to a good kernel
Steven Rostedta75fece2010-11-02 14:58:27 -04001242 if ($type ne "build") {
Steven Rostedtc23dca72011-03-08 09:26:31 -05001243 bisect_reboot;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001244 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001245 } else {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001246 $result = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001247 }
Steven Rostedt0a05c762010-11-08 11:14:10 -05001248 $in_bisect = 0;
1249
1250 return $result;
1251}
1252
1253sub run_bisect {
1254 my ($type) = @_;
1255 my $buildtype = "oldconfig";
1256
1257 # We should have a minconfig to use?
1258 if (defined($minconfig)) {
1259 $buildtype = "useconfig:$minconfig";
1260 }
1261
1262 my $ret = run_bisect_test $type, $buildtype;
1263
Steven Rostedtc960bb92011-03-08 09:22:39 -05001264 if ($bisect_manual) {
1265 $ret = answer_bisect;
1266 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001267
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04001268 # Are we looking for where it worked, not failed?
1269 if ($reverse_bisect) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001270 $ret = !$ret;
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04001271 }
1272
Steven Rostedtc23dca72011-03-08 09:26:31 -05001273 if ($ret > 0) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001274 return "good";
Steven Rostedtc23dca72011-03-08 09:26:31 -05001275 } elsif ($ret == 0) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001276 return "bad";
Steven Rostedtc23dca72011-03-08 09:26:31 -05001277 } elsif ($bisect_skip) {
1278 doprint "HIT A BAD COMMIT ... SKIPPING\n";
1279 return "skip";
Steven Rostedt0a05c762010-11-08 11:14:10 -05001280 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001281}
1282
1283sub bisect {
1284 my ($i) = @_;
1285
1286 my $result;
1287
1288 die "BISECT_GOOD[$i] not defined\n" if (!defined($opt{"BISECT_GOOD[$i]"}));
1289 die "BISECT_BAD[$i] not defined\n" if (!defined($opt{"BISECT_BAD[$i]"}));
1290 die "BISECT_TYPE[$i] not defined\n" if (!defined($opt{"BISECT_TYPE[$i]"}));
1291
1292 my $good = $opt{"BISECT_GOOD[$i]"};
1293 my $bad = $opt{"BISECT_BAD[$i]"};
1294 my $type = $opt{"BISECT_TYPE[$i]"};
Steven Rostedta75fece2010-11-02 14:58:27 -04001295 my $start = $opt{"BISECT_START[$i]"};
1296 my $replay = $opt{"BISECT_REPLAY[$i]"};
Steven Rostedt3410f6f2011-03-08 09:38:12 -05001297 my $start_files = $opt{"BISECT_FILES[$i]"};
1298
1299 if (defined($start_files)) {
1300 $start_files = " -- " . $start_files;
1301 } else {
1302 $start_files = "";
1303 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001304
Steven Rostedta57419b2010-11-02 15:13:54 -04001305 # convert to true sha1's
1306 $good = get_sha1($good);
1307 $bad = get_sha1($bad);
1308
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04001309 if (defined($opt{"BISECT_REVERSE[$i]"}) &&
1310 $opt{"BISECT_REVERSE[$i]"} == 1) {
1311 doprint "Performing a reverse bisect (bad is good, good is bad!)\n";
1312 $reverse_bisect = 1;
1313 } else {
1314 $reverse_bisect = 0;
1315 }
1316
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001317 # Can't have a test without having a test to run
1318 if ($type eq "test" && !defined($run_test)) {
1319 $type = "boot";
1320 }
1321
Steven Rostedta75fece2010-11-02 14:58:27 -04001322 my $check = $opt{"BISECT_CHECK[$i]"};
1323 if (defined($check) && $check ne "0") {
1324
1325 # get current HEAD
Steven Rostedta57419b2010-11-02 15:13:54 -04001326 my $head = get_sha1("HEAD");
Steven Rostedta75fece2010-11-02 14:58:27 -04001327
1328 if ($check ne "good") {
1329 doprint "TESTING BISECT BAD [$bad]\n";
1330 run_command "git checkout $bad" or
1331 die "Failed to checkout $bad";
1332
1333 $result = run_bisect $type;
1334
1335 if ($result ne "bad") {
1336 fail "Tested BISECT_BAD [$bad] and it succeeded" and return 0;
1337 }
1338 }
1339
1340 if ($check ne "bad") {
1341 doprint "TESTING BISECT GOOD [$good]\n";
1342 run_command "git checkout $good" or
1343 die "Failed to checkout $good";
1344
1345 $result = run_bisect $type;
1346
1347 if ($result ne "good") {
1348 fail "Tested BISECT_GOOD [$good] and it failed" and return 0;
1349 }
1350 }
1351
1352 # checkout where we started
1353 run_command "git checkout $head" or
1354 die "Failed to checkout $head";
1355 }
1356
Steven Rostedt3410f6f2011-03-08 09:38:12 -05001357 run_command "git bisect start$start_files" or
Steven Rostedta75fece2010-11-02 14:58:27 -04001358 dodie "could not start bisect";
1359
1360 run_command "git bisect good $good" or
1361 dodie "could not set bisect good to $good";
1362
1363 run_git_bisect "git bisect bad $bad" or
1364 dodie "could not set bisect bad to $bad";
1365
1366 if (defined($replay)) {
1367 run_command "git bisect replay $replay" or
1368 dodie "failed to run replay";
1369 }
1370
1371 if (defined($start)) {
1372 run_command "git checkout $start" or
1373 dodie "failed to checkout $start";
1374 }
1375
1376 my $test;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001377 do {
1378 $result = run_bisect $type;
Steven Rostedta75fece2010-11-02 14:58:27 -04001379 $test = run_git_bisect "git bisect $result";
1380 } while ($test);
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001381
1382 run_command "git bisect log" or
1383 dodie "could not capture git bisect log";
1384
1385 run_command "git bisect reset" or
1386 dodie "could not reset git bisect";
1387
1388 doprint "Bad commit was [$bisect_bad]\n";
1389
Steven Rostedt0a05c762010-11-08 11:14:10 -05001390 success $i;
1391}
1392
1393my %config_ignore;
1394my %config_set;
1395
1396my %config_list;
1397my %null_config;
1398
1399my %dependency;
1400
1401sub process_config_ignore {
1402 my ($config) = @_;
1403
1404 open (IN, $config)
1405 or dodie "Failed to read $config";
1406
1407 while (<IN>) {
1408 if (/^(.*?(CONFIG\S*)(=.*| is not set))/) {
1409 $config_ignore{$2} = $1;
1410 }
1411 }
1412
1413 close(IN);
1414}
1415
1416sub read_current_config {
1417 my ($config_ref) = @_;
1418
1419 %{$config_ref} = ();
1420 undef %{$config_ref};
1421
1422 my @key = keys %{$config_ref};
1423 if ($#key >= 0) {
1424 print "did not delete!\n";
1425 exit;
1426 }
1427 open (IN, "$output_config");
1428
1429 while (<IN>) {
1430 if (/^(CONFIG\S+)=(.*)/) {
1431 ${$config_ref}{$1} = $2;
1432 }
1433 }
1434 close(IN);
1435}
1436
1437sub get_dependencies {
1438 my ($config) = @_;
1439
1440 my $arr = $dependency{$config};
1441 if (!defined($arr)) {
1442 return ();
1443 }
1444
1445 my @deps = @{$arr};
1446
1447 foreach my $dep (@{$arr}) {
1448 print "ADD DEP $dep\n";
1449 @deps = (@deps, get_dependencies $dep);
1450 }
1451
1452 return @deps;
1453}
1454
1455sub create_config {
1456 my @configs = @_;
1457
1458 open(OUT, ">$output_config") or dodie "Can not write to $output_config";
1459
1460 foreach my $config (@configs) {
1461 print OUT "$config_set{$config}\n";
1462 my @deps = get_dependencies $config;
1463 foreach my $dep (@deps) {
1464 print OUT "$config_set{$dep}\n";
1465 }
1466 }
1467
1468 foreach my $config (keys %config_ignore) {
1469 print OUT "$config_ignore{$config}\n";
1470 }
1471 close(OUT);
1472
1473# exit;
Steven Rostedt612b9e92011-03-07 13:27:43 -05001474 make_oldconfig "";
Steven Rostedt0a05c762010-11-08 11:14:10 -05001475}
1476
1477sub compare_configs {
1478 my (%a, %b) = @_;
1479
1480 foreach my $item (keys %a) {
1481 if (!defined($b{$item})) {
1482 print "diff $item\n";
1483 return 1;
1484 }
1485 delete $b{$item};
1486 }
1487
1488 my @keys = keys %b;
1489 if ($#keys) {
1490 print "diff2 $keys[0]\n";
1491 }
1492 return -1 if ($#keys >= 0);
1493
1494 return 0;
1495}
1496
1497sub run_config_bisect_test {
1498 my ($type) = @_;
1499
1500 return run_bisect_test $type, "oldconfig";
1501}
1502
1503sub process_passed {
1504 my (%configs) = @_;
1505
1506 doprint "These configs had no failure: (Enabling them for further compiles)\n";
1507 # Passed! All these configs are part of a good compile.
1508 # Add them to the min options.
1509 foreach my $config (keys %configs) {
1510 if (defined($config_list{$config})) {
1511 doprint " removing $config\n";
1512 $config_ignore{$config} = $config_list{$config};
1513 delete $config_list{$config};
1514 }
1515 }
Steven Rostedtf1a27852010-11-11 11:34:38 -05001516 doprint "config copied to $outputdir/config_good\n";
1517 run_command "cp -f $output_config $outputdir/config_good";
Steven Rostedt0a05c762010-11-08 11:14:10 -05001518}
1519
1520sub process_failed {
1521 my ($config) = @_;
1522
1523 doprint "\n\n***************************************\n";
1524 doprint "Found bad config: $config\n";
1525 doprint "***************************************\n\n";
1526}
1527
1528sub run_config_bisect {
1529
1530 my @start_list = keys %config_list;
1531
1532 if ($#start_list < 0) {
1533 doprint "No more configs to test!!!\n";
1534 return -1;
1535 }
1536
1537 doprint "***** RUN TEST ***\n";
1538 my $type = $opt{"CONFIG_BISECT_TYPE[$iteration]"};
1539 my $ret;
1540 my %current_config;
1541
1542 my $count = $#start_list + 1;
1543 doprint " $count configs to test\n";
1544
1545 my $half = int($#start_list / 2);
1546
1547 do {
1548 my @tophalf = @start_list[0 .. $half];
1549
1550 create_config @tophalf;
1551 read_current_config \%current_config;
1552
1553 $count = $#tophalf + 1;
1554 doprint "Testing $count configs\n";
1555 my $found = 0;
1556 # make sure we test something
1557 foreach my $config (@tophalf) {
1558 if (defined($current_config{$config})) {
1559 logit " $config\n";
1560 $found = 1;
1561 }
1562 }
1563 if (!$found) {
1564 # try the other half
1565 doprint "Top half produced no set configs, trying bottom half\n";
1566 @tophalf = @start_list[$half .. $#start_list];
1567 create_config @tophalf;
1568 read_current_config \%current_config;
1569 foreach my $config (@tophalf) {
1570 if (defined($current_config{$config})) {
1571 logit " $config\n";
1572 $found = 1;
1573 }
1574 }
1575 if (!$found) {
1576 doprint "Failed: Can't make new config with current configs\n";
1577 foreach my $config (@start_list) {
1578 doprint " CONFIG: $config\n";
1579 }
1580 return -1;
1581 }
1582 $count = $#tophalf + 1;
1583 doprint "Testing $count configs\n";
1584 }
1585
1586 $ret = run_config_bisect_test $type;
Steven Rostedtc960bb92011-03-08 09:22:39 -05001587 if ($bisect_manual) {
1588 $ret = answer_bisect;
1589 }
Steven Rostedt0a05c762010-11-08 11:14:10 -05001590 if ($ret) {
1591 process_passed %current_config;
1592 return 0;
1593 }
1594
1595 doprint "This config had a failure.\n";
1596 doprint "Removing these configs that were not set in this config:\n";
Steven Rostedtf1a27852010-11-11 11:34:38 -05001597 doprint "config copied to $outputdir/config_bad\n";
1598 run_command "cp -f $output_config $outputdir/config_bad";
Steven Rostedt0a05c762010-11-08 11:14:10 -05001599
1600 # A config exists in this group that was bad.
1601 foreach my $config (keys %config_list) {
1602 if (!defined($current_config{$config})) {
1603 doprint " removing $config\n";
1604 delete $config_list{$config};
1605 }
1606 }
1607
1608 @start_list = @tophalf;
1609
1610 if ($#start_list == 0) {
1611 process_failed $start_list[0];
1612 return 1;
1613 }
1614
1615 # remove half the configs we are looking at and see if
1616 # they are good.
1617 $half = int($#start_list / 2);
1618 } while ($half > 0);
1619
Steven Rostedtc960bb92011-03-08 09:22:39 -05001620 # we found a single config, try it again unless we are running manually
1621
1622 if ($bisect_manual) {
1623 process_failed $start_list[0];
1624 return 1;
1625 }
1626
Steven Rostedt0a05c762010-11-08 11:14:10 -05001627 my @tophalf = @start_list[0 .. 0];
1628
1629 $ret = run_config_bisect_test $type;
1630 if ($ret) {
1631 process_passed %current_config;
1632 return 0;
1633 }
1634
1635 process_failed $start_list[0];
1636 return 1;
1637}
1638
1639sub config_bisect {
1640 my ($i) = @_;
1641
1642 my $start_config = $opt{"CONFIG_BISECT[$i]"};
1643
1644 my $tmpconfig = "$tmpdir/use_config";
1645
1646 # Make the file with the bad config and the min config
1647 if (defined($minconfig)) {
1648 # read the min config for things to ignore
1649 run_command "cp $minconfig $tmpconfig" or
1650 dodie "failed to copy $minconfig to $tmpconfig";
1651 } else {
1652 unlink $tmpconfig;
1653 }
1654
1655 # Add other configs
1656 if (defined($addconfig)) {
1657 run_command "cat $addconfig >> $tmpconfig" or
1658 dodie "failed to append $addconfig";
1659 }
1660
1661 my $defconfig = "";
1662 if (-f $tmpconfig) {
1663 $defconfig = "KCONFIG_ALLCONFIG=$tmpconfig";
1664 process_config_ignore $tmpconfig;
1665 }
1666
1667 # now process the start config
1668 run_command "cp $start_config $output_config" or
1669 dodie "failed to copy $start_config to $output_config";
1670
1671 # read directly what we want to check
1672 my %config_check;
1673 open (IN, $output_config)
1674 or dodie "faied to open $output_config";
1675
1676 while (<IN>) {
1677 if (/^((CONFIG\S*)=.*)/) {
1678 $config_check{$2} = $1;
1679 }
1680 }
1681 close(IN);
1682
1683 # Now run oldconfig with the minconfig (and addconfigs)
Steven Rostedt612b9e92011-03-07 13:27:43 -05001684 make_oldconfig $defconfig;
Steven Rostedt0a05c762010-11-08 11:14:10 -05001685
1686 # check to see what we lost (or gained)
1687 open (IN, $output_config)
1688 or dodie "Failed to read $start_config";
1689
1690 my %removed_configs;
1691 my %added_configs;
1692
1693 while (<IN>) {
1694 if (/^((CONFIG\S*)=.*)/) {
1695 # save off all options
1696 $config_set{$2} = $1;
1697 if (defined($config_check{$2})) {
1698 if (defined($config_ignore{$2})) {
1699 $removed_configs{$2} = $1;
1700 } else {
1701 $config_list{$2} = $1;
1702 }
1703 } elsif (!defined($config_ignore{$2})) {
1704 $added_configs{$2} = $1;
1705 $config_list{$2} = $1;
1706 }
1707 }
1708 }
1709 close(IN);
1710
1711 my @confs = keys %removed_configs;
1712 if ($#confs >= 0) {
1713 doprint "Configs overridden by default configs and removed from check:\n";
1714 foreach my $config (@confs) {
1715 doprint " $config\n";
1716 }
1717 }
1718 @confs = keys %added_configs;
1719 if ($#confs >= 0) {
1720 doprint "Configs appearing in make oldconfig and added:\n";
1721 foreach my $config (@confs) {
1722 doprint " $config\n";
1723 }
1724 }
1725
1726 my %config_test;
1727 my $once = 0;
1728
1729 # Sometimes kconfig does weird things. We must make sure
1730 # that the config we autocreate has everything we need
1731 # to test, otherwise we may miss testing configs, or
1732 # may not be able to create a new config.
1733 # Here we create a config with everything set.
1734 create_config (keys %config_list);
1735 read_current_config \%config_test;
1736 foreach my $config (keys %config_list) {
1737 if (!defined($config_test{$config})) {
1738 if (!$once) {
1739 $once = 1;
1740 doprint "Configs not produced by kconfig (will not be checked):\n";
1741 }
1742 doprint " $config\n";
1743 delete $config_list{$config};
1744 }
1745 }
1746 my $ret;
1747 do {
1748 $ret = run_config_bisect;
1749 } while (!$ret);
1750
1751 return $ret if ($ret < 0);
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001752
1753 success $i;
1754}
1755
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001756sub patchcheck {
1757 my ($i) = @_;
1758
1759 die "PATCHCHECK_START[$i] not defined\n"
1760 if (!defined($opt{"PATCHCHECK_START[$i]"}));
1761 die "PATCHCHECK_TYPE[$i] not defined\n"
1762 if (!defined($opt{"PATCHCHECK_TYPE[$i]"}));
1763
1764 my $start = $opt{"PATCHCHECK_START[$i]"};
1765
1766 my $end = "HEAD";
1767 if (defined($opt{"PATCHCHECK_END[$i]"})) {
1768 $end = $opt{"PATCHCHECK_END[$i]"};
1769 }
1770
Steven Rostedta57419b2010-11-02 15:13:54 -04001771 # Get the true sha1's since we can use things like HEAD~3
1772 $start = get_sha1($start);
1773 $end = get_sha1($end);
1774
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001775 my $type = $opt{"PATCHCHECK_TYPE[$i]"};
1776
1777 # Can't have a test without having a test to run
1778 if ($type eq "test" && !defined($run_test)) {
1779 $type = "boot";
1780 }
1781
1782 open (IN, "git log --pretty=oneline $end|") or
1783 dodie "could not get git list";
1784
1785 my @list;
1786
1787 while (<IN>) {
1788 chomp;
1789 $list[$#list+1] = $_;
1790 last if (/^$start/);
1791 }
1792 close(IN);
1793
1794 if ($list[$#list] !~ /^$start/) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001795 fail "SHA1 $start not found";
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001796 }
1797
1798 # go backwards in the list
1799 @list = reverse @list;
1800
1801 my $save_clean = $noclean;
1802
1803 $in_patchcheck = 1;
1804 foreach my $item (@list) {
1805 my $sha1 = $item;
1806 $sha1 =~ s/^([[:xdigit:]]+).*/$1/;
1807
1808 doprint "\nProcessing commit $item\n\n";
1809
1810 run_command "git checkout $sha1" or
1811 die "Failed to checkout $sha1";
1812
1813 # only clean on the first and last patch
1814 if ($item eq $list[0] ||
1815 $item eq $list[$#list]) {
1816 $noclean = $save_clean;
1817 } else {
1818 $noclean = 1;
1819 }
1820
1821 if (defined($minconfig)) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001822 build "useconfig:$minconfig" or return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001823 } else {
1824 # ?? no config to use?
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001825 build "oldconfig" or return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001826 }
1827
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001828 check_buildlog $sha1 or return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001829
1830 next if ($type eq "build");
1831
1832 get_grub_index;
1833 get_version;
1834 install;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001835
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001836 my $failed = 0;
1837
1838 start_monitor;
1839 monitor or $failed = 1;
1840
1841 if (!$failed && $type ne "boot"){
1842 do_run_test or $failed = 1;
1843 }
1844 end_monitor;
1845 return 0 if ($failed);
1846
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001847 }
1848 $in_patchcheck = 0;
1849 success $i;
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001850
1851 return 1;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001852}
1853
Steven Rostedt8d1491b2010-11-18 15:39:48 -05001854$#ARGV < 1 or die "ktest.pl version: $VERSION\n usage: ktest.pl config-file\n";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001855
Steven Rostedt8d1491b2010-11-18 15:39:48 -05001856if ($#ARGV == 0) {
1857 $ktest_config = $ARGV[0];
1858 if (! -f $ktest_config) {
1859 print "$ktest_config does not exist.\n";
1860 my $ans;
1861 for (;;) {
1862 print "Create it? [Y/n] ";
1863 $ans = <STDIN>;
1864 chomp $ans;
1865 if ($ans =~ /^\s*$/) {
1866 $ans = "y";
1867 }
1868 last if ($ans =~ /^y$/i || $ans =~ /^n$/i);
1869 print "Please answer either 'y' or 'n'.\n";
1870 }
1871 if ($ans !~ /^y$/i) {
1872 exit 0;
1873 }
1874 }
1875} else {
1876 $ktest_config = "ktest.conf";
1877}
1878
1879if (! -f $ktest_config) {
1880 open(OUT, ">$ktest_config") or die "Can not create $ktest_config";
1881 print OUT << "EOF"
1882# Generated by ktest.pl
1883#
1884# Define each test with TEST_START
1885# The config options below it will override the defaults
1886TEST_START
1887
1888DEFAULTS
1889EOF
1890;
1891 close(OUT);
1892}
1893read_config $ktest_config;
1894
1895# Append any configs entered in manually to the config file.
1896my @new_configs = keys %entered_configs;
1897if ($#new_configs >= 0) {
1898 print "\nAppending entered in configs to $ktest_config\n";
1899 open(OUT, ">>$ktest_config") or die "Can not append to $ktest_config";
1900 foreach my $config (@new_configs) {
1901 print OUT "$config = $entered_configs{$config}\n";
1902 $opt{$config} = $entered_configs{$config};
1903 }
1904}
Steven Rostedt2545eb62010-11-02 15:01:32 -04001905
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001906if ($opt{"CLEAR_LOG"} && defined($opt{"LOG_FILE"})) {
1907 unlink $opt{"LOG_FILE"};
1908}
Steven Rostedt2545eb62010-11-02 15:01:32 -04001909
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001910doprint "\n\nSTARTING AUTOMATED TESTS\n\n";
1911
Steven Rostedta57419b2010-11-02 15:13:54 -04001912for (my $i = 0, my $repeat = 1; $i <= $opt{"NUM_TESTS"}; $i += $repeat) {
1913
1914 if (!$i) {
1915 doprint "DEFAULT OPTIONS:\n";
1916 } else {
1917 doprint "\nTEST $i OPTIONS";
1918 if (defined($repeat_tests{$i})) {
1919 $repeat = $repeat_tests{$i};
1920 doprint " ITERATE $repeat";
1921 }
1922 doprint "\n";
1923 }
1924
1925 foreach my $option (sort keys %opt) {
1926
1927 if ($option =~ /\[(\d+)\]$/) {
1928 next if ($i != $1);
1929 } else {
1930 next if ($i);
1931 }
1932
1933 doprint "$option = $opt{$option}\n";
1934 }
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001935}
Steven Rostedt2545eb62010-11-02 15:01:32 -04001936
Steven Rostedta75fece2010-11-02 14:58:27 -04001937sub set_test_option {
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001938 my ($name, $i) = @_;
1939
1940 my $option = "$name\[$i\]";
1941
1942 if (defined($opt{$option})) {
1943 return $opt{$option};
1944 }
1945
Steven Rostedta57419b2010-11-02 15:13:54 -04001946 foreach my $test (keys %repeat_tests) {
1947 if ($i >= $test &&
1948 $i < $test + $repeat_tests{$test}) {
1949 $option = "$name\[$test\]";
1950 if (defined($opt{$option})) {
1951 return $opt{$option};
1952 }
1953 }
1954 }
1955
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001956 if (defined($opt{$name})) {
1957 return $opt{$name};
1958 }
1959
1960 return undef;
1961}
1962
Steven Rostedt2545eb62010-11-02 15:01:32 -04001963# First we need to do is the builds
Steven Rostedta75fece2010-11-02 14:58:27 -04001964for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
Steven Rostedt2545eb62010-11-02 15:01:32 -04001965
Steven Rostedt576f6272010-11-02 14:58:38 -04001966 $iteration = $i;
1967
Steven Rostedta75fece2010-11-02 14:58:27 -04001968 my $makecmd = set_test_option("MAKE_CMD", $i);
1969
1970 $machine = set_test_option("MACHINE", $i);
Steven Rostedte48c5292010-11-02 14:35:37 -04001971 $ssh_user = set_test_option("SSH_USER", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04001972 $tmpdir = set_test_option("TMP_DIR", $i);
1973 $outputdir = set_test_option("OUTPUT_DIR", $i);
1974 $builddir = set_test_option("BUILD_DIR", $i);
1975 $test_type = set_test_option("TEST_TYPE", $i);
1976 $build_type = set_test_option("BUILD_TYPE", $i);
1977 $build_options = set_test_option("BUILD_OPTIONS", $i);
1978 $power_cycle = set_test_option("POWER_CYCLE", $i);
Steven Rostedte48c5292010-11-02 14:35:37 -04001979 $reboot = set_test_option("REBOOT", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04001980 $noclean = set_test_option("BUILD_NOCLEAN", $i);
1981 $minconfig = set_test_option("MIN_CONFIG", $i);
1982 $run_test = set_test_option("TEST", $i);
1983 $addconfig = set_test_option("ADD_CONFIG", $i);
1984 $reboot_type = set_test_option("REBOOT_TYPE", $i);
1985 $grub_menu = set_test_option("GRUB_MENU", $i);
Steven Rostedt8b37ca82010-11-02 14:58:33 -04001986 $post_install = set_test_option("POST_INSTALL", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04001987 $reboot_script = set_test_option("REBOOT_SCRIPT", $i);
1988 $reboot_on_error = set_test_option("REBOOT_ON_ERROR", $i);
1989 $poweroff_on_error = set_test_option("POWEROFF_ON_ERROR", $i);
1990 $die_on_failure = set_test_option("DIE_ON_FAILURE", $i);
1991 $power_off = set_test_option("POWER_OFF", $i);
Steven Rostedt576f6272010-11-02 14:58:38 -04001992 $powercycle_after_reboot = set_test_option("POWERCYCLE_AFTER_REBOOT", $i);
1993 $poweroff_after_halt = set_test_option("POWEROFF_AFTER_HALT", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04001994 $sleep_time = set_test_option("SLEEP_TIME", $i);
1995 $bisect_sleep_time = set_test_option("BISECT_SLEEP_TIME", $i);
Steven Rostedtc960bb92011-03-08 09:22:39 -05001996 $bisect_manual = set_test_option("BISECT_MANUAL", $i);
Steven Rostedtc23dca72011-03-08 09:26:31 -05001997 $bisect_skip = set_test_option("BISECT_SKIP", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04001998 $store_failures = set_test_option("STORE_FAILURES", $i);
1999 $timeout = set_test_option("TIMEOUT", $i);
2000 $booted_timeout = set_test_option("BOOTED_TIMEOUT", $i);
2001 $console = set_test_option("CONSOLE", $i);
2002 $success_line = set_test_option("SUCCESS_LINE", $i);
Steven Rostedt1c8a6172010-11-09 12:55:40 -05002003 $stop_after_success = set_test_option("STOP_AFTER_SUCCESS", $i);
2004 $stop_after_failure = set_test_option("STOP_AFTER_FAILURE", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002005 $build_target = set_test_option("BUILD_TARGET", $i);
Steven Rostedte48c5292010-11-02 14:35:37 -04002006 $ssh_exec = set_test_option("SSH_EXEC", $i);
2007 $scp_to_target = set_test_option("SCP_TO_TARGET", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002008 $target_image = set_test_option("TARGET_IMAGE", $i);
2009 $localversion = set_test_option("LOCALVERSION", $i);
2010
2011 chdir $builddir || die "can't change directory to $builddir";
2012
2013 if (!-d $tmpdir) {
2014 mkpath($tmpdir) or
2015 die "can't create $tmpdir";
2016 }
2017
Steven Rostedte48c5292010-11-02 14:35:37 -04002018 $ENV{"SSH_USER"} = $ssh_user;
2019 $ENV{"MACHINE"} = $machine;
2020
Steven Rostedta75fece2010-11-02 14:58:27 -04002021 $target = "$ssh_user\@$machine";
2022
2023 $buildlog = "$tmpdir/buildlog-$machine";
2024 $dmesg = "$tmpdir/dmesg-$machine";
2025 $make = "$makecmd O=$outputdir";
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05002026 $output_config = "$outputdir/.config";
Steven Rostedta75fece2010-11-02 14:58:27 -04002027
2028 if ($reboot_type eq "grub") {
Steven Rostedt576f6272010-11-02 14:58:38 -04002029 dodie "GRUB_MENU not defined" if (!defined($grub_menu));
Steven Rostedta75fece2010-11-02 14:58:27 -04002030 } elsif (!defined($reboot_script)) {
Steven Rostedt576f6272010-11-02 14:58:38 -04002031 dodie "REBOOT_SCRIPT not defined"
Steven Rostedta75fece2010-11-02 14:58:27 -04002032 }
2033
2034 my $run_type = $build_type;
2035 if ($test_type eq "patchcheck") {
2036 $run_type = $opt{"PATCHCHECK_TYPE[$i]"};
2037 } elsif ($test_type eq "bisect") {
2038 $run_type = $opt{"BISECT_TYPE[$i]"};
Steven Rostedt0a05c762010-11-08 11:14:10 -05002039 } elsif ($test_type eq "config_bisect") {
2040 $run_type = $opt{"CONFIG_BISECT_TYPE[$i]"};
Steven Rostedta75fece2010-11-02 14:58:27 -04002041 }
2042
2043 # mistake in config file?
2044 if (!defined($run_type)) {
2045 $run_type = "ERROR";
2046 }
Steven Rostedt2545eb62010-11-02 15:01:32 -04002047
2048 doprint "\n\n";
Steven Rostedta75fece2010-11-02 14:58:27 -04002049 doprint "RUNNING TEST $i of $opt{NUM_TESTS} with option $test_type $run_type\n\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -04002050
2051 unlink $dmesg;
2052 unlink $buildlog;
Steven Rostedt2545eb62010-11-02 15:01:32 -04002053
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002054 if (!defined($minconfig)) {
2055 $minconfig = $addconfig;
2056
2057 } elsif (defined($addconfig)) {
Steven Rostedt9be2e6b2010-11-09 12:20:21 -05002058 run_command "cat $addconfig $minconfig > $tmpdir/add_config" or
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002059 dodie "Failed to create temp config";
Steven Rostedt9be2e6b2010-11-09 12:20:21 -05002060 $minconfig = "$tmpdir/add_config";
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002061 }
2062
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002063 my $checkout = $opt{"CHECKOUT[$i]"};
2064 if (defined($checkout)) {
2065 run_command "git checkout $checkout" or
2066 die "failed to checkout $checkout";
2067 }
2068
Steven Rostedta75fece2010-11-02 14:58:27 -04002069 if ($test_type eq "bisect") {
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04002070 bisect $i;
2071 next;
Steven Rostedt0a05c762010-11-08 11:14:10 -05002072 } elsif ($test_type eq "config_bisect") {
2073 config_bisect $i;
2074 next;
Steven Rostedta75fece2010-11-02 14:58:27 -04002075 } elsif ($test_type eq "patchcheck") {
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002076 patchcheck $i;
2077 next;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04002078 }
2079
Steven Rostedt7faafbd2010-11-02 14:58:22 -04002080 if ($build_type ne "nobuild") {
2081 build $build_type or next;
Steven Rostedt2545eb62010-11-02 15:01:32 -04002082 }
2083
Steven Rostedta75fece2010-11-02 14:58:27 -04002084 if ($test_type ne "build") {
2085 get_grub_index;
2086 get_version;
2087 install;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04002088
Steven Rostedta75fece2010-11-02 14:58:27 -04002089 my $failed = 0;
2090 start_monitor;
2091 monitor or $failed = 1;;
2092
2093 if (!$failed && $test_type ne "boot" && defined($run_test)) {
2094 do_run_test or $failed = 1;
2095 }
2096 end_monitor;
2097 next if ($failed);
Steven Rostedt5a391fb2010-11-02 14:57:43 -04002098 }
2099
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04002100 success $i;
Steven Rostedt2545eb62010-11-02 15:01:32 -04002101}
2102
Steven Rostedt5c42fc52010-11-02 14:57:01 -04002103if ($opt{"POWEROFF_ON_SUCCESS"}) {
Steven Rostedt75c3fda72010-11-02 14:57:21 -04002104 halt;
Steven Rostedt576f6272010-11-02 14:58:38 -04002105} elsif ($opt{"REBOOT_ON_SUCCESS"} && !do_not_reboot) {
Steven Rostedt75c3fda72010-11-02 14:57:21 -04002106 reboot;
Steven Rostedt5c42fc52010-11-02 14:57:01 -04002107}
Steven Rostedt75c3fda72010-11-02 14:57:21 -04002108
Steven Rostedte48c5292010-11-02 14:35:37 -04002109doprint "\n $successes of $opt{NUM_TESTS} tests were successful\n\n";
2110
Steven Rostedt2545eb62010-11-02 15:01:32 -04002111exit 0;