blob: 2011222c89183e9fba37acdba523555ea49e8326 [file] [log] [blame]
Steven Rostedt2545eb62010-11-02 15:01:32 -04001#!/usr/bin/perl -w
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04002#
Uwe Kleine-Königcce1dac2011-01-24 21:12:01 +01003# Copyright 2010 - Steven Rostedt <srostedt@redhat.com>, Red Hat Inc.
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04004# Licensed under the terms of the GNU GPL License version 2
5#
Steven Rostedt2545eb62010-11-02 15:01:32 -04006
7use strict;
8use IPC::Open2;
9use Fcntl qw(F_GETFL F_SETFL O_NONBLOCK);
Steven Rostedt7faafbd2010-11-02 14:58:22 -040010use File::Path qw(mkpath);
11use File::Copy qw(cp);
Steven Rostedt2545eb62010-11-02 15:01:32 -040012use FileHandle;
13
Steven Rostedte48c5292010-11-02 14:35:37 -040014my $VERSION = "0.2";
15
Steven Rostedt2545eb62010-11-02 15:01:32 -040016$| = 1;
17
18my %opt;
Steven Rostedta57419b2010-11-02 15:13:54 -040019my %repeat_tests;
20my %repeats;
Steven Rostedta75fece2010-11-02 14:58:27 -040021my %default;
Steven Rostedt2545eb62010-11-02 15:01:32 -040022
23#default opts
Steven Rostedta57419b2010-11-02 15:13:54 -040024$default{"NUM_TESTS"} = 1;
Steven Rostedta75fece2010-11-02 14:58:27 -040025$default{"REBOOT_TYPE"} = "grub";
26$default{"TEST_TYPE"} = "test";
27$default{"BUILD_TYPE"} = "randconfig";
28$default{"MAKE_CMD"} = "make";
29$default{"TIMEOUT"} = 120;
Steven 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 Rostedt2d01b262011-03-08 09:47:54 -050050$default{"STOP_TEST_AFTER"} = 600;
Steven Rostedt8d1491b2010-11-18 15:39:48 -050051$default{"LOCALVERSION"} = "-test";
Steven Rostedt2545eb62010-11-02 15:01:32 -040052
Steven Rostedt8d1491b2010-11-18 15:39:48 -050053my $ktest_config;
Steven Rostedt2545eb62010-11-02 15:01:32 -040054my $version;
Steven Rostedta75fece2010-11-02 14:58:27 -040055my $machine;
Steven Rostedte48c5292010-11-02 14:35:37 -040056my $ssh_user;
Steven Rostedta75fece2010-11-02 14:58:27 -040057my $tmpdir;
58my $builddir;
59my $outputdir;
Steven Rostedt51ad1dd2010-11-08 16:43:21 -050060my $output_config;
Steven Rostedta75fece2010-11-02 14:58:27 -040061my $test_type;
Steven Rostedt7faafbd2010-11-02 14:58:22 -040062my $build_type;
Steven Rostedta75fece2010-11-02 14:58:27 -040063my $build_options;
64my $reboot_type;
65my $reboot_script;
66my $power_cycle;
Steven Rostedte48c5292010-11-02 14:35:37 -040067my $reboot;
Steven Rostedta75fece2010-11-02 14:58:27 -040068my $reboot_on_error;
69my $poweroff_on_error;
70my $die_on_failure;
Steven Rostedt576f6272010-11-02 14:58:38 -040071my $powercycle_after_reboot;
72my $poweroff_after_halt;
Steven Rostedte48c5292010-11-02 14:35:37 -040073my $ssh_exec;
74my $scp_to_target;
Steven Rostedta75fece2010-11-02 14:58:27 -040075my $power_off;
76my $grub_menu;
Steven Rostedt2545eb62010-11-02 15:01:32 -040077my $grub_number;
78my $target;
79my $make;
Steven Rostedt8b37ca82010-11-02 14:58:33 -040080my $post_install;
Steven Rostedt5c42fc52010-11-02 14:57:01 -040081my $noclean;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -040082my $minconfig;
Steven Rostedt2b7d9b22010-11-02 14:58:15 -040083my $addconfig;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -040084my $in_bisect = 0;
85my $bisect_bad = "";
Steven Rostedtd6ce2a02010-11-02 14:58:05 -040086my $reverse_bisect;
Steven Rostedtc960bb92011-03-08 09:22:39 -050087my $bisect_manual;
Steven Rostedtc23dca72011-03-08 09:26:31 -050088my $bisect_skip;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -040089my $in_patchcheck = 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -040090my $run_test;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -040091my $redirect;
Steven Rostedt7faafbd2010-11-02 14:58:22 -040092my $buildlog;
93my $dmesg;
94my $monitor_fp;
95my $monitor_pid;
96my $monitor_cnt = 0;
Steven Rostedta75fece2010-11-02 14:58:27 -040097my $sleep_time;
98my $bisect_sleep_time;
99my $store_failures;
100my $timeout;
101my $booted_timeout;
102my $console;
103my $success_line;
Steven Rostedt1c8a6172010-11-09 12:55:40 -0500104my $stop_after_success;
105my $stop_after_failure;
Steven Rostedt2d01b262011-03-08 09:47:54 -0500106my $stop_test_after;
Steven Rostedta75fece2010-11-02 14:58:27 -0400107my $build_target;
108my $target_image;
109my $localversion;
Steven Rostedt576f6272010-11-02 14:58:38 -0400110my $iteration = 0;
Steven Rostedte48c5292010-11-02 14:35:37 -0400111my $successes = 0;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400112
Steven Rostedt8d1491b2010-11-18 15:39:48 -0500113my %entered_configs;
114my %config_help;
115
116$config_help{"MACHINE"} = << "EOF"
117 The machine hostname that you will test.
118EOF
119 ;
120$config_help{"SSH_USER"} = << "EOF"
121 The box is expected to have ssh on normal bootup, provide the user
122 (most likely root, since you need privileged operations)
123EOF
124 ;
125$config_help{"BUILD_DIR"} = << "EOF"
126 The directory that contains the Linux source code (full path).
127EOF
128 ;
129$config_help{"OUTPUT_DIR"} = << "EOF"
130 The directory that the objects will be built (full path).
131 (can not be same as BUILD_DIR)
132EOF
133 ;
134$config_help{"BUILD_TARGET"} = << "EOF"
135 The location of the compiled file to copy to the target.
136 (relative to OUTPUT_DIR)
137EOF
138 ;
139$config_help{"TARGET_IMAGE"} = << "EOF"
140 The place to put your image on the test machine.
141EOF
142 ;
143$config_help{"POWER_CYCLE"} = << "EOF"
144 A script or command to reboot the box.
145
146 Here is a digital loggers power switch example
147 POWER_CYCLE = wget --no-proxy -O /dev/null -q --auth-no-challenge 'http://admin:admin\@power/outlet?5=CCL'
148
149 Here is an example to reboot a virtual box on the current host
150 with the name "Guest".
151 POWER_CYCLE = virsh destroy Guest; sleep 5; virsh start Guest
152EOF
153 ;
154$config_help{"CONSOLE"} = << "EOF"
155 The script or command that reads the console
156
157 If you use ttywatch server, something like the following would work.
158CONSOLE = nc -d localhost 3001
159
160 For a virtual machine with guest name "Guest".
161CONSOLE = virsh console Guest
162EOF
163 ;
164$config_help{"LOCALVERSION"} = << "EOF"
165 Required version ending to differentiate the test
166 from other linux builds on the system.
167EOF
168 ;
169$config_help{"REBOOT_TYPE"} = << "EOF"
170 Way to reboot the box to the test kernel.
171 Only valid options so far are "grub" and "script".
172
173 If you specify grub, it will assume grub version 1
174 and will search in /boot/grub/menu.lst for the title \$GRUB_MENU
175 and select that target to reboot to the kernel. If this is not
176 your setup, then specify "script" and have a command or script
177 specified in REBOOT_SCRIPT to boot to the target.
178
179 The entry in /boot/grub/menu.lst must be entered in manually.
180 The test will not modify that file.
181EOF
182 ;
183$config_help{"GRUB_MENU"} = << "EOF"
184 The grub title name for the test kernel to boot
185 (Only mandatory if REBOOT_TYPE = grub)
186
187 Note, ktest.pl will not update the grub menu.lst, you need to
188 manually add an option for the test. ktest.pl will search
189 the grub menu.lst for this option to find what kernel to
190 reboot into.
191
192 For example, if in the /boot/grub/menu.lst the test kernel title has:
193 title Test Kernel
194 kernel vmlinuz-test
195 GRUB_MENU = Test Kernel
196EOF
197 ;
198$config_help{"REBOOT_SCRIPT"} = << "EOF"
199 A script to reboot the target into the test kernel
200 (Only mandatory if REBOOT_TYPE = script)
201EOF
202 ;
203
204
205sub get_ktest_config {
206 my ($config) = @_;
207
208 return if (defined($opt{$config}));
209
210 if (defined($config_help{$config})) {
211 print "\n";
212 print $config_help{$config};
213 }
214
215 for (;;) {
216 print "$config = ";
217 if (defined($default{$config})) {
218 print "\[$default{$config}\] ";
219 }
220 $entered_configs{$config} = <STDIN>;
221 $entered_configs{$config} =~ s/^\s*(.*\S)\s*$/$1/;
222 if ($entered_configs{$config} =~ /^\s*$/) {
223 if ($default{$config}) {
224 $entered_configs{$config} = $default{$config};
225 } else {
226 print "Your answer can not be blank\n";
227 next;
228 }
229 }
230 last;
231 }
232}
233
234sub get_ktest_configs {
235 get_ktest_config("MACHINE");
236 get_ktest_config("SSH_USER");
237 get_ktest_config("BUILD_DIR");
238 get_ktest_config("OUTPUT_DIR");
239 get_ktest_config("BUILD_TARGET");
240 get_ktest_config("TARGET_IMAGE");
241 get_ktest_config("POWER_CYCLE");
242 get_ktest_config("CONSOLE");
243 get_ktest_config("LOCALVERSION");
244
245 my $rtype = $opt{"REBOOT_TYPE"};
246
247 if (!defined($rtype)) {
248 if (!defined($opt{"GRUB_MENU"})) {
249 get_ktest_config("REBOOT_TYPE");
250 $rtype = $entered_configs{"REBOOT_TYPE"};
251 } else {
252 $rtype = "grub";
253 }
254 }
255
256 if ($rtype eq "grub") {
257 get_ktest_config("GRUB_MENU");
258 } else {
259 get_ktest_config("REBOOT_SCRIPT");
260 }
261}
262
Steven Rostedta57419b2010-11-02 15:13:54 -0400263sub set_value {
264 my ($lvalue, $rvalue) = @_;
265
266 if (defined($opt{$lvalue})) {
267 die "Error: Option $lvalue defined more than once!\n";
268 }
Steven Rostedt21a96792010-11-08 16:45:50 -0500269 if ($rvalue =~ /^\s*$/) {
270 delete $opt{$lvalue};
271 } else {
272 $opt{$lvalue} = $rvalue;
273 }
Steven Rostedta57419b2010-11-02 15:13:54 -0400274}
275
Steven Rostedt2545eb62010-11-02 15:01:32 -0400276sub read_config {
277 my ($config) = @_;
278
279 open(IN, $config) || die "can't read file $config";
280
Steven Rostedta57419b2010-11-02 15:13:54 -0400281 my $name = $config;
282 $name =~ s,.*/(.*),$1,;
283
284 my $test_num = 0;
285 my $default = 1;
286 my $repeat = 1;
287 my $num_tests_set = 0;
288 my $skip = 0;
289 my $rest;
290
Steven Rostedt2545eb62010-11-02 15:01:32 -0400291 while (<IN>) {
292
293 # ignore blank lines and comments
294 next if (/^\s*$/ || /\s*\#/);
295
Steven Rostedta57419b2010-11-02 15:13:54 -0400296 if (/^\s*TEST_START(.*)/) {
297
298 $rest = $1;
299
300 if ($num_tests_set) {
301 die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
302 }
303
304 my $old_test_num = $test_num;
Steven Rostedte48c5292010-11-02 14:35:37 -0400305 my $old_repeat = $repeat;
Steven Rostedta57419b2010-11-02 15:13:54 -0400306
307 $test_num += $repeat;
308 $default = 0;
309 $repeat = 1;
310
311 if ($rest =~ /\s+SKIP(.*)/) {
312 $rest = $1;
313 $skip = 1;
314 } else {
315 $skip = 0;
316 }
317
318 if ($rest =~ /\s+ITERATE\s+(\d+)(.*)$/) {
319 $repeat = $1;
320 $rest = $2;
321 $repeat_tests{"$test_num"} = $repeat;
322 }
323
324 if ($rest =~ /\s+SKIP(.*)/) {
325 $rest = $1;
326 $skip = 1;
327 }
328
329 if ($rest !~ /^\s*$/) {
330 die "$name: $.: Gargbage found after TEST_START\n$_";
331 }
332
333 if ($skip) {
334 $test_num = $old_test_num;
Steven Rostedte48c5292010-11-02 14:35:37 -0400335 $repeat = $old_repeat;
Steven Rostedta57419b2010-11-02 15:13:54 -0400336 }
337
338 } elsif (/^\s*DEFAULTS(.*)$/) {
339 $default = 1;
340
341 $rest = $1;
342
343 if ($rest =~ /\s+SKIP(.*)/) {
344 $rest = $1;
345 $skip = 1;
346 } else {
347 $skip = 0;
348 }
349
350 if ($rest !~ /^\s*$/) {
351 die "$name: $.: Gargbage found after DEFAULTS\n$_";
352 }
353
354 } elsif (/^\s*([A-Z_\[\]\d]+)\s*=\s*(.*?)\s*$/) {
355
356 next if ($skip);
357
Steven Rostedt2545eb62010-11-02 15:01:32 -0400358 my $lvalue = $1;
359 my $rvalue = $2;
360
Steven Rostedta57419b2010-11-02 15:13:54 -0400361 if (!$default &&
362 ($lvalue eq "NUM_TESTS" ||
363 $lvalue eq "LOG_FILE" ||
364 $lvalue eq "CLEAR_LOG")) {
365 die "$name: $.: $lvalue must be set in DEFAULTS section\n";
Steven Rostedta75fece2010-11-02 14:58:27 -0400366 }
Steven Rostedta57419b2010-11-02 15:13:54 -0400367
368 if ($lvalue eq "NUM_TESTS") {
369 if ($test_num) {
370 die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
371 }
372 if (!$default) {
373 die "$name: $.: NUM_TESTS must be set in default section\n";
374 }
375 $num_tests_set = 1;
376 }
377
378 if ($default || $lvalue =~ /\[\d+\]$/) {
379 set_value($lvalue, $rvalue);
380 } else {
381 my $val = "$lvalue\[$test_num\]";
382 set_value($val, $rvalue);
383
384 if ($repeat > 1) {
385 $repeats{$val} = $repeat;
386 }
387 }
388 } else {
389 die "$name: $.: Garbage found in config\n$_";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400390 }
391 }
392
393 close(IN);
Steven Rostedta75fece2010-11-02 14:58:27 -0400394
Steven Rostedta57419b2010-11-02 15:13:54 -0400395 if ($test_num) {
396 $test_num += $repeat - 1;
397 $opt{"NUM_TESTS"} = $test_num;
398 }
399
Steven Rostedt8d1491b2010-11-18 15:39:48 -0500400 # make sure we have all mandatory configs
401 get_ktest_configs;
402
Steven Rostedta75fece2010-11-02 14:58:27 -0400403 # set any defaults
404
405 foreach my $default (keys %default) {
406 if (!defined($opt{$default})) {
407 $opt{$default} = $default{$default};
408 }
409 }
Steven Rostedt2545eb62010-11-02 15:01:32 -0400410}
411
Steven Rostedtd1e2f222010-11-08 16:39:57 -0500412sub _logit {
Steven Rostedt2545eb62010-11-02 15:01:32 -0400413 if (defined($opt{"LOG_FILE"})) {
414 open(OUT, ">> $opt{LOG_FILE}") or die "Can't write to $opt{LOG_FILE}";
415 print OUT @_;
416 close(OUT);
417 }
418}
419
Steven Rostedtd1e2f222010-11-08 16:39:57 -0500420sub logit {
421 if (defined($opt{"LOG_FILE"})) {
422 _logit @_;
423 } else {
424 print @_;
425 }
426}
427
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400428sub doprint {
429 print @_;
Steven Rostedtd1e2f222010-11-08 16:39:57 -0500430 _logit @_;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400431}
432
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400433sub run_command;
434
435sub reboot {
436 # try to reboot normally
Steven Rostedte48c5292010-11-02 14:35:37 -0400437 if (run_command $reboot) {
Steven Rostedt576f6272010-11-02 14:58:38 -0400438 if (defined($powercycle_after_reboot)) {
439 sleep $powercycle_after_reboot;
440 run_command "$power_cycle";
441 }
442 } else {
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400443 # nope? power cycle it.
Steven Rostedta75fece2010-11-02 14:58:27 -0400444 run_command "$power_cycle";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400445 }
446}
447
Steven Rostedt576f6272010-11-02 14:58:38 -0400448sub do_not_reboot {
449 my $i = $iteration;
450
451 return $test_type eq "build" ||
452 ($test_type eq "patchcheck" && $opt{"PATCHCHECK_TYPE[$i]"} eq "build") ||
453 ($test_type eq "bisect" && $opt{"BISECT_TYPE[$i]"} eq "build");
454}
455
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400456sub dodie {
Steven Rostedt5a391fb2010-11-02 14:57:43 -0400457 doprint "CRITICAL FAILURE... ", @_, "\n";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400458
Steven Rostedt576f6272010-11-02 14:58:38 -0400459 my $i = $iteration;
460
461 if ($reboot_on_error && !do_not_reboot) {
462
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400463 doprint "REBOOTING\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400464 reboot;
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400465
Steven Rostedta75fece2010-11-02 14:58:27 -0400466 } elsif ($poweroff_on_error && defined($power_off)) {
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400467 doprint "POWERING OFF\n";
Steven Rostedta75fece2010-11-02 14:58:27 -0400468 `$power_off`;
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400469 }
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400470
Steven Rostedtf80802c2011-03-07 13:18:47 -0500471 if (defined($opt{"LOG_FILE"})) {
472 print " See $opt{LOG_FILE} for more info.\n";
473 }
474
Steven Rostedt576f6272010-11-02 14:58:38 -0400475 die @_, "\n";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400476}
477
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400478sub open_console {
479 my ($fp) = @_;
480
481 my $flags;
482
Steven Rostedta75fece2010-11-02 14:58:27 -0400483 my $pid = open($fp, "$console|") or
484 dodie "Can't open console $console";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400485
486 $flags = fcntl($fp, F_GETFL, 0) or
Steven Rostedt576f6272010-11-02 14:58:38 -0400487 dodie "Can't get flags for the socket: $!";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400488 $flags = fcntl($fp, F_SETFL, $flags | O_NONBLOCK) or
Steven Rostedt576f6272010-11-02 14:58:38 -0400489 dodie "Can't set flags for the socket: $!";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400490
491 return $pid;
492}
493
494sub close_console {
495 my ($fp, $pid) = @_;
496
497 doprint "kill child process $pid\n";
498 kill 2, $pid;
499
500 print "closing!\n";
501 close($fp);
502}
503
504sub start_monitor {
505 if ($monitor_cnt++) {
506 return;
507 }
508 $monitor_fp = \*MONFD;
509 $monitor_pid = open_console $monitor_fp;
Steven Rostedta75fece2010-11-02 14:58:27 -0400510
511 return;
512
513 open(MONFD, "Stop perl from warning about single use of MONFD");
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400514}
515
516sub end_monitor {
517 if (--$monitor_cnt) {
518 return;
519 }
520 close_console($monitor_fp, $monitor_pid);
521}
522
523sub wait_for_monitor {
524 my ($time) = @_;
525 my $line;
526
Steven Rostedta75fece2010-11-02 14:58:27 -0400527 doprint "** Wait for monitor to settle down **\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400528
529 # read the monitor and wait for the system to calm down
530 do {
531 $line = wait_for_input($monitor_fp, $time);
Steven Rostedta75fece2010-11-02 14:58:27 -0400532 print "$line" if (defined($line));
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400533 } while (defined($line));
Steven Rostedta75fece2010-11-02 14:58:27 -0400534 print "** Monitor flushed **\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400535}
536
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400537sub fail {
538
Steven Rostedta75fece2010-11-02 14:58:27 -0400539 if ($die_on_failure) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400540 dodie @_;
541 }
542
Steven Rostedta75fece2010-11-02 14:58:27 -0400543 doprint "FAILED\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400544
Steven Rostedt576f6272010-11-02 14:58:38 -0400545 my $i = $iteration;
546
Steven Rostedta75fece2010-11-02 14:58:27 -0400547 # no need to reboot for just building.
Steven Rostedt576f6272010-11-02 14:58:38 -0400548 if (!do_not_reboot) {
Steven Rostedta75fece2010-11-02 14:58:27 -0400549 doprint "REBOOTING\n";
550 reboot;
551 start_monitor;
552 wait_for_monitor $sleep_time;
553 end_monitor;
554 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400555
Steven Rostedt576f6272010-11-02 14:58:38 -0400556 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
557 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
Steven Rostedt7a849cd2010-11-08 16:49:25 -0500558 doprint "KTEST RESULT: TEST $i Failed: ", @_, "\n";
Steven Rostedt576f6272010-11-02 14:58:38 -0400559 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
560 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
Steven Rostedta75fece2010-11-02 14:58:27 -0400561
562 return 1 if (!defined($store_failures));
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400563
564 my @t = localtime;
565 my $date = sprintf "%04d%02d%02d%02d%02d%02d",
566 1900+$t[5],$t[4],$t[3],$t[2],$t[1],$t[0];
567
Steven Rostedtcccae1a2010-11-09 12:21:32 -0500568 my $type = $build_type;
569 if ($type =~ /useconfig/) {
570 $type = "useconfig";
571 }
572
573 my $dir = "$machine-$test_type-$type-fail-$date";
Steven Rostedta75fece2010-11-02 14:58:27 -0400574 my $faildir = "$store_failures/$dir";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400575
576 if (!-d $faildir) {
577 mkpath($faildir) or
Steven Rostedta75fece2010-11-02 14:58:27 -0400578 die "can't create $faildir";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400579 }
Steven Rostedt51ad1dd2010-11-08 16:43:21 -0500580 if (-f "$output_config") {
581 cp "$output_config", "$faildir/config" or
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400582 die "failed to copy .config";
583 }
584 if (-f $buildlog) {
585 cp $buildlog, "$faildir/buildlog" or
586 die "failed to move $buildlog";
587 }
588 if (-f $dmesg) {
589 cp $dmesg, "$faildir/dmesg" or
590 die "failed to move $dmesg";
591 }
592
593 doprint "*** Saved info to $faildir ***\n";
594
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400595 return 1;
596}
597
Steven Rostedt2545eb62010-11-02 15:01:32 -0400598sub run_command {
599 my ($command) = @_;
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400600 my $dolog = 0;
601 my $dord = 0;
602 my $pid;
603
Steven Rostedte48c5292010-11-02 14:35:37 -0400604 $command =~ s/\$SSH_USER/$ssh_user/g;
605 $command =~ s/\$MACHINE/$machine/g;
606
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400607 doprint("$command ... ");
608
609 $pid = open(CMD, "$command 2>&1 |") or
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400610 (fail "unable to exec $command" and return 0);
Steven Rostedt2545eb62010-11-02 15:01:32 -0400611
612 if (defined($opt{"LOG_FILE"})) {
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400613 open(LOG, ">>$opt{LOG_FILE}") or
614 dodie "failed to write to log";
615 $dolog = 1;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -0400616 }
617
618 if (defined($redirect)) {
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400619 open (RD, ">$redirect") or
620 dodie "failed to write to redirect $redirect";
621 $dord = 1;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400622 }
623
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400624 while (<CMD>) {
625 print LOG if ($dolog);
626 print RD if ($dord);
627 }
Steven Rostedt2545eb62010-11-02 15:01:32 -0400628
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400629 waitpid($pid, 0);
Steven Rostedt2545eb62010-11-02 15:01:32 -0400630 my $failed = $?;
631
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400632 close(CMD);
633 close(LOG) if ($dolog);
634 close(RD) if ($dord);
635
Steven Rostedt2545eb62010-11-02 15:01:32 -0400636 if ($failed) {
637 doprint "FAILED!\n";
638 } else {
639 doprint "SUCCESS\n";
640 }
641
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400642 return !$failed;
643}
644
Steven Rostedte48c5292010-11-02 14:35:37 -0400645sub run_ssh {
646 my ($cmd) = @_;
647 my $cp_exec = $ssh_exec;
648
649 $cp_exec =~ s/\$SSH_COMMAND/$cmd/g;
650 return run_command "$cp_exec";
651}
652
653sub run_scp {
654 my ($src, $dst) = @_;
655 my $cp_scp = $scp_to_target;
656
657 $cp_scp =~ s/\$SRC_FILE/$src/g;
658 $cp_scp =~ s/\$DST_FILE/$dst/g;
659
660 return run_command "$cp_scp";
661}
662
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400663sub get_grub_index {
664
Steven Rostedta75fece2010-11-02 14:58:27 -0400665 if ($reboot_type ne "grub") {
666 return;
667 }
Steven Rostedt5a391fb2010-11-02 14:57:43 -0400668 return if (defined($grub_number));
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400669
670 doprint "Find grub menu ... ";
671 $grub_number = -1;
Steven Rostedte48c5292010-11-02 14:35:37 -0400672
673 my $ssh_grub = $ssh_exec;
674 $ssh_grub =~ s,\$SSH_COMMAND,cat /boot/grub/menu.lst,g;
675
676 open(IN, "$ssh_grub |")
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400677 or die "unable to get menu.lst";
Steven Rostedte48c5292010-11-02 14:35:37 -0400678
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400679 while (<IN>) {
Steven Rostedta75fece2010-11-02 14:58:27 -0400680 if (/^\s*title\s+$grub_menu\s*$/) {
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400681 $grub_number++;
682 last;
683 } elsif (/^\s*title\s/) {
684 $grub_number++;
685 }
686 }
687 close(IN);
688
Steven Rostedta75fece2010-11-02 14:58:27 -0400689 die "Could not find '$grub_menu' in /boot/grub/menu on $machine"
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400690 if ($grub_number < 0);
691 doprint "$grub_number\n";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400692}
693
Steven Rostedt2545eb62010-11-02 15:01:32 -0400694sub wait_for_input
695{
696 my ($fp, $time) = @_;
697 my $rin;
698 my $ready;
699 my $line;
700 my $ch;
701
702 if (!defined($time)) {
703 $time = $timeout;
704 }
705
706 $rin = '';
707 vec($rin, fileno($fp), 1) = 1;
708 $ready = select($rin, undef, undef, $time);
709
710 $line = "";
711
712 # try to read one char at a time
713 while (sysread $fp, $ch, 1) {
714 $line .= $ch;
715 last if ($ch eq "\n");
716 }
717
718 if (!length($line)) {
719 return undef;
720 }
721
722 return $line;
723}
724
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400725sub reboot_to {
Steven Rostedta75fece2010-11-02 14:58:27 -0400726 if ($reboot_type eq "grub") {
Steven Rostedteec56462010-11-10 09:08:20 -0500727 run_ssh "'(echo \"savedefault --default=$grub_number --once\" | grub --batch; reboot)'";
Steven Rostedta75fece2010-11-02 14:58:27 -0400728 return;
729 }
730
731 run_command "$reboot_script";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400732}
733
Steven Rostedta57419b2010-11-02 15:13:54 -0400734sub get_sha1 {
735 my ($commit) = @_;
736
737 doprint "git rev-list --max-count=1 $commit ... ";
738 my $sha1 = `git rev-list --max-count=1 $commit`;
739 my $ret = $?;
740
741 logit $sha1;
742
743 if ($ret) {
744 doprint "FAILED\n";
745 dodie "Failed to get git $commit";
746 }
747
748 print "SUCCESS\n";
749
750 chomp $sha1;
751
752 return $sha1;
753}
754
Steven Rostedt5a391fb2010-11-02 14:57:43 -0400755sub monitor {
Steven Rostedt2545eb62010-11-02 15:01:32 -0400756 my $booted = 0;
757 my $bug = 0;
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400758 my $skip_call_trace = 0;
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400759 my $loops;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400760
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400761 wait_for_monitor 5;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400762
763 my $line;
764 my $full_line = "";
765
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400766 open(DMESG, "> $dmesg") or
767 die "unable to write to $dmesg";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400768
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400769 reboot_to;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400770
Steven Rostedt1c8a6172010-11-09 12:55:40 -0500771 my $success_start;
772 my $failure_start;
Steven Rostedt2d01b262011-03-08 09:47:54 -0500773 my $monitor_start = time;
774 my $done = 0;
Steven Rostedt1c8a6172010-11-09 12:55:40 -0500775
Steven Rostedt2d01b262011-03-08 09:47:54 -0500776 while (!$done) {
Steven Rostedt2545eb62010-11-02 15:01:32 -0400777
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400778 if ($booted) {
Steven Rostedta75fece2010-11-02 14:58:27 -0400779 $line = wait_for_input($monitor_fp, $booted_timeout);
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400780 } else {
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400781 $line = wait_for_input($monitor_fp);
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400782 }
Steven Rostedt2545eb62010-11-02 15:01:32 -0400783
784 last if (!defined($line));
785
786 doprint $line;
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400787 print DMESG $line;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400788
789 # we are not guaranteed to get a full line
790 $full_line .= $line;
791
Steven Rostedta75fece2010-11-02 14:58:27 -0400792 if ($full_line =~ /$success_line/) {
Steven Rostedt2545eb62010-11-02 15:01:32 -0400793 $booted = 1;
Steven Rostedt1c8a6172010-11-09 12:55:40 -0500794 $success_start = time;
795 }
796
797 if ($booted && defined($stop_after_success) &&
798 $stop_after_success >= 0) {
799 my $now = time;
800 if ($now - $success_start >= $stop_after_success) {
801 doprint "Test forced to stop after $stop_after_success seconds after success\n";
802 last;
803 }
Steven Rostedt2545eb62010-11-02 15:01:32 -0400804 }
805
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400806 if ($full_line =~ /\[ backtrace testing \]/) {
807 $skip_call_trace = 1;
808 }
809
Steven Rostedt2545eb62010-11-02 15:01:32 -0400810 if ($full_line =~ /call trace:/i) {
Steven Rostedt46519202011-03-08 09:40:31 -0500811 if (!$bug && !$skip_call_trace) {
Steven Rostedt1c8a6172010-11-09 12:55:40 -0500812 $bug = 1;
813 $failure_start = time;
814 }
815 }
816
817 if ($bug && defined($stop_after_failure) &&
818 $stop_after_failure >= 0) {
819 my $now = time;
820 if ($now - $failure_start >= $stop_after_failure) {
821 doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
822 last;
823 }
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400824 }
825
826 if ($full_line =~ /\[ end of backtrace testing \]/) {
827 $skip_call_trace = 0;
828 }
829
830 if ($full_line =~ /Kernel panic -/) {
Steven Rostedt10abf112011-03-07 13:21:00 -0500831 $failure_start = time;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400832 $bug = 1;
833 }
834
835 if ($line =~ /\n/) {
836 $full_line = "";
837 }
Steven Rostedt2d01b262011-03-08 09:47:54 -0500838
839 if ($stop_test_after > 0 && !$booted && !$bug) {
840 if (time - $monitor_start > $stop_test_after) {
Steven Rostedt4d62bf52011-05-20 09:14:35 -0400841 doprint "STOP_TEST_AFTER ($stop_test_after seconds) timed out\n";
Steven Rostedt2d01b262011-03-08 09:47:54 -0500842 $done = 1;
843 }
844 }
Steven Rostedt2545eb62010-11-02 15:01:32 -0400845 }
846
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400847 close(DMESG);
Steven Rostedt2545eb62010-11-02 15:01:32 -0400848
Steven Rostedt2545eb62010-11-02 15:01:32 -0400849 if ($bug) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400850 return 0 if ($in_bisect);
Steven Rostedt576f6272010-11-02 14:58:38 -0400851 fail "failed - got a bug report" and return 0;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400852 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400853
Steven Rostedta75fece2010-11-02 14:58:27 -0400854 if (!$booted) {
855 return 0 if ($in_bisect);
Steven Rostedt576f6272010-11-02 14:58:38 -0400856 fail "failed - never got a boot prompt." and return 0;
Steven Rostedta75fece2010-11-02 14:58:27 -0400857 }
858
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400859 return 1;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400860}
861
862sub install {
863
Steven Rostedte48c5292010-11-02 14:35:37 -0400864 run_scp "$outputdir/$build_target", "$target_image" or
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400865 dodie "failed to copy image";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400866
867 my $install_mods = 0;
868
869 # should we process modules?
870 $install_mods = 0;
Steven Rostedt51ad1dd2010-11-08 16:43:21 -0500871 open(IN, "$output_config") or dodie("Can't read config file");
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400872 while (<IN>) {
873 if (/CONFIG_MODULES(=y)?/) {
874 $install_mods = 1 if (defined($1));
875 last;
876 }
877 }
878 close(IN);
879
880 if (!$install_mods) {
881 doprint "No modules needed\n";
882 return;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400883 }
884
Steven Rostedta75fece2010-11-02 14:58:27 -0400885 run_command "$make INSTALL_MOD_PATH=$tmpdir modules_install" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400886 dodie "Failed to install modules";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400887
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400888 my $modlib = "/lib/modules/$version";
Steven Rostedta57419b2010-11-02 15:13:54 -0400889 my $modtar = "ktest-mods.tar.bz2";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400890
Steven Rostedte48c5292010-11-02 14:35:37 -0400891 run_ssh "rm -rf $modlib" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400892 dodie "failed to remove old mods: $modlib";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400893
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400894 # would be nice if scp -r did not follow symbolic links
Steven Rostedta75fece2010-11-02 14:58:27 -0400895 run_command "cd $tmpdir && tar -cjf $modtar lib/modules/$version" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400896 dodie "making tarball";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400897
Steven Rostedte48c5292010-11-02 14:35:37 -0400898 run_scp "$tmpdir/$modtar", "/tmp" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400899 dodie "failed to copy modules";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400900
Steven Rostedta75fece2010-11-02 14:58:27 -0400901 unlink "$tmpdir/$modtar";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400902
Steven Rostedte48c5292010-11-02 14:35:37 -0400903 run_ssh "'(cd / && tar xf /tmp/$modtar)'" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400904 dodie "failed to tar modules";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400905
Steven Rostedte48c5292010-11-02 14:35:37 -0400906 run_ssh "rm -f /tmp/$modtar";
Steven Rostedt8b37ca82010-11-02 14:58:33 -0400907
908 return if (!defined($post_install));
909
Steven Rostedte48c5292010-11-02 14:35:37 -0400910 my $cp_post_install = $post_install;
Steven Rostedtca6a21f2011-03-25 22:42:53 -0400911 $cp_post_install =~ s/\$KERNEL_VERSION/$version/g;
Steven Rostedte48c5292010-11-02 14:35:37 -0400912 run_command "$cp_post_install" or
Steven Rostedt576f6272010-11-02 14:58:38 -0400913 dodie "Failed to run post install";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400914}
915
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -0400916sub check_buildlog {
917 my ($patch) = @_;
918
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -0400919 my @files = `git show $patch | diffstat -l`;
920
921 open(IN, "git show $patch |") or
922 dodie "failed to show $patch";
923 while (<IN>) {
924 if (m,^--- a/(.*),) {
925 chomp $1;
926 $files[$#files] = $1;
927 }
928 }
929 close(IN);
930
931 open(IN, $buildlog) or dodie "Can't open $buildlog";
932 while (<IN>) {
933 if (/^\s*(.*?):.*(warning|error)/) {
934 my $err = $1;
935 foreach my $file (@files) {
Steven Rostedta75fece2010-11-02 14:58:27 -0400936 my $fullpath = "$builddir/$file";
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -0400937 if ($file eq $err || $fullpath eq $err) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400938 fail "$file built with warnings" and return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -0400939 }
940 }
941 }
942 }
943 close(IN);
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400944
945 return 1;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -0400946}
947
Steven Rostedt612b9e92011-03-07 13:27:43 -0500948sub make_oldconfig {
949 my ($defconfig) = @_;
950
951 if (!run_command "$defconfig $make oldnoconfig") {
952 # Perhaps oldnoconfig doesn't exist in this version of the kernel
953 # try a yes '' | oldconfig
954 doprint "oldnoconfig failed, trying yes '' | make oldconfig\n";
955 run_command "yes '' | $defconfig $make oldconfig" or
956 dodie "failed make config oldconfig";
957 }
958}
959
Steven Rostedt2545eb62010-11-02 15:01:32 -0400960sub build {
961 my ($type) = @_;
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400962 my $defconfig = "";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400963
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400964 unlink $buildlog;
965
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400966 if ($type =~ /^useconfig:(.*)/) {
Steven Rostedt51ad1dd2010-11-08 16:43:21 -0500967 run_command "cp $1 $output_config" or
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400968 dodie "could not copy $1 to .config";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400969
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400970 $type = "oldconfig";
971 }
972
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400973 # old config can ask questions
974 if ($type eq "oldconfig") {
Steven Rostedt9386c6a2010-11-08 16:35:48 -0500975 $type = "oldnoconfig";
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400976
977 # allow for empty configs
Steven Rostedt51ad1dd2010-11-08 16:43:21 -0500978 run_command "touch $output_config";
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400979
Steven Rostedt51ad1dd2010-11-08 16:43:21 -0500980 run_command "mv $output_config $outputdir/config_temp" or
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400981 dodie "moving .config";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400982
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400983 if (!$noclean && !run_command "$make mrproper") {
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400984 dodie "make mrproper";
985 }
986
Steven Rostedt51ad1dd2010-11-08 16:43:21 -0500987 run_command "mv $outputdir/config_temp $output_config" or
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400988 dodie "moving config_temp";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400989
990 } elsif (!$noclean) {
Steven Rostedt51ad1dd2010-11-08 16:43:21 -0500991 unlink "$output_config";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400992 run_command "$make mrproper" or
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400993 dodie "make mrproper";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400994 }
Steven Rostedt2545eb62010-11-02 15:01:32 -0400995
996 # add something to distinguish this build
Steven Rostedta75fece2010-11-02 14:58:27 -0400997 open(OUT, "> $outputdir/localversion") or dodie("Can't make localversion file");
998 print OUT "$localversion\n";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400999 close(OUT);
1000
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001001 if (defined($minconfig)) {
1002 $defconfig = "KCONFIG_ALLCONFIG=$minconfig";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001003 }
1004
Steven Rostedt612b9e92011-03-07 13:27:43 -05001005 if ($type eq "oldnoconfig") {
1006 make_oldconfig $defconfig;
1007 } else {
1008 run_command "$defconfig $make $type" or
1009 dodie "failed make config";
1010 }
Steven Rostedt2545eb62010-11-02 15:01:32 -04001011
Steven Rostedta75fece2010-11-02 14:58:27 -04001012 $redirect = "$buildlog";
1013 if (!run_command "$make $build_options") {
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001014 undef $redirect;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001015 # bisect may need this to pass
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001016 return 0 if ($in_bisect);
1017 fail "failed build" and return 0;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001018 }
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001019 undef $redirect;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001020
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001021 return 1;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001022}
1023
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001024sub halt {
Steven Rostedte48c5292010-11-02 14:35:37 -04001025 if (!run_ssh "halt" or defined($power_off)) {
Steven Rostedt576f6272010-11-02 14:58:38 -04001026 if (defined($poweroff_after_halt)) {
1027 sleep $poweroff_after_halt;
1028 run_command "$power_off";
1029 }
1030 } else {
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001031 # nope? the zap it!
Steven Rostedta75fece2010-11-02 14:58:27 -04001032 run_command "$power_off";
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001033 }
1034}
1035
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001036sub success {
1037 my ($i) = @_;
1038
Steven Rostedte48c5292010-11-02 14:35:37 -04001039 $successes++;
1040
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001041 doprint "\n\n*******************************************\n";
1042 doprint "*******************************************\n";
Steven Rostedt7a849cd2010-11-08 16:49:25 -05001043 doprint "KTEST RESULT: TEST $i SUCCESS!!!! **\n";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001044 doprint "*******************************************\n";
1045 doprint "*******************************************\n";
1046
Steven Rostedt576f6272010-11-02 14:58:38 -04001047 if ($i != $opt{"NUM_TESTS"} && !do_not_reboot) {
Steven Rostedta75fece2010-11-02 14:58:27 -04001048 doprint "Reboot and wait $sleep_time seconds\n";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001049 reboot;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001050 start_monitor;
Steven Rostedta75fece2010-11-02 14:58:27 -04001051 wait_for_monitor $sleep_time;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001052 end_monitor;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001053 }
1054}
1055
1056sub get_version {
1057 # get the release name
1058 doprint "$make kernelrelease ... ";
1059 $version = `$make kernelrelease | tail -1`;
1060 chomp($version);
1061 doprint "$version\n";
1062}
1063
Steven Rostedtc960bb92011-03-08 09:22:39 -05001064sub answer_bisect {
1065 for (;;) {
1066 doprint "Pass or fail? [p/f]";
1067 my $ans = <STDIN>;
1068 chomp $ans;
1069 if ($ans eq "p" || $ans eq "P") {
1070 return 1;
1071 } elsif ($ans eq "f" || $ans eq "F") {
1072 return 0;
1073 } else {
1074 print "Please answer 'P' or 'F'\n";
1075 }
1076 }
1077}
1078
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001079sub child_run_test {
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001080 my $failed = 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001081
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001082 # child should have no power
Steven Rostedta75fece2010-11-02 14:58:27 -04001083 $reboot_on_error = 0;
1084 $poweroff_on_error = 0;
1085 $die_on_failure = 1;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001086
1087 run_command $run_test or $failed = 1;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001088 exit $failed;
1089}
1090
1091my $child_done;
1092
1093sub child_finished {
1094 $child_done = 1;
1095}
1096
1097sub do_run_test {
1098 my $child_pid;
1099 my $child_exit;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001100 my $line;
1101 my $full_line;
1102 my $bug = 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001103
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001104 wait_for_monitor 1;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001105
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001106 doprint "run test $run_test\n";
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001107
1108 $child_done = 0;
1109
1110 $SIG{CHLD} = qw(child_finished);
1111
1112 $child_pid = fork;
1113
1114 child_run_test if (!$child_pid);
1115
1116 $full_line = "";
1117
1118 do {
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001119 $line = wait_for_input($monitor_fp, 1);
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001120 if (defined($line)) {
1121
1122 # we are not guaranteed to get a full line
1123 $full_line .= $line;
Steven Rostedt8ea0e062011-03-08 09:44:35 -05001124 doprint $line;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001125
1126 if ($full_line =~ /call trace:/i) {
1127 $bug = 1;
1128 }
1129
1130 if ($full_line =~ /Kernel panic -/) {
1131 $bug = 1;
1132 }
1133
1134 if ($line =~ /\n/) {
1135 $full_line = "";
1136 }
1137 }
1138 } while (!$child_done && !$bug);
1139
1140 if ($bug) {
Steven Rostedt8ea0e062011-03-08 09:44:35 -05001141 my $failure_start = time;
1142 my $now;
1143 do {
1144 $line = wait_for_input($monitor_fp, 1);
1145 if (defined($line)) {
1146 doprint $line;
1147 }
1148 $now = time;
1149 if ($now - $failure_start >= $stop_after_failure) {
1150 last;
1151 }
1152 } while (defined($line));
1153
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001154 doprint "Detected kernel crash!\n";
1155 # kill the child with extreme prejudice
1156 kill 9, $child_pid;
1157 }
1158
1159 waitpid $child_pid, 0;
1160 $child_exit = $?;
1161
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001162 if ($bug || $child_exit) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001163 return 0 if $in_bisect;
1164 fail "test failed" and return 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001165 }
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001166 return 1;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001167}
1168
Steven Rostedta75fece2010-11-02 14:58:27 -04001169sub run_git_bisect {
1170 my ($command) = @_;
1171
1172 doprint "$command ... ";
1173
1174 my $output = `$command 2>&1`;
1175 my $ret = $?;
1176
1177 logit $output;
1178
1179 if ($ret) {
1180 doprint "FAILED\n";
1181 dodie "Failed to git bisect";
1182 }
1183
1184 doprint "SUCCESS\n";
1185 if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\))\s+\[([[:xdigit:]]+)\]/) {
1186 doprint "$1 [$2]\n";
1187 } elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) {
1188 $bisect_bad = $1;
1189 doprint "Found bad commit... $1\n";
1190 return 0;
1191 } else {
1192 # we already logged it, just print it now.
1193 print $output;
1194 }
1195
1196 return 1;
1197}
1198
Steven Rostedtc23dca72011-03-08 09:26:31 -05001199sub bisect_reboot {
1200 doprint "Reboot and sleep $bisect_sleep_time seconds\n";
1201 reboot;
1202 start_monitor;
1203 wait_for_monitor $bisect_sleep_time;
1204 end_monitor;
1205}
1206
1207# returns 1 on success, 0 on failure, -1 on skip
Steven Rostedt0a05c762010-11-08 11:14:10 -05001208sub run_bisect_test {
1209 my ($type, $buildtype) = @_;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001210
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001211 my $failed = 0;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001212 my $result;
1213 my $output;
1214 my $ret;
1215
Steven Rostedt0a05c762010-11-08 11:14:10 -05001216 $in_bisect = 1;
1217
1218 build $buildtype or $failed = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001219
1220 if ($type ne "build") {
Steven Rostedtc23dca72011-03-08 09:26:31 -05001221 if ($failed && $bisect_skip) {
1222 $in_bisect = 0;
1223 return -1;
1224 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001225 dodie "Failed on build" if $failed;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001226
1227 # Now boot the box
1228 get_grub_index;
1229 get_version;
1230 install;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001231
1232 start_monitor;
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001233 monitor or $failed = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001234
1235 if ($type ne "boot") {
Steven Rostedtc23dca72011-03-08 09:26:31 -05001236 if ($failed && $bisect_skip) {
1237 end_monitor;
1238 bisect_reboot;
1239 $in_bisect = 0;
1240 return -1;
1241 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001242 dodie "Failed on boot" if $failed;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001243
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001244 do_run_test or $failed = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001245 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001246 end_monitor;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001247 }
1248
1249 if ($failed) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001250 $result = 0;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001251 } else {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001252 $result = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001253 }
Steven Rostedt4025bc62011-05-20 09:16:29 -04001254
1255 # reboot the box to a kernel we can ssh to
1256 if ($type ne "build") {
1257 bisect_reboot;
1258 }
Steven Rostedt0a05c762010-11-08 11:14:10 -05001259 $in_bisect = 0;
1260
1261 return $result;
1262}
1263
1264sub run_bisect {
1265 my ($type) = @_;
1266 my $buildtype = "oldconfig";
1267
1268 # We should have a minconfig to use?
1269 if (defined($minconfig)) {
1270 $buildtype = "useconfig:$minconfig";
1271 }
1272
1273 my $ret = run_bisect_test $type, $buildtype;
1274
Steven Rostedtc960bb92011-03-08 09:22:39 -05001275 if ($bisect_manual) {
1276 $ret = answer_bisect;
1277 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001278
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04001279 # Are we looking for where it worked, not failed?
1280 if ($reverse_bisect) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001281 $ret = !$ret;
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04001282 }
1283
Steven Rostedtc23dca72011-03-08 09:26:31 -05001284 if ($ret > 0) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001285 return "good";
Steven Rostedtc23dca72011-03-08 09:26:31 -05001286 } elsif ($ret == 0) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001287 return "bad";
Steven Rostedtc23dca72011-03-08 09:26:31 -05001288 } elsif ($bisect_skip) {
1289 doprint "HIT A BAD COMMIT ... SKIPPING\n";
1290 return "skip";
Steven Rostedt0a05c762010-11-08 11:14:10 -05001291 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001292}
1293
1294sub bisect {
1295 my ($i) = @_;
1296
1297 my $result;
1298
1299 die "BISECT_GOOD[$i] not defined\n" if (!defined($opt{"BISECT_GOOD[$i]"}));
1300 die "BISECT_BAD[$i] not defined\n" if (!defined($opt{"BISECT_BAD[$i]"}));
1301 die "BISECT_TYPE[$i] not defined\n" if (!defined($opt{"BISECT_TYPE[$i]"}));
1302
1303 my $good = $opt{"BISECT_GOOD[$i]"};
1304 my $bad = $opt{"BISECT_BAD[$i]"};
1305 my $type = $opt{"BISECT_TYPE[$i]"};
Steven Rostedta75fece2010-11-02 14:58:27 -04001306 my $start = $opt{"BISECT_START[$i]"};
1307 my $replay = $opt{"BISECT_REPLAY[$i]"};
Steven Rostedt3410f6f2011-03-08 09:38:12 -05001308 my $start_files = $opt{"BISECT_FILES[$i]"};
1309
1310 if (defined($start_files)) {
1311 $start_files = " -- " . $start_files;
1312 } else {
1313 $start_files = "";
1314 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001315
Steven Rostedta57419b2010-11-02 15:13:54 -04001316 # convert to true sha1's
1317 $good = get_sha1($good);
1318 $bad = get_sha1($bad);
1319
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04001320 if (defined($opt{"BISECT_REVERSE[$i]"}) &&
1321 $opt{"BISECT_REVERSE[$i]"} == 1) {
1322 doprint "Performing a reverse bisect (bad is good, good is bad!)\n";
1323 $reverse_bisect = 1;
1324 } else {
1325 $reverse_bisect = 0;
1326 }
1327
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001328 # Can't have a test without having a test to run
1329 if ($type eq "test" && !defined($run_test)) {
1330 $type = "boot";
1331 }
1332
Steven Rostedta75fece2010-11-02 14:58:27 -04001333 my $check = $opt{"BISECT_CHECK[$i]"};
1334 if (defined($check) && $check ne "0") {
1335
1336 # get current HEAD
Steven Rostedta57419b2010-11-02 15:13:54 -04001337 my $head = get_sha1("HEAD");
Steven Rostedta75fece2010-11-02 14:58:27 -04001338
1339 if ($check ne "good") {
1340 doprint "TESTING BISECT BAD [$bad]\n";
1341 run_command "git checkout $bad" or
1342 die "Failed to checkout $bad";
1343
1344 $result = run_bisect $type;
1345
1346 if ($result ne "bad") {
1347 fail "Tested BISECT_BAD [$bad] and it succeeded" and return 0;
1348 }
1349 }
1350
1351 if ($check ne "bad") {
1352 doprint "TESTING BISECT GOOD [$good]\n";
1353 run_command "git checkout $good" or
1354 die "Failed to checkout $good";
1355
1356 $result = run_bisect $type;
1357
1358 if ($result ne "good") {
1359 fail "Tested BISECT_GOOD [$good] and it failed" and return 0;
1360 }
1361 }
1362
1363 # checkout where we started
1364 run_command "git checkout $head" or
1365 die "Failed to checkout $head";
1366 }
1367
Steven Rostedt3410f6f2011-03-08 09:38:12 -05001368 run_command "git bisect start$start_files" or
Steven Rostedta75fece2010-11-02 14:58:27 -04001369 dodie "could not start bisect";
1370
1371 run_command "git bisect good $good" or
1372 dodie "could not set bisect good to $good";
1373
1374 run_git_bisect "git bisect bad $bad" or
1375 dodie "could not set bisect bad to $bad";
1376
1377 if (defined($replay)) {
1378 run_command "git bisect replay $replay" or
1379 dodie "failed to run replay";
1380 }
1381
1382 if (defined($start)) {
1383 run_command "git checkout $start" or
1384 dodie "failed to checkout $start";
1385 }
1386
1387 my $test;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001388 do {
1389 $result = run_bisect $type;
Steven Rostedta75fece2010-11-02 14:58:27 -04001390 $test = run_git_bisect "git bisect $result";
1391 } while ($test);
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001392
1393 run_command "git bisect log" or
1394 dodie "could not capture git bisect log";
1395
1396 run_command "git bisect reset" or
1397 dodie "could not reset git bisect";
1398
1399 doprint "Bad commit was [$bisect_bad]\n";
1400
Steven Rostedt0a05c762010-11-08 11:14:10 -05001401 success $i;
1402}
1403
1404my %config_ignore;
1405my %config_set;
1406
1407my %config_list;
1408my %null_config;
1409
1410my %dependency;
1411
1412sub process_config_ignore {
1413 my ($config) = @_;
1414
1415 open (IN, $config)
1416 or dodie "Failed to read $config";
1417
1418 while (<IN>) {
1419 if (/^(.*?(CONFIG\S*)(=.*| is not set))/) {
1420 $config_ignore{$2} = $1;
1421 }
1422 }
1423
1424 close(IN);
1425}
1426
1427sub read_current_config {
1428 my ($config_ref) = @_;
1429
1430 %{$config_ref} = ();
1431 undef %{$config_ref};
1432
1433 my @key = keys %{$config_ref};
1434 if ($#key >= 0) {
1435 print "did not delete!\n";
1436 exit;
1437 }
1438 open (IN, "$output_config");
1439
1440 while (<IN>) {
1441 if (/^(CONFIG\S+)=(.*)/) {
1442 ${$config_ref}{$1} = $2;
1443 }
1444 }
1445 close(IN);
1446}
1447
1448sub get_dependencies {
1449 my ($config) = @_;
1450
1451 my $arr = $dependency{$config};
1452 if (!defined($arr)) {
1453 return ();
1454 }
1455
1456 my @deps = @{$arr};
1457
1458 foreach my $dep (@{$arr}) {
1459 print "ADD DEP $dep\n";
1460 @deps = (@deps, get_dependencies $dep);
1461 }
1462
1463 return @deps;
1464}
1465
1466sub create_config {
1467 my @configs = @_;
1468
1469 open(OUT, ">$output_config") or dodie "Can not write to $output_config";
1470
1471 foreach my $config (@configs) {
1472 print OUT "$config_set{$config}\n";
1473 my @deps = get_dependencies $config;
1474 foreach my $dep (@deps) {
1475 print OUT "$config_set{$dep}\n";
1476 }
1477 }
1478
1479 foreach my $config (keys %config_ignore) {
1480 print OUT "$config_ignore{$config}\n";
1481 }
1482 close(OUT);
1483
1484# exit;
Steven Rostedt612b9e92011-03-07 13:27:43 -05001485 make_oldconfig "";
Steven Rostedt0a05c762010-11-08 11:14:10 -05001486}
1487
1488sub compare_configs {
1489 my (%a, %b) = @_;
1490
1491 foreach my $item (keys %a) {
1492 if (!defined($b{$item})) {
1493 print "diff $item\n";
1494 return 1;
1495 }
1496 delete $b{$item};
1497 }
1498
1499 my @keys = keys %b;
1500 if ($#keys) {
1501 print "diff2 $keys[0]\n";
1502 }
1503 return -1 if ($#keys >= 0);
1504
1505 return 0;
1506}
1507
1508sub run_config_bisect_test {
1509 my ($type) = @_;
1510
1511 return run_bisect_test $type, "oldconfig";
1512}
1513
1514sub process_passed {
1515 my (%configs) = @_;
1516
1517 doprint "These configs had no failure: (Enabling them for further compiles)\n";
1518 # Passed! All these configs are part of a good compile.
1519 # Add them to the min options.
1520 foreach my $config (keys %configs) {
1521 if (defined($config_list{$config})) {
1522 doprint " removing $config\n";
1523 $config_ignore{$config} = $config_list{$config};
1524 delete $config_list{$config};
1525 }
1526 }
Steven Rostedtf1a27852010-11-11 11:34:38 -05001527 doprint "config copied to $outputdir/config_good\n";
1528 run_command "cp -f $output_config $outputdir/config_good";
Steven Rostedt0a05c762010-11-08 11:14:10 -05001529}
1530
1531sub process_failed {
1532 my ($config) = @_;
1533
1534 doprint "\n\n***************************************\n";
1535 doprint "Found bad config: $config\n";
1536 doprint "***************************************\n\n";
1537}
1538
1539sub run_config_bisect {
1540
1541 my @start_list = keys %config_list;
1542
1543 if ($#start_list < 0) {
1544 doprint "No more configs to test!!!\n";
1545 return -1;
1546 }
1547
1548 doprint "***** RUN TEST ***\n";
1549 my $type = $opt{"CONFIG_BISECT_TYPE[$iteration]"};
1550 my $ret;
1551 my %current_config;
1552
1553 my $count = $#start_list + 1;
1554 doprint " $count configs to test\n";
1555
1556 my $half = int($#start_list / 2);
1557
1558 do {
1559 my @tophalf = @start_list[0 .. $half];
1560
1561 create_config @tophalf;
1562 read_current_config \%current_config;
1563
1564 $count = $#tophalf + 1;
1565 doprint "Testing $count configs\n";
1566 my $found = 0;
1567 # make sure we test something
1568 foreach my $config (@tophalf) {
1569 if (defined($current_config{$config})) {
1570 logit " $config\n";
1571 $found = 1;
1572 }
1573 }
1574 if (!$found) {
1575 # try the other half
1576 doprint "Top half produced no set configs, trying bottom half\n";
1577 @tophalf = @start_list[$half .. $#start_list];
1578 create_config @tophalf;
1579 read_current_config \%current_config;
1580 foreach my $config (@tophalf) {
1581 if (defined($current_config{$config})) {
1582 logit " $config\n";
1583 $found = 1;
1584 }
1585 }
1586 if (!$found) {
1587 doprint "Failed: Can't make new config with current configs\n";
1588 foreach my $config (@start_list) {
1589 doprint " CONFIG: $config\n";
1590 }
1591 return -1;
1592 }
1593 $count = $#tophalf + 1;
1594 doprint "Testing $count configs\n";
1595 }
1596
1597 $ret = run_config_bisect_test $type;
Steven Rostedtc960bb92011-03-08 09:22:39 -05001598 if ($bisect_manual) {
1599 $ret = answer_bisect;
1600 }
Steven Rostedt0a05c762010-11-08 11:14:10 -05001601 if ($ret) {
1602 process_passed %current_config;
1603 return 0;
1604 }
1605
1606 doprint "This config had a failure.\n";
1607 doprint "Removing these configs that were not set in this config:\n";
Steven Rostedtf1a27852010-11-11 11:34:38 -05001608 doprint "config copied to $outputdir/config_bad\n";
1609 run_command "cp -f $output_config $outputdir/config_bad";
Steven Rostedt0a05c762010-11-08 11:14:10 -05001610
1611 # A config exists in this group that was bad.
1612 foreach my $config (keys %config_list) {
1613 if (!defined($current_config{$config})) {
1614 doprint " removing $config\n";
1615 delete $config_list{$config};
1616 }
1617 }
1618
1619 @start_list = @tophalf;
1620
1621 if ($#start_list == 0) {
1622 process_failed $start_list[0];
1623 return 1;
1624 }
1625
1626 # remove half the configs we are looking at and see if
1627 # they are good.
1628 $half = int($#start_list / 2);
1629 } while ($half > 0);
1630
Steven Rostedtc960bb92011-03-08 09:22:39 -05001631 # we found a single config, try it again unless we are running manually
1632
1633 if ($bisect_manual) {
1634 process_failed $start_list[0];
1635 return 1;
1636 }
1637
Steven Rostedt0a05c762010-11-08 11:14:10 -05001638 my @tophalf = @start_list[0 .. 0];
1639
1640 $ret = run_config_bisect_test $type;
1641 if ($ret) {
1642 process_passed %current_config;
1643 return 0;
1644 }
1645
1646 process_failed $start_list[0];
1647 return 1;
1648}
1649
1650sub config_bisect {
1651 my ($i) = @_;
1652
1653 my $start_config = $opt{"CONFIG_BISECT[$i]"};
1654
1655 my $tmpconfig = "$tmpdir/use_config";
1656
1657 # Make the file with the bad config and the min config
1658 if (defined($minconfig)) {
1659 # read the min config for things to ignore
1660 run_command "cp $minconfig $tmpconfig" or
1661 dodie "failed to copy $minconfig to $tmpconfig";
1662 } else {
1663 unlink $tmpconfig;
1664 }
1665
1666 # Add other configs
1667 if (defined($addconfig)) {
1668 run_command "cat $addconfig >> $tmpconfig" or
1669 dodie "failed to append $addconfig";
1670 }
1671
1672 my $defconfig = "";
1673 if (-f $tmpconfig) {
1674 $defconfig = "KCONFIG_ALLCONFIG=$tmpconfig";
1675 process_config_ignore $tmpconfig;
1676 }
1677
1678 # now process the start config
1679 run_command "cp $start_config $output_config" or
1680 dodie "failed to copy $start_config to $output_config";
1681
1682 # read directly what we want to check
1683 my %config_check;
1684 open (IN, $output_config)
1685 or dodie "faied to open $output_config";
1686
1687 while (<IN>) {
1688 if (/^((CONFIG\S*)=.*)/) {
1689 $config_check{$2} = $1;
1690 }
1691 }
1692 close(IN);
1693
1694 # Now run oldconfig with the minconfig (and addconfigs)
Steven Rostedt612b9e92011-03-07 13:27:43 -05001695 make_oldconfig $defconfig;
Steven Rostedt0a05c762010-11-08 11:14:10 -05001696
1697 # check to see what we lost (or gained)
1698 open (IN, $output_config)
1699 or dodie "Failed to read $start_config";
1700
1701 my %removed_configs;
1702 my %added_configs;
1703
1704 while (<IN>) {
1705 if (/^((CONFIG\S*)=.*)/) {
1706 # save off all options
1707 $config_set{$2} = $1;
1708 if (defined($config_check{$2})) {
1709 if (defined($config_ignore{$2})) {
1710 $removed_configs{$2} = $1;
1711 } else {
1712 $config_list{$2} = $1;
1713 }
1714 } elsif (!defined($config_ignore{$2})) {
1715 $added_configs{$2} = $1;
1716 $config_list{$2} = $1;
1717 }
1718 }
1719 }
1720 close(IN);
1721
1722 my @confs = keys %removed_configs;
1723 if ($#confs >= 0) {
1724 doprint "Configs overridden by default configs and removed from check:\n";
1725 foreach my $config (@confs) {
1726 doprint " $config\n";
1727 }
1728 }
1729 @confs = keys %added_configs;
1730 if ($#confs >= 0) {
1731 doprint "Configs appearing in make oldconfig and added:\n";
1732 foreach my $config (@confs) {
1733 doprint " $config\n";
1734 }
1735 }
1736
1737 my %config_test;
1738 my $once = 0;
1739
1740 # Sometimes kconfig does weird things. We must make sure
1741 # that the config we autocreate has everything we need
1742 # to test, otherwise we may miss testing configs, or
1743 # may not be able to create a new config.
1744 # Here we create a config with everything set.
1745 create_config (keys %config_list);
1746 read_current_config \%config_test;
1747 foreach my $config (keys %config_list) {
1748 if (!defined($config_test{$config})) {
1749 if (!$once) {
1750 $once = 1;
1751 doprint "Configs not produced by kconfig (will not be checked):\n";
1752 }
1753 doprint " $config\n";
1754 delete $config_list{$config};
1755 }
1756 }
1757 my $ret;
1758 do {
1759 $ret = run_config_bisect;
1760 } while (!$ret);
1761
1762 return $ret if ($ret < 0);
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001763
1764 success $i;
1765}
1766
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001767sub patchcheck {
1768 my ($i) = @_;
1769
1770 die "PATCHCHECK_START[$i] not defined\n"
1771 if (!defined($opt{"PATCHCHECK_START[$i]"}));
1772 die "PATCHCHECK_TYPE[$i] not defined\n"
1773 if (!defined($opt{"PATCHCHECK_TYPE[$i]"}));
1774
1775 my $start = $opt{"PATCHCHECK_START[$i]"};
1776
1777 my $end = "HEAD";
1778 if (defined($opt{"PATCHCHECK_END[$i]"})) {
1779 $end = $opt{"PATCHCHECK_END[$i]"};
1780 }
1781
Steven Rostedta57419b2010-11-02 15:13:54 -04001782 # Get the true sha1's since we can use things like HEAD~3
1783 $start = get_sha1($start);
1784 $end = get_sha1($end);
1785
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001786 my $type = $opt{"PATCHCHECK_TYPE[$i]"};
1787
1788 # Can't have a test without having a test to run
1789 if ($type eq "test" && !defined($run_test)) {
1790 $type = "boot";
1791 }
1792
1793 open (IN, "git log --pretty=oneline $end|") or
1794 dodie "could not get git list";
1795
1796 my @list;
1797
1798 while (<IN>) {
1799 chomp;
1800 $list[$#list+1] = $_;
1801 last if (/^$start/);
1802 }
1803 close(IN);
1804
1805 if ($list[$#list] !~ /^$start/) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001806 fail "SHA1 $start not found";
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001807 }
1808
1809 # go backwards in the list
1810 @list = reverse @list;
1811
1812 my $save_clean = $noclean;
1813
1814 $in_patchcheck = 1;
1815 foreach my $item (@list) {
1816 my $sha1 = $item;
1817 $sha1 =~ s/^([[:xdigit:]]+).*/$1/;
1818
1819 doprint "\nProcessing commit $item\n\n";
1820
1821 run_command "git checkout $sha1" or
1822 die "Failed to checkout $sha1";
1823
1824 # only clean on the first and last patch
1825 if ($item eq $list[0] ||
1826 $item eq $list[$#list]) {
1827 $noclean = $save_clean;
1828 } else {
1829 $noclean = 1;
1830 }
1831
1832 if (defined($minconfig)) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001833 build "useconfig:$minconfig" or return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001834 } else {
1835 # ?? no config to use?
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001836 build "oldconfig" or return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001837 }
1838
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001839 check_buildlog $sha1 or return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001840
1841 next if ($type eq "build");
1842
1843 get_grub_index;
1844 get_version;
1845 install;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001846
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001847 my $failed = 0;
1848
1849 start_monitor;
1850 monitor or $failed = 1;
1851
1852 if (!$failed && $type ne "boot"){
1853 do_run_test or $failed = 1;
1854 }
1855 end_monitor;
1856 return 0 if ($failed);
1857
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001858 }
1859 $in_patchcheck = 0;
1860 success $i;
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001861
1862 return 1;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001863}
1864
Steven Rostedt8d1491b2010-11-18 15:39:48 -05001865$#ARGV < 1 or die "ktest.pl version: $VERSION\n usage: ktest.pl config-file\n";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001866
Steven Rostedt8d1491b2010-11-18 15:39:48 -05001867if ($#ARGV == 0) {
1868 $ktest_config = $ARGV[0];
1869 if (! -f $ktest_config) {
1870 print "$ktest_config does not exist.\n";
1871 my $ans;
1872 for (;;) {
1873 print "Create it? [Y/n] ";
1874 $ans = <STDIN>;
1875 chomp $ans;
1876 if ($ans =~ /^\s*$/) {
1877 $ans = "y";
1878 }
1879 last if ($ans =~ /^y$/i || $ans =~ /^n$/i);
1880 print "Please answer either 'y' or 'n'.\n";
1881 }
1882 if ($ans !~ /^y$/i) {
1883 exit 0;
1884 }
1885 }
1886} else {
1887 $ktest_config = "ktest.conf";
1888}
1889
1890if (! -f $ktest_config) {
1891 open(OUT, ">$ktest_config") or die "Can not create $ktest_config";
1892 print OUT << "EOF"
1893# Generated by ktest.pl
1894#
1895# Define each test with TEST_START
1896# The config options below it will override the defaults
1897TEST_START
1898
1899DEFAULTS
1900EOF
1901;
1902 close(OUT);
1903}
1904read_config $ktest_config;
1905
1906# Append any configs entered in manually to the config file.
1907my @new_configs = keys %entered_configs;
1908if ($#new_configs >= 0) {
1909 print "\nAppending entered in configs to $ktest_config\n";
1910 open(OUT, ">>$ktest_config") or die "Can not append to $ktest_config";
1911 foreach my $config (@new_configs) {
1912 print OUT "$config = $entered_configs{$config}\n";
1913 $opt{$config} = $entered_configs{$config};
1914 }
1915}
Steven Rostedt2545eb62010-11-02 15:01:32 -04001916
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001917if ($opt{"CLEAR_LOG"} && defined($opt{"LOG_FILE"})) {
1918 unlink $opt{"LOG_FILE"};
1919}
Steven Rostedt2545eb62010-11-02 15:01:32 -04001920
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001921doprint "\n\nSTARTING AUTOMATED TESTS\n\n";
1922
Steven Rostedta57419b2010-11-02 15:13:54 -04001923for (my $i = 0, my $repeat = 1; $i <= $opt{"NUM_TESTS"}; $i += $repeat) {
1924
1925 if (!$i) {
1926 doprint "DEFAULT OPTIONS:\n";
1927 } else {
1928 doprint "\nTEST $i OPTIONS";
1929 if (defined($repeat_tests{$i})) {
1930 $repeat = $repeat_tests{$i};
1931 doprint " ITERATE $repeat";
1932 }
1933 doprint "\n";
1934 }
1935
1936 foreach my $option (sort keys %opt) {
1937
1938 if ($option =~ /\[(\d+)\]$/) {
1939 next if ($i != $1);
1940 } else {
1941 next if ($i);
1942 }
1943
1944 doprint "$option = $opt{$option}\n";
1945 }
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001946}
Steven Rostedt2545eb62010-11-02 15:01:32 -04001947
Steven Rostedta75fece2010-11-02 14:58:27 -04001948sub set_test_option {
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001949 my ($name, $i) = @_;
1950
1951 my $option = "$name\[$i\]";
1952
1953 if (defined($opt{$option})) {
1954 return $opt{$option};
1955 }
1956
Steven Rostedta57419b2010-11-02 15:13:54 -04001957 foreach my $test (keys %repeat_tests) {
1958 if ($i >= $test &&
1959 $i < $test + $repeat_tests{$test}) {
1960 $option = "$name\[$test\]";
1961 if (defined($opt{$option})) {
1962 return $opt{$option};
1963 }
1964 }
1965 }
1966
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001967 if (defined($opt{$name})) {
1968 return $opt{$name};
1969 }
1970
1971 return undef;
1972}
1973
Steven Rostedt2545eb62010-11-02 15:01:32 -04001974# First we need to do is the builds
Steven Rostedta75fece2010-11-02 14:58:27 -04001975for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
Steven Rostedt2545eb62010-11-02 15:01:32 -04001976
Steven Rostedt576f6272010-11-02 14:58:38 -04001977 $iteration = $i;
1978
Steven Rostedta75fece2010-11-02 14:58:27 -04001979 my $makecmd = set_test_option("MAKE_CMD", $i);
1980
1981 $machine = set_test_option("MACHINE", $i);
Steven Rostedte48c5292010-11-02 14:35:37 -04001982 $ssh_user = set_test_option("SSH_USER", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04001983 $tmpdir = set_test_option("TMP_DIR", $i);
1984 $outputdir = set_test_option("OUTPUT_DIR", $i);
1985 $builddir = set_test_option("BUILD_DIR", $i);
1986 $test_type = set_test_option("TEST_TYPE", $i);
1987 $build_type = set_test_option("BUILD_TYPE", $i);
1988 $build_options = set_test_option("BUILD_OPTIONS", $i);
1989 $power_cycle = set_test_option("POWER_CYCLE", $i);
Steven Rostedte48c5292010-11-02 14:35:37 -04001990 $reboot = set_test_option("REBOOT", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04001991 $noclean = set_test_option("BUILD_NOCLEAN", $i);
1992 $minconfig = set_test_option("MIN_CONFIG", $i);
1993 $run_test = set_test_option("TEST", $i);
1994 $addconfig = set_test_option("ADD_CONFIG", $i);
1995 $reboot_type = set_test_option("REBOOT_TYPE", $i);
1996 $grub_menu = set_test_option("GRUB_MENU", $i);
Steven Rostedt8b37ca82010-11-02 14:58:33 -04001997 $post_install = set_test_option("POST_INSTALL", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04001998 $reboot_script = set_test_option("REBOOT_SCRIPT", $i);
1999 $reboot_on_error = set_test_option("REBOOT_ON_ERROR", $i);
2000 $poweroff_on_error = set_test_option("POWEROFF_ON_ERROR", $i);
2001 $die_on_failure = set_test_option("DIE_ON_FAILURE", $i);
2002 $power_off = set_test_option("POWER_OFF", $i);
Steven Rostedt576f6272010-11-02 14:58:38 -04002003 $powercycle_after_reboot = set_test_option("POWERCYCLE_AFTER_REBOOT", $i);
2004 $poweroff_after_halt = set_test_option("POWEROFF_AFTER_HALT", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002005 $sleep_time = set_test_option("SLEEP_TIME", $i);
2006 $bisect_sleep_time = set_test_option("BISECT_SLEEP_TIME", $i);
Steven Rostedtc960bb92011-03-08 09:22:39 -05002007 $bisect_manual = set_test_option("BISECT_MANUAL", $i);
Steven Rostedtc23dca72011-03-08 09:26:31 -05002008 $bisect_skip = set_test_option("BISECT_SKIP", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002009 $store_failures = set_test_option("STORE_FAILURES", $i);
2010 $timeout = set_test_option("TIMEOUT", $i);
2011 $booted_timeout = set_test_option("BOOTED_TIMEOUT", $i);
2012 $console = set_test_option("CONSOLE", $i);
2013 $success_line = set_test_option("SUCCESS_LINE", $i);
Steven Rostedt1c8a6172010-11-09 12:55:40 -05002014 $stop_after_success = set_test_option("STOP_AFTER_SUCCESS", $i);
2015 $stop_after_failure = set_test_option("STOP_AFTER_FAILURE", $i);
Steven Rostedt2d01b262011-03-08 09:47:54 -05002016 $stop_test_after = set_test_option("STOP_TEST_AFTER", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002017 $build_target = set_test_option("BUILD_TARGET", $i);
Steven Rostedte48c5292010-11-02 14:35:37 -04002018 $ssh_exec = set_test_option("SSH_EXEC", $i);
2019 $scp_to_target = set_test_option("SCP_TO_TARGET", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002020 $target_image = set_test_option("TARGET_IMAGE", $i);
2021 $localversion = set_test_option("LOCALVERSION", $i);
2022
2023 chdir $builddir || die "can't change directory to $builddir";
2024
2025 if (!-d $tmpdir) {
2026 mkpath($tmpdir) or
2027 die "can't create $tmpdir";
2028 }
2029
Steven Rostedte48c5292010-11-02 14:35:37 -04002030 $ENV{"SSH_USER"} = $ssh_user;
2031 $ENV{"MACHINE"} = $machine;
2032
Steven Rostedta75fece2010-11-02 14:58:27 -04002033 $target = "$ssh_user\@$machine";
2034
2035 $buildlog = "$tmpdir/buildlog-$machine";
2036 $dmesg = "$tmpdir/dmesg-$machine";
2037 $make = "$makecmd O=$outputdir";
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05002038 $output_config = "$outputdir/.config";
Steven Rostedta75fece2010-11-02 14:58:27 -04002039
2040 if ($reboot_type eq "grub") {
Steven Rostedt576f6272010-11-02 14:58:38 -04002041 dodie "GRUB_MENU not defined" if (!defined($grub_menu));
Steven Rostedta75fece2010-11-02 14:58:27 -04002042 } elsif (!defined($reboot_script)) {
Steven Rostedt576f6272010-11-02 14:58:38 -04002043 dodie "REBOOT_SCRIPT not defined"
Steven Rostedta75fece2010-11-02 14:58:27 -04002044 }
2045
2046 my $run_type = $build_type;
2047 if ($test_type eq "patchcheck") {
2048 $run_type = $opt{"PATCHCHECK_TYPE[$i]"};
2049 } elsif ($test_type eq "bisect") {
2050 $run_type = $opt{"BISECT_TYPE[$i]"};
Steven Rostedt0a05c762010-11-08 11:14:10 -05002051 } elsif ($test_type eq "config_bisect") {
2052 $run_type = $opt{"CONFIG_BISECT_TYPE[$i]"};
Steven Rostedta75fece2010-11-02 14:58:27 -04002053 }
2054
2055 # mistake in config file?
2056 if (!defined($run_type)) {
2057 $run_type = "ERROR";
2058 }
Steven Rostedt2545eb62010-11-02 15:01:32 -04002059
2060 doprint "\n\n";
Steven Rostedta75fece2010-11-02 14:58:27 -04002061 doprint "RUNNING TEST $i of $opt{NUM_TESTS} with option $test_type $run_type\n\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -04002062
2063 unlink $dmesg;
2064 unlink $buildlog;
Steven Rostedt2545eb62010-11-02 15:01:32 -04002065
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002066 if (!defined($minconfig)) {
2067 $minconfig = $addconfig;
2068
2069 } elsif (defined($addconfig)) {
Steven Rostedt9be2e6b2010-11-09 12:20:21 -05002070 run_command "cat $addconfig $minconfig > $tmpdir/add_config" or
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002071 dodie "Failed to create temp config";
Steven Rostedt9be2e6b2010-11-09 12:20:21 -05002072 $minconfig = "$tmpdir/add_config";
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002073 }
2074
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002075 my $checkout = $opt{"CHECKOUT[$i]"};
2076 if (defined($checkout)) {
2077 run_command "git checkout $checkout" or
2078 die "failed to checkout $checkout";
2079 }
2080
Steven Rostedta75fece2010-11-02 14:58:27 -04002081 if ($test_type eq "bisect") {
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04002082 bisect $i;
2083 next;
Steven Rostedt0a05c762010-11-08 11:14:10 -05002084 } elsif ($test_type eq "config_bisect") {
2085 config_bisect $i;
2086 next;
Steven Rostedta75fece2010-11-02 14:58:27 -04002087 } elsif ($test_type eq "patchcheck") {
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002088 patchcheck $i;
2089 next;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04002090 }
2091
Steven Rostedt7faafbd2010-11-02 14:58:22 -04002092 if ($build_type ne "nobuild") {
2093 build $build_type or next;
Steven Rostedt2545eb62010-11-02 15:01:32 -04002094 }
2095
Steven Rostedta75fece2010-11-02 14:58:27 -04002096 if ($test_type ne "build") {
2097 get_grub_index;
2098 get_version;
2099 install;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04002100
Steven Rostedta75fece2010-11-02 14:58:27 -04002101 my $failed = 0;
2102 start_monitor;
2103 monitor or $failed = 1;;
2104
2105 if (!$failed && $test_type ne "boot" && defined($run_test)) {
2106 do_run_test or $failed = 1;
2107 }
2108 end_monitor;
2109 next if ($failed);
Steven Rostedt5a391fb2010-11-02 14:57:43 -04002110 }
2111
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04002112 success $i;
Steven Rostedt2545eb62010-11-02 15:01:32 -04002113}
2114
Steven Rostedt5c42fc52010-11-02 14:57:01 -04002115if ($opt{"POWEROFF_ON_SUCCESS"}) {
Steven Rostedt75c3fda72010-11-02 14:57:21 -04002116 halt;
Steven Rostedt576f6272010-11-02 14:58:38 -04002117} elsif ($opt{"REBOOT_ON_SUCCESS"} && !do_not_reboot) {
Steven Rostedt75c3fda72010-11-02 14:57:21 -04002118 reboot;
Steven Rostedt5c42fc52010-11-02 14:57:01 -04002119}
Steven Rostedt75c3fda72010-11-02 14:57:21 -04002120
Steven Rostedte48c5292010-11-02 14:35:37 -04002121doprint "\n $successes of $opt{NUM_TESTS} tests were successful\n\n";
2122
Steven Rostedt2545eb62010-11-02 15:01:32 -04002123exit 0;