blob: 0f62916a43f71c3222d1b990f977b644eb81966e [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 Rostedt1c8a6172010-11-09 12:55:40 -0500807 if (!$skip_call_trace) {
808 $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;
1113
1114 if ($full_line =~ /call trace:/i) {
1115 $bug = 1;
1116 }
1117
1118 if ($full_line =~ /Kernel panic -/) {
1119 $bug = 1;
1120 }
1121
1122 if ($line =~ /\n/) {
1123 $full_line = "";
1124 }
1125 }
1126 } while (!$child_done && !$bug);
1127
1128 if ($bug) {
1129 doprint "Detected kernel crash!\n";
1130 # kill the child with extreme prejudice
1131 kill 9, $child_pid;
1132 }
1133
1134 waitpid $child_pid, 0;
1135 $child_exit = $?;
1136
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001137 if ($bug || $child_exit) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001138 return 0 if $in_bisect;
1139 fail "test failed" and return 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001140 }
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001141 return 1;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001142}
1143
Steven Rostedta75fece2010-11-02 14:58:27 -04001144sub run_git_bisect {
1145 my ($command) = @_;
1146
1147 doprint "$command ... ";
1148
1149 my $output = `$command 2>&1`;
1150 my $ret = $?;
1151
1152 logit $output;
1153
1154 if ($ret) {
1155 doprint "FAILED\n";
1156 dodie "Failed to git bisect";
1157 }
1158
1159 doprint "SUCCESS\n";
1160 if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\))\s+\[([[:xdigit:]]+)\]/) {
1161 doprint "$1 [$2]\n";
1162 } elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) {
1163 $bisect_bad = $1;
1164 doprint "Found bad commit... $1\n";
1165 return 0;
1166 } else {
1167 # we already logged it, just print it now.
1168 print $output;
1169 }
1170
1171 return 1;
1172}
1173
Steven Rostedtc23dca72011-03-08 09:26:31 -05001174sub bisect_reboot {
1175 doprint "Reboot and sleep $bisect_sleep_time seconds\n";
1176 reboot;
1177 start_monitor;
1178 wait_for_monitor $bisect_sleep_time;
1179 end_monitor;
1180}
1181
1182# returns 1 on success, 0 on failure, -1 on skip
Steven Rostedt0a05c762010-11-08 11:14:10 -05001183sub run_bisect_test {
1184 my ($type, $buildtype) = @_;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001185
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001186 my $failed = 0;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001187 my $result;
1188 my $output;
1189 my $ret;
1190
Steven Rostedt0a05c762010-11-08 11:14:10 -05001191 $in_bisect = 1;
1192
1193 build $buildtype or $failed = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001194
1195 if ($type ne "build") {
Steven Rostedtc23dca72011-03-08 09:26:31 -05001196 if ($failed && $bisect_skip) {
1197 $in_bisect = 0;
1198 return -1;
1199 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001200 dodie "Failed on build" if $failed;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001201
1202 # Now boot the box
1203 get_grub_index;
1204 get_version;
1205 install;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001206
1207 start_monitor;
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001208 monitor or $failed = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001209
1210 if ($type ne "boot") {
Steven Rostedtc23dca72011-03-08 09:26:31 -05001211 if ($failed && $bisect_skip) {
1212 end_monitor;
1213 bisect_reboot;
1214 $in_bisect = 0;
1215 return -1;
1216 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001217 dodie "Failed on boot" if $failed;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001218
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001219 do_run_test or $failed = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001220 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001221 end_monitor;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001222 }
1223
1224 if ($failed) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001225 $result = 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001226
1227 # reboot the box to a good kernel
Steven Rostedta75fece2010-11-02 14:58:27 -04001228 if ($type ne "build") {
Steven Rostedtc23dca72011-03-08 09:26:31 -05001229 bisect_reboot;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001230 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001231 } else {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001232 $result = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001233 }
Steven Rostedt0a05c762010-11-08 11:14:10 -05001234 $in_bisect = 0;
1235
1236 return $result;
1237}
1238
1239sub run_bisect {
1240 my ($type) = @_;
1241 my $buildtype = "oldconfig";
1242
1243 # We should have a minconfig to use?
1244 if (defined($minconfig)) {
1245 $buildtype = "useconfig:$minconfig";
1246 }
1247
1248 my $ret = run_bisect_test $type, $buildtype;
1249
Steven Rostedtc960bb92011-03-08 09:22:39 -05001250 if ($bisect_manual) {
1251 $ret = answer_bisect;
1252 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001253
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04001254 # Are we looking for where it worked, not failed?
1255 if ($reverse_bisect) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001256 $ret = !$ret;
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04001257 }
1258
Steven Rostedtc23dca72011-03-08 09:26:31 -05001259 if ($ret > 0) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001260 return "good";
Steven Rostedtc23dca72011-03-08 09:26:31 -05001261 } elsif ($ret == 0) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001262 return "bad";
Steven Rostedtc23dca72011-03-08 09:26:31 -05001263 } elsif ($bisect_skip) {
1264 doprint "HIT A BAD COMMIT ... SKIPPING\n";
1265 return "skip";
Steven Rostedt0a05c762010-11-08 11:14:10 -05001266 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001267}
1268
1269sub bisect {
1270 my ($i) = @_;
1271
1272 my $result;
1273
1274 die "BISECT_GOOD[$i] not defined\n" if (!defined($opt{"BISECT_GOOD[$i]"}));
1275 die "BISECT_BAD[$i] not defined\n" if (!defined($opt{"BISECT_BAD[$i]"}));
1276 die "BISECT_TYPE[$i] not defined\n" if (!defined($opt{"BISECT_TYPE[$i]"}));
1277
1278 my $good = $opt{"BISECT_GOOD[$i]"};
1279 my $bad = $opt{"BISECT_BAD[$i]"};
1280 my $type = $opt{"BISECT_TYPE[$i]"};
Steven Rostedta75fece2010-11-02 14:58:27 -04001281 my $start = $opt{"BISECT_START[$i]"};
1282 my $replay = $opt{"BISECT_REPLAY[$i]"};
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001283
Steven Rostedta57419b2010-11-02 15:13:54 -04001284 # convert to true sha1's
1285 $good = get_sha1($good);
1286 $bad = get_sha1($bad);
1287
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04001288 if (defined($opt{"BISECT_REVERSE[$i]"}) &&
1289 $opt{"BISECT_REVERSE[$i]"} == 1) {
1290 doprint "Performing a reverse bisect (bad is good, good is bad!)\n";
1291 $reverse_bisect = 1;
1292 } else {
1293 $reverse_bisect = 0;
1294 }
1295
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001296 # Can't have a test without having a test to run
1297 if ($type eq "test" && !defined($run_test)) {
1298 $type = "boot";
1299 }
1300
Steven Rostedta75fece2010-11-02 14:58:27 -04001301 my $check = $opt{"BISECT_CHECK[$i]"};
1302 if (defined($check) && $check ne "0") {
1303
1304 # get current HEAD
Steven Rostedta57419b2010-11-02 15:13:54 -04001305 my $head = get_sha1("HEAD");
Steven Rostedta75fece2010-11-02 14:58:27 -04001306
1307 if ($check ne "good") {
1308 doprint "TESTING BISECT BAD [$bad]\n";
1309 run_command "git checkout $bad" or
1310 die "Failed to checkout $bad";
1311
1312 $result = run_bisect $type;
1313
1314 if ($result ne "bad") {
1315 fail "Tested BISECT_BAD [$bad] and it succeeded" and return 0;
1316 }
1317 }
1318
1319 if ($check ne "bad") {
1320 doprint "TESTING BISECT GOOD [$good]\n";
1321 run_command "git checkout $good" or
1322 die "Failed to checkout $good";
1323
1324 $result = run_bisect $type;
1325
1326 if ($result ne "good") {
1327 fail "Tested BISECT_GOOD [$good] and it failed" and return 0;
1328 }
1329 }
1330
1331 # checkout where we started
1332 run_command "git checkout $head" or
1333 die "Failed to checkout $head";
1334 }
1335
1336 run_command "git bisect start" or
1337 dodie "could not start bisect";
1338
1339 run_command "git bisect good $good" or
1340 dodie "could not set bisect good to $good";
1341
1342 run_git_bisect "git bisect bad $bad" or
1343 dodie "could not set bisect bad to $bad";
1344
1345 if (defined($replay)) {
1346 run_command "git bisect replay $replay" or
1347 dodie "failed to run replay";
1348 }
1349
1350 if (defined($start)) {
1351 run_command "git checkout $start" or
1352 dodie "failed to checkout $start";
1353 }
1354
1355 my $test;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001356 do {
1357 $result = run_bisect $type;
Steven Rostedta75fece2010-11-02 14:58:27 -04001358 $test = run_git_bisect "git bisect $result";
1359 } while ($test);
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001360
1361 run_command "git bisect log" or
1362 dodie "could not capture git bisect log";
1363
1364 run_command "git bisect reset" or
1365 dodie "could not reset git bisect";
1366
1367 doprint "Bad commit was [$bisect_bad]\n";
1368
Steven Rostedt0a05c762010-11-08 11:14:10 -05001369 success $i;
1370}
1371
1372my %config_ignore;
1373my %config_set;
1374
1375my %config_list;
1376my %null_config;
1377
1378my %dependency;
1379
1380sub process_config_ignore {
1381 my ($config) = @_;
1382
1383 open (IN, $config)
1384 or dodie "Failed to read $config";
1385
1386 while (<IN>) {
1387 if (/^(.*?(CONFIG\S*)(=.*| is not set))/) {
1388 $config_ignore{$2} = $1;
1389 }
1390 }
1391
1392 close(IN);
1393}
1394
1395sub read_current_config {
1396 my ($config_ref) = @_;
1397
1398 %{$config_ref} = ();
1399 undef %{$config_ref};
1400
1401 my @key = keys %{$config_ref};
1402 if ($#key >= 0) {
1403 print "did not delete!\n";
1404 exit;
1405 }
1406 open (IN, "$output_config");
1407
1408 while (<IN>) {
1409 if (/^(CONFIG\S+)=(.*)/) {
1410 ${$config_ref}{$1} = $2;
1411 }
1412 }
1413 close(IN);
1414}
1415
1416sub get_dependencies {
1417 my ($config) = @_;
1418
1419 my $arr = $dependency{$config};
1420 if (!defined($arr)) {
1421 return ();
1422 }
1423
1424 my @deps = @{$arr};
1425
1426 foreach my $dep (@{$arr}) {
1427 print "ADD DEP $dep\n";
1428 @deps = (@deps, get_dependencies $dep);
1429 }
1430
1431 return @deps;
1432}
1433
1434sub create_config {
1435 my @configs = @_;
1436
1437 open(OUT, ">$output_config") or dodie "Can not write to $output_config";
1438
1439 foreach my $config (@configs) {
1440 print OUT "$config_set{$config}\n";
1441 my @deps = get_dependencies $config;
1442 foreach my $dep (@deps) {
1443 print OUT "$config_set{$dep}\n";
1444 }
1445 }
1446
1447 foreach my $config (keys %config_ignore) {
1448 print OUT "$config_ignore{$config}\n";
1449 }
1450 close(OUT);
1451
1452# exit;
Steven Rostedt612b9e92011-03-07 13:27:43 -05001453 make_oldconfig "";
Steven Rostedt0a05c762010-11-08 11:14:10 -05001454}
1455
1456sub compare_configs {
1457 my (%a, %b) = @_;
1458
1459 foreach my $item (keys %a) {
1460 if (!defined($b{$item})) {
1461 print "diff $item\n";
1462 return 1;
1463 }
1464 delete $b{$item};
1465 }
1466
1467 my @keys = keys %b;
1468 if ($#keys) {
1469 print "diff2 $keys[0]\n";
1470 }
1471 return -1 if ($#keys >= 0);
1472
1473 return 0;
1474}
1475
1476sub run_config_bisect_test {
1477 my ($type) = @_;
1478
1479 return run_bisect_test $type, "oldconfig";
1480}
1481
1482sub process_passed {
1483 my (%configs) = @_;
1484
1485 doprint "These configs had no failure: (Enabling them for further compiles)\n";
1486 # Passed! All these configs are part of a good compile.
1487 # Add them to the min options.
1488 foreach my $config (keys %configs) {
1489 if (defined($config_list{$config})) {
1490 doprint " removing $config\n";
1491 $config_ignore{$config} = $config_list{$config};
1492 delete $config_list{$config};
1493 }
1494 }
Steven Rostedtf1a27852010-11-11 11:34:38 -05001495 doprint "config copied to $outputdir/config_good\n";
1496 run_command "cp -f $output_config $outputdir/config_good";
Steven Rostedt0a05c762010-11-08 11:14:10 -05001497}
1498
1499sub process_failed {
1500 my ($config) = @_;
1501
1502 doprint "\n\n***************************************\n";
1503 doprint "Found bad config: $config\n";
1504 doprint "***************************************\n\n";
1505}
1506
1507sub run_config_bisect {
1508
1509 my @start_list = keys %config_list;
1510
1511 if ($#start_list < 0) {
1512 doprint "No more configs to test!!!\n";
1513 return -1;
1514 }
1515
1516 doprint "***** RUN TEST ***\n";
1517 my $type = $opt{"CONFIG_BISECT_TYPE[$iteration]"};
1518 my $ret;
1519 my %current_config;
1520
1521 my $count = $#start_list + 1;
1522 doprint " $count configs to test\n";
1523
1524 my $half = int($#start_list / 2);
1525
1526 do {
1527 my @tophalf = @start_list[0 .. $half];
1528
1529 create_config @tophalf;
1530 read_current_config \%current_config;
1531
1532 $count = $#tophalf + 1;
1533 doprint "Testing $count configs\n";
1534 my $found = 0;
1535 # make sure we test something
1536 foreach my $config (@tophalf) {
1537 if (defined($current_config{$config})) {
1538 logit " $config\n";
1539 $found = 1;
1540 }
1541 }
1542 if (!$found) {
1543 # try the other half
1544 doprint "Top half produced no set configs, trying bottom half\n";
1545 @tophalf = @start_list[$half .. $#start_list];
1546 create_config @tophalf;
1547 read_current_config \%current_config;
1548 foreach my $config (@tophalf) {
1549 if (defined($current_config{$config})) {
1550 logit " $config\n";
1551 $found = 1;
1552 }
1553 }
1554 if (!$found) {
1555 doprint "Failed: Can't make new config with current configs\n";
1556 foreach my $config (@start_list) {
1557 doprint " CONFIG: $config\n";
1558 }
1559 return -1;
1560 }
1561 $count = $#tophalf + 1;
1562 doprint "Testing $count configs\n";
1563 }
1564
1565 $ret = run_config_bisect_test $type;
Steven Rostedtc960bb92011-03-08 09:22:39 -05001566 if ($bisect_manual) {
1567 $ret = answer_bisect;
1568 }
Steven Rostedt0a05c762010-11-08 11:14:10 -05001569 if ($ret) {
1570 process_passed %current_config;
1571 return 0;
1572 }
1573
1574 doprint "This config had a failure.\n";
1575 doprint "Removing these configs that were not set in this config:\n";
Steven Rostedtf1a27852010-11-11 11:34:38 -05001576 doprint "config copied to $outputdir/config_bad\n";
1577 run_command "cp -f $output_config $outputdir/config_bad";
Steven Rostedt0a05c762010-11-08 11:14:10 -05001578
1579 # A config exists in this group that was bad.
1580 foreach my $config (keys %config_list) {
1581 if (!defined($current_config{$config})) {
1582 doprint " removing $config\n";
1583 delete $config_list{$config};
1584 }
1585 }
1586
1587 @start_list = @tophalf;
1588
1589 if ($#start_list == 0) {
1590 process_failed $start_list[0];
1591 return 1;
1592 }
1593
1594 # remove half the configs we are looking at and see if
1595 # they are good.
1596 $half = int($#start_list / 2);
1597 } while ($half > 0);
1598
Steven Rostedtc960bb92011-03-08 09:22:39 -05001599 # we found a single config, try it again unless we are running manually
1600
1601 if ($bisect_manual) {
1602 process_failed $start_list[0];
1603 return 1;
1604 }
1605
Steven Rostedt0a05c762010-11-08 11:14:10 -05001606 my @tophalf = @start_list[0 .. 0];
1607
1608 $ret = run_config_bisect_test $type;
1609 if ($ret) {
1610 process_passed %current_config;
1611 return 0;
1612 }
1613
1614 process_failed $start_list[0];
1615 return 1;
1616}
1617
1618sub config_bisect {
1619 my ($i) = @_;
1620
1621 my $start_config = $opt{"CONFIG_BISECT[$i]"};
1622
1623 my $tmpconfig = "$tmpdir/use_config";
1624
1625 # Make the file with the bad config and the min config
1626 if (defined($minconfig)) {
1627 # read the min config for things to ignore
1628 run_command "cp $minconfig $tmpconfig" or
1629 dodie "failed to copy $minconfig to $tmpconfig";
1630 } else {
1631 unlink $tmpconfig;
1632 }
1633
1634 # Add other configs
1635 if (defined($addconfig)) {
1636 run_command "cat $addconfig >> $tmpconfig" or
1637 dodie "failed to append $addconfig";
1638 }
1639
1640 my $defconfig = "";
1641 if (-f $tmpconfig) {
1642 $defconfig = "KCONFIG_ALLCONFIG=$tmpconfig";
1643 process_config_ignore $tmpconfig;
1644 }
1645
1646 # now process the start config
1647 run_command "cp $start_config $output_config" or
1648 dodie "failed to copy $start_config to $output_config";
1649
1650 # read directly what we want to check
1651 my %config_check;
1652 open (IN, $output_config)
1653 or dodie "faied to open $output_config";
1654
1655 while (<IN>) {
1656 if (/^((CONFIG\S*)=.*)/) {
1657 $config_check{$2} = $1;
1658 }
1659 }
1660 close(IN);
1661
1662 # Now run oldconfig with the minconfig (and addconfigs)
Steven Rostedt612b9e92011-03-07 13:27:43 -05001663 make_oldconfig $defconfig;
Steven Rostedt0a05c762010-11-08 11:14:10 -05001664
1665 # check to see what we lost (or gained)
1666 open (IN, $output_config)
1667 or dodie "Failed to read $start_config";
1668
1669 my %removed_configs;
1670 my %added_configs;
1671
1672 while (<IN>) {
1673 if (/^((CONFIG\S*)=.*)/) {
1674 # save off all options
1675 $config_set{$2} = $1;
1676 if (defined($config_check{$2})) {
1677 if (defined($config_ignore{$2})) {
1678 $removed_configs{$2} = $1;
1679 } else {
1680 $config_list{$2} = $1;
1681 }
1682 } elsif (!defined($config_ignore{$2})) {
1683 $added_configs{$2} = $1;
1684 $config_list{$2} = $1;
1685 }
1686 }
1687 }
1688 close(IN);
1689
1690 my @confs = keys %removed_configs;
1691 if ($#confs >= 0) {
1692 doprint "Configs overridden by default configs and removed from check:\n";
1693 foreach my $config (@confs) {
1694 doprint " $config\n";
1695 }
1696 }
1697 @confs = keys %added_configs;
1698 if ($#confs >= 0) {
1699 doprint "Configs appearing in make oldconfig and added:\n";
1700 foreach my $config (@confs) {
1701 doprint " $config\n";
1702 }
1703 }
1704
1705 my %config_test;
1706 my $once = 0;
1707
1708 # Sometimes kconfig does weird things. We must make sure
1709 # that the config we autocreate has everything we need
1710 # to test, otherwise we may miss testing configs, or
1711 # may not be able to create a new config.
1712 # Here we create a config with everything set.
1713 create_config (keys %config_list);
1714 read_current_config \%config_test;
1715 foreach my $config (keys %config_list) {
1716 if (!defined($config_test{$config})) {
1717 if (!$once) {
1718 $once = 1;
1719 doprint "Configs not produced by kconfig (will not be checked):\n";
1720 }
1721 doprint " $config\n";
1722 delete $config_list{$config};
1723 }
1724 }
1725 my $ret;
1726 do {
1727 $ret = run_config_bisect;
1728 } while (!$ret);
1729
1730 return $ret if ($ret < 0);
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001731
1732 success $i;
1733}
1734
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001735sub patchcheck {
1736 my ($i) = @_;
1737
1738 die "PATCHCHECK_START[$i] not defined\n"
1739 if (!defined($opt{"PATCHCHECK_START[$i]"}));
1740 die "PATCHCHECK_TYPE[$i] not defined\n"
1741 if (!defined($opt{"PATCHCHECK_TYPE[$i]"}));
1742
1743 my $start = $opt{"PATCHCHECK_START[$i]"};
1744
1745 my $end = "HEAD";
1746 if (defined($opt{"PATCHCHECK_END[$i]"})) {
1747 $end = $opt{"PATCHCHECK_END[$i]"};
1748 }
1749
Steven Rostedta57419b2010-11-02 15:13:54 -04001750 # Get the true sha1's since we can use things like HEAD~3
1751 $start = get_sha1($start);
1752 $end = get_sha1($end);
1753
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001754 my $type = $opt{"PATCHCHECK_TYPE[$i]"};
1755
1756 # Can't have a test without having a test to run
1757 if ($type eq "test" && !defined($run_test)) {
1758 $type = "boot";
1759 }
1760
1761 open (IN, "git log --pretty=oneline $end|") or
1762 dodie "could not get git list";
1763
1764 my @list;
1765
1766 while (<IN>) {
1767 chomp;
1768 $list[$#list+1] = $_;
1769 last if (/^$start/);
1770 }
1771 close(IN);
1772
1773 if ($list[$#list] !~ /^$start/) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001774 fail "SHA1 $start not found";
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001775 }
1776
1777 # go backwards in the list
1778 @list = reverse @list;
1779
1780 my $save_clean = $noclean;
1781
1782 $in_patchcheck = 1;
1783 foreach my $item (@list) {
1784 my $sha1 = $item;
1785 $sha1 =~ s/^([[:xdigit:]]+).*/$1/;
1786
1787 doprint "\nProcessing commit $item\n\n";
1788
1789 run_command "git checkout $sha1" or
1790 die "Failed to checkout $sha1";
1791
1792 # only clean on the first and last patch
1793 if ($item eq $list[0] ||
1794 $item eq $list[$#list]) {
1795 $noclean = $save_clean;
1796 } else {
1797 $noclean = 1;
1798 }
1799
1800 if (defined($minconfig)) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001801 build "useconfig:$minconfig" or return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001802 } else {
1803 # ?? no config to use?
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001804 build "oldconfig" or return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001805 }
1806
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001807 check_buildlog $sha1 or return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001808
1809 next if ($type eq "build");
1810
1811 get_grub_index;
1812 get_version;
1813 install;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001814
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001815 my $failed = 0;
1816
1817 start_monitor;
1818 monitor or $failed = 1;
1819
1820 if (!$failed && $type ne "boot"){
1821 do_run_test or $failed = 1;
1822 }
1823 end_monitor;
1824 return 0 if ($failed);
1825
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001826 }
1827 $in_patchcheck = 0;
1828 success $i;
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001829
1830 return 1;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001831}
1832
Steven Rostedt8d1491b2010-11-18 15:39:48 -05001833$#ARGV < 1 or die "ktest.pl version: $VERSION\n usage: ktest.pl config-file\n";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001834
Steven Rostedt8d1491b2010-11-18 15:39:48 -05001835if ($#ARGV == 0) {
1836 $ktest_config = $ARGV[0];
1837 if (! -f $ktest_config) {
1838 print "$ktest_config does not exist.\n";
1839 my $ans;
1840 for (;;) {
1841 print "Create it? [Y/n] ";
1842 $ans = <STDIN>;
1843 chomp $ans;
1844 if ($ans =~ /^\s*$/) {
1845 $ans = "y";
1846 }
1847 last if ($ans =~ /^y$/i || $ans =~ /^n$/i);
1848 print "Please answer either 'y' or 'n'.\n";
1849 }
1850 if ($ans !~ /^y$/i) {
1851 exit 0;
1852 }
1853 }
1854} else {
1855 $ktest_config = "ktest.conf";
1856}
1857
1858if (! -f $ktest_config) {
1859 open(OUT, ">$ktest_config") or die "Can not create $ktest_config";
1860 print OUT << "EOF"
1861# Generated by ktest.pl
1862#
1863# Define each test with TEST_START
1864# The config options below it will override the defaults
1865TEST_START
1866
1867DEFAULTS
1868EOF
1869;
1870 close(OUT);
1871}
1872read_config $ktest_config;
1873
1874# Append any configs entered in manually to the config file.
1875my @new_configs = keys %entered_configs;
1876if ($#new_configs >= 0) {
1877 print "\nAppending entered in configs to $ktest_config\n";
1878 open(OUT, ">>$ktest_config") or die "Can not append to $ktest_config";
1879 foreach my $config (@new_configs) {
1880 print OUT "$config = $entered_configs{$config}\n";
1881 $opt{$config} = $entered_configs{$config};
1882 }
1883}
Steven Rostedt2545eb62010-11-02 15:01:32 -04001884
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001885if ($opt{"CLEAR_LOG"} && defined($opt{"LOG_FILE"})) {
1886 unlink $opt{"LOG_FILE"};
1887}
Steven Rostedt2545eb62010-11-02 15:01:32 -04001888
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001889doprint "\n\nSTARTING AUTOMATED TESTS\n\n";
1890
Steven Rostedta57419b2010-11-02 15:13:54 -04001891for (my $i = 0, my $repeat = 1; $i <= $opt{"NUM_TESTS"}; $i += $repeat) {
1892
1893 if (!$i) {
1894 doprint "DEFAULT OPTIONS:\n";
1895 } else {
1896 doprint "\nTEST $i OPTIONS";
1897 if (defined($repeat_tests{$i})) {
1898 $repeat = $repeat_tests{$i};
1899 doprint " ITERATE $repeat";
1900 }
1901 doprint "\n";
1902 }
1903
1904 foreach my $option (sort keys %opt) {
1905
1906 if ($option =~ /\[(\d+)\]$/) {
1907 next if ($i != $1);
1908 } else {
1909 next if ($i);
1910 }
1911
1912 doprint "$option = $opt{$option}\n";
1913 }
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001914}
Steven Rostedt2545eb62010-11-02 15:01:32 -04001915
Steven Rostedta75fece2010-11-02 14:58:27 -04001916sub set_test_option {
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001917 my ($name, $i) = @_;
1918
1919 my $option = "$name\[$i\]";
1920
1921 if (defined($opt{$option})) {
1922 return $opt{$option};
1923 }
1924
Steven Rostedta57419b2010-11-02 15:13:54 -04001925 foreach my $test (keys %repeat_tests) {
1926 if ($i >= $test &&
1927 $i < $test + $repeat_tests{$test}) {
1928 $option = "$name\[$test\]";
1929 if (defined($opt{$option})) {
1930 return $opt{$option};
1931 }
1932 }
1933 }
1934
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001935 if (defined($opt{$name})) {
1936 return $opt{$name};
1937 }
1938
1939 return undef;
1940}
1941
Steven Rostedt2545eb62010-11-02 15:01:32 -04001942# First we need to do is the builds
Steven Rostedta75fece2010-11-02 14:58:27 -04001943for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
Steven Rostedt2545eb62010-11-02 15:01:32 -04001944
Steven Rostedt576f6272010-11-02 14:58:38 -04001945 $iteration = $i;
1946
Steven Rostedta75fece2010-11-02 14:58:27 -04001947 my $makecmd = set_test_option("MAKE_CMD", $i);
1948
1949 $machine = set_test_option("MACHINE", $i);
Steven Rostedte48c5292010-11-02 14:35:37 -04001950 $ssh_user = set_test_option("SSH_USER", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04001951 $tmpdir = set_test_option("TMP_DIR", $i);
1952 $outputdir = set_test_option("OUTPUT_DIR", $i);
1953 $builddir = set_test_option("BUILD_DIR", $i);
1954 $test_type = set_test_option("TEST_TYPE", $i);
1955 $build_type = set_test_option("BUILD_TYPE", $i);
1956 $build_options = set_test_option("BUILD_OPTIONS", $i);
1957 $power_cycle = set_test_option("POWER_CYCLE", $i);
Steven Rostedte48c5292010-11-02 14:35:37 -04001958 $reboot = set_test_option("REBOOT", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04001959 $noclean = set_test_option("BUILD_NOCLEAN", $i);
1960 $minconfig = set_test_option("MIN_CONFIG", $i);
1961 $run_test = set_test_option("TEST", $i);
1962 $addconfig = set_test_option("ADD_CONFIG", $i);
1963 $reboot_type = set_test_option("REBOOT_TYPE", $i);
1964 $grub_menu = set_test_option("GRUB_MENU", $i);
Steven Rostedt8b37ca82010-11-02 14:58:33 -04001965 $post_install = set_test_option("POST_INSTALL", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04001966 $reboot_script = set_test_option("REBOOT_SCRIPT", $i);
1967 $reboot_on_error = set_test_option("REBOOT_ON_ERROR", $i);
1968 $poweroff_on_error = set_test_option("POWEROFF_ON_ERROR", $i);
1969 $die_on_failure = set_test_option("DIE_ON_FAILURE", $i);
1970 $power_off = set_test_option("POWER_OFF", $i);
Steven Rostedt576f6272010-11-02 14:58:38 -04001971 $powercycle_after_reboot = set_test_option("POWERCYCLE_AFTER_REBOOT", $i);
1972 $poweroff_after_halt = set_test_option("POWEROFF_AFTER_HALT", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04001973 $sleep_time = set_test_option("SLEEP_TIME", $i);
1974 $bisect_sleep_time = set_test_option("BISECT_SLEEP_TIME", $i);
Steven Rostedtc960bb92011-03-08 09:22:39 -05001975 $bisect_manual = set_test_option("BISECT_MANUAL", $i);
Steven Rostedtc23dca72011-03-08 09:26:31 -05001976 $bisect_skip = set_test_option("BISECT_SKIP", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04001977 $store_failures = set_test_option("STORE_FAILURES", $i);
1978 $timeout = set_test_option("TIMEOUT", $i);
1979 $booted_timeout = set_test_option("BOOTED_TIMEOUT", $i);
1980 $console = set_test_option("CONSOLE", $i);
1981 $success_line = set_test_option("SUCCESS_LINE", $i);
Steven Rostedt1c8a6172010-11-09 12:55:40 -05001982 $stop_after_success = set_test_option("STOP_AFTER_SUCCESS", $i);
1983 $stop_after_failure = set_test_option("STOP_AFTER_FAILURE", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04001984 $build_target = set_test_option("BUILD_TARGET", $i);
Steven Rostedte48c5292010-11-02 14:35:37 -04001985 $ssh_exec = set_test_option("SSH_EXEC", $i);
1986 $scp_to_target = set_test_option("SCP_TO_TARGET", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04001987 $target_image = set_test_option("TARGET_IMAGE", $i);
1988 $localversion = set_test_option("LOCALVERSION", $i);
1989
1990 chdir $builddir || die "can't change directory to $builddir";
1991
1992 if (!-d $tmpdir) {
1993 mkpath($tmpdir) or
1994 die "can't create $tmpdir";
1995 }
1996
Steven Rostedte48c5292010-11-02 14:35:37 -04001997 $ENV{"SSH_USER"} = $ssh_user;
1998 $ENV{"MACHINE"} = $machine;
1999
Steven Rostedta75fece2010-11-02 14:58:27 -04002000 $target = "$ssh_user\@$machine";
2001
2002 $buildlog = "$tmpdir/buildlog-$machine";
2003 $dmesg = "$tmpdir/dmesg-$machine";
2004 $make = "$makecmd O=$outputdir";
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05002005 $output_config = "$outputdir/.config";
Steven Rostedta75fece2010-11-02 14:58:27 -04002006
2007 if ($reboot_type eq "grub") {
Steven Rostedt576f6272010-11-02 14:58:38 -04002008 dodie "GRUB_MENU not defined" if (!defined($grub_menu));
Steven Rostedta75fece2010-11-02 14:58:27 -04002009 } elsif (!defined($reboot_script)) {
Steven Rostedt576f6272010-11-02 14:58:38 -04002010 dodie "REBOOT_SCRIPT not defined"
Steven Rostedta75fece2010-11-02 14:58:27 -04002011 }
2012
2013 my $run_type = $build_type;
2014 if ($test_type eq "patchcheck") {
2015 $run_type = $opt{"PATCHCHECK_TYPE[$i]"};
2016 } elsif ($test_type eq "bisect") {
2017 $run_type = $opt{"BISECT_TYPE[$i]"};
Steven Rostedt0a05c762010-11-08 11:14:10 -05002018 } elsif ($test_type eq "config_bisect") {
2019 $run_type = $opt{"CONFIG_BISECT_TYPE[$i]"};
Steven Rostedta75fece2010-11-02 14:58:27 -04002020 }
2021
2022 # mistake in config file?
2023 if (!defined($run_type)) {
2024 $run_type = "ERROR";
2025 }
Steven Rostedt2545eb62010-11-02 15:01:32 -04002026
2027 doprint "\n\n";
Steven Rostedta75fece2010-11-02 14:58:27 -04002028 doprint "RUNNING TEST $i of $opt{NUM_TESTS} with option $test_type $run_type\n\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -04002029
2030 unlink $dmesg;
2031 unlink $buildlog;
Steven Rostedt2545eb62010-11-02 15:01:32 -04002032
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002033 if (!defined($minconfig)) {
2034 $minconfig = $addconfig;
2035
2036 } elsif (defined($addconfig)) {
Steven Rostedt9be2e6b2010-11-09 12:20:21 -05002037 run_command "cat $addconfig $minconfig > $tmpdir/add_config" or
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002038 dodie "Failed to create temp config";
Steven Rostedt9be2e6b2010-11-09 12:20:21 -05002039 $minconfig = "$tmpdir/add_config";
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002040 }
2041
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002042 my $checkout = $opt{"CHECKOUT[$i]"};
2043 if (defined($checkout)) {
2044 run_command "git checkout $checkout" or
2045 die "failed to checkout $checkout";
2046 }
2047
Steven Rostedta75fece2010-11-02 14:58:27 -04002048 if ($test_type eq "bisect") {
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04002049 bisect $i;
2050 next;
Steven Rostedt0a05c762010-11-08 11:14:10 -05002051 } elsif ($test_type eq "config_bisect") {
2052 config_bisect $i;
2053 next;
Steven Rostedta75fece2010-11-02 14:58:27 -04002054 } elsif ($test_type eq "patchcheck") {
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002055 patchcheck $i;
2056 next;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04002057 }
2058
Steven Rostedt7faafbd2010-11-02 14:58:22 -04002059 if ($build_type ne "nobuild") {
2060 build $build_type or next;
Steven Rostedt2545eb62010-11-02 15:01:32 -04002061 }
2062
Steven Rostedta75fece2010-11-02 14:58:27 -04002063 if ($test_type ne "build") {
2064 get_grub_index;
2065 get_version;
2066 install;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04002067
Steven Rostedta75fece2010-11-02 14:58:27 -04002068 my $failed = 0;
2069 start_monitor;
2070 monitor or $failed = 1;;
2071
2072 if (!$failed && $test_type ne "boot" && defined($run_test)) {
2073 do_run_test or $failed = 1;
2074 }
2075 end_monitor;
2076 next if ($failed);
Steven Rostedt5a391fb2010-11-02 14:57:43 -04002077 }
2078
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04002079 success $i;
Steven Rostedt2545eb62010-11-02 15:01:32 -04002080}
2081
Steven Rostedt5c42fc52010-11-02 14:57:01 -04002082if ($opt{"POWEROFF_ON_SUCCESS"}) {
Steven Rostedt75c3fda72010-11-02 14:57:21 -04002083 halt;
Steven Rostedt576f6272010-11-02 14:58:38 -04002084} elsif ($opt{"REBOOT_ON_SUCCESS"} && !do_not_reboot) {
Steven Rostedt75c3fda72010-11-02 14:57:21 -04002085 reboot;
Steven Rostedt5c42fc52010-11-02 14:57:01 -04002086}
Steven Rostedt75c3fda72010-11-02 14:57:21 -04002087
Steven Rostedte48c5292010-11-02 14:35:37 -04002088doprint "\n $successes of $opt{NUM_TESTS} tests were successful\n\n";
2089
Steven Rostedt2545eb62010-11-02 15:01:32 -04002090exit 0;