blob: 65003a196305b3502639c814a9a26c6b1839dc15 [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
Steven Rostedt27d934b2011-05-20 09:18:18 -040039$default{"PATCHCHECK_SLEEP_TIME"} = 60; # sleep time between patch checks
Steven Rostedta75fece2010-11-02 14:58:27 -040040$default{"CLEAR_LOG"} = 0;
Steven Rostedtc960bb92011-03-08 09:22:39 -050041$default{"BISECT_MANUAL"} = 0;
Steven Rostedtc23dca72011-03-08 09:26:31 -050042$default{"BISECT_SKIP"} = 1;
Steven Rostedta75fece2010-11-02 14:58:27 -040043$default{"SUCCESS_LINE"} = "login:";
44$default{"BOOTED_TIMEOUT"} = 1;
45$default{"DIE_ON_FAILURE"} = 1;
Steven Rostedte48c5292010-11-02 14:35:37 -040046$default{"SSH_EXEC"} = "ssh \$SSH_USER\@\$MACHINE \$SSH_COMMAND";
47$default{"SCP_TO_TARGET"} = "scp \$SRC_FILE \$SSH_USER\@\$MACHINE:\$DST_FILE";
48$default{"REBOOT"} = "ssh \$SSH_USER\@\$MACHINE reboot";
Steven Rostedt1c8a6172010-11-09 12:55:40 -050049$default{"STOP_AFTER_SUCCESS"} = 10;
50$default{"STOP_AFTER_FAILURE"} = 60;
Steven Rostedt2d01b262011-03-08 09:47:54 -050051$default{"STOP_TEST_AFTER"} = 600;
Steven Rostedt8d1491b2010-11-18 15:39:48 -050052$default{"LOCALVERSION"} = "-test";
Steven Rostedt2545eb62010-11-02 15:01:32 -040053
Steven Rostedt8d1491b2010-11-18 15:39:48 -050054my $ktest_config;
Steven Rostedt2545eb62010-11-02 15:01:32 -040055my $version;
Steven Rostedta75fece2010-11-02 14:58:27 -040056my $machine;
Steven Rostedte48c5292010-11-02 14:35:37 -040057my $ssh_user;
Steven Rostedta75fece2010-11-02 14:58:27 -040058my $tmpdir;
59my $builddir;
60my $outputdir;
Steven Rostedt51ad1dd2010-11-08 16:43:21 -050061my $output_config;
Steven Rostedta75fece2010-11-02 14:58:27 -040062my $test_type;
Steven Rostedt7faafbd2010-11-02 14:58:22 -040063my $build_type;
Steven Rostedta75fece2010-11-02 14:58:27 -040064my $build_options;
65my $reboot_type;
66my $reboot_script;
67my $power_cycle;
Steven Rostedte48c5292010-11-02 14:35:37 -040068my $reboot;
Steven Rostedta75fece2010-11-02 14:58:27 -040069my $reboot_on_error;
70my $poweroff_on_error;
71my $die_on_failure;
Steven Rostedt576f6272010-11-02 14:58:38 -040072my $powercycle_after_reboot;
73my $poweroff_after_halt;
Steven Rostedte48c5292010-11-02 14:35:37 -040074my $ssh_exec;
75my $scp_to_target;
Steven Rostedta75fece2010-11-02 14:58:27 -040076my $power_off;
77my $grub_menu;
Steven Rostedt2545eb62010-11-02 15:01:32 -040078my $grub_number;
79my $target;
80my $make;
Steven Rostedt8b37ca82010-11-02 14:58:33 -040081my $post_install;
Steven Rostedt5c42fc52010-11-02 14:57:01 -040082my $noclean;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -040083my $minconfig;
Steven Rostedt2b7d9b22010-11-02 14:58:15 -040084my $addconfig;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -040085my $in_bisect = 0;
86my $bisect_bad = "";
Steven Rostedtd6ce2a02010-11-02 14:58:05 -040087my $reverse_bisect;
Steven Rostedtc960bb92011-03-08 09:22:39 -050088my $bisect_manual;
Steven Rostedtc23dca72011-03-08 09:26:31 -050089my $bisect_skip;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -040090my $in_patchcheck = 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -040091my $run_test;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -040092my $redirect;
Steven Rostedt7faafbd2010-11-02 14:58:22 -040093my $buildlog;
94my $dmesg;
95my $monitor_fp;
96my $monitor_pid;
97my $monitor_cnt = 0;
Steven Rostedta75fece2010-11-02 14:58:27 -040098my $sleep_time;
99my $bisect_sleep_time;
Steven Rostedt27d934b2011-05-20 09:18:18 -0400100my $patchcheck_sleep_time;
Steven Rostedta75fece2010-11-02 14:58:27 -0400101my $store_failures;
102my $timeout;
103my $booted_timeout;
104my $console;
105my $success_line;
Steven Rostedt1c8a6172010-11-09 12:55:40 -0500106my $stop_after_success;
107my $stop_after_failure;
Steven Rostedt2d01b262011-03-08 09:47:54 -0500108my $stop_test_after;
Steven Rostedta75fece2010-11-02 14:58:27 -0400109my $build_target;
110my $target_image;
111my $localversion;
Steven Rostedt576f6272010-11-02 14:58:38 -0400112my $iteration = 0;
Steven Rostedte48c5292010-11-02 14:35:37 -0400113my $successes = 0;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400114
Steven Rostedt8d1491b2010-11-18 15:39:48 -0500115my %entered_configs;
116my %config_help;
117
118$config_help{"MACHINE"} = << "EOF"
119 The machine hostname that you will test.
120EOF
121 ;
122$config_help{"SSH_USER"} = << "EOF"
123 The box is expected to have ssh on normal bootup, provide the user
124 (most likely root, since you need privileged operations)
125EOF
126 ;
127$config_help{"BUILD_DIR"} = << "EOF"
128 The directory that contains the Linux source code (full path).
129EOF
130 ;
131$config_help{"OUTPUT_DIR"} = << "EOF"
132 The directory that the objects will be built (full path).
133 (can not be same as BUILD_DIR)
134EOF
135 ;
136$config_help{"BUILD_TARGET"} = << "EOF"
137 The location of the compiled file to copy to the target.
138 (relative to OUTPUT_DIR)
139EOF
140 ;
141$config_help{"TARGET_IMAGE"} = << "EOF"
142 The place to put your image on the test machine.
143EOF
144 ;
145$config_help{"POWER_CYCLE"} = << "EOF"
146 A script or command to reboot the box.
147
148 Here is a digital loggers power switch example
149 POWER_CYCLE = wget --no-proxy -O /dev/null -q --auth-no-challenge 'http://admin:admin\@power/outlet?5=CCL'
150
151 Here is an example to reboot a virtual box on the current host
152 with the name "Guest".
153 POWER_CYCLE = virsh destroy Guest; sleep 5; virsh start Guest
154EOF
155 ;
156$config_help{"CONSOLE"} = << "EOF"
157 The script or command that reads the console
158
159 If you use ttywatch server, something like the following would work.
160CONSOLE = nc -d localhost 3001
161
162 For a virtual machine with guest name "Guest".
163CONSOLE = virsh console Guest
164EOF
165 ;
166$config_help{"LOCALVERSION"} = << "EOF"
167 Required version ending to differentiate the test
168 from other linux builds on the system.
169EOF
170 ;
171$config_help{"REBOOT_TYPE"} = << "EOF"
172 Way to reboot the box to the test kernel.
173 Only valid options so far are "grub" and "script".
174
175 If you specify grub, it will assume grub version 1
176 and will search in /boot/grub/menu.lst for the title \$GRUB_MENU
177 and select that target to reboot to the kernel. If this is not
178 your setup, then specify "script" and have a command or script
179 specified in REBOOT_SCRIPT to boot to the target.
180
181 The entry in /boot/grub/menu.lst must be entered in manually.
182 The test will not modify that file.
183EOF
184 ;
185$config_help{"GRUB_MENU"} = << "EOF"
186 The grub title name for the test kernel to boot
187 (Only mandatory if REBOOT_TYPE = grub)
188
189 Note, ktest.pl will not update the grub menu.lst, you need to
190 manually add an option for the test. ktest.pl will search
191 the grub menu.lst for this option to find what kernel to
192 reboot into.
193
194 For example, if in the /boot/grub/menu.lst the test kernel title has:
195 title Test Kernel
196 kernel vmlinuz-test
197 GRUB_MENU = Test Kernel
198EOF
199 ;
200$config_help{"REBOOT_SCRIPT"} = << "EOF"
201 A script to reboot the target into the test kernel
202 (Only mandatory if REBOOT_TYPE = script)
203EOF
204 ;
205
206
207sub get_ktest_config {
208 my ($config) = @_;
209
210 return if (defined($opt{$config}));
211
212 if (defined($config_help{$config})) {
213 print "\n";
214 print $config_help{$config};
215 }
216
217 for (;;) {
218 print "$config = ";
219 if (defined($default{$config})) {
220 print "\[$default{$config}\] ";
221 }
222 $entered_configs{$config} = <STDIN>;
223 $entered_configs{$config} =~ s/^\s*(.*\S)\s*$/$1/;
224 if ($entered_configs{$config} =~ /^\s*$/) {
225 if ($default{$config}) {
226 $entered_configs{$config} = $default{$config};
227 } else {
228 print "Your answer can not be blank\n";
229 next;
230 }
231 }
232 last;
233 }
234}
235
236sub get_ktest_configs {
237 get_ktest_config("MACHINE");
238 get_ktest_config("SSH_USER");
239 get_ktest_config("BUILD_DIR");
240 get_ktest_config("OUTPUT_DIR");
241 get_ktest_config("BUILD_TARGET");
242 get_ktest_config("TARGET_IMAGE");
243 get_ktest_config("POWER_CYCLE");
244 get_ktest_config("CONSOLE");
245 get_ktest_config("LOCALVERSION");
246
247 my $rtype = $opt{"REBOOT_TYPE"};
248
249 if (!defined($rtype)) {
250 if (!defined($opt{"GRUB_MENU"})) {
251 get_ktest_config("REBOOT_TYPE");
252 $rtype = $entered_configs{"REBOOT_TYPE"};
253 } else {
254 $rtype = "grub";
255 }
256 }
257
258 if ($rtype eq "grub") {
259 get_ktest_config("GRUB_MENU");
260 } else {
261 get_ktest_config("REBOOT_SCRIPT");
262 }
263}
264
Steven Rostedta57419b2010-11-02 15:13:54 -0400265sub set_value {
266 my ($lvalue, $rvalue) = @_;
267
268 if (defined($opt{$lvalue})) {
269 die "Error: Option $lvalue defined more than once!\n";
270 }
Steven Rostedt21a96792010-11-08 16:45:50 -0500271 if ($rvalue =~ /^\s*$/) {
272 delete $opt{$lvalue};
273 } else {
274 $opt{$lvalue} = $rvalue;
275 }
Steven Rostedta57419b2010-11-02 15:13:54 -0400276}
277
Steven Rostedt2545eb62010-11-02 15:01:32 -0400278sub read_config {
279 my ($config) = @_;
280
281 open(IN, $config) || die "can't read file $config";
282
Steven Rostedta57419b2010-11-02 15:13:54 -0400283 my $name = $config;
284 $name =~ s,.*/(.*),$1,;
285
286 my $test_num = 0;
287 my $default = 1;
288 my $repeat = 1;
289 my $num_tests_set = 0;
290 my $skip = 0;
291 my $rest;
292
Steven Rostedt2545eb62010-11-02 15:01:32 -0400293 while (<IN>) {
294
295 # ignore blank lines and comments
296 next if (/^\s*$/ || /\s*\#/);
297
Steven Rostedta57419b2010-11-02 15:13:54 -0400298 if (/^\s*TEST_START(.*)/) {
299
300 $rest = $1;
301
302 if ($num_tests_set) {
303 die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
304 }
305
306 my $old_test_num = $test_num;
Steven Rostedte48c5292010-11-02 14:35:37 -0400307 my $old_repeat = $repeat;
Steven Rostedta57419b2010-11-02 15:13:54 -0400308
309 $test_num += $repeat;
310 $default = 0;
311 $repeat = 1;
312
313 if ($rest =~ /\s+SKIP(.*)/) {
314 $rest = $1;
315 $skip = 1;
316 } else {
317 $skip = 0;
318 }
319
320 if ($rest =~ /\s+ITERATE\s+(\d+)(.*)$/) {
321 $repeat = $1;
322 $rest = $2;
323 $repeat_tests{"$test_num"} = $repeat;
324 }
325
326 if ($rest =~ /\s+SKIP(.*)/) {
327 $rest = $1;
328 $skip = 1;
329 }
330
331 if ($rest !~ /^\s*$/) {
332 die "$name: $.: Gargbage found after TEST_START\n$_";
333 }
334
335 if ($skip) {
336 $test_num = $old_test_num;
Steven Rostedte48c5292010-11-02 14:35:37 -0400337 $repeat = $old_repeat;
Steven Rostedta57419b2010-11-02 15:13:54 -0400338 }
339
340 } elsif (/^\s*DEFAULTS(.*)$/) {
341 $default = 1;
342
343 $rest = $1;
344
345 if ($rest =~ /\s+SKIP(.*)/) {
346 $rest = $1;
347 $skip = 1;
348 } else {
349 $skip = 0;
350 }
351
352 if ($rest !~ /^\s*$/) {
353 die "$name: $.: Gargbage found after DEFAULTS\n$_";
354 }
355
356 } elsif (/^\s*([A-Z_\[\]\d]+)\s*=\s*(.*?)\s*$/) {
357
358 next if ($skip);
359
Steven Rostedt2545eb62010-11-02 15:01:32 -0400360 my $lvalue = $1;
361 my $rvalue = $2;
362
Steven Rostedta57419b2010-11-02 15:13:54 -0400363 if (!$default &&
364 ($lvalue eq "NUM_TESTS" ||
365 $lvalue eq "LOG_FILE" ||
366 $lvalue eq "CLEAR_LOG")) {
367 die "$name: $.: $lvalue must be set in DEFAULTS section\n";
Steven Rostedta75fece2010-11-02 14:58:27 -0400368 }
Steven Rostedta57419b2010-11-02 15:13:54 -0400369
370 if ($lvalue eq "NUM_TESTS") {
371 if ($test_num) {
372 die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
373 }
374 if (!$default) {
375 die "$name: $.: NUM_TESTS must be set in default section\n";
376 }
377 $num_tests_set = 1;
378 }
379
380 if ($default || $lvalue =~ /\[\d+\]$/) {
381 set_value($lvalue, $rvalue);
382 } else {
383 my $val = "$lvalue\[$test_num\]";
384 set_value($val, $rvalue);
385
386 if ($repeat > 1) {
387 $repeats{$val} = $repeat;
388 }
389 }
390 } else {
391 die "$name: $.: Garbage found in config\n$_";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400392 }
393 }
394
395 close(IN);
Steven Rostedta75fece2010-11-02 14:58:27 -0400396
Steven Rostedta57419b2010-11-02 15:13:54 -0400397 if ($test_num) {
398 $test_num += $repeat - 1;
399 $opt{"NUM_TESTS"} = $test_num;
400 }
401
Steven Rostedt8d1491b2010-11-18 15:39:48 -0500402 # make sure we have all mandatory configs
403 get_ktest_configs;
404
Steven Rostedta75fece2010-11-02 14:58:27 -0400405 # set any defaults
406
407 foreach my $default (keys %default) {
408 if (!defined($opt{$default})) {
409 $opt{$default} = $default{$default};
410 }
411 }
Steven Rostedt2545eb62010-11-02 15:01:32 -0400412}
413
Steven Rostedtd1e2f222010-11-08 16:39:57 -0500414sub _logit {
Steven Rostedt2545eb62010-11-02 15:01:32 -0400415 if (defined($opt{"LOG_FILE"})) {
416 open(OUT, ">> $opt{LOG_FILE}") or die "Can't write to $opt{LOG_FILE}";
417 print OUT @_;
418 close(OUT);
419 }
420}
421
Steven Rostedtd1e2f222010-11-08 16:39:57 -0500422sub logit {
423 if (defined($opt{"LOG_FILE"})) {
424 _logit @_;
425 } else {
426 print @_;
427 }
428}
429
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400430sub doprint {
431 print @_;
Steven Rostedtd1e2f222010-11-08 16:39:57 -0500432 _logit @_;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400433}
434
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400435sub run_command;
436
437sub reboot {
438 # try to reboot normally
Steven Rostedte48c5292010-11-02 14:35:37 -0400439 if (run_command $reboot) {
Steven Rostedt576f6272010-11-02 14:58:38 -0400440 if (defined($powercycle_after_reboot)) {
441 sleep $powercycle_after_reboot;
442 run_command "$power_cycle";
443 }
444 } else {
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400445 # nope? power cycle it.
Steven Rostedta75fece2010-11-02 14:58:27 -0400446 run_command "$power_cycle";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400447 }
448}
449
Steven Rostedt576f6272010-11-02 14:58:38 -0400450sub do_not_reboot {
451 my $i = $iteration;
452
453 return $test_type eq "build" ||
454 ($test_type eq "patchcheck" && $opt{"PATCHCHECK_TYPE[$i]"} eq "build") ||
455 ($test_type eq "bisect" && $opt{"BISECT_TYPE[$i]"} eq "build");
456}
457
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400458sub dodie {
Steven Rostedt5a391fb2010-11-02 14:57:43 -0400459 doprint "CRITICAL FAILURE... ", @_, "\n";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400460
Steven Rostedt576f6272010-11-02 14:58:38 -0400461 my $i = $iteration;
462
463 if ($reboot_on_error && !do_not_reboot) {
464
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400465 doprint "REBOOTING\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400466 reboot;
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400467
Steven Rostedta75fece2010-11-02 14:58:27 -0400468 } elsif ($poweroff_on_error && defined($power_off)) {
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400469 doprint "POWERING OFF\n";
Steven Rostedta75fece2010-11-02 14:58:27 -0400470 `$power_off`;
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400471 }
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400472
Steven Rostedtf80802c2011-03-07 13:18:47 -0500473 if (defined($opt{"LOG_FILE"})) {
474 print " See $opt{LOG_FILE} for more info.\n";
475 }
476
Steven Rostedt576f6272010-11-02 14:58:38 -0400477 die @_, "\n";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400478}
479
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400480sub open_console {
481 my ($fp) = @_;
482
483 my $flags;
484
Steven Rostedta75fece2010-11-02 14:58:27 -0400485 my $pid = open($fp, "$console|") or
486 dodie "Can't open console $console";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400487
488 $flags = fcntl($fp, F_GETFL, 0) or
Steven Rostedt576f6272010-11-02 14:58:38 -0400489 dodie "Can't get flags for the socket: $!";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400490 $flags = fcntl($fp, F_SETFL, $flags | O_NONBLOCK) or
Steven Rostedt576f6272010-11-02 14:58:38 -0400491 dodie "Can't set flags for the socket: $!";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400492
493 return $pid;
494}
495
496sub close_console {
497 my ($fp, $pid) = @_;
498
499 doprint "kill child process $pid\n";
500 kill 2, $pid;
501
502 print "closing!\n";
503 close($fp);
504}
505
506sub start_monitor {
507 if ($monitor_cnt++) {
508 return;
509 }
510 $monitor_fp = \*MONFD;
511 $monitor_pid = open_console $monitor_fp;
Steven Rostedta75fece2010-11-02 14:58:27 -0400512
513 return;
514
515 open(MONFD, "Stop perl from warning about single use of MONFD");
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400516}
517
518sub end_monitor {
519 if (--$monitor_cnt) {
520 return;
521 }
522 close_console($monitor_fp, $monitor_pid);
523}
524
525sub wait_for_monitor {
526 my ($time) = @_;
527 my $line;
528
Steven Rostedta75fece2010-11-02 14:58:27 -0400529 doprint "** Wait for monitor to settle down **\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400530
531 # read the monitor and wait for the system to calm down
532 do {
533 $line = wait_for_input($monitor_fp, $time);
Steven Rostedta75fece2010-11-02 14:58:27 -0400534 print "$line" if (defined($line));
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400535 } while (defined($line));
Steven Rostedta75fece2010-11-02 14:58:27 -0400536 print "** Monitor flushed **\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400537}
538
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400539sub fail {
540
Steven Rostedta75fece2010-11-02 14:58:27 -0400541 if ($die_on_failure) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400542 dodie @_;
543 }
544
Steven Rostedta75fece2010-11-02 14:58:27 -0400545 doprint "FAILED\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400546
Steven Rostedt576f6272010-11-02 14:58:38 -0400547 my $i = $iteration;
548
Steven Rostedta75fece2010-11-02 14:58:27 -0400549 # no need to reboot for just building.
Steven Rostedt576f6272010-11-02 14:58:38 -0400550 if (!do_not_reboot) {
Steven Rostedta75fece2010-11-02 14:58:27 -0400551 doprint "REBOOTING\n";
552 reboot;
553 start_monitor;
554 wait_for_monitor $sleep_time;
555 end_monitor;
556 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400557
Steven Rostedt576f6272010-11-02 14:58:38 -0400558 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
559 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
Steven Rostedt7a849cd2010-11-08 16:49:25 -0500560 doprint "KTEST RESULT: TEST $i Failed: ", @_, "\n";
Steven Rostedt576f6272010-11-02 14:58:38 -0400561 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
562 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
Steven Rostedta75fece2010-11-02 14:58:27 -0400563
564 return 1 if (!defined($store_failures));
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400565
566 my @t = localtime;
567 my $date = sprintf "%04d%02d%02d%02d%02d%02d",
568 1900+$t[5],$t[4],$t[3],$t[2],$t[1],$t[0];
569
Steven Rostedtcccae1a2010-11-09 12:21:32 -0500570 my $type = $build_type;
571 if ($type =~ /useconfig/) {
572 $type = "useconfig";
573 }
574
575 my $dir = "$machine-$test_type-$type-fail-$date";
Steven Rostedta75fece2010-11-02 14:58:27 -0400576 my $faildir = "$store_failures/$dir";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400577
578 if (!-d $faildir) {
579 mkpath($faildir) or
Steven Rostedta75fece2010-11-02 14:58:27 -0400580 die "can't create $faildir";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400581 }
Steven Rostedt51ad1dd2010-11-08 16:43:21 -0500582 if (-f "$output_config") {
583 cp "$output_config", "$faildir/config" or
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400584 die "failed to copy .config";
585 }
586 if (-f $buildlog) {
587 cp $buildlog, "$faildir/buildlog" or
588 die "failed to move $buildlog";
589 }
590 if (-f $dmesg) {
591 cp $dmesg, "$faildir/dmesg" or
592 die "failed to move $dmesg";
593 }
594
595 doprint "*** Saved info to $faildir ***\n";
596
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400597 return 1;
598}
599
Steven Rostedt2545eb62010-11-02 15:01:32 -0400600sub run_command {
601 my ($command) = @_;
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400602 my $dolog = 0;
603 my $dord = 0;
604 my $pid;
605
Steven Rostedte48c5292010-11-02 14:35:37 -0400606 $command =~ s/\$SSH_USER/$ssh_user/g;
607 $command =~ s/\$MACHINE/$machine/g;
608
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400609 doprint("$command ... ");
610
611 $pid = open(CMD, "$command 2>&1 |") or
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400612 (fail "unable to exec $command" and return 0);
Steven Rostedt2545eb62010-11-02 15:01:32 -0400613
614 if (defined($opt{"LOG_FILE"})) {
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400615 open(LOG, ">>$opt{LOG_FILE}") or
616 dodie "failed to write to log";
617 $dolog = 1;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -0400618 }
619
620 if (defined($redirect)) {
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400621 open (RD, ">$redirect") or
622 dodie "failed to write to redirect $redirect";
623 $dord = 1;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400624 }
625
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400626 while (<CMD>) {
627 print LOG if ($dolog);
628 print RD if ($dord);
629 }
Steven Rostedt2545eb62010-11-02 15:01:32 -0400630
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400631 waitpid($pid, 0);
Steven Rostedt2545eb62010-11-02 15:01:32 -0400632 my $failed = $?;
633
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400634 close(CMD);
635 close(LOG) if ($dolog);
636 close(RD) if ($dord);
637
Steven Rostedt2545eb62010-11-02 15:01:32 -0400638 if ($failed) {
639 doprint "FAILED!\n";
640 } else {
641 doprint "SUCCESS\n";
642 }
643
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400644 return !$failed;
645}
646
Steven Rostedte48c5292010-11-02 14:35:37 -0400647sub run_ssh {
648 my ($cmd) = @_;
649 my $cp_exec = $ssh_exec;
650
651 $cp_exec =~ s/\$SSH_COMMAND/$cmd/g;
652 return run_command "$cp_exec";
653}
654
655sub run_scp {
656 my ($src, $dst) = @_;
657 my $cp_scp = $scp_to_target;
658
659 $cp_scp =~ s/\$SRC_FILE/$src/g;
660 $cp_scp =~ s/\$DST_FILE/$dst/g;
661
662 return run_command "$cp_scp";
663}
664
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400665sub get_grub_index {
666
Steven Rostedta75fece2010-11-02 14:58:27 -0400667 if ($reboot_type ne "grub") {
668 return;
669 }
Steven Rostedt5a391fb2010-11-02 14:57:43 -0400670 return if (defined($grub_number));
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400671
672 doprint "Find grub menu ... ";
673 $grub_number = -1;
Steven Rostedte48c5292010-11-02 14:35:37 -0400674
675 my $ssh_grub = $ssh_exec;
676 $ssh_grub =~ s,\$SSH_COMMAND,cat /boot/grub/menu.lst,g;
677
678 open(IN, "$ssh_grub |")
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400679 or die "unable to get menu.lst";
Steven Rostedte48c5292010-11-02 14:35:37 -0400680
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400681 while (<IN>) {
Steven Rostedta75fece2010-11-02 14:58:27 -0400682 if (/^\s*title\s+$grub_menu\s*$/) {
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400683 $grub_number++;
684 last;
685 } elsif (/^\s*title\s/) {
686 $grub_number++;
687 }
688 }
689 close(IN);
690
Steven Rostedta75fece2010-11-02 14:58:27 -0400691 die "Could not find '$grub_menu' in /boot/grub/menu on $machine"
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400692 if ($grub_number < 0);
693 doprint "$grub_number\n";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400694}
695
Steven Rostedt2545eb62010-11-02 15:01:32 -0400696sub wait_for_input
697{
698 my ($fp, $time) = @_;
699 my $rin;
700 my $ready;
701 my $line;
702 my $ch;
703
704 if (!defined($time)) {
705 $time = $timeout;
706 }
707
708 $rin = '';
709 vec($rin, fileno($fp), 1) = 1;
710 $ready = select($rin, undef, undef, $time);
711
712 $line = "";
713
714 # try to read one char at a time
715 while (sysread $fp, $ch, 1) {
716 $line .= $ch;
717 last if ($ch eq "\n");
718 }
719
720 if (!length($line)) {
721 return undef;
722 }
723
724 return $line;
725}
726
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400727sub reboot_to {
Steven Rostedta75fece2010-11-02 14:58:27 -0400728 if ($reboot_type eq "grub") {
Steven Rostedteec56462010-11-10 09:08:20 -0500729 run_ssh "'(echo \"savedefault --default=$grub_number --once\" | grub --batch; reboot)'";
Steven Rostedta75fece2010-11-02 14:58:27 -0400730 return;
731 }
732
733 run_command "$reboot_script";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400734}
735
Steven Rostedta57419b2010-11-02 15:13:54 -0400736sub get_sha1 {
737 my ($commit) = @_;
738
739 doprint "git rev-list --max-count=1 $commit ... ";
740 my $sha1 = `git rev-list --max-count=1 $commit`;
741 my $ret = $?;
742
743 logit $sha1;
744
745 if ($ret) {
746 doprint "FAILED\n";
747 dodie "Failed to get git $commit";
748 }
749
750 print "SUCCESS\n";
751
752 chomp $sha1;
753
754 return $sha1;
755}
756
Steven Rostedt5a391fb2010-11-02 14:57:43 -0400757sub monitor {
Steven Rostedt2545eb62010-11-02 15:01:32 -0400758 my $booted = 0;
759 my $bug = 0;
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400760 my $skip_call_trace = 0;
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400761 my $loops;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400762
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400763 wait_for_monitor 5;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400764
765 my $line;
766 my $full_line = "";
767
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400768 open(DMESG, "> $dmesg") or
769 die "unable to write to $dmesg";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400770
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400771 reboot_to;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400772
Steven Rostedt1c8a6172010-11-09 12:55:40 -0500773 my $success_start;
774 my $failure_start;
Steven Rostedt2d01b262011-03-08 09:47:54 -0500775 my $monitor_start = time;
776 my $done = 0;
Steven Rostedt1c8a6172010-11-09 12:55:40 -0500777
Steven Rostedt2d01b262011-03-08 09:47:54 -0500778 while (!$done) {
Steven Rostedt2545eb62010-11-02 15:01:32 -0400779
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400780 if ($booted) {
Steven Rostedta75fece2010-11-02 14:58:27 -0400781 $line = wait_for_input($monitor_fp, $booted_timeout);
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400782 } else {
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400783 $line = wait_for_input($monitor_fp);
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400784 }
Steven Rostedt2545eb62010-11-02 15:01:32 -0400785
786 last if (!defined($line));
787
788 doprint $line;
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400789 print DMESG $line;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400790
791 # we are not guaranteed to get a full line
792 $full_line .= $line;
793
Steven Rostedta75fece2010-11-02 14:58:27 -0400794 if ($full_line =~ /$success_line/) {
Steven Rostedt2545eb62010-11-02 15:01:32 -0400795 $booted = 1;
Steven Rostedt1c8a6172010-11-09 12:55:40 -0500796 $success_start = time;
797 }
798
799 if ($booted && defined($stop_after_success) &&
800 $stop_after_success >= 0) {
801 my $now = time;
802 if ($now - $success_start >= $stop_after_success) {
803 doprint "Test forced to stop after $stop_after_success seconds after success\n";
804 last;
805 }
Steven Rostedt2545eb62010-11-02 15:01:32 -0400806 }
807
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400808 if ($full_line =~ /\[ backtrace testing \]/) {
809 $skip_call_trace = 1;
810 }
811
Steven Rostedt2545eb62010-11-02 15:01:32 -0400812 if ($full_line =~ /call trace:/i) {
Steven Rostedt46519202011-03-08 09:40:31 -0500813 if (!$bug && !$skip_call_trace) {
Steven Rostedt1c8a6172010-11-09 12:55:40 -0500814 $bug = 1;
815 $failure_start = time;
816 }
817 }
818
819 if ($bug && defined($stop_after_failure) &&
820 $stop_after_failure >= 0) {
821 my $now = time;
822 if ($now - $failure_start >= $stop_after_failure) {
823 doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
824 last;
825 }
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400826 }
827
828 if ($full_line =~ /\[ end of backtrace testing \]/) {
829 $skip_call_trace = 0;
830 }
831
832 if ($full_line =~ /Kernel panic -/) {
Steven Rostedt10abf112011-03-07 13:21:00 -0500833 $failure_start = time;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400834 $bug = 1;
835 }
836
837 if ($line =~ /\n/) {
838 $full_line = "";
839 }
Steven Rostedt2d01b262011-03-08 09:47:54 -0500840
841 if ($stop_test_after > 0 && !$booted && !$bug) {
842 if (time - $monitor_start > $stop_test_after) {
Steven Rostedt4d62bf52011-05-20 09:14:35 -0400843 doprint "STOP_TEST_AFTER ($stop_test_after seconds) timed out\n";
Steven Rostedt2d01b262011-03-08 09:47:54 -0500844 $done = 1;
845 }
846 }
Steven Rostedt2545eb62010-11-02 15:01:32 -0400847 }
848
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400849 close(DMESG);
Steven Rostedt2545eb62010-11-02 15:01:32 -0400850
Steven Rostedt2545eb62010-11-02 15:01:32 -0400851 if ($bug) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400852 return 0 if ($in_bisect);
Steven Rostedt576f6272010-11-02 14:58:38 -0400853 fail "failed - got a bug report" and return 0;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400854 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400855
Steven Rostedta75fece2010-11-02 14:58:27 -0400856 if (!$booted) {
857 return 0 if ($in_bisect);
Steven Rostedt576f6272010-11-02 14:58:38 -0400858 fail "failed - never got a boot prompt." and return 0;
Steven Rostedta75fece2010-11-02 14:58:27 -0400859 }
860
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400861 return 1;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400862}
863
864sub install {
865
Steven Rostedte48c5292010-11-02 14:35:37 -0400866 run_scp "$outputdir/$build_target", "$target_image" or
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400867 dodie "failed to copy image";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400868
869 my $install_mods = 0;
870
871 # should we process modules?
872 $install_mods = 0;
Steven Rostedt51ad1dd2010-11-08 16:43:21 -0500873 open(IN, "$output_config") or dodie("Can't read config file");
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400874 while (<IN>) {
875 if (/CONFIG_MODULES(=y)?/) {
876 $install_mods = 1 if (defined($1));
877 last;
878 }
879 }
880 close(IN);
881
882 if (!$install_mods) {
883 doprint "No modules needed\n";
884 return;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400885 }
886
Steven Rostedta75fece2010-11-02 14:58:27 -0400887 run_command "$make INSTALL_MOD_PATH=$tmpdir modules_install" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400888 dodie "Failed to install modules";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400889
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400890 my $modlib = "/lib/modules/$version";
Steven Rostedta57419b2010-11-02 15:13:54 -0400891 my $modtar = "ktest-mods.tar.bz2";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400892
Steven Rostedte48c5292010-11-02 14:35:37 -0400893 run_ssh "rm -rf $modlib" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400894 dodie "failed to remove old mods: $modlib";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400895
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400896 # would be nice if scp -r did not follow symbolic links
Steven Rostedta75fece2010-11-02 14:58:27 -0400897 run_command "cd $tmpdir && tar -cjf $modtar lib/modules/$version" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400898 dodie "making tarball";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400899
Steven Rostedte48c5292010-11-02 14:35:37 -0400900 run_scp "$tmpdir/$modtar", "/tmp" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400901 dodie "failed to copy modules";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400902
Steven Rostedta75fece2010-11-02 14:58:27 -0400903 unlink "$tmpdir/$modtar";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400904
Steven Rostedte48c5292010-11-02 14:35:37 -0400905 run_ssh "'(cd / && tar xf /tmp/$modtar)'" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400906 dodie "failed to tar modules";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400907
Steven Rostedte48c5292010-11-02 14:35:37 -0400908 run_ssh "rm -f /tmp/$modtar";
Steven Rostedt8b37ca82010-11-02 14:58:33 -0400909
910 return if (!defined($post_install));
911
Steven Rostedte48c5292010-11-02 14:35:37 -0400912 my $cp_post_install = $post_install;
Steven Rostedtca6a21f2011-03-25 22:42:53 -0400913 $cp_post_install =~ s/\$KERNEL_VERSION/$version/g;
Steven Rostedte48c5292010-11-02 14:35:37 -0400914 run_command "$cp_post_install" or
Steven Rostedt576f6272010-11-02 14:58:38 -0400915 dodie "Failed to run post install";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400916}
917
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -0400918sub check_buildlog {
919 my ($patch) = @_;
920
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -0400921 my @files = `git show $patch | diffstat -l`;
922
923 open(IN, "git show $patch |") or
924 dodie "failed to show $patch";
925 while (<IN>) {
926 if (m,^--- a/(.*),) {
927 chomp $1;
928 $files[$#files] = $1;
929 }
930 }
931 close(IN);
932
933 open(IN, $buildlog) or dodie "Can't open $buildlog";
934 while (<IN>) {
935 if (/^\s*(.*?):.*(warning|error)/) {
936 my $err = $1;
937 foreach my $file (@files) {
Steven Rostedta75fece2010-11-02 14:58:27 -0400938 my $fullpath = "$builddir/$file";
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -0400939 if ($file eq $err || $fullpath eq $err) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400940 fail "$file built with warnings" and return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -0400941 }
942 }
943 }
944 }
945 close(IN);
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400946
947 return 1;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -0400948}
949
Steven Rostedt612b9e92011-03-07 13:27:43 -0500950sub make_oldconfig {
951 my ($defconfig) = @_;
952
953 if (!run_command "$defconfig $make oldnoconfig") {
954 # Perhaps oldnoconfig doesn't exist in this version of the kernel
955 # try a yes '' | oldconfig
956 doprint "oldnoconfig failed, trying yes '' | make oldconfig\n";
957 run_command "yes '' | $defconfig $make oldconfig" or
958 dodie "failed make config oldconfig";
959 }
960}
961
Steven Rostedt2545eb62010-11-02 15:01:32 -0400962sub build {
963 my ($type) = @_;
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400964 my $defconfig = "";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400965
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400966 unlink $buildlog;
967
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400968 if ($type =~ /^useconfig:(.*)/) {
Steven Rostedt51ad1dd2010-11-08 16:43:21 -0500969 run_command "cp $1 $output_config" or
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400970 dodie "could not copy $1 to .config";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400971
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400972 $type = "oldconfig";
973 }
974
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400975 # old config can ask questions
976 if ($type eq "oldconfig") {
Steven Rostedt9386c6a2010-11-08 16:35:48 -0500977 $type = "oldnoconfig";
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400978
979 # allow for empty configs
Steven Rostedt51ad1dd2010-11-08 16:43:21 -0500980 run_command "touch $output_config";
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400981
Steven Rostedt51ad1dd2010-11-08 16:43:21 -0500982 run_command "mv $output_config $outputdir/config_temp" or
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400983 dodie "moving .config";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400984
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400985 if (!$noclean && !run_command "$make mrproper") {
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400986 dodie "make mrproper";
987 }
988
Steven Rostedt51ad1dd2010-11-08 16:43:21 -0500989 run_command "mv $outputdir/config_temp $output_config" or
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400990 dodie "moving config_temp";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400991
992 } elsif (!$noclean) {
Steven Rostedt51ad1dd2010-11-08 16:43:21 -0500993 unlink "$output_config";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400994 run_command "$make mrproper" or
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400995 dodie "make mrproper";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400996 }
Steven Rostedt2545eb62010-11-02 15:01:32 -0400997
998 # add something to distinguish this build
Steven Rostedta75fece2010-11-02 14:58:27 -0400999 open(OUT, "> $outputdir/localversion") or dodie("Can't make localversion file");
1000 print OUT "$localversion\n";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001001 close(OUT);
1002
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001003 if (defined($minconfig)) {
1004 $defconfig = "KCONFIG_ALLCONFIG=$minconfig";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001005 }
1006
Steven Rostedt612b9e92011-03-07 13:27:43 -05001007 if ($type eq "oldnoconfig") {
1008 make_oldconfig $defconfig;
1009 } else {
1010 run_command "$defconfig $make $type" or
1011 dodie "failed make config";
1012 }
Steven Rostedt2545eb62010-11-02 15:01:32 -04001013
Steven Rostedta75fece2010-11-02 14:58:27 -04001014 $redirect = "$buildlog";
1015 if (!run_command "$make $build_options") {
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001016 undef $redirect;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001017 # bisect may need this to pass
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001018 return 0 if ($in_bisect);
1019 fail "failed build" and return 0;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001020 }
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001021 undef $redirect;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001022
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001023 return 1;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001024}
1025
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001026sub halt {
Steven Rostedte48c5292010-11-02 14:35:37 -04001027 if (!run_ssh "halt" or defined($power_off)) {
Steven Rostedt576f6272010-11-02 14:58:38 -04001028 if (defined($poweroff_after_halt)) {
1029 sleep $poweroff_after_halt;
1030 run_command "$power_off";
1031 }
1032 } else {
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001033 # nope? the zap it!
Steven Rostedta75fece2010-11-02 14:58:27 -04001034 run_command "$power_off";
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001035 }
1036}
1037
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001038sub success {
1039 my ($i) = @_;
1040
Steven Rostedte48c5292010-11-02 14:35:37 -04001041 $successes++;
1042
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001043 doprint "\n\n*******************************************\n";
1044 doprint "*******************************************\n";
Steven Rostedt7a849cd2010-11-08 16:49:25 -05001045 doprint "KTEST RESULT: TEST $i SUCCESS!!!! **\n";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001046 doprint "*******************************************\n";
1047 doprint "*******************************************\n";
1048
Steven Rostedt576f6272010-11-02 14:58:38 -04001049 if ($i != $opt{"NUM_TESTS"} && !do_not_reboot) {
Steven Rostedta75fece2010-11-02 14:58:27 -04001050 doprint "Reboot and wait $sleep_time seconds\n";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001051 reboot;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001052 start_monitor;
Steven Rostedta75fece2010-11-02 14:58:27 -04001053 wait_for_monitor $sleep_time;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001054 end_monitor;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001055 }
1056}
1057
1058sub get_version {
1059 # get the release name
1060 doprint "$make kernelrelease ... ";
1061 $version = `$make kernelrelease | tail -1`;
1062 chomp($version);
1063 doprint "$version\n";
1064}
1065
Steven Rostedtc960bb92011-03-08 09:22:39 -05001066sub answer_bisect {
1067 for (;;) {
1068 doprint "Pass or fail? [p/f]";
1069 my $ans = <STDIN>;
1070 chomp $ans;
1071 if ($ans eq "p" || $ans eq "P") {
1072 return 1;
1073 } elsif ($ans eq "f" || $ans eq "F") {
1074 return 0;
1075 } else {
1076 print "Please answer 'P' or 'F'\n";
1077 }
1078 }
1079}
1080
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001081sub child_run_test {
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001082 my $failed = 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001083
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001084 # child should have no power
Steven Rostedta75fece2010-11-02 14:58:27 -04001085 $reboot_on_error = 0;
1086 $poweroff_on_error = 0;
1087 $die_on_failure = 1;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001088
1089 run_command $run_test or $failed = 1;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001090 exit $failed;
1091}
1092
1093my $child_done;
1094
1095sub child_finished {
1096 $child_done = 1;
1097}
1098
1099sub do_run_test {
1100 my $child_pid;
1101 my $child_exit;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001102 my $line;
1103 my $full_line;
1104 my $bug = 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001105
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001106 wait_for_monitor 1;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001107
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001108 doprint "run test $run_test\n";
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001109
1110 $child_done = 0;
1111
1112 $SIG{CHLD} = qw(child_finished);
1113
1114 $child_pid = fork;
1115
1116 child_run_test if (!$child_pid);
1117
1118 $full_line = "";
1119
1120 do {
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001121 $line = wait_for_input($monitor_fp, 1);
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001122 if (defined($line)) {
1123
1124 # we are not guaranteed to get a full line
1125 $full_line .= $line;
Steven Rostedt8ea0e062011-03-08 09:44:35 -05001126 doprint $line;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001127
1128 if ($full_line =~ /call trace:/i) {
1129 $bug = 1;
1130 }
1131
1132 if ($full_line =~ /Kernel panic -/) {
1133 $bug = 1;
1134 }
1135
1136 if ($line =~ /\n/) {
1137 $full_line = "";
1138 }
1139 }
1140 } while (!$child_done && !$bug);
1141
1142 if ($bug) {
Steven Rostedt8ea0e062011-03-08 09:44:35 -05001143 my $failure_start = time;
1144 my $now;
1145 do {
1146 $line = wait_for_input($monitor_fp, 1);
1147 if (defined($line)) {
1148 doprint $line;
1149 }
1150 $now = time;
1151 if ($now - $failure_start >= $stop_after_failure) {
1152 last;
1153 }
1154 } while (defined($line));
1155
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001156 doprint "Detected kernel crash!\n";
1157 # kill the child with extreme prejudice
1158 kill 9, $child_pid;
1159 }
1160
1161 waitpid $child_pid, 0;
1162 $child_exit = $?;
1163
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001164 if ($bug || $child_exit) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001165 return 0 if $in_bisect;
1166 fail "test failed" and return 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001167 }
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001168 return 1;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001169}
1170
Steven Rostedta75fece2010-11-02 14:58:27 -04001171sub run_git_bisect {
1172 my ($command) = @_;
1173
1174 doprint "$command ... ";
1175
1176 my $output = `$command 2>&1`;
1177 my $ret = $?;
1178
1179 logit $output;
1180
1181 if ($ret) {
1182 doprint "FAILED\n";
1183 dodie "Failed to git bisect";
1184 }
1185
1186 doprint "SUCCESS\n";
1187 if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\))\s+\[([[:xdigit:]]+)\]/) {
1188 doprint "$1 [$2]\n";
1189 } elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) {
1190 $bisect_bad = $1;
1191 doprint "Found bad commit... $1\n";
1192 return 0;
1193 } else {
1194 # we already logged it, just print it now.
1195 print $output;
1196 }
1197
1198 return 1;
1199}
1200
Steven Rostedtc23dca72011-03-08 09:26:31 -05001201sub bisect_reboot {
1202 doprint "Reboot and sleep $bisect_sleep_time seconds\n";
1203 reboot;
1204 start_monitor;
1205 wait_for_monitor $bisect_sleep_time;
1206 end_monitor;
1207}
1208
1209# returns 1 on success, 0 on failure, -1 on skip
Steven Rostedt0a05c762010-11-08 11:14:10 -05001210sub run_bisect_test {
1211 my ($type, $buildtype) = @_;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001212
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001213 my $failed = 0;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001214 my $result;
1215 my $output;
1216 my $ret;
1217
Steven Rostedt0a05c762010-11-08 11:14:10 -05001218 $in_bisect = 1;
1219
1220 build $buildtype or $failed = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001221
1222 if ($type ne "build") {
Steven Rostedtc23dca72011-03-08 09:26:31 -05001223 if ($failed && $bisect_skip) {
1224 $in_bisect = 0;
1225 return -1;
1226 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001227 dodie "Failed on build" if $failed;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001228
1229 # Now boot the box
1230 get_grub_index;
1231 get_version;
1232 install;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001233
1234 start_monitor;
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001235 monitor or $failed = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001236
1237 if ($type ne "boot") {
Steven Rostedtc23dca72011-03-08 09:26:31 -05001238 if ($failed && $bisect_skip) {
1239 end_monitor;
1240 bisect_reboot;
1241 $in_bisect = 0;
1242 return -1;
1243 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001244 dodie "Failed on boot" if $failed;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001245
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001246 do_run_test or $failed = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001247 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001248 end_monitor;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001249 }
1250
1251 if ($failed) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001252 $result = 0;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001253 } else {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001254 $result = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001255 }
Steven Rostedt4025bc62011-05-20 09:16:29 -04001256
1257 # reboot the box to a kernel we can ssh to
1258 if ($type ne "build") {
1259 bisect_reboot;
1260 }
Steven Rostedt0a05c762010-11-08 11:14:10 -05001261 $in_bisect = 0;
1262
1263 return $result;
1264}
1265
1266sub run_bisect {
1267 my ($type) = @_;
1268 my $buildtype = "oldconfig";
1269
1270 # We should have a minconfig to use?
1271 if (defined($minconfig)) {
1272 $buildtype = "useconfig:$minconfig";
1273 }
1274
1275 my $ret = run_bisect_test $type, $buildtype;
1276
Steven Rostedtc960bb92011-03-08 09:22:39 -05001277 if ($bisect_manual) {
1278 $ret = answer_bisect;
1279 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001280
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04001281 # Are we looking for where it worked, not failed?
1282 if ($reverse_bisect) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001283 $ret = !$ret;
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04001284 }
1285
Steven Rostedtc23dca72011-03-08 09:26:31 -05001286 if ($ret > 0) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001287 return "good";
Steven Rostedtc23dca72011-03-08 09:26:31 -05001288 } elsif ($ret == 0) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001289 return "bad";
Steven Rostedtc23dca72011-03-08 09:26:31 -05001290 } elsif ($bisect_skip) {
1291 doprint "HIT A BAD COMMIT ... SKIPPING\n";
1292 return "skip";
Steven Rostedt0a05c762010-11-08 11:14:10 -05001293 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001294}
1295
1296sub bisect {
1297 my ($i) = @_;
1298
1299 my $result;
1300
1301 die "BISECT_GOOD[$i] not defined\n" if (!defined($opt{"BISECT_GOOD[$i]"}));
1302 die "BISECT_BAD[$i] not defined\n" if (!defined($opt{"BISECT_BAD[$i]"}));
1303 die "BISECT_TYPE[$i] not defined\n" if (!defined($opt{"BISECT_TYPE[$i]"}));
1304
1305 my $good = $opt{"BISECT_GOOD[$i]"};
1306 my $bad = $opt{"BISECT_BAD[$i]"};
1307 my $type = $opt{"BISECT_TYPE[$i]"};
Steven Rostedta75fece2010-11-02 14:58:27 -04001308 my $start = $opt{"BISECT_START[$i]"};
1309 my $replay = $opt{"BISECT_REPLAY[$i]"};
Steven Rostedt3410f6f2011-03-08 09:38:12 -05001310 my $start_files = $opt{"BISECT_FILES[$i]"};
1311
1312 if (defined($start_files)) {
1313 $start_files = " -- " . $start_files;
1314 } else {
1315 $start_files = "";
1316 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001317
Steven Rostedta57419b2010-11-02 15:13:54 -04001318 # convert to true sha1's
1319 $good = get_sha1($good);
1320 $bad = get_sha1($bad);
1321
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04001322 if (defined($opt{"BISECT_REVERSE[$i]"}) &&
1323 $opt{"BISECT_REVERSE[$i]"} == 1) {
1324 doprint "Performing a reverse bisect (bad is good, good is bad!)\n";
1325 $reverse_bisect = 1;
1326 } else {
1327 $reverse_bisect = 0;
1328 }
1329
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001330 # Can't have a test without having a test to run
1331 if ($type eq "test" && !defined($run_test)) {
1332 $type = "boot";
1333 }
1334
Steven Rostedta75fece2010-11-02 14:58:27 -04001335 my $check = $opt{"BISECT_CHECK[$i]"};
1336 if (defined($check) && $check ne "0") {
1337
1338 # get current HEAD
Steven Rostedta57419b2010-11-02 15:13:54 -04001339 my $head = get_sha1("HEAD");
Steven Rostedta75fece2010-11-02 14:58:27 -04001340
1341 if ($check ne "good") {
1342 doprint "TESTING BISECT BAD [$bad]\n";
1343 run_command "git checkout $bad" or
1344 die "Failed to checkout $bad";
1345
1346 $result = run_bisect $type;
1347
1348 if ($result ne "bad") {
1349 fail "Tested BISECT_BAD [$bad] and it succeeded" and return 0;
1350 }
1351 }
1352
1353 if ($check ne "bad") {
1354 doprint "TESTING BISECT GOOD [$good]\n";
1355 run_command "git checkout $good" or
1356 die "Failed to checkout $good";
1357
1358 $result = run_bisect $type;
1359
1360 if ($result ne "good") {
1361 fail "Tested BISECT_GOOD [$good] and it failed" and return 0;
1362 }
1363 }
1364
1365 # checkout where we started
1366 run_command "git checkout $head" or
1367 die "Failed to checkout $head";
1368 }
1369
Steven Rostedt3410f6f2011-03-08 09:38:12 -05001370 run_command "git bisect start$start_files" or
Steven Rostedta75fece2010-11-02 14:58:27 -04001371 dodie "could not start bisect";
1372
1373 run_command "git bisect good $good" or
1374 dodie "could not set bisect good to $good";
1375
1376 run_git_bisect "git bisect bad $bad" or
1377 dodie "could not set bisect bad to $bad";
1378
1379 if (defined($replay)) {
1380 run_command "git bisect replay $replay" or
1381 dodie "failed to run replay";
1382 }
1383
1384 if (defined($start)) {
1385 run_command "git checkout $start" or
1386 dodie "failed to checkout $start";
1387 }
1388
1389 my $test;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001390 do {
1391 $result = run_bisect $type;
Steven Rostedta75fece2010-11-02 14:58:27 -04001392 $test = run_git_bisect "git bisect $result";
1393 } while ($test);
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001394
1395 run_command "git bisect log" or
1396 dodie "could not capture git bisect log";
1397
1398 run_command "git bisect reset" or
1399 dodie "could not reset git bisect";
1400
1401 doprint "Bad commit was [$bisect_bad]\n";
1402
Steven Rostedt0a05c762010-11-08 11:14:10 -05001403 success $i;
1404}
1405
1406my %config_ignore;
1407my %config_set;
1408
1409my %config_list;
1410my %null_config;
1411
1412my %dependency;
1413
1414sub process_config_ignore {
1415 my ($config) = @_;
1416
1417 open (IN, $config)
1418 or dodie "Failed to read $config";
1419
1420 while (<IN>) {
1421 if (/^(.*?(CONFIG\S*)(=.*| is not set))/) {
1422 $config_ignore{$2} = $1;
1423 }
1424 }
1425
1426 close(IN);
1427}
1428
1429sub read_current_config {
1430 my ($config_ref) = @_;
1431
1432 %{$config_ref} = ();
1433 undef %{$config_ref};
1434
1435 my @key = keys %{$config_ref};
1436 if ($#key >= 0) {
1437 print "did not delete!\n";
1438 exit;
1439 }
1440 open (IN, "$output_config");
1441
1442 while (<IN>) {
1443 if (/^(CONFIG\S+)=(.*)/) {
1444 ${$config_ref}{$1} = $2;
1445 }
1446 }
1447 close(IN);
1448}
1449
1450sub get_dependencies {
1451 my ($config) = @_;
1452
1453 my $arr = $dependency{$config};
1454 if (!defined($arr)) {
1455 return ();
1456 }
1457
1458 my @deps = @{$arr};
1459
1460 foreach my $dep (@{$arr}) {
1461 print "ADD DEP $dep\n";
1462 @deps = (@deps, get_dependencies $dep);
1463 }
1464
1465 return @deps;
1466}
1467
1468sub create_config {
1469 my @configs = @_;
1470
1471 open(OUT, ">$output_config") or dodie "Can not write to $output_config";
1472
1473 foreach my $config (@configs) {
1474 print OUT "$config_set{$config}\n";
1475 my @deps = get_dependencies $config;
1476 foreach my $dep (@deps) {
1477 print OUT "$config_set{$dep}\n";
1478 }
1479 }
1480
1481 foreach my $config (keys %config_ignore) {
1482 print OUT "$config_ignore{$config}\n";
1483 }
1484 close(OUT);
1485
1486# exit;
Steven Rostedt612b9e92011-03-07 13:27:43 -05001487 make_oldconfig "";
Steven Rostedt0a05c762010-11-08 11:14:10 -05001488}
1489
1490sub compare_configs {
1491 my (%a, %b) = @_;
1492
1493 foreach my $item (keys %a) {
1494 if (!defined($b{$item})) {
1495 print "diff $item\n";
1496 return 1;
1497 }
1498 delete $b{$item};
1499 }
1500
1501 my @keys = keys %b;
1502 if ($#keys) {
1503 print "diff2 $keys[0]\n";
1504 }
1505 return -1 if ($#keys >= 0);
1506
1507 return 0;
1508}
1509
1510sub run_config_bisect_test {
1511 my ($type) = @_;
1512
1513 return run_bisect_test $type, "oldconfig";
1514}
1515
1516sub process_passed {
1517 my (%configs) = @_;
1518
1519 doprint "These configs had no failure: (Enabling them for further compiles)\n";
1520 # Passed! All these configs are part of a good compile.
1521 # Add them to the min options.
1522 foreach my $config (keys %configs) {
1523 if (defined($config_list{$config})) {
1524 doprint " removing $config\n";
1525 $config_ignore{$config} = $config_list{$config};
1526 delete $config_list{$config};
1527 }
1528 }
Steven Rostedtf1a27852010-11-11 11:34:38 -05001529 doprint "config copied to $outputdir/config_good\n";
1530 run_command "cp -f $output_config $outputdir/config_good";
Steven Rostedt0a05c762010-11-08 11:14:10 -05001531}
1532
1533sub process_failed {
1534 my ($config) = @_;
1535
1536 doprint "\n\n***************************************\n";
1537 doprint "Found bad config: $config\n";
1538 doprint "***************************************\n\n";
1539}
1540
1541sub run_config_bisect {
1542
1543 my @start_list = keys %config_list;
1544
1545 if ($#start_list < 0) {
1546 doprint "No more configs to test!!!\n";
1547 return -1;
1548 }
1549
1550 doprint "***** RUN TEST ***\n";
1551 my $type = $opt{"CONFIG_BISECT_TYPE[$iteration]"};
1552 my $ret;
1553 my %current_config;
1554
1555 my $count = $#start_list + 1;
1556 doprint " $count configs to test\n";
1557
1558 my $half = int($#start_list / 2);
1559
1560 do {
1561 my @tophalf = @start_list[0 .. $half];
1562
1563 create_config @tophalf;
1564 read_current_config \%current_config;
1565
1566 $count = $#tophalf + 1;
1567 doprint "Testing $count configs\n";
1568 my $found = 0;
1569 # make sure we test something
1570 foreach my $config (@tophalf) {
1571 if (defined($current_config{$config})) {
1572 logit " $config\n";
1573 $found = 1;
1574 }
1575 }
1576 if (!$found) {
1577 # try the other half
1578 doprint "Top half produced no set configs, trying bottom half\n";
1579 @tophalf = @start_list[$half .. $#start_list];
1580 create_config @tophalf;
1581 read_current_config \%current_config;
1582 foreach my $config (@tophalf) {
1583 if (defined($current_config{$config})) {
1584 logit " $config\n";
1585 $found = 1;
1586 }
1587 }
1588 if (!$found) {
1589 doprint "Failed: Can't make new config with current configs\n";
1590 foreach my $config (@start_list) {
1591 doprint " CONFIG: $config\n";
1592 }
1593 return -1;
1594 }
1595 $count = $#tophalf + 1;
1596 doprint "Testing $count configs\n";
1597 }
1598
1599 $ret = run_config_bisect_test $type;
Steven Rostedtc960bb92011-03-08 09:22:39 -05001600 if ($bisect_manual) {
1601 $ret = answer_bisect;
1602 }
Steven Rostedt0a05c762010-11-08 11:14:10 -05001603 if ($ret) {
1604 process_passed %current_config;
1605 return 0;
1606 }
1607
1608 doprint "This config had a failure.\n";
1609 doprint "Removing these configs that were not set in this config:\n";
Steven Rostedtf1a27852010-11-11 11:34:38 -05001610 doprint "config copied to $outputdir/config_bad\n";
1611 run_command "cp -f $output_config $outputdir/config_bad";
Steven Rostedt0a05c762010-11-08 11:14:10 -05001612
1613 # A config exists in this group that was bad.
1614 foreach my $config (keys %config_list) {
1615 if (!defined($current_config{$config})) {
1616 doprint " removing $config\n";
1617 delete $config_list{$config};
1618 }
1619 }
1620
1621 @start_list = @tophalf;
1622
1623 if ($#start_list == 0) {
1624 process_failed $start_list[0];
1625 return 1;
1626 }
1627
1628 # remove half the configs we are looking at and see if
1629 # they are good.
1630 $half = int($#start_list / 2);
1631 } while ($half > 0);
1632
Steven Rostedtc960bb92011-03-08 09:22:39 -05001633 # we found a single config, try it again unless we are running manually
1634
1635 if ($bisect_manual) {
1636 process_failed $start_list[0];
1637 return 1;
1638 }
1639
Steven Rostedt0a05c762010-11-08 11:14:10 -05001640 my @tophalf = @start_list[0 .. 0];
1641
1642 $ret = run_config_bisect_test $type;
1643 if ($ret) {
1644 process_passed %current_config;
1645 return 0;
1646 }
1647
1648 process_failed $start_list[0];
1649 return 1;
1650}
1651
1652sub config_bisect {
1653 my ($i) = @_;
1654
1655 my $start_config = $opt{"CONFIG_BISECT[$i]"};
1656
1657 my $tmpconfig = "$tmpdir/use_config";
1658
1659 # Make the file with the bad config and the min config
1660 if (defined($minconfig)) {
1661 # read the min config for things to ignore
1662 run_command "cp $minconfig $tmpconfig" or
1663 dodie "failed to copy $minconfig to $tmpconfig";
1664 } else {
1665 unlink $tmpconfig;
1666 }
1667
1668 # Add other configs
1669 if (defined($addconfig)) {
1670 run_command "cat $addconfig >> $tmpconfig" or
1671 dodie "failed to append $addconfig";
1672 }
1673
1674 my $defconfig = "";
1675 if (-f $tmpconfig) {
1676 $defconfig = "KCONFIG_ALLCONFIG=$tmpconfig";
1677 process_config_ignore $tmpconfig;
1678 }
1679
1680 # now process the start config
1681 run_command "cp $start_config $output_config" or
1682 dodie "failed to copy $start_config to $output_config";
1683
1684 # read directly what we want to check
1685 my %config_check;
1686 open (IN, $output_config)
1687 or dodie "faied to open $output_config";
1688
1689 while (<IN>) {
1690 if (/^((CONFIG\S*)=.*)/) {
1691 $config_check{$2} = $1;
1692 }
1693 }
1694 close(IN);
1695
1696 # Now run oldconfig with the minconfig (and addconfigs)
Steven Rostedt612b9e92011-03-07 13:27:43 -05001697 make_oldconfig $defconfig;
Steven Rostedt0a05c762010-11-08 11:14:10 -05001698
1699 # check to see what we lost (or gained)
1700 open (IN, $output_config)
1701 or dodie "Failed to read $start_config";
1702
1703 my %removed_configs;
1704 my %added_configs;
1705
1706 while (<IN>) {
1707 if (/^((CONFIG\S*)=.*)/) {
1708 # save off all options
1709 $config_set{$2} = $1;
1710 if (defined($config_check{$2})) {
1711 if (defined($config_ignore{$2})) {
1712 $removed_configs{$2} = $1;
1713 } else {
1714 $config_list{$2} = $1;
1715 }
1716 } elsif (!defined($config_ignore{$2})) {
1717 $added_configs{$2} = $1;
1718 $config_list{$2} = $1;
1719 }
1720 }
1721 }
1722 close(IN);
1723
1724 my @confs = keys %removed_configs;
1725 if ($#confs >= 0) {
1726 doprint "Configs overridden by default configs and removed from check:\n";
1727 foreach my $config (@confs) {
1728 doprint " $config\n";
1729 }
1730 }
1731 @confs = keys %added_configs;
1732 if ($#confs >= 0) {
1733 doprint "Configs appearing in make oldconfig and added:\n";
1734 foreach my $config (@confs) {
1735 doprint " $config\n";
1736 }
1737 }
1738
1739 my %config_test;
1740 my $once = 0;
1741
1742 # Sometimes kconfig does weird things. We must make sure
1743 # that the config we autocreate has everything we need
1744 # to test, otherwise we may miss testing configs, or
1745 # may not be able to create a new config.
1746 # Here we create a config with everything set.
1747 create_config (keys %config_list);
1748 read_current_config \%config_test;
1749 foreach my $config (keys %config_list) {
1750 if (!defined($config_test{$config})) {
1751 if (!$once) {
1752 $once = 1;
1753 doprint "Configs not produced by kconfig (will not be checked):\n";
1754 }
1755 doprint " $config\n";
1756 delete $config_list{$config};
1757 }
1758 }
1759 my $ret;
1760 do {
1761 $ret = run_config_bisect;
1762 } while (!$ret);
1763
1764 return $ret if ($ret < 0);
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001765
1766 success $i;
1767}
1768
Steven Rostedt27d934b2011-05-20 09:18:18 -04001769sub patchcheck_reboot {
1770 doprint "Reboot and sleep $patchcheck_sleep_time seconds\n";
1771 reboot;
1772 start_monitor;
1773 wait_for_monitor $patchcheck_sleep_time;
1774 end_monitor;
1775}
1776
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001777sub patchcheck {
1778 my ($i) = @_;
1779
1780 die "PATCHCHECK_START[$i] not defined\n"
1781 if (!defined($opt{"PATCHCHECK_START[$i]"}));
1782 die "PATCHCHECK_TYPE[$i] not defined\n"
1783 if (!defined($opt{"PATCHCHECK_TYPE[$i]"}));
1784
1785 my $start = $opt{"PATCHCHECK_START[$i]"};
1786
1787 my $end = "HEAD";
1788 if (defined($opt{"PATCHCHECK_END[$i]"})) {
1789 $end = $opt{"PATCHCHECK_END[$i]"};
1790 }
1791
Steven Rostedta57419b2010-11-02 15:13:54 -04001792 # Get the true sha1's since we can use things like HEAD~3
1793 $start = get_sha1($start);
1794 $end = get_sha1($end);
1795
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001796 my $type = $opt{"PATCHCHECK_TYPE[$i]"};
1797
1798 # Can't have a test without having a test to run
1799 if ($type eq "test" && !defined($run_test)) {
1800 $type = "boot";
1801 }
1802
1803 open (IN, "git log --pretty=oneline $end|") or
1804 dodie "could not get git list";
1805
1806 my @list;
1807
1808 while (<IN>) {
1809 chomp;
1810 $list[$#list+1] = $_;
1811 last if (/^$start/);
1812 }
1813 close(IN);
1814
1815 if ($list[$#list] !~ /^$start/) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001816 fail "SHA1 $start not found";
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001817 }
1818
1819 # go backwards in the list
1820 @list = reverse @list;
1821
1822 my $save_clean = $noclean;
1823
1824 $in_patchcheck = 1;
1825 foreach my $item (@list) {
1826 my $sha1 = $item;
1827 $sha1 =~ s/^([[:xdigit:]]+).*/$1/;
1828
1829 doprint "\nProcessing commit $item\n\n";
1830
1831 run_command "git checkout $sha1" or
1832 die "Failed to checkout $sha1";
1833
1834 # only clean on the first and last patch
1835 if ($item eq $list[0] ||
1836 $item eq $list[$#list]) {
1837 $noclean = $save_clean;
1838 } else {
1839 $noclean = 1;
1840 }
1841
1842 if (defined($minconfig)) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001843 build "useconfig:$minconfig" or return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001844 } else {
1845 # ?? no config to use?
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001846 build "oldconfig" or return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001847 }
1848
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001849 check_buildlog $sha1 or return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001850
1851 next if ($type eq "build");
1852
1853 get_grub_index;
1854 get_version;
1855 install;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001856
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001857 my $failed = 0;
1858
1859 start_monitor;
1860 monitor or $failed = 1;
1861
1862 if (!$failed && $type ne "boot"){
1863 do_run_test or $failed = 1;
1864 }
1865 end_monitor;
1866 return 0 if ($failed);
1867
Steven Rostedt27d934b2011-05-20 09:18:18 -04001868 patchcheck_reboot;
1869
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001870 }
1871 $in_patchcheck = 0;
1872 success $i;
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001873
1874 return 1;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001875}
1876
Steven Rostedt8d1491b2010-11-18 15:39:48 -05001877$#ARGV < 1 or die "ktest.pl version: $VERSION\n usage: ktest.pl config-file\n";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001878
Steven Rostedt8d1491b2010-11-18 15:39:48 -05001879if ($#ARGV == 0) {
1880 $ktest_config = $ARGV[0];
1881 if (! -f $ktest_config) {
1882 print "$ktest_config does not exist.\n";
1883 my $ans;
1884 for (;;) {
1885 print "Create it? [Y/n] ";
1886 $ans = <STDIN>;
1887 chomp $ans;
1888 if ($ans =~ /^\s*$/) {
1889 $ans = "y";
1890 }
1891 last if ($ans =~ /^y$/i || $ans =~ /^n$/i);
1892 print "Please answer either 'y' or 'n'.\n";
1893 }
1894 if ($ans !~ /^y$/i) {
1895 exit 0;
1896 }
1897 }
1898} else {
1899 $ktest_config = "ktest.conf";
1900}
1901
1902if (! -f $ktest_config) {
1903 open(OUT, ">$ktest_config") or die "Can not create $ktest_config";
1904 print OUT << "EOF"
1905# Generated by ktest.pl
1906#
1907# Define each test with TEST_START
1908# The config options below it will override the defaults
1909TEST_START
1910
1911DEFAULTS
1912EOF
1913;
1914 close(OUT);
1915}
1916read_config $ktest_config;
1917
1918# Append any configs entered in manually to the config file.
1919my @new_configs = keys %entered_configs;
1920if ($#new_configs >= 0) {
1921 print "\nAppending entered in configs to $ktest_config\n";
1922 open(OUT, ">>$ktest_config") or die "Can not append to $ktest_config";
1923 foreach my $config (@new_configs) {
1924 print OUT "$config = $entered_configs{$config}\n";
1925 $opt{$config} = $entered_configs{$config};
1926 }
1927}
Steven Rostedt2545eb62010-11-02 15:01:32 -04001928
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001929if ($opt{"CLEAR_LOG"} && defined($opt{"LOG_FILE"})) {
1930 unlink $opt{"LOG_FILE"};
1931}
Steven Rostedt2545eb62010-11-02 15:01:32 -04001932
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001933doprint "\n\nSTARTING AUTOMATED TESTS\n\n";
1934
Steven Rostedta57419b2010-11-02 15:13:54 -04001935for (my $i = 0, my $repeat = 1; $i <= $opt{"NUM_TESTS"}; $i += $repeat) {
1936
1937 if (!$i) {
1938 doprint "DEFAULT OPTIONS:\n";
1939 } else {
1940 doprint "\nTEST $i OPTIONS";
1941 if (defined($repeat_tests{$i})) {
1942 $repeat = $repeat_tests{$i};
1943 doprint " ITERATE $repeat";
1944 }
1945 doprint "\n";
1946 }
1947
1948 foreach my $option (sort keys %opt) {
1949
1950 if ($option =~ /\[(\d+)\]$/) {
1951 next if ($i != $1);
1952 } else {
1953 next if ($i);
1954 }
1955
1956 doprint "$option = $opt{$option}\n";
1957 }
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001958}
Steven Rostedt2545eb62010-11-02 15:01:32 -04001959
Steven Rostedta75fece2010-11-02 14:58:27 -04001960sub set_test_option {
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001961 my ($name, $i) = @_;
1962
1963 my $option = "$name\[$i\]";
1964
1965 if (defined($opt{$option})) {
1966 return $opt{$option};
1967 }
1968
Steven Rostedta57419b2010-11-02 15:13:54 -04001969 foreach my $test (keys %repeat_tests) {
1970 if ($i >= $test &&
1971 $i < $test + $repeat_tests{$test}) {
1972 $option = "$name\[$test\]";
1973 if (defined($opt{$option})) {
1974 return $opt{$option};
1975 }
1976 }
1977 }
1978
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001979 if (defined($opt{$name})) {
1980 return $opt{$name};
1981 }
1982
1983 return undef;
1984}
1985
Steven Rostedt2545eb62010-11-02 15:01:32 -04001986# First we need to do is the builds
Steven Rostedta75fece2010-11-02 14:58:27 -04001987for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
Steven Rostedt2545eb62010-11-02 15:01:32 -04001988
Steven Rostedt576f6272010-11-02 14:58:38 -04001989 $iteration = $i;
1990
Steven Rostedta75fece2010-11-02 14:58:27 -04001991 my $makecmd = set_test_option("MAKE_CMD", $i);
1992
1993 $machine = set_test_option("MACHINE", $i);
Steven Rostedte48c5292010-11-02 14:35:37 -04001994 $ssh_user = set_test_option("SSH_USER", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04001995 $tmpdir = set_test_option("TMP_DIR", $i);
1996 $outputdir = set_test_option("OUTPUT_DIR", $i);
1997 $builddir = set_test_option("BUILD_DIR", $i);
1998 $test_type = set_test_option("TEST_TYPE", $i);
1999 $build_type = set_test_option("BUILD_TYPE", $i);
2000 $build_options = set_test_option("BUILD_OPTIONS", $i);
2001 $power_cycle = set_test_option("POWER_CYCLE", $i);
Steven Rostedte48c5292010-11-02 14:35:37 -04002002 $reboot = set_test_option("REBOOT", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002003 $noclean = set_test_option("BUILD_NOCLEAN", $i);
2004 $minconfig = set_test_option("MIN_CONFIG", $i);
2005 $run_test = set_test_option("TEST", $i);
2006 $addconfig = set_test_option("ADD_CONFIG", $i);
2007 $reboot_type = set_test_option("REBOOT_TYPE", $i);
2008 $grub_menu = set_test_option("GRUB_MENU", $i);
Steven Rostedt8b37ca82010-11-02 14:58:33 -04002009 $post_install = set_test_option("POST_INSTALL", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002010 $reboot_script = set_test_option("REBOOT_SCRIPT", $i);
2011 $reboot_on_error = set_test_option("REBOOT_ON_ERROR", $i);
2012 $poweroff_on_error = set_test_option("POWEROFF_ON_ERROR", $i);
2013 $die_on_failure = set_test_option("DIE_ON_FAILURE", $i);
2014 $power_off = set_test_option("POWER_OFF", $i);
Steven Rostedt576f6272010-11-02 14:58:38 -04002015 $powercycle_after_reboot = set_test_option("POWERCYCLE_AFTER_REBOOT", $i);
2016 $poweroff_after_halt = set_test_option("POWEROFF_AFTER_HALT", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002017 $sleep_time = set_test_option("SLEEP_TIME", $i);
2018 $bisect_sleep_time = set_test_option("BISECT_SLEEP_TIME", $i);
Steven Rostedt27d934b2011-05-20 09:18:18 -04002019 $patchcheck_sleep_time = set_test_option("PATCHCHECK_SLEEP_TIME", $i);
Steven Rostedtc960bb92011-03-08 09:22:39 -05002020 $bisect_manual = set_test_option("BISECT_MANUAL", $i);
Steven Rostedtc23dca72011-03-08 09:26:31 -05002021 $bisect_skip = set_test_option("BISECT_SKIP", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002022 $store_failures = set_test_option("STORE_FAILURES", $i);
2023 $timeout = set_test_option("TIMEOUT", $i);
2024 $booted_timeout = set_test_option("BOOTED_TIMEOUT", $i);
2025 $console = set_test_option("CONSOLE", $i);
2026 $success_line = set_test_option("SUCCESS_LINE", $i);
Steven Rostedt1c8a6172010-11-09 12:55:40 -05002027 $stop_after_success = set_test_option("STOP_AFTER_SUCCESS", $i);
2028 $stop_after_failure = set_test_option("STOP_AFTER_FAILURE", $i);
Steven Rostedt2d01b262011-03-08 09:47:54 -05002029 $stop_test_after = set_test_option("STOP_TEST_AFTER", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002030 $build_target = set_test_option("BUILD_TARGET", $i);
Steven Rostedte48c5292010-11-02 14:35:37 -04002031 $ssh_exec = set_test_option("SSH_EXEC", $i);
2032 $scp_to_target = set_test_option("SCP_TO_TARGET", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002033 $target_image = set_test_option("TARGET_IMAGE", $i);
2034 $localversion = set_test_option("LOCALVERSION", $i);
2035
2036 chdir $builddir || die "can't change directory to $builddir";
2037
2038 if (!-d $tmpdir) {
2039 mkpath($tmpdir) or
2040 die "can't create $tmpdir";
2041 }
2042
Steven Rostedte48c5292010-11-02 14:35:37 -04002043 $ENV{"SSH_USER"} = $ssh_user;
2044 $ENV{"MACHINE"} = $machine;
2045
Steven Rostedta75fece2010-11-02 14:58:27 -04002046 $target = "$ssh_user\@$machine";
2047
2048 $buildlog = "$tmpdir/buildlog-$machine";
2049 $dmesg = "$tmpdir/dmesg-$machine";
2050 $make = "$makecmd O=$outputdir";
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05002051 $output_config = "$outputdir/.config";
Steven Rostedta75fece2010-11-02 14:58:27 -04002052
2053 if ($reboot_type eq "grub") {
Steven Rostedt576f6272010-11-02 14:58:38 -04002054 dodie "GRUB_MENU not defined" if (!defined($grub_menu));
Steven Rostedta75fece2010-11-02 14:58:27 -04002055 } elsif (!defined($reboot_script)) {
Steven Rostedt576f6272010-11-02 14:58:38 -04002056 dodie "REBOOT_SCRIPT not defined"
Steven Rostedta75fece2010-11-02 14:58:27 -04002057 }
2058
2059 my $run_type = $build_type;
2060 if ($test_type eq "patchcheck") {
2061 $run_type = $opt{"PATCHCHECK_TYPE[$i]"};
2062 } elsif ($test_type eq "bisect") {
2063 $run_type = $opt{"BISECT_TYPE[$i]"};
Steven Rostedt0a05c762010-11-08 11:14:10 -05002064 } elsif ($test_type eq "config_bisect") {
2065 $run_type = $opt{"CONFIG_BISECT_TYPE[$i]"};
Steven Rostedta75fece2010-11-02 14:58:27 -04002066 }
2067
2068 # mistake in config file?
2069 if (!defined($run_type)) {
2070 $run_type = "ERROR";
2071 }
Steven Rostedt2545eb62010-11-02 15:01:32 -04002072
2073 doprint "\n\n";
Steven Rostedta75fece2010-11-02 14:58:27 -04002074 doprint "RUNNING TEST $i of $opt{NUM_TESTS} with option $test_type $run_type\n\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -04002075
2076 unlink $dmesg;
2077 unlink $buildlog;
Steven Rostedt2545eb62010-11-02 15:01:32 -04002078
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002079 if (!defined($minconfig)) {
2080 $minconfig = $addconfig;
2081
2082 } elsif (defined($addconfig)) {
Steven Rostedt9be2e6b2010-11-09 12:20:21 -05002083 run_command "cat $addconfig $minconfig > $tmpdir/add_config" or
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002084 dodie "Failed to create temp config";
Steven Rostedt9be2e6b2010-11-09 12:20:21 -05002085 $minconfig = "$tmpdir/add_config";
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002086 }
2087
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002088 my $checkout = $opt{"CHECKOUT[$i]"};
2089 if (defined($checkout)) {
2090 run_command "git checkout $checkout" or
2091 die "failed to checkout $checkout";
2092 }
2093
Steven Rostedta75fece2010-11-02 14:58:27 -04002094 if ($test_type eq "bisect") {
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04002095 bisect $i;
2096 next;
Steven Rostedt0a05c762010-11-08 11:14:10 -05002097 } elsif ($test_type eq "config_bisect") {
2098 config_bisect $i;
2099 next;
Steven Rostedta75fece2010-11-02 14:58:27 -04002100 } elsif ($test_type eq "patchcheck") {
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002101 patchcheck $i;
2102 next;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04002103 }
2104
Steven Rostedt7faafbd2010-11-02 14:58:22 -04002105 if ($build_type ne "nobuild") {
2106 build $build_type or next;
Steven Rostedt2545eb62010-11-02 15:01:32 -04002107 }
2108
Steven Rostedta75fece2010-11-02 14:58:27 -04002109 if ($test_type ne "build") {
2110 get_grub_index;
2111 get_version;
2112 install;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04002113
Steven Rostedta75fece2010-11-02 14:58:27 -04002114 my $failed = 0;
2115 start_monitor;
2116 monitor or $failed = 1;;
2117
2118 if (!$failed && $test_type ne "boot" && defined($run_test)) {
2119 do_run_test or $failed = 1;
2120 }
2121 end_monitor;
2122 next if ($failed);
Steven Rostedt5a391fb2010-11-02 14:57:43 -04002123 }
2124
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04002125 success $i;
Steven Rostedt2545eb62010-11-02 15:01:32 -04002126}
2127
Steven Rostedt5c42fc52010-11-02 14:57:01 -04002128if ($opt{"POWEROFF_ON_SUCCESS"}) {
Steven Rostedt75c3fda72010-11-02 14:57:21 -04002129 halt;
Steven Rostedt576f6272010-11-02 14:58:38 -04002130} elsif ($opt{"REBOOT_ON_SUCCESS"} && !do_not_reboot) {
Steven Rostedt75c3fda72010-11-02 14:57:21 -04002131 reboot;
Steven Rostedt5c42fc52010-11-02 14:57:01 -04002132}
Steven Rostedt75c3fda72010-11-02 14:57:21 -04002133
Steven Rostedte48c5292010-11-02 14:35:37 -04002134doprint "\n $successes of $opt{NUM_TESTS} tests were successful\n\n";
2135
Steven Rostedt2545eb62010-11-02 15:01:32 -04002136exit 0;