blob: a8b3292d063962ec8ff15946ff87364e047ef771 [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 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) {
841 $done = 1;
842 }
843 }
Steven Rostedt2545eb62010-11-02 15:01:32 -0400844 }
845
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400846 close(DMESG);
Steven Rostedt2545eb62010-11-02 15:01:32 -0400847
Steven Rostedt2545eb62010-11-02 15:01:32 -0400848 if ($bug) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400849 return 0 if ($in_bisect);
Steven Rostedt576f6272010-11-02 14:58:38 -0400850 fail "failed - got a bug report" and return 0;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400851 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400852
Steven Rostedta75fece2010-11-02 14:58:27 -0400853 if (!$booted) {
854 return 0 if ($in_bisect);
Steven Rostedt576f6272010-11-02 14:58:38 -0400855 fail "failed - never got a boot prompt." and return 0;
Steven Rostedta75fece2010-11-02 14:58:27 -0400856 }
857
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400858 return 1;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400859}
860
861sub install {
862
Steven Rostedte48c5292010-11-02 14:35:37 -0400863 run_scp "$outputdir/$build_target", "$target_image" or
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400864 dodie "failed to copy image";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400865
866 my $install_mods = 0;
867
868 # should we process modules?
869 $install_mods = 0;
Steven Rostedt51ad1dd2010-11-08 16:43:21 -0500870 open(IN, "$output_config") or dodie("Can't read config file");
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400871 while (<IN>) {
872 if (/CONFIG_MODULES(=y)?/) {
873 $install_mods = 1 if (defined($1));
874 last;
875 }
876 }
877 close(IN);
878
879 if (!$install_mods) {
880 doprint "No modules needed\n";
881 return;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400882 }
883
Steven Rostedta75fece2010-11-02 14:58:27 -0400884 run_command "$make INSTALL_MOD_PATH=$tmpdir modules_install" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400885 dodie "Failed to install modules";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400886
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400887 my $modlib = "/lib/modules/$version";
Steven Rostedta57419b2010-11-02 15:13:54 -0400888 my $modtar = "ktest-mods.tar.bz2";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400889
Steven Rostedte48c5292010-11-02 14:35:37 -0400890 run_ssh "rm -rf $modlib" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400891 dodie "failed to remove old mods: $modlib";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400892
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400893 # would be nice if scp -r did not follow symbolic links
Steven Rostedta75fece2010-11-02 14:58:27 -0400894 run_command "cd $tmpdir && tar -cjf $modtar lib/modules/$version" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400895 dodie "making tarball";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400896
Steven Rostedte48c5292010-11-02 14:35:37 -0400897 run_scp "$tmpdir/$modtar", "/tmp" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400898 dodie "failed to copy modules";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400899
Steven Rostedta75fece2010-11-02 14:58:27 -0400900 unlink "$tmpdir/$modtar";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400901
Steven Rostedte48c5292010-11-02 14:35:37 -0400902 run_ssh "'(cd / && tar xf /tmp/$modtar)'" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400903 dodie "failed to tar modules";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400904
Steven Rostedte48c5292010-11-02 14:35:37 -0400905 run_ssh "rm -f /tmp/$modtar";
Steven Rostedt8b37ca82010-11-02 14:58:33 -0400906
907 return if (!defined($post_install));
908
Steven Rostedte48c5292010-11-02 14:35:37 -0400909 my $cp_post_install = $post_install;
910 $cp_post_install = s/\$KERNEL_VERSION/$version/g;
911 run_command "$cp_post_install" or
Steven Rostedt576f6272010-11-02 14:58:38 -0400912 dodie "Failed to run post install";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400913}
914
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -0400915sub check_buildlog {
916 my ($patch) = @_;
917
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -0400918 my @files = `git show $patch | diffstat -l`;
919
920 open(IN, "git show $patch |") or
921 dodie "failed to show $patch";
922 while (<IN>) {
923 if (m,^--- a/(.*),) {
924 chomp $1;
925 $files[$#files] = $1;
926 }
927 }
928 close(IN);
929
930 open(IN, $buildlog) or dodie "Can't open $buildlog";
931 while (<IN>) {
932 if (/^\s*(.*?):.*(warning|error)/) {
933 my $err = $1;
934 foreach my $file (@files) {
Steven Rostedta75fece2010-11-02 14:58:27 -0400935 my $fullpath = "$builddir/$file";
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -0400936 if ($file eq $err || $fullpath eq $err) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400937 fail "$file built with warnings" and return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -0400938 }
939 }
940 }
941 }
942 close(IN);
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400943
944 return 1;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -0400945}
946
Steven Rostedt612b9e92011-03-07 13:27:43 -0500947sub make_oldconfig {
948 my ($defconfig) = @_;
949
950 if (!run_command "$defconfig $make oldnoconfig") {
951 # Perhaps oldnoconfig doesn't exist in this version of the kernel
952 # try a yes '' | oldconfig
953 doprint "oldnoconfig failed, trying yes '' | make oldconfig\n";
954 run_command "yes '' | $defconfig $make oldconfig" or
955 dodie "failed make config oldconfig";
956 }
957}
958
Steven Rostedt2545eb62010-11-02 15:01:32 -0400959sub build {
960 my ($type) = @_;
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400961 my $defconfig = "";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400962
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400963 unlink $buildlog;
964
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400965 if ($type =~ /^useconfig:(.*)/) {
Steven Rostedt51ad1dd2010-11-08 16:43:21 -0500966 run_command "cp $1 $output_config" or
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400967 dodie "could not copy $1 to .config";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400968
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400969 $type = "oldconfig";
970 }
971
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400972 # old config can ask questions
973 if ($type eq "oldconfig") {
Steven Rostedt9386c6a2010-11-08 16:35:48 -0500974 $type = "oldnoconfig";
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400975
976 # allow for empty configs
Steven Rostedt51ad1dd2010-11-08 16:43:21 -0500977 run_command "touch $output_config";
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400978
Steven Rostedt51ad1dd2010-11-08 16:43:21 -0500979 run_command "mv $output_config $outputdir/config_temp" or
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400980 dodie "moving .config";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400981
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400982 if (!$noclean && !run_command "$make mrproper") {
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400983 dodie "make mrproper";
984 }
985
Steven Rostedt51ad1dd2010-11-08 16:43:21 -0500986 run_command "mv $outputdir/config_temp $output_config" or
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400987 dodie "moving config_temp";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400988
989 } elsif (!$noclean) {
Steven Rostedt51ad1dd2010-11-08 16:43:21 -0500990 unlink "$output_config";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400991 run_command "$make mrproper" or
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400992 dodie "make mrproper";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400993 }
Steven Rostedt2545eb62010-11-02 15:01:32 -0400994
995 # add something to distinguish this build
Steven Rostedta75fece2010-11-02 14:58:27 -0400996 open(OUT, "> $outputdir/localversion") or dodie("Can't make localversion file");
997 print OUT "$localversion\n";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400998 close(OUT);
999
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001000 if (defined($minconfig)) {
1001 $defconfig = "KCONFIG_ALLCONFIG=$minconfig";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001002 }
1003
Steven Rostedt612b9e92011-03-07 13:27:43 -05001004 if ($type eq "oldnoconfig") {
1005 make_oldconfig $defconfig;
1006 } else {
1007 run_command "$defconfig $make $type" or
1008 dodie "failed make config";
1009 }
Steven Rostedt2545eb62010-11-02 15:01:32 -04001010
Steven Rostedta75fece2010-11-02 14:58:27 -04001011 $redirect = "$buildlog";
1012 if (!run_command "$make $build_options") {
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001013 undef $redirect;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001014 # bisect may need this to pass
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001015 return 0 if ($in_bisect);
1016 fail "failed build" and return 0;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001017 }
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001018 undef $redirect;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001019
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001020 return 1;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001021}
1022
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001023sub halt {
Steven Rostedte48c5292010-11-02 14:35:37 -04001024 if (!run_ssh "halt" or defined($power_off)) {
Steven Rostedt576f6272010-11-02 14:58:38 -04001025 if (defined($poweroff_after_halt)) {
1026 sleep $poweroff_after_halt;
1027 run_command "$power_off";
1028 }
1029 } else {
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001030 # nope? the zap it!
Steven Rostedta75fece2010-11-02 14:58:27 -04001031 run_command "$power_off";
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001032 }
1033}
1034
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001035sub success {
1036 my ($i) = @_;
1037
Steven Rostedte48c5292010-11-02 14:35:37 -04001038 $successes++;
1039
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001040 doprint "\n\n*******************************************\n";
1041 doprint "*******************************************\n";
Steven Rostedt7a849cd2010-11-08 16:49:25 -05001042 doprint "KTEST RESULT: TEST $i SUCCESS!!!! **\n";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001043 doprint "*******************************************\n";
1044 doprint "*******************************************\n";
1045
Steven Rostedt576f6272010-11-02 14:58:38 -04001046 if ($i != $opt{"NUM_TESTS"} && !do_not_reboot) {
Steven Rostedta75fece2010-11-02 14:58:27 -04001047 doprint "Reboot and wait $sleep_time seconds\n";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001048 reboot;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001049 start_monitor;
Steven Rostedta75fece2010-11-02 14:58:27 -04001050 wait_for_monitor $sleep_time;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001051 end_monitor;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001052 }
1053}
1054
1055sub get_version {
1056 # get the release name
1057 doprint "$make kernelrelease ... ";
1058 $version = `$make kernelrelease | tail -1`;
1059 chomp($version);
1060 doprint "$version\n";
1061}
1062
Steven Rostedtc960bb92011-03-08 09:22:39 -05001063sub answer_bisect {
1064 for (;;) {
1065 doprint "Pass or fail? [p/f]";
1066 my $ans = <STDIN>;
1067 chomp $ans;
1068 if ($ans eq "p" || $ans eq "P") {
1069 return 1;
1070 } elsif ($ans eq "f" || $ans eq "F") {
1071 return 0;
1072 } else {
1073 print "Please answer 'P' or 'F'\n";
1074 }
1075 }
1076}
1077
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001078sub child_run_test {
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001079 my $failed = 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001080
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001081 # child should have no power
Steven Rostedta75fece2010-11-02 14:58:27 -04001082 $reboot_on_error = 0;
1083 $poweroff_on_error = 0;
1084 $die_on_failure = 1;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001085
1086 run_command $run_test or $failed = 1;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001087 exit $failed;
1088}
1089
1090my $child_done;
1091
1092sub child_finished {
1093 $child_done = 1;
1094}
1095
1096sub do_run_test {
1097 my $child_pid;
1098 my $child_exit;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001099 my $line;
1100 my $full_line;
1101 my $bug = 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001102
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001103 wait_for_monitor 1;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001104
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001105 doprint "run test $run_test\n";
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001106
1107 $child_done = 0;
1108
1109 $SIG{CHLD} = qw(child_finished);
1110
1111 $child_pid = fork;
1112
1113 child_run_test if (!$child_pid);
1114
1115 $full_line = "";
1116
1117 do {
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001118 $line = wait_for_input($monitor_fp, 1);
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001119 if (defined($line)) {
1120
1121 # we are not guaranteed to get a full line
1122 $full_line .= $line;
Steven Rostedt8ea0e062011-03-08 09:44:35 -05001123 doprint $line;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001124
1125 if ($full_line =~ /call trace:/i) {
1126 $bug = 1;
1127 }
1128
1129 if ($full_line =~ /Kernel panic -/) {
1130 $bug = 1;
1131 }
1132
1133 if ($line =~ /\n/) {
1134 $full_line = "";
1135 }
1136 }
1137 } while (!$child_done && !$bug);
1138
1139 if ($bug) {
Steven Rostedt8ea0e062011-03-08 09:44:35 -05001140 my $failure_start = time;
1141 my $now;
1142 do {
1143 $line = wait_for_input($monitor_fp, 1);
1144 if (defined($line)) {
1145 doprint $line;
1146 }
1147 $now = time;
1148 if ($now - $failure_start >= $stop_after_failure) {
1149 last;
1150 }
1151 } while (defined($line));
1152
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001153 doprint "Detected kernel crash!\n";
1154 # kill the child with extreme prejudice
1155 kill 9, $child_pid;
1156 }
1157
1158 waitpid $child_pid, 0;
1159 $child_exit = $?;
1160
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001161 if ($bug || $child_exit) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001162 return 0 if $in_bisect;
1163 fail "test failed" and return 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001164 }
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001165 return 1;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001166}
1167
Steven Rostedta75fece2010-11-02 14:58:27 -04001168sub run_git_bisect {
1169 my ($command) = @_;
1170
1171 doprint "$command ... ";
1172
1173 my $output = `$command 2>&1`;
1174 my $ret = $?;
1175
1176 logit $output;
1177
1178 if ($ret) {
1179 doprint "FAILED\n";
1180 dodie "Failed to git bisect";
1181 }
1182
1183 doprint "SUCCESS\n";
1184 if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\))\s+\[([[:xdigit:]]+)\]/) {
1185 doprint "$1 [$2]\n";
1186 } elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) {
1187 $bisect_bad = $1;
1188 doprint "Found bad commit... $1\n";
1189 return 0;
1190 } else {
1191 # we already logged it, just print it now.
1192 print $output;
1193 }
1194
1195 return 1;
1196}
1197
Steven Rostedtc23dca72011-03-08 09:26:31 -05001198sub bisect_reboot {
1199 doprint "Reboot and sleep $bisect_sleep_time seconds\n";
1200 reboot;
1201 start_monitor;
1202 wait_for_monitor $bisect_sleep_time;
1203 end_monitor;
1204}
1205
1206# returns 1 on success, 0 on failure, -1 on skip
Steven Rostedt0a05c762010-11-08 11:14:10 -05001207sub run_bisect_test {
1208 my ($type, $buildtype) = @_;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001209
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001210 my $failed = 0;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001211 my $result;
1212 my $output;
1213 my $ret;
1214
Steven Rostedt0a05c762010-11-08 11:14:10 -05001215 $in_bisect = 1;
1216
1217 build $buildtype or $failed = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001218
1219 if ($type ne "build") {
Steven Rostedtc23dca72011-03-08 09:26:31 -05001220 if ($failed && $bisect_skip) {
1221 $in_bisect = 0;
1222 return -1;
1223 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001224 dodie "Failed on build" if $failed;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001225
1226 # Now boot the box
1227 get_grub_index;
1228 get_version;
1229 install;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001230
1231 start_monitor;
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001232 monitor or $failed = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001233
1234 if ($type ne "boot") {
Steven Rostedtc23dca72011-03-08 09:26:31 -05001235 if ($failed && $bisect_skip) {
1236 end_monitor;
1237 bisect_reboot;
1238 $in_bisect = 0;
1239 return -1;
1240 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001241 dodie "Failed on boot" if $failed;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001242
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001243 do_run_test or $failed = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001244 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001245 end_monitor;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001246 }
1247
1248 if ($failed) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001249 $result = 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001250
1251 # reboot the box to a good kernel
Steven Rostedta75fece2010-11-02 14:58:27 -04001252 if ($type ne "build") {
Steven Rostedtc23dca72011-03-08 09:26:31 -05001253 bisect_reboot;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001254 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001255 } else {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001256 $result = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001257 }
Steven Rostedt0a05c762010-11-08 11:14:10 -05001258 $in_bisect = 0;
1259
1260 return $result;
1261}
1262
1263sub run_bisect {
1264 my ($type) = @_;
1265 my $buildtype = "oldconfig";
1266
1267 # We should have a minconfig to use?
1268 if (defined($minconfig)) {
1269 $buildtype = "useconfig:$minconfig";
1270 }
1271
1272 my $ret = run_bisect_test $type, $buildtype;
1273
Steven Rostedtc960bb92011-03-08 09:22:39 -05001274 if ($bisect_manual) {
1275 $ret = answer_bisect;
1276 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001277
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04001278 # Are we looking for where it worked, not failed?
1279 if ($reverse_bisect) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001280 $ret = !$ret;
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04001281 }
1282
Steven Rostedtc23dca72011-03-08 09:26:31 -05001283 if ($ret > 0) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001284 return "good";
Steven Rostedtc23dca72011-03-08 09:26:31 -05001285 } elsif ($ret == 0) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001286 return "bad";
Steven Rostedtc23dca72011-03-08 09:26:31 -05001287 } elsif ($bisect_skip) {
1288 doprint "HIT A BAD COMMIT ... SKIPPING\n";
1289 return "skip";
Steven Rostedt0a05c762010-11-08 11:14:10 -05001290 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001291}
1292
1293sub bisect {
1294 my ($i) = @_;
1295
1296 my $result;
1297
1298 die "BISECT_GOOD[$i] not defined\n" if (!defined($opt{"BISECT_GOOD[$i]"}));
1299 die "BISECT_BAD[$i] not defined\n" if (!defined($opt{"BISECT_BAD[$i]"}));
1300 die "BISECT_TYPE[$i] not defined\n" if (!defined($opt{"BISECT_TYPE[$i]"}));
1301
1302 my $good = $opt{"BISECT_GOOD[$i]"};
1303 my $bad = $opt{"BISECT_BAD[$i]"};
1304 my $type = $opt{"BISECT_TYPE[$i]"};
Steven Rostedta75fece2010-11-02 14:58:27 -04001305 my $start = $opt{"BISECT_START[$i]"};
1306 my $replay = $opt{"BISECT_REPLAY[$i]"};
Steven Rostedt3410f6f2011-03-08 09:38:12 -05001307 my $start_files = $opt{"BISECT_FILES[$i]"};
1308
1309 if (defined($start_files)) {
1310 $start_files = " -- " . $start_files;
1311 } else {
1312 $start_files = "";
1313 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001314
Steven Rostedta57419b2010-11-02 15:13:54 -04001315 # convert to true sha1's
1316 $good = get_sha1($good);
1317 $bad = get_sha1($bad);
1318
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04001319 if (defined($opt{"BISECT_REVERSE[$i]"}) &&
1320 $opt{"BISECT_REVERSE[$i]"} == 1) {
1321 doprint "Performing a reverse bisect (bad is good, good is bad!)\n";
1322 $reverse_bisect = 1;
1323 } else {
1324 $reverse_bisect = 0;
1325 }
1326
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001327 # Can't have a test without having a test to run
1328 if ($type eq "test" && !defined($run_test)) {
1329 $type = "boot";
1330 }
1331
Steven Rostedta75fece2010-11-02 14:58:27 -04001332 my $check = $opt{"BISECT_CHECK[$i]"};
1333 if (defined($check) && $check ne "0") {
1334
1335 # get current HEAD
Steven Rostedta57419b2010-11-02 15:13:54 -04001336 my $head = get_sha1("HEAD");
Steven Rostedta75fece2010-11-02 14:58:27 -04001337
1338 if ($check ne "good") {
1339 doprint "TESTING BISECT BAD [$bad]\n";
1340 run_command "git checkout $bad" or
1341 die "Failed to checkout $bad";
1342
1343 $result = run_bisect $type;
1344
1345 if ($result ne "bad") {
1346 fail "Tested BISECT_BAD [$bad] and it succeeded" and return 0;
1347 }
1348 }
1349
1350 if ($check ne "bad") {
1351 doprint "TESTING BISECT GOOD [$good]\n";
1352 run_command "git checkout $good" or
1353 die "Failed to checkout $good";
1354
1355 $result = run_bisect $type;
1356
1357 if ($result ne "good") {
1358 fail "Tested BISECT_GOOD [$good] and it failed" and return 0;
1359 }
1360 }
1361
1362 # checkout where we started
1363 run_command "git checkout $head" or
1364 die "Failed to checkout $head";
1365 }
1366
Steven Rostedt3410f6f2011-03-08 09:38:12 -05001367 run_command "git bisect start$start_files" or
Steven Rostedta75fece2010-11-02 14:58:27 -04001368 dodie "could not start bisect";
1369
1370 run_command "git bisect good $good" or
1371 dodie "could not set bisect good to $good";
1372
1373 run_git_bisect "git bisect bad $bad" or
1374 dodie "could not set bisect bad to $bad";
1375
1376 if (defined($replay)) {
1377 run_command "git bisect replay $replay" or
1378 dodie "failed to run replay";
1379 }
1380
1381 if (defined($start)) {
1382 run_command "git checkout $start" or
1383 dodie "failed to checkout $start";
1384 }
1385
1386 my $test;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001387 do {
1388 $result = run_bisect $type;
Steven Rostedta75fece2010-11-02 14:58:27 -04001389 $test = run_git_bisect "git bisect $result";
1390 } while ($test);
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001391
1392 run_command "git bisect log" or
1393 dodie "could not capture git bisect log";
1394
1395 run_command "git bisect reset" or
1396 dodie "could not reset git bisect";
1397
1398 doprint "Bad commit was [$bisect_bad]\n";
1399
Steven Rostedt0a05c762010-11-08 11:14:10 -05001400 success $i;
1401}
1402
1403my %config_ignore;
1404my %config_set;
1405
1406my %config_list;
1407my %null_config;
1408
1409my %dependency;
1410
1411sub process_config_ignore {
1412 my ($config) = @_;
1413
1414 open (IN, $config)
1415 or dodie "Failed to read $config";
1416
1417 while (<IN>) {
1418 if (/^(.*?(CONFIG\S*)(=.*| is not set))/) {
1419 $config_ignore{$2} = $1;
1420 }
1421 }
1422
1423 close(IN);
1424}
1425
1426sub read_current_config {
1427 my ($config_ref) = @_;
1428
1429 %{$config_ref} = ();
1430 undef %{$config_ref};
1431
1432 my @key = keys %{$config_ref};
1433 if ($#key >= 0) {
1434 print "did not delete!\n";
1435 exit;
1436 }
1437 open (IN, "$output_config");
1438
1439 while (<IN>) {
1440 if (/^(CONFIG\S+)=(.*)/) {
1441 ${$config_ref}{$1} = $2;
1442 }
1443 }
1444 close(IN);
1445}
1446
1447sub get_dependencies {
1448 my ($config) = @_;
1449
1450 my $arr = $dependency{$config};
1451 if (!defined($arr)) {
1452 return ();
1453 }
1454
1455 my @deps = @{$arr};
1456
1457 foreach my $dep (@{$arr}) {
1458 print "ADD DEP $dep\n";
1459 @deps = (@deps, get_dependencies $dep);
1460 }
1461
1462 return @deps;
1463}
1464
1465sub create_config {
1466 my @configs = @_;
1467
1468 open(OUT, ">$output_config") or dodie "Can not write to $output_config";
1469
1470 foreach my $config (@configs) {
1471 print OUT "$config_set{$config}\n";
1472 my @deps = get_dependencies $config;
1473 foreach my $dep (@deps) {
1474 print OUT "$config_set{$dep}\n";
1475 }
1476 }
1477
1478 foreach my $config (keys %config_ignore) {
1479 print OUT "$config_ignore{$config}\n";
1480 }
1481 close(OUT);
1482
1483# exit;
Steven Rostedt612b9e92011-03-07 13:27:43 -05001484 make_oldconfig "";
Steven Rostedt0a05c762010-11-08 11:14:10 -05001485}
1486
1487sub compare_configs {
1488 my (%a, %b) = @_;
1489
1490 foreach my $item (keys %a) {
1491 if (!defined($b{$item})) {
1492 print "diff $item\n";
1493 return 1;
1494 }
1495 delete $b{$item};
1496 }
1497
1498 my @keys = keys %b;
1499 if ($#keys) {
1500 print "diff2 $keys[0]\n";
1501 }
1502 return -1 if ($#keys >= 0);
1503
1504 return 0;
1505}
1506
1507sub run_config_bisect_test {
1508 my ($type) = @_;
1509
1510 return run_bisect_test $type, "oldconfig";
1511}
1512
1513sub process_passed {
1514 my (%configs) = @_;
1515
1516 doprint "These configs had no failure: (Enabling them for further compiles)\n";
1517 # Passed! All these configs are part of a good compile.
1518 # Add them to the min options.
1519 foreach my $config (keys %configs) {
1520 if (defined($config_list{$config})) {
1521 doprint " removing $config\n";
1522 $config_ignore{$config} = $config_list{$config};
1523 delete $config_list{$config};
1524 }
1525 }
Steven Rostedtf1a27852010-11-11 11:34:38 -05001526 doprint "config copied to $outputdir/config_good\n";
1527 run_command "cp -f $output_config $outputdir/config_good";
Steven Rostedt0a05c762010-11-08 11:14:10 -05001528}
1529
1530sub process_failed {
1531 my ($config) = @_;
1532
1533 doprint "\n\n***************************************\n";
1534 doprint "Found bad config: $config\n";
1535 doprint "***************************************\n\n";
1536}
1537
1538sub run_config_bisect {
1539
1540 my @start_list = keys %config_list;
1541
1542 if ($#start_list < 0) {
1543 doprint "No more configs to test!!!\n";
1544 return -1;
1545 }
1546
1547 doprint "***** RUN TEST ***\n";
1548 my $type = $opt{"CONFIG_BISECT_TYPE[$iteration]"};
1549 my $ret;
1550 my %current_config;
1551
1552 my $count = $#start_list + 1;
1553 doprint " $count configs to test\n";
1554
1555 my $half = int($#start_list / 2);
1556
1557 do {
1558 my @tophalf = @start_list[0 .. $half];
1559
1560 create_config @tophalf;
1561 read_current_config \%current_config;
1562
1563 $count = $#tophalf + 1;
1564 doprint "Testing $count configs\n";
1565 my $found = 0;
1566 # make sure we test something
1567 foreach my $config (@tophalf) {
1568 if (defined($current_config{$config})) {
1569 logit " $config\n";
1570 $found = 1;
1571 }
1572 }
1573 if (!$found) {
1574 # try the other half
1575 doprint "Top half produced no set configs, trying bottom half\n";
1576 @tophalf = @start_list[$half .. $#start_list];
1577 create_config @tophalf;
1578 read_current_config \%current_config;
1579 foreach my $config (@tophalf) {
1580 if (defined($current_config{$config})) {
1581 logit " $config\n";
1582 $found = 1;
1583 }
1584 }
1585 if (!$found) {
1586 doprint "Failed: Can't make new config with current configs\n";
1587 foreach my $config (@start_list) {
1588 doprint " CONFIG: $config\n";
1589 }
1590 return -1;
1591 }
1592 $count = $#tophalf + 1;
1593 doprint "Testing $count configs\n";
1594 }
1595
1596 $ret = run_config_bisect_test $type;
Steven Rostedtc960bb92011-03-08 09:22:39 -05001597 if ($bisect_manual) {
1598 $ret = answer_bisect;
1599 }
Steven Rostedt0a05c762010-11-08 11:14:10 -05001600 if ($ret) {
1601 process_passed %current_config;
1602 return 0;
1603 }
1604
1605 doprint "This config had a failure.\n";
1606 doprint "Removing these configs that were not set in this config:\n";
Steven Rostedtf1a27852010-11-11 11:34:38 -05001607 doprint "config copied to $outputdir/config_bad\n";
1608 run_command "cp -f $output_config $outputdir/config_bad";
Steven Rostedt0a05c762010-11-08 11:14:10 -05001609
1610 # A config exists in this group that was bad.
1611 foreach my $config (keys %config_list) {
1612 if (!defined($current_config{$config})) {
1613 doprint " removing $config\n";
1614 delete $config_list{$config};
1615 }
1616 }
1617
1618 @start_list = @tophalf;
1619
1620 if ($#start_list == 0) {
1621 process_failed $start_list[0];
1622 return 1;
1623 }
1624
1625 # remove half the configs we are looking at and see if
1626 # they are good.
1627 $half = int($#start_list / 2);
1628 } while ($half > 0);
1629
Steven Rostedtc960bb92011-03-08 09:22:39 -05001630 # we found a single config, try it again unless we are running manually
1631
1632 if ($bisect_manual) {
1633 process_failed $start_list[0];
1634 return 1;
1635 }
1636
Steven Rostedt0a05c762010-11-08 11:14:10 -05001637 my @tophalf = @start_list[0 .. 0];
1638
1639 $ret = run_config_bisect_test $type;
1640 if ($ret) {
1641 process_passed %current_config;
1642 return 0;
1643 }
1644
1645 process_failed $start_list[0];
1646 return 1;
1647}
1648
1649sub config_bisect {
1650 my ($i) = @_;
1651
1652 my $start_config = $opt{"CONFIG_BISECT[$i]"};
1653
1654 my $tmpconfig = "$tmpdir/use_config";
1655
1656 # Make the file with the bad config and the min config
1657 if (defined($minconfig)) {
1658 # read the min config for things to ignore
1659 run_command "cp $minconfig $tmpconfig" or
1660 dodie "failed to copy $minconfig to $tmpconfig";
1661 } else {
1662 unlink $tmpconfig;
1663 }
1664
1665 # Add other configs
1666 if (defined($addconfig)) {
1667 run_command "cat $addconfig >> $tmpconfig" or
1668 dodie "failed to append $addconfig";
1669 }
1670
1671 my $defconfig = "";
1672 if (-f $tmpconfig) {
1673 $defconfig = "KCONFIG_ALLCONFIG=$tmpconfig";
1674 process_config_ignore $tmpconfig;
1675 }
1676
1677 # now process the start config
1678 run_command "cp $start_config $output_config" or
1679 dodie "failed to copy $start_config to $output_config";
1680
1681 # read directly what we want to check
1682 my %config_check;
1683 open (IN, $output_config)
1684 or dodie "faied to open $output_config";
1685
1686 while (<IN>) {
1687 if (/^((CONFIG\S*)=.*)/) {
1688 $config_check{$2} = $1;
1689 }
1690 }
1691 close(IN);
1692
1693 # Now run oldconfig with the minconfig (and addconfigs)
Steven Rostedt612b9e92011-03-07 13:27:43 -05001694 make_oldconfig $defconfig;
Steven Rostedt0a05c762010-11-08 11:14:10 -05001695
1696 # check to see what we lost (or gained)
1697 open (IN, $output_config)
1698 or dodie "Failed to read $start_config";
1699
1700 my %removed_configs;
1701 my %added_configs;
1702
1703 while (<IN>) {
1704 if (/^((CONFIG\S*)=.*)/) {
1705 # save off all options
1706 $config_set{$2} = $1;
1707 if (defined($config_check{$2})) {
1708 if (defined($config_ignore{$2})) {
1709 $removed_configs{$2} = $1;
1710 } else {
1711 $config_list{$2} = $1;
1712 }
1713 } elsif (!defined($config_ignore{$2})) {
1714 $added_configs{$2} = $1;
1715 $config_list{$2} = $1;
1716 }
1717 }
1718 }
1719 close(IN);
1720
1721 my @confs = keys %removed_configs;
1722 if ($#confs >= 0) {
1723 doprint "Configs overridden by default configs and removed from check:\n";
1724 foreach my $config (@confs) {
1725 doprint " $config\n";
1726 }
1727 }
1728 @confs = keys %added_configs;
1729 if ($#confs >= 0) {
1730 doprint "Configs appearing in make oldconfig and added:\n";
1731 foreach my $config (@confs) {
1732 doprint " $config\n";
1733 }
1734 }
1735
1736 my %config_test;
1737 my $once = 0;
1738
1739 # Sometimes kconfig does weird things. We must make sure
1740 # that the config we autocreate has everything we need
1741 # to test, otherwise we may miss testing configs, or
1742 # may not be able to create a new config.
1743 # Here we create a config with everything set.
1744 create_config (keys %config_list);
1745 read_current_config \%config_test;
1746 foreach my $config (keys %config_list) {
1747 if (!defined($config_test{$config})) {
1748 if (!$once) {
1749 $once = 1;
1750 doprint "Configs not produced by kconfig (will not be checked):\n";
1751 }
1752 doprint " $config\n";
1753 delete $config_list{$config};
1754 }
1755 }
1756 my $ret;
1757 do {
1758 $ret = run_config_bisect;
1759 } while (!$ret);
1760
1761 return $ret if ($ret < 0);
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001762
1763 success $i;
1764}
1765
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001766sub patchcheck {
1767 my ($i) = @_;
1768
1769 die "PATCHCHECK_START[$i] not defined\n"
1770 if (!defined($opt{"PATCHCHECK_START[$i]"}));
1771 die "PATCHCHECK_TYPE[$i] not defined\n"
1772 if (!defined($opt{"PATCHCHECK_TYPE[$i]"}));
1773
1774 my $start = $opt{"PATCHCHECK_START[$i]"};
1775
1776 my $end = "HEAD";
1777 if (defined($opt{"PATCHCHECK_END[$i]"})) {
1778 $end = $opt{"PATCHCHECK_END[$i]"};
1779 }
1780
Steven Rostedta57419b2010-11-02 15:13:54 -04001781 # Get the true sha1's since we can use things like HEAD~3
1782 $start = get_sha1($start);
1783 $end = get_sha1($end);
1784
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001785 my $type = $opt{"PATCHCHECK_TYPE[$i]"};
1786
1787 # Can't have a test without having a test to run
1788 if ($type eq "test" && !defined($run_test)) {
1789 $type = "boot";
1790 }
1791
1792 open (IN, "git log --pretty=oneline $end|") or
1793 dodie "could not get git list";
1794
1795 my @list;
1796
1797 while (<IN>) {
1798 chomp;
1799 $list[$#list+1] = $_;
1800 last if (/^$start/);
1801 }
1802 close(IN);
1803
1804 if ($list[$#list] !~ /^$start/) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001805 fail "SHA1 $start not found";
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001806 }
1807
1808 # go backwards in the list
1809 @list = reverse @list;
1810
1811 my $save_clean = $noclean;
1812
1813 $in_patchcheck = 1;
1814 foreach my $item (@list) {
1815 my $sha1 = $item;
1816 $sha1 =~ s/^([[:xdigit:]]+).*/$1/;
1817
1818 doprint "\nProcessing commit $item\n\n";
1819
1820 run_command "git checkout $sha1" or
1821 die "Failed to checkout $sha1";
1822
1823 # only clean on the first and last patch
1824 if ($item eq $list[0] ||
1825 $item eq $list[$#list]) {
1826 $noclean = $save_clean;
1827 } else {
1828 $noclean = 1;
1829 }
1830
1831 if (defined($minconfig)) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001832 build "useconfig:$minconfig" or return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001833 } else {
1834 # ?? no config to use?
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001835 build "oldconfig" or return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001836 }
1837
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001838 check_buildlog $sha1 or return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001839
1840 next if ($type eq "build");
1841
1842 get_grub_index;
1843 get_version;
1844 install;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001845
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001846 my $failed = 0;
1847
1848 start_monitor;
1849 monitor or $failed = 1;
1850
1851 if (!$failed && $type ne "boot"){
1852 do_run_test or $failed = 1;
1853 }
1854 end_monitor;
1855 return 0 if ($failed);
1856
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001857 }
1858 $in_patchcheck = 0;
1859 success $i;
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001860
1861 return 1;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001862}
1863
Steven Rostedt8d1491b2010-11-18 15:39:48 -05001864$#ARGV < 1 or die "ktest.pl version: $VERSION\n usage: ktest.pl config-file\n";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001865
Steven Rostedt8d1491b2010-11-18 15:39:48 -05001866if ($#ARGV == 0) {
1867 $ktest_config = $ARGV[0];
1868 if (! -f $ktest_config) {
1869 print "$ktest_config does not exist.\n";
1870 my $ans;
1871 for (;;) {
1872 print "Create it? [Y/n] ";
1873 $ans = <STDIN>;
1874 chomp $ans;
1875 if ($ans =~ /^\s*$/) {
1876 $ans = "y";
1877 }
1878 last if ($ans =~ /^y$/i || $ans =~ /^n$/i);
1879 print "Please answer either 'y' or 'n'.\n";
1880 }
1881 if ($ans !~ /^y$/i) {
1882 exit 0;
1883 }
1884 }
1885} else {
1886 $ktest_config = "ktest.conf";
1887}
1888
1889if (! -f $ktest_config) {
1890 open(OUT, ">$ktest_config") or die "Can not create $ktest_config";
1891 print OUT << "EOF"
1892# Generated by ktest.pl
1893#
1894# Define each test with TEST_START
1895# The config options below it will override the defaults
1896TEST_START
1897
1898DEFAULTS
1899EOF
1900;
1901 close(OUT);
1902}
1903read_config $ktest_config;
1904
1905# Append any configs entered in manually to the config file.
1906my @new_configs = keys %entered_configs;
1907if ($#new_configs >= 0) {
1908 print "\nAppending entered in configs to $ktest_config\n";
1909 open(OUT, ">>$ktest_config") or die "Can not append to $ktest_config";
1910 foreach my $config (@new_configs) {
1911 print OUT "$config = $entered_configs{$config}\n";
1912 $opt{$config} = $entered_configs{$config};
1913 }
1914}
Steven Rostedt2545eb62010-11-02 15:01:32 -04001915
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001916if ($opt{"CLEAR_LOG"} && defined($opt{"LOG_FILE"})) {
1917 unlink $opt{"LOG_FILE"};
1918}
Steven Rostedt2545eb62010-11-02 15:01:32 -04001919
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001920doprint "\n\nSTARTING AUTOMATED TESTS\n\n";
1921
Steven Rostedta57419b2010-11-02 15:13:54 -04001922for (my $i = 0, my $repeat = 1; $i <= $opt{"NUM_TESTS"}; $i += $repeat) {
1923
1924 if (!$i) {
1925 doprint "DEFAULT OPTIONS:\n";
1926 } else {
1927 doprint "\nTEST $i OPTIONS";
1928 if (defined($repeat_tests{$i})) {
1929 $repeat = $repeat_tests{$i};
1930 doprint " ITERATE $repeat";
1931 }
1932 doprint "\n";
1933 }
1934
1935 foreach my $option (sort keys %opt) {
1936
1937 if ($option =~ /\[(\d+)\]$/) {
1938 next if ($i != $1);
1939 } else {
1940 next if ($i);
1941 }
1942
1943 doprint "$option = $opt{$option}\n";
1944 }
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001945}
Steven Rostedt2545eb62010-11-02 15:01:32 -04001946
Steven Rostedta75fece2010-11-02 14:58:27 -04001947sub set_test_option {
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001948 my ($name, $i) = @_;
1949
1950 my $option = "$name\[$i\]";
1951
1952 if (defined($opt{$option})) {
1953 return $opt{$option};
1954 }
1955
Steven Rostedta57419b2010-11-02 15:13:54 -04001956 foreach my $test (keys %repeat_tests) {
1957 if ($i >= $test &&
1958 $i < $test + $repeat_tests{$test}) {
1959 $option = "$name\[$test\]";
1960 if (defined($opt{$option})) {
1961 return $opt{$option};
1962 }
1963 }
1964 }
1965
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001966 if (defined($opt{$name})) {
1967 return $opt{$name};
1968 }
1969
1970 return undef;
1971}
1972
Steven Rostedt2545eb62010-11-02 15:01:32 -04001973# First we need to do is the builds
Steven Rostedta75fece2010-11-02 14:58:27 -04001974for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
Steven Rostedt2545eb62010-11-02 15:01:32 -04001975
Steven Rostedt576f6272010-11-02 14:58:38 -04001976 $iteration = $i;
1977
Steven Rostedta75fece2010-11-02 14:58:27 -04001978 my $makecmd = set_test_option("MAKE_CMD", $i);
1979
1980 $machine = set_test_option("MACHINE", $i);
Steven Rostedte48c5292010-11-02 14:35:37 -04001981 $ssh_user = set_test_option("SSH_USER", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04001982 $tmpdir = set_test_option("TMP_DIR", $i);
1983 $outputdir = set_test_option("OUTPUT_DIR", $i);
1984 $builddir = set_test_option("BUILD_DIR", $i);
1985 $test_type = set_test_option("TEST_TYPE", $i);
1986 $build_type = set_test_option("BUILD_TYPE", $i);
1987 $build_options = set_test_option("BUILD_OPTIONS", $i);
1988 $power_cycle = set_test_option("POWER_CYCLE", $i);
Steven Rostedte48c5292010-11-02 14:35:37 -04001989 $reboot = set_test_option("REBOOT", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04001990 $noclean = set_test_option("BUILD_NOCLEAN", $i);
1991 $minconfig = set_test_option("MIN_CONFIG", $i);
1992 $run_test = set_test_option("TEST", $i);
1993 $addconfig = set_test_option("ADD_CONFIG", $i);
1994 $reboot_type = set_test_option("REBOOT_TYPE", $i);
1995 $grub_menu = set_test_option("GRUB_MENU", $i);
Steven Rostedt8b37ca82010-11-02 14:58:33 -04001996 $post_install = set_test_option("POST_INSTALL", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04001997 $reboot_script = set_test_option("REBOOT_SCRIPT", $i);
1998 $reboot_on_error = set_test_option("REBOOT_ON_ERROR", $i);
1999 $poweroff_on_error = set_test_option("POWEROFF_ON_ERROR", $i);
2000 $die_on_failure = set_test_option("DIE_ON_FAILURE", $i);
2001 $power_off = set_test_option("POWER_OFF", $i);
Steven Rostedt576f6272010-11-02 14:58:38 -04002002 $powercycle_after_reboot = set_test_option("POWERCYCLE_AFTER_REBOOT", $i);
2003 $poweroff_after_halt = set_test_option("POWEROFF_AFTER_HALT", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002004 $sleep_time = set_test_option("SLEEP_TIME", $i);
2005 $bisect_sleep_time = set_test_option("BISECT_SLEEP_TIME", $i);
Steven Rostedtc960bb92011-03-08 09:22:39 -05002006 $bisect_manual = set_test_option("BISECT_MANUAL", $i);
Steven Rostedtc23dca72011-03-08 09:26:31 -05002007 $bisect_skip = set_test_option("BISECT_SKIP", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002008 $store_failures = set_test_option("STORE_FAILURES", $i);
2009 $timeout = set_test_option("TIMEOUT", $i);
2010 $booted_timeout = set_test_option("BOOTED_TIMEOUT", $i);
2011 $console = set_test_option("CONSOLE", $i);
2012 $success_line = set_test_option("SUCCESS_LINE", $i);
Steven Rostedt1c8a6172010-11-09 12:55:40 -05002013 $stop_after_success = set_test_option("STOP_AFTER_SUCCESS", $i);
2014 $stop_after_failure = set_test_option("STOP_AFTER_FAILURE", $i);
Steven Rostedt2d01b262011-03-08 09:47:54 -05002015 $stop_test_after = set_test_option("STOP_TEST_AFTER", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002016 $build_target = set_test_option("BUILD_TARGET", $i);
Steven Rostedte48c5292010-11-02 14:35:37 -04002017 $ssh_exec = set_test_option("SSH_EXEC", $i);
2018 $scp_to_target = set_test_option("SCP_TO_TARGET", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002019 $target_image = set_test_option("TARGET_IMAGE", $i);
2020 $localversion = set_test_option("LOCALVERSION", $i);
2021
2022 chdir $builddir || die "can't change directory to $builddir";
2023
2024 if (!-d $tmpdir) {
2025 mkpath($tmpdir) or
2026 die "can't create $tmpdir";
2027 }
2028
Steven Rostedte48c5292010-11-02 14:35:37 -04002029 $ENV{"SSH_USER"} = $ssh_user;
2030 $ENV{"MACHINE"} = $machine;
2031
Steven Rostedta75fece2010-11-02 14:58:27 -04002032 $target = "$ssh_user\@$machine";
2033
2034 $buildlog = "$tmpdir/buildlog-$machine";
2035 $dmesg = "$tmpdir/dmesg-$machine";
2036 $make = "$makecmd O=$outputdir";
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05002037 $output_config = "$outputdir/.config";
Steven Rostedta75fece2010-11-02 14:58:27 -04002038
2039 if ($reboot_type eq "grub") {
Steven Rostedt576f6272010-11-02 14:58:38 -04002040 dodie "GRUB_MENU not defined" if (!defined($grub_menu));
Steven Rostedta75fece2010-11-02 14:58:27 -04002041 } elsif (!defined($reboot_script)) {
Steven Rostedt576f6272010-11-02 14:58:38 -04002042 dodie "REBOOT_SCRIPT not defined"
Steven Rostedta75fece2010-11-02 14:58:27 -04002043 }
2044
2045 my $run_type = $build_type;
2046 if ($test_type eq "patchcheck") {
2047 $run_type = $opt{"PATCHCHECK_TYPE[$i]"};
2048 } elsif ($test_type eq "bisect") {
2049 $run_type = $opt{"BISECT_TYPE[$i]"};
Steven Rostedt0a05c762010-11-08 11:14:10 -05002050 } elsif ($test_type eq "config_bisect") {
2051 $run_type = $opt{"CONFIG_BISECT_TYPE[$i]"};
Steven Rostedta75fece2010-11-02 14:58:27 -04002052 }
2053
2054 # mistake in config file?
2055 if (!defined($run_type)) {
2056 $run_type = "ERROR";
2057 }
Steven Rostedt2545eb62010-11-02 15:01:32 -04002058
2059 doprint "\n\n";
Steven Rostedta75fece2010-11-02 14:58:27 -04002060 doprint "RUNNING TEST $i of $opt{NUM_TESTS} with option $test_type $run_type\n\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -04002061
2062 unlink $dmesg;
2063 unlink $buildlog;
Steven Rostedt2545eb62010-11-02 15:01:32 -04002064
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002065 if (!defined($minconfig)) {
2066 $minconfig = $addconfig;
2067
2068 } elsif (defined($addconfig)) {
Steven Rostedt9be2e6b2010-11-09 12:20:21 -05002069 run_command "cat $addconfig $minconfig > $tmpdir/add_config" or
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002070 dodie "Failed to create temp config";
Steven Rostedt9be2e6b2010-11-09 12:20:21 -05002071 $minconfig = "$tmpdir/add_config";
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002072 }
2073
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002074 my $checkout = $opt{"CHECKOUT[$i]"};
2075 if (defined($checkout)) {
2076 run_command "git checkout $checkout" or
2077 die "failed to checkout $checkout";
2078 }
2079
Steven Rostedta75fece2010-11-02 14:58:27 -04002080 if ($test_type eq "bisect") {
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04002081 bisect $i;
2082 next;
Steven Rostedt0a05c762010-11-08 11:14:10 -05002083 } elsif ($test_type eq "config_bisect") {
2084 config_bisect $i;
2085 next;
Steven Rostedta75fece2010-11-02 14:58:27 -04002086 } elsif ($test_type eq "patchcheck") {
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002087 patchcheck $i;
2088 next;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04002089 }
2090
Steven Rostedt7faafbd2010-11-02 14:58:22 -04002091 if ($build_type ne "nobuild") {
2092 build $build_type or next;
Steven Rostedt2545eb62010-11-02 15:01:32 -04002093 }
2094
Steven Rostedta75fece2010-11-02 14:58:27 -04002095 if ($test_type ne "build") {
2096 get_grub_index;
2097 get_version;
2098 install;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04002099
Steven Rostedta75fece2010-11-02 14:58:27 -04002100 my $failed = 0;
2101 start_monitor;
2102 monitor or $failed = 1;;
2103
2104 if (!$failed && $test_type ne "boot" && defined($run_test)) {
2105 do_run_test or $failed = 1;
2106 }
2107 end_monitor;
2108 next if ($failed);
Steven Rostedt5a391fb2010-11-02 14:57:43 -04002109 }
2110
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04002111 success $i;
Steven Rostedt2545eb62010-11-02 15:01:32 -04002112}
2113
Steven Rostedt5c42fc52010-11-02 14:57:01 -04002114if ($opt{"POWEROFF_ON_SUCCESS"}) {
Steven Rostedt75c3fda72010-11-02 14:57:21 -04002115 halt;
Steven Rostedt576f6272010-11-02 14:58:38 -04002116} elsif ($opt{"REBOOT_ON_SUCCESS"} && !do_not_reboot) {
Steven Rostedt75c3fda72010-11-02 14:57:21 -04002117 reboot;
Steven Rostedt5c42fc52010-11-02 14:57:01 -04002118}
Steven Rostedt75c3fda72010-11-02 14:57:21 -04002119
Steven Rostedte48c5292010-11-02 14:35:37 -04002120doprint "\n $successes of $opt{NUM_TESTS} tests were successful\n\n";
2121
Steven Rostedt2545eb62010-11-02 15:01:32 -04002122exit 0;