ktest: Handle kernels before make oldnoconfig
[deliverable/linux.git] / tools / testing / ktest / ktest.pl
CommitLineData
2545eb61 1#!/usr/bin/perl -w
d6ce2a0b
SR
2#
3# Copywrite 2010 - Steven Rostedt <srostedt@redhat.com>, Red Hat Inc.
4# Licensed under the terms of the GNU GPL License version 2
5#
2545eb61
SR
6
7use strict;
8use IPC::Open2;
9use Fcntl qw(F_GETFL F_SETFL O_NONBLOCK);
7faafbd6
SR
10use File::Path qw(mkpath);
11use File::Copy qw(cp);
2545eb61
SR
12use FileHandle;
13
e48c5293
SR
14my $VERSION = "0.2";
15
2545eb61
SR
16$| = 1;
17
18my %opt;
a57419b3
SR
19my %repeat_tests;
20my %repeats;
a75fecec 21my %default;
2545eb61
SR
22
23#default opts
a57419b3 24$default{"NUM_TESTS"} = 1;
a75fecec
SR
25$default{"REBOOT_TYPE"} = "grub";
26$default{"TEST_TYPE"} = "test";
27$default{"BUILD_TYPE"} = "randconfig";
28$default{"MAKE_CMD"} = "make";
29$default{"TIMEOUT"} = 120;
a57419b3 30$default{"TMP_DIR"} = "/tmp/ktest";
a75fecec
SR
31$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;
40$default{"SUCCESS_LINE"} = "login:";
41$default{"BOOTED_TIMEOUT"} = 1;
42$default{"DIE_ON_FAILURE"} = 1;
e48c5293
SR
43$default{"SSH_EXEC"} = "ssh \$SSH_USER\@\$MACHINE \$SSH_COMMAND";
44$default{"SCP_TO_TARGET"} = "scp \$SRC_FILE \$SSH_USER\@\$MACHINE:\$DST_FILE";
45$default{"REBOOT"} = "ssh \$SSH_USER\@\$MACHINE reboot";
1c8a617a
SR
46$default{"STOP_AFTER_SUCCESS"} = 10;
47$default{"STOP_AFTER_FAILURE"} = 60;
8d1491ba 48$default{"LOCALVERSION"} = "-test";
2545eb61 49
8d1491ba 50my $ktest_config;
2545eb61 51my $version;
a75fecec 52my $machine;
e48c5293 53my $ssh_user;
a75fecec
SR
54my $tmpdir;
55my $builddir;
56my $outputdir;
51ad1dd1 57my $output_config;
a75fecec 58my $test_type;
7faafbd6 59my $build_type;
a75fecec
SR
60my $build_options;
61my $reboot_type;
62my $reboot_script;
63my $power_cycle;
e48c5293 64my $reboot;
a75fecec
SR
65my $reboot_on_error;
66my $poweroff_on_error;
67my $die_on_failure;
576f627c
SR
68my $powercycle_after_reboot;
69my $poweroff_after_halt;
e48c5293
SR
70my $ssh_exec;
71my $scp_to_target;
a75fecec
SR
72my $power_off;
73my $grub_menu;
2545eb61
SR
74my $grub_number;
75my $target;
76my $make;
8b37ca8c 77my $post_install;
5c42fc5b 78my $noclean;
5f9b6ced 79my $minconfig;
2b7d9b21 80my $addconfig;
5f9b6ced
SR
81my $in_bisect = 0;
82my $bisect_bad = "";
d6ce2a0b 83my $reverse_bisect;
6c5ee0be 84my $in_patchcheck = 0;
5a391fbf 85my $run_test;
6c5ee0be 86my $redirect;
7faafbd6
SR
87my $buildlog;
88my $dmesg;
89my $monitor_fp;
90my $monitor_pid;
91my $monitor_cnt = 0;
a75fecec
SR
92my $sleep_time;
93my $bisect_sleep_time;
94my $store_failures;
95my $timeout;
96my $booted_timeout;
97my $console;
98my $success_line;
1c8a617a
SR
99my $stop_after_success;
100my $stop_after_failure;
a75fecec
SR
101my $build_target;
102my $target_image;
103my $localversion;
576f627c 104my $iteration = 0;
e48c5293 105my $successes = 0;
2545eb61 106
8d1491ba
SR
107my %entered_configs;
108my %config_help;
109
110$config_help{"MACHINE"} = << "EOF"
111 The machine hostname that you will test.
112EOF
113 ;
114$config_help{"SSH_USER"} = << "EOF"
115 The box is expected to have ssh on normal bootup, provide the user
116 (most likely root, since you need privileged operations)
117EOF
118 ;
119$config_help{"BUILD_DIR"} = << "EOF"
120 The directory that contains the Linux source code (full path).
121EOF
122 ;
123$config_help{"OUTPUT_DIR"} = << "EOF"
124 The directory that the objects will be built (full path).
125 (can not be same as BUILD_DIR)
126EOF
127 ;
128$config_help{"BUILD_TARGET"} = << "EOF"
129 The location of the compiled file to copy to the target.
130 (relative to OUTPUT_DIR)
131EOF
132 ;
133$config_help{"TARGET_IMAGE"} = << "EOF"
134 The place to put your image on the test machine.
135EOF
136 ;
137$config_help{"POWER_CYCLE"} = << "EOF"
138 A script or command to reboot the box.
139
140 Here is a digital loggers power switch example
141 POWER_CYCLE = wget --no-proxy -O /dev/null -q --auth-no-challenge 'http://admin:admin\@power/outlet?5=CCL'
142
143 Here is an example to reboot a virtual box on the current host
144 with the name "Guest".
145 POWER_CYCLE = virsh destroy Guest; sleep 5; virsh start Guest
146EOF
147 ;
148$config_help{"CONSOLE"} = << "EOF"
149 The script or command that reads the console
150
151 If you use ttywatch server, something like the following would work.
152CONSOLE = nc -d localhost 3001
153
154 For a virtual machine with guest name "Guest".
155CONSOLE = virsh console Guest
156EOF
157 ;
158$config_help{"LOCALVERSION"} = << "EOF"
159 Required version ending to differentiate the test
160 from other linux builds on the system.
161EOF
162 ;
163$config_help{"REBOOT_TYPE"} = << "EOF"
164 Way to reboot the box to the test kernel.
165 Only valid options so far are "grub" and "script".
166
167 If you specify grub, it will assume grub version 1
168 and will search in /boot/grub/menu.lst for the title \$GRUB_MENU
169 and select that target to reboot to the kernel. If this is not
170 your setup, then specify "script" and have a command or script
171 specified in REBOOT_SCRIPT to boot to the target.
172
173 The entry in /boot/grub/menu.lst must be entered in manually.
174 The test will not modify that file.
175EOF
176 ;
177$config_help{"GRUB_MENU"} = << "EOF"
178 The grub title name for the test kernel to boot
179 (Only mandatory if REBOOT_TYPE = grub)
180
181 Note, ktest.pl will not update the grub menu.lst, you need to
182 manually add an option for the test. ktest.pl will search
183 the grub menu.lst for this option to find what kernel to
184 reboot into.
185
186 For example, if in the /boot/grub/menu.lst the test kernel title has:
187 title Test Kernel
188 kernel vmlinuz-test
189 GRUB_MENU = Test Kernel
190EOF
191 ;
192$config_help{"REBOOT_SCRIPT"} = << "EOF"
193 A script to reboot the target into the test kernel
194 (Only mandatory if REBOOT_TYPE = script)
195EOF
196 ;
197
198
199sub get_ktest_config {
200 my ($config) = @_;
201
202 return if (defined($opt{$config}));
203
204 if (defined($config_help{$config})) {
205 print "\n";
206 print $config_help{$config};
207 }
208
209 for (;;) {
210 print "$config = ";
211 if (defined($default{$config})) {
212 print "\[$default{$config}\] ";
213 }
214 $entered_configs{$config} = <STDIN>;
215 $entered_configs{$config} =~ s/^\s*(.*\S)\s*$/$1/;
216 if ($entered_configs{$config} =~ /^\s*$/) {
217 if ($default{$config}) {
218 $entered_configs{$config} = $default{$config};
219 } else {
220 print "Your answer can not be blank\n";
221 next;
222 }
223 }
224 last;
225 }
226}
227
228sub get_ktest_configs {
229 get_ktest_config("MACHINE");
230 get_ktest_config("SSH_USER");
231 get_ktest_config("BUILD_DIR");
232 get_ktest_config("OUTPUT_DIR");
233 get_ktest_config("BUILD_TARGET");
234 get_ktest_config("TARGET_IMAGE");
235 get_ktest_config("POWER_CYCLE");
236 get_ktest_config("CONSOLE");
237 get_ktest_config("LOCALVERSION");
238
239 my $rtype = $opt{"REBOOT_TYPE"};
240
241 if (!defined($rtype)) {
242 if (!defined($opt{"GRUB_MENU"})) {
243 get_ktest_config("REBOOT_TYPE");
244 $rtype = $entered_configs{"REBOOT_TYPE"};
245 } else {
246 $rtype = "grub";
247 }
248 }
249
250 if ($rtype eq "grub") {
251 get_ktest_config("GRUB_MENU");
252 } else {
253 get_ktest_config("REBOOT_SCRIPT");
254 }
255}
256
a57419b3
SR
257sub set_value {
258 my ($lvalue, $rvalue) = @_;
259
260 if (defined($opt{$lvalue})) {
261 die "Error: Option $lvalue defined more than once!\n";
262 }
21a9679f
SR
263 if ($rvalue =~ /^\s*$/) {
264 delete $opt{$lvalue};
265 } else {
266 $opt{$lvalue} = $rvalue;
267 }
a57419b3
SR
268}
269
2545eb61
SR
270sub read_config {
271 my ($config) = @_;
272
273 open(IN, $config) || die "can't read file $config";
274
a57419b3
SR
275 my $name = $config;
276 $name =~ s,.*/(.*),$1,;
277
278 my $test_num = 0;
279 my $default = 1;
280 my $repeat = 1;
281 my $num_tests_set = 0;
282 my $skip = 0;
283 my $rest;
284
2545eb61
SR
285 while (<IN>) {
286
287 # ignore blank lines and comments
288 next if (/^\s*$/ || /\s*\#/);
289
a57419b3
SR
290 if (/^\s*TEST_START(.*)/) {
291
292 $rest = $1;
293
294 if ($num_tests_set) {
295 die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
296 }
297
298 my $old_test_num = $test_num;
e48c5293 299 my $old_repeat = $repeat;
a57419b3
SR
300
301 $test_num += $repeat;
302 $default = 0;
303 $repeat = 1;
304
305 if ($rest =~ /\s+SKIP(.*)/) {
306 $rest = $1;
307 $skip = 1;
308 } else {
309 $skip = 0;
310 }
311
312 if ($rest =~ /\s+ITERATE\s+(\d+)(.*)$/) {
313 $repeat = $1;
314 $rest = $2;
315 $repeat_tests{"$test_num"} = $repeat;
316 }
317
318 if ($rest =~ /\s+SKIP(.*)/) {
319 $rest = $1;
320 $skip = 1;
321 }
322
323 if ($rest !~ /^\s*$/) {
324 die "$name: $.: Gargbage found after TEST_START\n$_";
325 }
326
327 if ($skip) {
328 $test_num = $old_test_num;
e48c5293 329 $repeat = $old_repeat;
a57419b3
SR
330 }
331
332 } elsif (/^\s*DEFAULTS(.*)$/) {
333 $default = 1;
334
335 $rest = $1;
336
337 if ($rest =~ /\s+SKIP(.*)/) {
338 $rest = $1;
339 $skip = 1;
340 } else {
341 $skip = 0;
342 }
343
344 if ($rest !~ /^\s*$/) {
345 die "$name: $.: Gargbage found after DEFAULTS\n$_";
346 }
347
348 } elsif (/^\s*([A-Z_\[\]\d]+)\s*=\s*(.*?)\s*$/) {
349
350 next if ($skip);
351
2545eb61
SR
352 my $lvalue = $1;
353 my $rvalue = $2;
354
a57419b3
SR
355 if (!$default &&
356 ($lvalue eq "NUM_TESTS" ||
357 $lvalue eq "LOG_FILE" ||
358 $lvalue eq "CLEAR_LOG")) {
359 die "$name: $.: $lvalue must be set in DEFAULTS section\n";
360 }
361
362 if ($lvalue eq "NUM_TESTS") {
363 if ($test_num) {
364 die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
365 }
366 if (!$default) {
367 die "$name: $.: NUM_TESTS must be set in default section\n";
368 }
369 $num_tests_set = 1;
370 }
371
372 if ($default || $lvalue =~ /\[\d+\]$/) {
373 set_value($lvalue, $rvalue);
374 } else {
375 my $val = "$lvalue\[$test_num\]";
376 set_value($val, $rvalue);
377
378 if ($repeat > 1) {
379 $repeats{$val} = $repeat;
380 }
a75fecec 381 }
a57419b3
SR
382 } else {
383 die "$name: $.: Garbage found in config\n$_";
2545eb61
SR
384 }
385 }
386
387 close(IN);
a75fecec 388
a57419b3
SR
389 if ($test_num) {
390 $test_num += $repeat - 1;
391 $opt{"NUM_TESTS"} = $test_num;
392 }
393
8d1491ba
SR
394 # make sure we have all mandatory configs
395 get_ktest_configs;
396
a75fecec
SR
397 # set any defaults
398
399 foreach my $default (keys %default) {
400 if (!defined($opt{$default})) {
401 $opt{$default} = $default{$default};
402 }
403 }
2545eb61
SR
404}
405
d1e2f22a 406sub _logit {
2545eb61
SR
407 if (defined($opt{"LOG_FILE"})) {
408 open(OUT, ">> $opt{LOG_FILE}") or die "Can't write to $opt{LOG_FILE}";
409 print OUT @_;
410 close(OUT);
411 }
412}
413
d1e2f22a
SR
414sub logit {
415 if (defined($opt{"LOG_FILE"})) {
416 _logit @_;
417 } else {
418 print @_;
419 }
420}
421
5f9b6ced
SR
422sub doprint {
423 print @_;
d1e2f22a 424 _logit @_;
5f9b6ced
SR
425}
426
7faafbd6
SR
427sub run_command;
428
429sub reboot {
430 # try to reboot normally
e48c5293 431 if (run_command $reboot) {
576f627c
SR
432 if (defined($powercycle_after_reboot)) {
433 sleep $powercycle_after_reboot;
434 run_command "$power_cycle";
435 }
436 } else {
7faafbd6 437 # nope? power cycle it.
a75fecec 438 run_command "$power_cycle";
7faafbd6
SR
439 }
440}
441
576f627c
SR
442sub do_not_reboot {
443 my $i = $iteration;
444
445 return $test_type eq "build" ||
446 ($test_type eq "patchcheck" && $opt{"PATCHCHECK_TYPE[$i]"} eq "build") ||
447 ($test_type eq "bisect" && $opt{"BISECT_TYPE[$i]"} eq "build");
448}
449
5c42fc5b 450sub dodie {
5a391fbf 451 doprint "CRITICAL FAILURE... ", @_, "\n";
5c42fc5b 452
576f627c
SR
453 my $i = $iteration;
454
455 if ($reboot_on_error && !do_not_reboot) {
456
75c3fda7 457 doprint "REBOOTING\n";
7faafbd6 458 reboot;
75c3fda7 459
a75fecec 460 } elsif ($poweroff_on_error && defined($power_off)) {
5c42fc5b 461 doprint "POWERING OFF\n";
a75fecec 462 `$power_off`;
5c42fc5b 463 }
75c3fda7 464
f80802cb
SR
465 if (defined($opt{"LOG_FILE"})) {
466 print " See $opt{LOG_FILE} for more info.\n";
467 }
468
576f627c 469 die @_, "\n";
5c42fc5b
SR
470}
471
7faafbd6
SR
472sub open_console {
473 my ($fp) = @_;
474
475 my $flags;
476
a75fecec
SR
477 my $pid = open($fp, "$console|") or
478 dodie "Can't open console $console";
7faafbd6
SR
479
480 $flags = fcntl($fp, F_GETFL, 0) or
576f627c 481 dodie "Can't get flags for the socket: $!";
7faafbd6 482 $flags = fcntl($fp, F_SETFL, $flags | O_NONBLOCK) or
576f627c 483 dodie "Can't set flags for the socket: $!";
7faafbd6
SR
484
485 return $pid;
486}
487
488sub close_console {
489 my ($fp, $pid) = @_;
490
491 doprint "kill child process $pid\n";
492 kill 2, $pid;
493
494 print "closing!\n";
495 close($fp);
496}
497
498sub start_monitor {
499 if ($monitor_cnt++) {
500 return;
501 }
502 $monitor_fp = \*MONFD;
503 $monitor_pid = open_console $monitor_fp;
a75fecec
SR
504
505 return;
506
507 open(MONFD, "Stop perl from warning about single use of MONFD");
7faafbd6
SR
508}
509
510sub end_monitor {
511 if (--$monitor_cnt) {
512 return;
513 }
514 close_console($monitor_fp, $monitor_pid);
515}
516
517sub wait_for_monitor {
518 my ($time) = @_;
519 my $line;
520
a75fecec 521 doprint "** Wait for monitor to settle down **\n";
7faafbd6
SR
522
523 # read the monitor and wait for the system to calm down
524 do {
525 $line = wait_for_input($monitor_fp, $time);
a75fecec 526 print "$line" if (defined($line));
7faafbd6 527 } while (defined($line));
a75fecec 528 print "** Monitor flushed **\n";
7faafbd6
SR
529}
530
2b7d9b21
SR
531sub fail {
532
a75fecec 533 if ($die_on_failure) {
2b7d9b21
SR
534 dodie @_;
535 }
536
a75fecec 537 doprint "FAILED\n";
7faafbd6 538
576f627c
SR
539 my $i = $iteration;
540
a75fecec 541 # no need to reboot for just building.
576f627c 542 if (!do_not_reboot) {
a75fecec
SR
543 doprint "REBOOTING\n";
544 reboot;
545 start_monitor;
546 wait_for_monitor $sleep_time;
547 end_monitor;
548 }
7faafbd6 549
576f627c
SR
550 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
551 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
7a849cd9 552 doprint "KTEST RESULT: TEST $i Failed: ", @_, "\n";
576f627c
SR
553 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
554 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
a75fecec
SR
555
556 return 1 if (!defined($store_failures));
7faafbd6
SR
557
558 my @t = localtime;
559 my $date = sprintf "%04d%02d%02d%02d%02d%02d",
560 1900+$t[5],$t[4],$t[3],$t[2],$t[1],$t[0];
561
cccae1a6
SR
562 my $type = $build_type;
563 if ($type =~ /useconfig/) {
564 $type = "useconfig";
565 }
566
567 my $dir = "$machine-$test_type-$type-fail-$date";
a75fecec 568 my $faildir = "$store_failures/$dir";
7faafbd6
SR
569
570 if (!-d $faildir) {
571 mkpath($faildir) or
a75fecec 572 die "can't create $faildir";
7faafbd6 573 }
51ad1dd1
SR
574 if (-f "$output_config") {
575 cp "$output_config", "$faildir/config" or
7faafbd6
SR
576 die "failed to copy .config";
577 }
578 if (-f $buildlog) {
579 cp $buildlog, "$faildir/buildlog" or
580 die "failed to move $buildlog";
581 }
582 if (-f $dmesg) {
583 cp $dmesg, "$faildir/dmesg" or
584 die "failed to move $dmesg";
585 }
586
587 doprint "*** Saved info to $faildir ***\n";
588
2b7d9b21
SR
589 return 1;
590}
591
2545eb61
SR
592sub run_command {
593 my ($command) = @_;
d6ce2a0b
SR
594 my $dolog = 0;
595 my $dord = 0;
596 my $pid;
597
e48c5293
SR
598 $command =~ s/\$SSH_USER/$ssh_user/g;
599 $command =~ s/\$MACHINE/$machine/g;
600
d6ce2a0b
SR
601 doprint("$command ... ");
602
603 $pid = open(CMD, "$command 2>&1 |") or
2b7d9b21 604 (fail "unable to exec $command" and return 0);
2545eb61
SR
605
606 if (defined($opt{"LOG_FILE"})) {
d6ce2a0b
SR
607 open(LOG, ">>$opt{LOG_FILE}") or
608 dodie "failed to write to log";
609 $dolog = 1;
6c5ee0be
SR
610 }
611
612 if (defined($redirect)) {
d6ce2a0b
SR
613 open (RD, ">$redirect") or
614 dodie "failed to write to redirect $redirect";
615 $dord = 1;
2545eb61
SR
616 }
617
d6ce2a0b
SR
618 while (<CMD>) {
619 print LOG if ($dolog);
620 print RD if ($dord);
621 }
2545eb61 622
d6ce2a0b 623 waitpid($pid, 0);
2545eb61
SR
624 my $failed = $?;
625
d6ce2a0b
SR
626 close(CMD);
627 close(LOG) if ($dolog);
628 close(RD) if ($dord);
629
2545eb61
SR
630 if ($failed) {
631 doprint "FAILED!\n";
632 } else {
633 doprint "SUCCESS\n";
634 }
635
5f9b6ced
SR
636 return !$failed;
637}
638
e48c5293
SR
639sub run_ssh {
640 my ($cmd) = @_;
641 my $cp_exec = $ssh_exec;
642
643 $cp_exec =~ s/\$SSH_COMMAND/$cmd/g;
644 return run_command "$cp_exec";
645}
646
647sub run_scp {
648 my ($src, $dst) = @_;
649 my $cp_scp = $scp_to_target;
650
651 $cp_scp =~ s/\$SRC_FILE/$src/g;
652 $cp_scp =~ s/\$DST_FILE/$dst/g;
653
654 return run_command "$cp_scp";
655}
656
5f9b6ced
SR
657sub get_grub_index {
658
a75fecec
SR
659 if ($reboot_type ne "grub") {
660 return;
661 }
5a391fbf 662 return if (defined($grub_number));
5f9b6ced
SR
663
664 doprint "Find grub menu ... ";
665 $grub_number = -1;
e48c5293
SR
666
667 my $ssh_grub = $ssh_exec;
668 $ssh_grub =~ s,\$SSH_COMMAND,cat /boot/grub/menu.lst,g;
669
670 open(IN, "$ssh_grub |")
5f9b6ced 671 or die "unable to get menu.lst";
e48c5293 672
5f9b6ced 673 while (<IN>) {
a75fecec 674 if (/^\s*title\s+$grub_menu\s*$/) {
5f9b6ced
SR
675 $grub_number++;
676 last;
677 } elsif (/^\s*title\s/) {
678 $grub_number++;
679 }
680 }
681 close(IN);
682
a75fecec 683 die "Could not find '$grub_menu' in /boot/grub/menu on $machine"
5f9b6ced
SR
684 if ($grub_number < 0);
685 doprint "$grub_number\n";
2545eb61
SR
686}
687
2545eb61
SR
688sub wait_for_input
689{
690 my ($fp, $time) = @_;
691 my $rin;
692 my $ready;
693 my $line;
694 my $ch;
695
696 if (!defined($time)) {
697 $time = $timeout;
698 }
699
700 $rin = '';
701 vec($rin, fileno($fp), 1) = 1;
702 $ready = select($rin, undef, undef, $time);
703
704 $line = "";
705
706 # try to read one char at a time
707 while (sysread $fp, $ch, 1) {
708 $line .= $ch;
709 last if ($ch eq "\n");
710 }
711
712 if (!length($line)) {
713 return undef;
714 }
715
716 return $line;
717}
718
75c3fda7 719sub reboot_to {
a75fecec 720 if ($reboot_type eq "grub") {
eec56460 721 run_ssh "'(echo \"savedefault --default=$grub_number --once\" | grub --batch; reboot)'";
a75fecec
SR
722 return;
723 }
724
725 run_command "$reboot_script";
2545eb61
SR
726}
727
a57419b3
SR
728sub get_sha1 {
729 my ($commit) = @_;
730
731 doprint "git rev-list --max-count=1 $commit ... ";
732 my $sha1 = `git rev-list --max-count=1 $commit`;
733 my $ret = $?;
734
735 logit $sha1;
736
737 if ($ret) {
738 doprint "FAILED\n";
739 dodie "Failed to get git $commit";
740 }
741
742 print "SUCCESS\n";
743
744 chomp $sha1;
745
746 return $sha1;
747}
748
5a391fbf 749sub monitor {
2545eb61
SR
750 my $booted = 0;
751 my $bug = 0;
5c42fc5b 752 my $skip_call_trace = 0;
2b7d9b21 753 my $loops;
2545eb61 754
7faafbd6 755 wait_for_monitor 5;
2545eb61
SR
756
757 my $line;
758 my $full_line = "";
759
7faafbd6
SR
760 open(DMESG, "> $dmesg") or
761 die "unable to write to $dmesg";
2545eb61 762
75c3fda7 763 reboot_to;
2545eb61 764
1c8a617a
SR
765 my $success_start;
766 my $failure_start;
767
2545eb61
SR
768 for (;;) {
769
2b7d9b21 770 if ($booted) {
a75fecec 771 $line = wait_for_input($monitor_fp, $booted_timeout);
2b7d9b21 772 } else {
7faafbd6 773 $line = wait_for_input($monitor_fp);
2b7d9b21 774 }
2545eb61
SR
775
776 last if (!defined($line));
777
778 doprint $line;
7faafbd6 779 print DMESG $line;
2545eb61
SR
780
781 # we are not guaranteed to get a full line
782 $full_line .= $line;
783
a75fecec 784 if ($full_line =~ /$success_line/) {
2545eb61 785 $booted = 1;
1c8a617a
SR
786 $success_start = time;
787 }
788
789 if ($booted && defined($stop_after_success) &&
790 $stop_after_success >= 0) {
791 my $now = time;
792 if ($now - $success_start >= $stop_after_success) {
793 doprint "Test forced to stop after $stop_after_success seconds after success\n";
794 last;
795 }
2545eb61
SR
796 }
797
5c42fc5b
SR
798 if ($full_line =~ /\[ backtrace testing \]/) {
799 $skip_call_trace = 1;
800 }
801
2545eb61 802 if ($full_line =~ /call trace:/i) {
1c8a617a
SR
803 if (!$skip_call_trace) {
804 $bug = 1;
805 $failure_start = time;
806 }
807 }
808
809 if ($bug && defined($stop_after_failure) &&
810 $stop_after_failure >= 0) {
811 my $now = time;
812 if ($now - $failure_start >= $stop_after_failure) {
813 doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
814 last;
815 }
5c42fc5b
SR
816 }
817
818 if ($full_line =~ /\[ end of backtrace testing \]/) {
819 $skip_call_trace = 0;
820 }
821
822 if ($full_line =~ /Kernel panic -/) {
10abf118 823 $failure_start = time;
2545eb61
SR
824 $bug = 1;
825 }
826
827 if ($line =~ /\n/) {
828 $full_line = "";
829 }
830 }
831
7faafbd6 832 close(DMESG);
2545eb61 833
a75fecec 834 if ($bug) {
2b7d9b21 835 return 0 if ($in_bisect);
576f627c 836 fail "failed - got a bug report" and return 0;
2545eb61
SR
837 }
838
a75fecec 839 if (!$booted) {
2b7d9b21 840 return 0 if ($in_bisect);
576f627c 841 fail "failed - never got a boot prompt." and return 0;
2545eb61 842 }
5f9b6ced 843
2b7d9b21 844 return 1;
2545eb61
SR
845}
846
847sub install {
848
e48c5293 849 run_scp "$outputdir/$build_target", "$target_image" or
5c42fc5b 850 dodie "failed to copy image";
2545eb61 851
5f9b6ced 852 my $install_mods = 0;
2545eb61 853
5f9b6ced
SR
854 # should we process modules?
855 $install_mods = 0;
51ad1dd1 856 open(IN, "$output_config") or dodie("Can't read config file");
5f9b6ced
SR
857 while (<IN>) {
858 if (/CONFIG_MODULES(=y)?/) {
859 $install_mods = 1 if (defined($1));
860 last;
5c42fc5b 861 }
5f9b6ced
SR
862 }
863 close(IN);
5c42fc5b 864
5f9b6ced
SR
865 if (!$install_mods) {
866 doprint "No modules needed\n";
867 return;
868 }
2545eb61 869
a75fecec 870 run_command "$make INSTALL_MOD_PATH=$tmpdir modules_install" or
5f9b6ced 871 dodie "Failed to install modules";
5c42fc5b 872
5f9b6ced 873 my $modlib = "/lib/modules/$version";
a57419b3 874 my $modtar = "ktest-mods.tar.bz2";
5c42fc5b 875
e48c5293 876 run_ssh "rm -rf $modlib" or
5f9b6ced 877 dodie "failed to remove old mods: $modlib";
5c42fc5b 878
5f9b6ced 879 # would be nice if scp -r did not follow symbolic links
a75fecec 880 run_command "cd $tmpdir && tar -cjf $modtar lib/modules/$version" or
5f9b6ced
SR
881 dodie "making tarball";
882
e48c5293 883 run_scp "$tmpdir/$modtar", "/tmp" or
5f9b6ced
SR
884 dodie "failed to copy modules";
885
a75fecec 886 unlink "$tmpdir/$modtar";
5f9b6ced 887
e48c5293 888 run_ssh "'(cd / && tar xf /tmp/$modtar)'" or
5f9b6ced 889 dodie "failed to tar modules";
2545eb61 890
e48c5293 891 run_ssh "rm -f /tmp/$modtar";
8b37ca8c
SR
892
893 return if (!defined($post_install));
894
e48c5293
SR
895 my $cp_post_install = $post_install;
896 $cp_post_install = s/\$KERNEL_VERSION/$version/g;
897 run_command "$cp_post_install" or
576f627c 898 dodie "Failed to run post install";
2545eb61
SR
899}
900
6c5ee0be
SR
901sub check_buildlog {
902 my ($patch) = @_;
903
6c5ee0be
SR
904 my @files = `git show $patch | diffstat -l`;
905
906 open(IN, "git show $patch |") or
907 dodie "failed to show $patch";
908 while (<IN>) {
909 if (m,^--- a/(.*),) {
910 chomp $1;
911 $files[$#files] = $1;
912 }
913 }
914 close(IN);
915
916 open(IN, $buildlog) or dodie "Can't open $buildlog";
917 while (<IN>) {
918 if (/^\s*(.*?):.*(warning|error)/) {
919 my $err = $1;
920 foreach my $file (@files) {
a75fecec 921 my $fullpath = "$builddir/$file";
6c5ee0be 922 if ($file eq $err || $fullpath eq $err) {
2b7d9b21 923 fail "$file built with warnings" and return 0;
6c5ee0be
SR
924 }
925 }
926 }
927 }
928 close(IN);
2b7d9b21
SR
929
930 return 1;
6c5ee0be
SR
931}
932
612b9e9b
SR
933sub make_oldconfig {
934 my ($defconfig) = @_;
935
936 if (!run_command "$defconfig $make oldnoconfig") {
937 # Perhaps oldnoconfig doesn't exist in this version of the kernel
938 # try a yes '' | oldconfig
939 doprint "oldnoconfig failed, trying yes '' | make oldconfig\n";
940 run_command "yes '' | $defconfig $make oldconfig" or
941 dodie "failed make config oldconfig";
942 }
943}
944
2545eb61
SR
945sub build {
946 my ($type) = @_;
5c42fc5b 947 my $defconfig = "";
5c42fc5b 948
7faafbd6
SR
949 unlink $buildlog;
950
75c3fda7 951 if ($type =~ /^useconfig:(.*)/) {
51ad1dd1 952 run_command "cp $1 $output_config" or
75c3fda7 953 dodie "could not copy $1 to .config";
5f9b6ced 954
75c3fda7
SR
955 $type = "oldconfig";
956 }
957
5c42fc5b
SR
958 # old config can ask questions
959 if ($type eq "oldconfig") {
9386c6ab 960 $type = "oldnoconfig";
75c3fda7
SR
961
962 # allow for empty configs
51ad1dd1 963 run_command "touch $output_config";
75c3fda7 964
51ad1dd1 965 run_command "mv $output_config $outputdir/config_temp" or
5c42fc5b 966 dodie "moving .config";
2545eb61 967
5f9b6ced 968 if (!$noclean && !run_command "$make mrproper") {
5c42fc5b
SR
969 dodie "make mrproper";
970 }
2545eb61 971
51ad1dd1 972 run_command "mv $outputdir/config_temp $output_config" or
5c42fc5b 973 dodie "moving config_temp";
5c42fc5b
SR
974
975 } elsif (!$noclean) {
51ad1dd1 976 unlink "$output_config";
5f9b6ced 977 run_command "$make mrproper" or
5c42fc5b 978 dodie "make mrproper";
5c42fc5b 979 }
2545eb61
SR
980
981 # add something to distinguish this build
a75fecec
SR
982 open(OUT, "> $outputdir/localversion") or dodie("Can't make localversion file");
983 print OUT "$localversion\n";
2545eb61
SR
984 close(OUT);
985
5f9b6ced
SR
986 if (defined($minconfig)) {
987 $defconfig = "KCONFIG_ALLCONFIG=$minconfig";
2545eb61
SR
988 }
989
612b9e9b
SR
990 if ($type eq "oldnoconfig") {
991 make_oldconfig $defconfig;
992 } else {
993 run_command "$defconfig $make $type" or
994 dodie "failed make config";
995 }
2545eb61 996
a75fecec
SR
997 $redirect = "$buildlog";
998 if (!run_command "$make $build_options") {
6c5ee0be 999 undef $redirect;
5f9b6ced 1000 # bisect may need this to pass
2b7d9b21
SR
1001 return 0 if ($in_bisect);
1002 fail "failed build" and return 0;
2545eb61 1003 }
6c5ee0be 1004 undef $redirect;
5f9b6ced 1005
2b7d9b21 1006 return 1;
2545eb61
SR
1007}
1008
75c3fda7 1009sub halt {
e48c5293 1010 if (!run_ssh "halt" or defined($power_off)) {
576f627c
SR
1011 if (defined($poweroff_after_halt)) {
1012 sleep $poweroff_after_halt;
1013 run_command "$power_off";
1014 }
1015 } else {
75c3fda7 1016 # nope? the zap it!
a75fecec 1017 run_command "$power_off";
75c3fda7
SR
1018 }
1019}
1020
5f9b6ced
SR
1021sub success {
1022 my ($i) = @_;
1023
e48c5293
SR
1024 $successes++;
1025
5f9b6ced
SR
1026 doprint "\n\n*******************************************\n";
1027 doprint "*******************************************\n";
7a849cd9 1028 doprint "KTEST RESULT: TEST $i SUCCESS!!!! **\n";
5f9b6ced
SR
1029 doprint "*******************************************\n";
1030 doprint "*******************************************\n";
1031
576f627c 1032 if ($i != $opt{"NUM_TESTS"} && !do_not_reboot) {
a75fecec 1033 doprint "Reboot and wait $sleep_time seconds\n";
5f9b6ced 1034 reboot;
7faafbd6 1035 start_monitor;
a75fecec 1036 wait_for_monitor $sleep_time;
7faafbd6 1037 end_monitor;
5f9b6ced
SR
1038 }
1039}
1040
1041sub get_version {
1042 # get the release name
1043 doprint "$make kernelrelease ... ";
1044 $version = `$make kernelrelease | tail -1`;
1045 chomp($version);
1046 doprint "$version\n";
1047}
1048
5a391fbf 1049sub child_run_test {
7faafbd6 1050 my $failed = 0;
5a391fbf 1051
7faafbd6 1052 # child should have no power
a75fecec
SR
1053 $reboot_on_error = 0;
1054 $poweroff_on_error = 0;
1055 $die_on_failure = 1;
7faafbd6
SR
1056
1057 run_command $run_test or $failed = 1;
5a391fbf
SR
1058 exit $failed;
1059}
1060
1061my $child_done;
1062
1063sub child_finished {
1064 $child_done = 1;
1065}
1066
1067sub do_run_test {
1068 my $child_pid;
1069 my $child_exit;
5a391fbf
SR
1070 my $line;
1071 my $full_line;
1072 my $bug = 0;
5a391fbf 1073
7faafbd6 1074 wait_for_monitor 1;
5a391fbf 1075
7faafbd6 1076 doprint "run test $run_test\n";
5a391fbf
SR
1077
1078 $child_done = 0;
1079
1080 $SIG{CHLD} = qw(child_finished);
1081
1082 $child_pid = fork;
1083
1084 child_run_test if (!$child_pid);
1085
1086 $full_line = "";
1087
1088 do {
7faafbd6 1089 $line = wait_for_input($monitor_fp, 1);
5a391fbf
SR
1090 if (defined($line)) {
1091
1092 # we are not guaranteed to get a full line
1093 $full_line .= $line;
1094
1095 if ($full_line =~ /call trace:/i) {
1096 $bug = 1;
1097 }
1098
1099 if ($full_line =~ /Kernel panic -/) {
1100 $bug = 1;
1101 }
1102
1103 if ($line =~ /\n/) {
1104 $full_line = "";
1105 }
1106 }
1107 } while (!$child_done && !$bug);
1108
1109 if ($bug) {
1110 doprint "Detected kernel crash!\n";
1111 # kill the child with extreme prejudice
1112 kill 9, $child_pid;
1113 }
1114
1115 waitpid $child_pid, 0;
1116 $child_exit = $?;
1117
5a391fbf 1118 if ($bug || $child_exit) {
2b7d9b21
SR
1119 return 0 if $in_bisect;
1120 fail "test failed" and return 0;
5a391fbf 1121 }
2b7d9b21 1122 return 1;
5a391fbf
SR
1123}
1124
a75fecec
SR
1125sub run_git_bisect {
1126 my ($command) = @_;
1127
1128 doprint "$command ... ";
1129
1130 my $output = `$command 2>&1`;
1131 my $ret = $?;
1132
1133 logit $output;
1134
1135 if ($ret) {
1136 doprint "FAILED\n";
1137 dodie "Failed to git bisect";
1138 }
1139
1140 doprint "SUCCESS\n";
1141 if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\))\s+\[([[:xdigit:]]+)\]/) {
1142 doprint "$1 [$2]\n";
1143 } elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) {
1144 $bisect_bad = $1;
1145 doprint "Found bad commit... $1\n";
1146 return 0;
1147 } else {
1148 # we already logged it, just print it now.
1149 print $output;
1150 }
1151
1152 return 1;
1153}
1154
0a05c769
SR
1155# returns 1 on success, 0 on failure
1156sub run_bisect_test {
1157 my ($type, $buildtype) = @_;
5f9b6ced 1158
2b7d9b21 1159 my $failed = 0;
5f9b6ced
SR
1160 my $result;
1161 my $output;
1162 my $ret;
1163
0a05c769
SR
1164 $in_bisect = 1;
1165
1166 build $buildtype or $failed = 1;
5f9b6ced
SR
1167
1168 if ($type ne "build") {
7faafbd6 1169 dodie "Failed on build" if $failed;
5f9b6ced
SR
1170
1171 # Now boot the box
1172 get_grub_index;
1173 get_version;
1174 install;
7faafbd6
SR
1175
1176 start_monitor;
2b7d9b21 1177 monitor or $failed = 1;
5f9b6ced
SR
1178
1179 if ($type ne "boot") {
7faafbd6 1180 dodie "Failed on boot" if $failed;
5a391fbf 1181
2b7d9b21 1182 do_run_test or $failed = 1;
5f9b6ced 1183 }
7faafbd6 1184 end_monitor;
5f9b6ced
SR
1185 }
1186
1187 if ($failed) {
0a05c769 1188 $result = 0;
5a391fbf
SR
1189
1190 # reboot the box to a good kernel
a75fecec
SR
1191 if ($type ne "build") {
1192 doprint "Reboot and sleep $bisect_sleep_time seconds\n";
5a391fbf 1193 reboot;
7faafbd6 1194 start_monitor;
a75fecec 1195 wait_for_monitor $bisect_sleep_time;
7faafbd6 1196 end_monitor;
5a391fbf 1197 }
5f9b6ced 1198 } else {
0a05c769
SR
1199 $result = 1;
1200 }
1201 $in_bisect = 0;
1202
1203 return $result;
1204}
1205
1206sub run_bisect {
1207 my ($type) = @_;
1208 my $buildtype = "oldconfig";
1209
1210 # We should have a minconfig to use?
1211 if (defined($minconfig)) {
1212 $buildtype = "useconfig:$minconfig";
5f9b6ced
SR
1213 }
1214
0a05c769
SR
1215 my $ret = run_bisect_test $type, $buildtype;
1216
1217
d6ce2a0b
SR
1218 # Are we looking for where it worked, not failed?
1219 if ($reverse_bisect) {
0a05c769 1220 $ret = !$ret;
d6ce2a0b
SR
1221 }
1222
0a05c769
SR
1223 if ($ret) {
1224 return "good";
1225 } else {
1226 return "bad";
1227 }
5f9b6ced
SR
1228}
1229
1230sub bisect {
1231 my ($i) = @_;
1232
1233 my $result;
1234
1235 die "BISECT_GOOD[$i] not defined\n" if (!defined($opt{"BISECT_GOOD[$i]"}));
1236 die "BISECT_BAD[$i] not defined\n" if (!defined($opt{"BISECT_BAD[$i]"}));
1237 die "BISECT_TYPE[$i] not defined\n" if (!defined($opt{"BISECT_TYPE[$i]"}));
1238
1239 my $good = $opt{"BISECT_GOOD[$i]"};
1240 my $bad = $opt{"BISECT_BAD[$i]"};
1241 my $type = $opt{"BISECT_TYPE[$i]"};
a75fecec
SR
1242 my $start = $opt{"BISECT_START[$i]"};
1243 my $replay = $opt{"BISECT_REPLAY[$i]"};
5f9b6ced 1244
a57419b3
SR
1245 # convert to true sha1's
1246 $good = get_sha1($good);
1247 $bad = get_sha1($bad);
1248
d6ce2a0b
SR
1249 if (defined($opt{"BISECT_REVERSE[$i]"}) &&
1250 $opt{"BISECT_REVERSE[$i]"} == 1) {
1251 doprint "Performing a reverse bisect (bad is good, good is bad!)\n";
1252 $reverse_bisect = 1;
1253 } else {
1254 $reverse_bisect = 0;
1255 }
1256
a75fecec
SR
1257 # Can't have a test without having a test to run
1258 if ($type eq "test" && !defined($run_test)) {
1259 $type = "boot";
1260 }
1261
1262 my $check = $opt{"BISECT_CHECK[$i]"};
1263 if (defined($check) && $check ne "0") {
1264
1265 # get current HEAD
a57419b3 1266 my $head = get_sha1("HEAD");
a75fecec
SR
1267
1268 if ($check ne "good") {
1269 doprint "TESTING BISECT BAD [$bad]\n";
1270 run_command "git checkout $bad" or
1271 die "Failed to checkout $bad";
1272
1273 $result = run_bisect $type;
1274
1275 if ($result ne "bad") {
1276 fail "Tested BISECT_BAD [$bad] and it succeeded" and return 0;
1277 }
1278 }
1279
1280 if ($check ne "bad") {
1281 doprint "TESTING BISECT GOOD [$good]\n";
1282 run_command "git checkout $good" or
1283 die "Failed to checkout $good";
1284
1285 $result = run_bisect $type;
1286
1287 if ($result ne "good") {
1288 fail "Tested BISECT_GOOD [$good] and it failed" and return 0;
1289 }
1290 }
1291
1292 # checkout where we started
1293 run_command "git checkout $head" or
1294 die "Failed to checkout $head";
1295 }
1296
5f9b6ced 1297 run_command "git bisect start" or
a75fecec 1298 dodie "could not start bisect";
5f9b6ced
SR
1299
1300 run_command "git bisect good $good" or
a75fecec 1301 dodie "could not set bisect good to $good";
5f9b6ced 1302
a75fecec
SR
1303 run_git_bisect "git bisect bad $bad" or
1304 dodie "could not set bisect bad to $bad";
5f9b6ced 1305
a75fecec
SR
1306 if (defined($replay)) {
1307 run_command "git bisect replay $replay" or
1308 dodie "failed to run replay";
5a391fbf
SR
1309 }
1310
a75fecec
SR
1311 if (defined($start)) {
1312 run_command "git checkout $start" or
1313 dodie "failed to checkout $start";
1314 }
1315
1316 my $test;
5f9b6ced
SR
1317 do {
1318 $result = run_bisect $type;
a75fecec
SR
1319 $test = run_git_bisect "git bisect $result";
1320 } while ($test);
5f9b6ced
SR
1321
1322 run_command "git bisect log" or
1323 dodie "could not capture git bisect log";
1324
1325 run_command "git bisect reset" or
1326 dodie "could not reset git bisect";
1327
1328 doprint "Bad commit was [$bisect_bad]\n";
1329
0a05c769
SR
1330 success $i;
1331}
1332
1333my %config_ignore;
1334my %config_set;
1335
1336my %config_list;
1337my %null_config;
1338
1339my %dependency;
1340
1341sub process_config_ignore {
1342 my ($config) = @_;
1343
1344 open (IN, $config)
1345 or dodie "Failed to read $config";
1346
1347 while (<IN>) {
1348 if (/^(.*?(CONFIG\S*)(=.*| is not set))/) {
1349 $config_ignore{$2} = $1;
1350 }
1351 }
1352
1353 close(IN);
1354}
1355
1356sub read_current_config {
1357 my ($config_ref) = @_;
1358
1359 %{$config_ref} = ();
1360 undef %{$config_ref};
1361
1362 my @key = keys %{$config_ref};
1363 if ($#key >= 0) {
1364 print "did not delete!\n";
1365 exit;
1366 }
1367 open (IN, "$output_config");
1368
1369 while (<IN>) {
1370 if (/^(CONFIG\S+)=(.*)/) {
1371 ${$config_ref}{$1} = $2;
1372 }
1373 }
1374 close(IN);
1375}
1376
1377sub get_dependencies {
1378 my ($config) = @_;
1379
1380 my $arr = $dependency{$config};
1381 if (!defined($arr)) {
1382 return ();
1383 }
1384
1385 my @deps = @{$arr};
1386
1387 foreach my $dep (@{$arr}) {
1388 print "ADD DEP $dep\n";
1389 @deps = (@deps, get_dependencies $dep);
1390 }
1391
1392 return @deps;
1393}
1394
1395sub create_config {
1396 my @configs = @_;
1397
1398 open(OUT, ">$output_config") or dodie "Can not write to $output_config";
1399
1400 foreach my $config (@configs) {
1401 print OUT "$config_set{$config}\n";
1402 my @deps = get_dependencies $config;
1403 foreach my $dep (@deps) {
1404 print OUT "$config_set{$dep}\n";
1405 }
1406 }
1407
1408 foreach my $config (keys %config_ignore) {
1409 print OUT "$config_ignore{$config}\n";
1410 }
1411 close(OUT);
1412
1413# exit;
612b9e9b 1414 make_oldconfig "";
0a05c769
SR
1415}
1416
1417sub compare_configs {
1418 my (%a, %b) = @_;
1419
1420 foreach my $item (keys %a) {
1421 if (!defined($b{$item})) {
1422 print "diff $item\n";
1423 return 1;
1424 }
1425 delete $b{$item};
1426 }
1427
1428 my @keys = keys %b;
1429 if ($#keys) {
1430 print "diff2 $keys[0]\n";
1431 }
1432 return -1 if ($#keys >= 0);
1433
1434 return 0;
1435}
1436
1437sub run_config_bisect_test {
1438 my ($type) = @_;
1439
1440 return run_bisect_test $type, "oldconfig";
1441}
1442
1443sub process_passed {
1444 my (%configs) = @_;
1445
1446 doprint "These configs had no failure: (Enabling them for further compiles)\n";
1447 # Passed! All these configs are part of a good compile.
1448 # Add them to the min options.
1449 foreach my $config (keys %configs) {
1450 if (defined($config_list{$config})) {
1451 doprint " removing $config\n";
1452 $config_ignore{$config} = $config_list{$config};
1453 delete $config_list{$config};
1454 }
1455 }
f1a27850
SR
1456 doprint "config copied to $outputdir/config_good\n";
1457 run_command "cp -f $output_config $outputdir/config_good";
0a05c769
SR
1458}
1459
1460sub process_failed {
1461 my ($config) = @_;
1462
1463 doprint "\n\n***************************************\n";
1464 doprint "Found bad config: $config\n";
1465 doprint "***************************************\n\n";
1466}
1467
1468sub run_config_bisect {
1469
1470 my @start_list = keys %config_list;
1471
1472 if ($#start_list < 0) {
1473 doprint "No more configs to test!!!\n";
1474 return -1;
1475 }
1476
1477 doprint "***** RUN TEST ***\n";
1478 my $type = $opt{"CONFIG_BISECT_TYPE[$iteration]"};
1479 my $ret;
1480 my %current_config;
1481
1482 my $count = $#start_list + 1;
1483 doprint " $count configs to test\n";
1484
1485 my $half = int($#start_list / 2);
1486
1487 do {
1488 my @tophalf = @start_list[0 .. $half];
1489
1490 create_config @tophalf;
1491 read_current_config \%current_config;
1492
1493 $count = $#tophalf + 1;
1494 doprint "Testing $count configs\n";
1495 my $found = 0;
1496 # make sure we test something
1497 foreach my $config (@tophalf) {
1498 if (defined($current_config{$config})) {
1499 logit " $config\n";
1500 $found = 1;
1501 }
1502 }
1503 if (!$found) {
1504 # try the other half
1505 doprint "Top half produced no set configs, trying bottom half\n";
1506 @tophalf = @start_list[$half .. $#start_list];
1507 create_config @tophalf;
1508 read_current_config \%current_config;
1509 foreach my $config (@tophalf) {
1510 if (defined($current_config{$config})) {
1511 logit " $config\n";
1512 $found = 1;
1513 }
1514 }
1515 if (!$found) {
1516 doprint "Failed: Can't make new config with current configs\n";
1517 foreach my $config (@start_list) {
1518 doprint " CONFIG: $config\n";
1519 }
1520 return -1;
1521 }
1522 $count = $#tophalf + 1;
1523 doprint "Testing $count configs\n";
1524 }
1525
1526 $ret = run_config_bisect_test $type;
1527
1528 if ($ret) {
1529 process_passed %current_config;
1530 return 0;
1531 }
1532
1533 doprint "This config had a failure.\n";
1534 doprint "Removing these configs that were not set in this config:\n";
f1a27850
SR
1535 doprint "config copied to $outputdir/config_bad\n";
1536 run_command "cp -f $output_config $outputdir/config_bad";
0a05c769
SR
1537
1538 # A config exists in this group that was bad.
1539 foreach my $config (keys %config_list) {
1540 if (!defined($current_config{$config})) {
1541 doprint " removing $config\n";
1542 delete $config_list{$config};
1543 }
1544 }
1545
1546 @start_list = @tophalf;
1547
1548 if ($#start_list == 0) {
1549 process_failed $start_list[0];
1550 return 1;
1551 }
1552
1553 # remove half the configs we are looking at and see if
1554 # they are good.
1555 $half = int($#start_list / 2);
1556 } while ($half > 0);
1557
1558 # we found a single config, try it again
1559 my @tophalf = @start_list[0 .. 0];
1560
1561 $ret = run_config_bisect_test $type;
1562 if ($ret) {
1563 process_passed %current_config;
1564 return 0;
1565 }
1566
1567 process_failed $start_list[0];
1568 return 1;
1569}
1570
1571sub config_bisect {
1572 my ($i) = @_;
1573
1574 my $start_config = $opt{"CONFIG_BISECT[$i]"};
1575
1576 my $tmpconfig = "$tmpdir/use_config";
1577
1578 # Make the file with the bad config and the min config
1579 if (defined($minconfig)) {
1580 # read the min config for things to ignore
1581 run_command "cp $minconfig $tmpconfig" or
1582 dodie "failed to copy $minconfig to $tmpconfig";
1583 } else {
1584 unlink $tmpconfig;
1585 }
1586
1587 # Add other configs
1588 if (defined($addconfig)) {
1589 run_command "cat $addconfig >> $tmpconfig" or
1590 dodie "failed to append $addconfig";
1591 }
1592
1593 my $defconfig = "";
1594 if (-f $tmpconfig) {
1595 $defconfig = "KCONFIG_ALLCONFIG=$tmpconfig";
1596 process_config_ignore $tmpconfig;
1597 }
1598
1599 # now process the start config
1600 run_command "cp $start_config $output_config" or
1601 dodie "failed to copy $start_config to $output_config";
1602
1603 # read directly what we want to check
1604 my %config_check;
1605 open (IN, $output_config)
1606 or dodie "faied to open $output_config";
1607
1608 while (<IN>) {
1609 if (/^((CONFIG\S*)=.*)/) {
1610 $config_check{$2} = $1;
1611 }
1612 }
1613 close(IN);
1614
1615 # Now run oldconfig with the minconfig (and addconfigs)
612b9e9b 1616 make_oldconfig $defconfig;
0a05c769
SR
1617
1618 # check to see what we lost (or gained)
1619 open (IN, $output_config)
1620 or dodie "Failed to read $start_config";
1621
1622 my %removed_configs;
1623 my %added_configs;
1624
1625 while (<IN>) {
1626 if (/^((CONFIG\S*)=.*)/) {
1627 # save off all options
1628 $config_set{$2} = $1;
1629 if (defined($config_check{$2})) {
1630 if (defined($config_ignore{$2})) {
1631 $removed_configs{$2} = $1;
1632 } else {
1633 $config_list{$2} = $1;
1634 }
1635 } elsif (!defined($config_ignore{$2})) {
1636 $added_configs{$2} = $1;
1637 $config_list{$2} = $1;
1638 }
1639 }
1640 }
1641 close(IN);
1642
1643 my @confs = keys %removed_configs;
1644 if ($#confs >= 0) {
1645 doprint "Configs overridden by default configs and removed from check:\n";
1646 foreach my $config (@confs) {
1647 doprint " $config\n";
1648 }
1649 }
1650 @confs = keys %added_configs;
1651 if ($#confs >= 0) {
1652 doprint "Configs appearing in make oldconfig and added:\n";
1653 foreach my $config (@confs) {
1654 doprint " $config\n";
1655 }
1656 }
1657
1658 my %config_test;
1659 my $once = 0;
1660
1661 # Sometimes kconfig does weird things. We must make sure
1662 # that the config we autocreate has everything we need
1663 # to test, otherwise we may miss testing configs, or
1664 # may not be able to create a new config.
1665 # Here we create a config with everything set.
1666 create_config (keys %config_list);
1667 read_current_config \%config_test;
1668 foreach my $config (keys %config_list) {
1669 if (!defined($config_test{$config})) {
1670 if (!$once) {
1671 $once = 1;
1672 doprint "Configs not produced by kconfig (will not be checked):\n";
1673 }
1674 doprint " $config\n";
1675 delete $config_list{$config};
1676 }
1677 }
1678 my $ret;
1679 do {
1680 $ret = run_config_bisect;
1681 } while (!$ret);
1682
1683 return $ret if ($ret < 0);
5f9b6ced
SR
1684
1685 success $i;
1686}
1687
6c5ee0be
SR
1688sub patchcheck {
1689 my ($i) = @_;
1690
1691 die "PATCHCHECK_START[$i] not defined\n"
1692 if (!defined($opt{"PATCHCHECK_START[$i]"}));
1693 die "PATCHCHECK_TYPE[$i] not defined\n"
1694 if (!defined($opt{"PATCHCHECK_TYPE[$i]"}));
1695
1696 my $start = $opt{"PATCHCHECK_START[$i]"};
1697
1698 my $end = "HEAD";
1699 if (defined($opt{"PATCHCHECK_END[$i]"})) {
1700 $end = $opt{"PATCHCHECK_END[$i]"};
1701 }
1702
a57419b3
SR
1703 # Get the true sha1's since we can use things like HEAD~3
1704 $start = get_sha1($start);
1705 $end = get_sha1($end);
1706
6c5ee0be
SR
1707 my $type = $opt{"PATCHCHECK_TYPE[$i]"};
1708
1709 # Can't have a test without having a test to run
1710 if ($type eq "test" && !defined($run_test)) {
1711 $type = "boot";
1712 }
1713
1714 open (IN, "git log --pretty=oneline $end|") or
1715 dodie "could not get git list";
1716
1717 my @list;
1718
1719 while (<IN>) {
1720 chomp;
1721 $list[$#list+1] = $_;
1722 last if (/^$start/);
1723 }
1724 close(IN);
1725
1726 if ($list[$#list] !~ /^$start/) {
2b7d9b21 1727 fail "SHA1 $start not found";
6c5ee0be
SR
1728 }
1729
1730 # go backwards in the list
1731 @list = reverse @list;
1732
1733 my $save_clean = $noclean;
1734
1735 $in_patchcheck = 1;
1736 foreach my $item (@list) {
1737 my $sha1 = $item;
1738 $sha1 =~ s/^([[:xdigit:]]+).*/$1/;
1739
1740 doprint "\nProcessing commit $item\n\n";
1741
1742 run_command "git checkout $sha1" or
1743 die "Failed to checkout $sha1";
1744
1745 # only clean on the first and last patch
1746 if ($item eq $list[0] ||
1747 $item eq $list[$#list]) {
1748 $noclean = $save_clean;
1749 } else {
1750 $noclean = 1;
1751 }
1752
1753 if (defined($minconfig)) {
2b7d9b21 1754 build "useconfig:$minconfig" or return 0;
6c5ee0be
SR
1755 } else {
1756 # ?? no config to use?
2b7d9b21 1757 build "oldconfig" or return 0;
6c5ee0be
SR
1758 }
1759
2b7d9b21 1760 check_buildlog $sha1 or return 0;
6c5ee0be
SR
1761
1762 next if ($type eq "build");
1763
1764 get_grub_index;
1765 get_version;
1766 install;
6c5ee0be 1767
7faafbd6
SR
1768 my $failed = 0;
1769
1770 start_monitor;
1771 monitor or $failed = 1;
1772
1773 if (!$failed && $type ne "boot"){
1774 do_run_test or $failed = 1;
1775 }
1776 end_monitor;
1777 return 0 if ($failed);
1778
6c5ee0be
SR
1779 }
1780 $in_patchcheck = 0;
1781 success $i;
2b7d9b21
SR
1782
1783 return 1;
6c5ee0be
SR
1784}
1785
8d1491ba
SR
1786$#ARGV < 1 or die "ktest.pl version: $VERSION\n usage: ktest.pl config-file\n";
1787
1788if ($#ARGV == 0) {
1789 $ktest_config = $ARGV[0];
1790 if (! -f $ktest_config) {
1791 print "$ktest_config does not exist.\n";
1792 my $ans;
1793 for (;;) {
1794 print "Create it? [Y/n] ";
1795 $ans = <STDIN>;
1796 chomp $ans;
1797 if ($ans =~ /^\s*$/) {
1798 $ans = "y";
1799 }
1800 last if ($ans =~ /^y$/i || $ans =~ /^n$/i);
1801 print "Please answer either 'y' or 'n'.\n";
1802 }
1803 if ($ans !~ /^y$/i) {
1804 exit 0;
1805 }
1806 }
1807} else {
1808 $ktest_config = "ktest.conf";
1809}
1810
1811if (! -f $ktest_config) {
1812 open(OUT, ">$ktest_config") or die "Can not create $ktest_config";
1813 print OUT << "EOF"
1814# Generated by ktest.pl
1815#
1816# Define each test with TEST_START
1817# The config options below it will override the defaults
1818TEST_START
1819
1820DEFAULTS
1821EOF
1822;
1823 close(OUT);
1824}
1825read_config $ktest_config;
1826
1827# Append any configs entered in manually to the config file.
1828my @new_configs = keys %entered_configs;
1829if ($#new_configs >= 0) {
1830 print "\nAppending entered in configs to $ktest_config\n";
1831 open(OUT, ">>$ktest_config") or die "Can not append to $ktest_config";
1832 foreach my $config (@new_configs) {
1833 print OUT "$config = $entered_configs{$config}\n";
1834 $opt{$config} = $entered_configs{$config};
1835 }
1836}
2545eb61 1837
2b7d9b21
SR
1838if ($opt{"CLEAR_LOG"} && defined($opt{"LOG_FILE"})) {
1839 unlink $opt{"LOG_FILE"};
1840}
2545eb61 1841
2b7d9b21
SR
1842doprint "\n\nSTARTING AUTOMATED TESTS\n\n";
1843
a57419b3
SR
1844for (my $i = 0, my $repeat = 1; $i <= $opt{"NUM_TESTS"}; $i += $repeat) {
1845
1846 if (!$i) {
1847 doprint "DEFAULT OPTIONS:\n";
1848 } else {
1849 doprint "\nTEST $i OPTIONS";
1850 if (defined($repeat_tests{$i})) {
1851 $repeat = $repeat_tests{$i};
1852 doprint " ITERATE $repeat";
1853 }
1854 doprint "\n";
1855 }
1856
1857 foreach my $option (sort keys %opt) {
1858
1859 if ($option =~ /\[(\d+)\]$/) {
1860 next if ($i != $1);
1861 } else {
1862 next if ($i);
1863 }
1864
1865 doprint "$option = $opt{$option}\n";
1866 }
2b7d9b21 1867}
2545eb61 1868
a75fecec 1869sub set_test_option {
5a391fbf 1870 my ($name, $i) = @_;
2545eb61 1871
5a391fbf 1872 my $option = "$name\[$i\]";
5c42fc5b 1873
5a391fbf
SR
1874 if (defined($opt{$option})) {
1875 return $opt{$option};
5f9b6ced
SR
1876 }
1877
a57419b3
SR
1878 foreach my $test (keys %repeat_tests) {
1879 if ($i >= $test &&
1880 $i < $test + $repeat_tests{$test}) {
1881 $option = "$name\[$test\]";
1882 if (defined($opt{$option})) {
1883 return $opt{$option};
1884 }
1885 }
1886 }
1887
5a391fbf
SR
1888 if (defined($opt{$name})) {
1889 return $opt{$name};
2545eb61
SR
1890 }
1891
5a391fbf
SR
1892 return undef;
1893}
1894
1895# First we need to do is the builds
a75fecec
SR
1896for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
1897
576f627c
SR
1898 $iteration = $i;
1899
a75fecec
SR
1900 my $makecmd = set_test_option("MAKE_CMD", $i);
1901
1902 $machine = set_test_option("MACHINE", $i);
e48c5293 1903 $ssh_user = set_test_option("SSH_USER", $i);
a75fecec
SR
1904 $tmpdir = set_test_option("TMP_DIR", $i);
1905 $outputdir = set_test_option("OUTPUT_DIR", $i);
1906 $builddir = set_test_option("BUILD_DIR", $i);
1907 $test_type = set_test_option("TEST_TYPE", $i);
1908 $build_type = set_test_option("BUILD_TYPE", $i);
1909 $build_options = set_test_option("BUILD_OPTIONS", $i);
1910 $power_cycle = set_test_option("POWER_CYCLE", $i);
e48c5293 1911 $reboot = set_test_option("REBOOT", $i);
a75fecec
SR
1912 $noclean = set_test_option("BUILD_NOCLEAN", $i);
1913 $minconfig = set_test_option("MIN_CONFIG", $i);
1914 $run_test = set_test_option("TEST", $i);
1915 $addconfig = set_test_option("ADD_CONFIG", $i);
1916 $reboot_type = set_test_option("REBOOT_TYPE", $i);
1917 $grub_menu = set_test_option("GRUB_MENU", $i);
8b37ca8c 1918 $post_install = set_test_option("POST_INSTALL", $i);
a75fecec
SR
1919 $reboot_script = set_test_option("REBOOT_SCRIPT", $i);
1920 $reboot_on_error = set_test_option("REBOOT_ON_ERROR", $i);
1921 $poweroff_on_error = set_test_option("POWEROFF_ON_ERROR", $i);
1922 $die_on_failure = set_test_option("DIE_ON_FAILURE", $i);
1923 $power_off = set_test_option("POWER_OFF", $i);
576f627c
SR
1924 $powercycle_after_reboot = set_test_option("POWERCYCLE_AFTER_REBOOT", $i);
1925 $poweroff_after_halt = set_test_option("POWEROFF_AFTER_HALT", $i);
a75fecec
SR
1926 $sleep_time = set_test_option("SLEEP_TIME", $i);
1927 $bisect_sleep_time = set_test_option("BISECT_SLEEP_TIME", $i);
1928 $store_failures = set_test_option("STORE_FAILURES", $i);
1929 $timeout = set_test_option("TIMEOUT", $i);
1930 $booted_timeout = set_test_option("BOOTED_TIMEOUT", $i);
1931 $console = set_test_option("CONSOLE", $i);
1932 $success_line = set_test_option("SUCCESS_LINE", $i);
1c8a617a
SR
1933 $stop_after_success = set_test_option("STOP_AFTER_SUCCESS", $i);
1934 $stop_after_failure = set_test_option("STOP_AFTER_FAILURE", $i);
a75fecec 1935 $build_target = set_test_option("BUILD_TARGET", $i);
e48c5293
SR
1936 $ssh_exec = set_test_option("SSH_EXEC", $i);
1937 $scp_to_target = set_test_option("SCP_TO_TARGET", $i);
a75fecec
SR
1938 $target_image = set_test_option("TARGET_IMAGE", $i);
1939 $localversion = set_test_option("LOCALVERSION", $i);
1940
1941 chdir $builddir || die "can't change directory to $builddir";
1942
1943 if (!-d $tmpdir) {
1944 mkpath($tmpdir) or
1945 die "can't create $tmpdir";
1946 }
1a5cfce3 1947
e48c5293
SR
1948 $ENV{"SSH_USER"} = $ssh_user;
1949 $ENV{"MACHINE"} = $machine;
1950
a75fecec
SR
1951 $target = "$ssh_user\@$machine";
1952
1953 $buildlog = "$tmpdir/buildlog-$machine";
1954 $dmesg = "$tmpdir/dmesg-$machine";
1955 $make = "$makecmd O=$outputdir";
51ad1dd1 1956 $output_config = "$outputdir/.config";
a75fecec
SR
1957
1958 if ($reboot_type eq "grub") {
576f627c 1959 dodie "GRUB_MENU not defined" if (!defined($grub_menu));
a75fecec 1960 } elsif (!defined($reboot_script)) {
576f627c 1961 dodie "REBOOT_SCRIPT not defined"
a75fecec
SR
1962 }
1963
1964 my $run_type = $build_type;
1965 if ($test_type eq "patchcheck") {
1966 $run_type = $opt{"PATCHCHECK_TYPE[$i]"};
1967 } elsif ($test_type eq "bisect") {
1968 $run_type = $opt{"BISECT_TYPE[$i]"};
0a05c769
SR
1969 } elsif ($test_type eq "config_bisect") {
1970 $run_type = $opt{"CONFIG_BISECT_TYPE[$i]"};
a75fecec
SR
1971 }
1972
1973 # mistake in config file?
1974 if (!defined($run_type)) {
1975 $run_type = "ERROR";
1976 }
5a391fbf 1977
2545eb61 1978 doprint "\n\n";
a75fecec 1979 doprint "RUNNING TEST $i of $opt{NUM_TESTS} with option $test_type $run_type\n\n";
7faafbd6
SR
1980
1981 unlink $dmesg;
1982 unlink $buildlog;
2545eb61 1983
2b7d9b21
SR
1984 if (!defined($minconfig)) {
1985 $minconfig = $addconfig;
1986
1987 } elsif (defined($addconfig)) {
9be2e6b5 1988 run_command "cat $addconfig $minconfig > $tmpdir/add_config" or
2b7d9b21 1989 dodie "Failed to create temp config";
9be2e6b5 1990 $minconfig = "$tmpdir/add_config";
2b7d9b21
SR
1991 }
1992
6c5ee0be
SR
1993 my $checkout = $opt{"CHECKOUT[$i]"};
1994 if (defined($checkout)) {
1995 run_command "git checkout $checkout" or
1996 die "failed to checkout $checkout";
1997 }
1998
a75fecec 1999 if ($test_type eq "bisect") {
5f9b6ced
SR
2000 bisect $i;
2001 next;
0a05c769
SR
2002 } elsif ($test_type eq "config_bisect") {
2003 config_bisect $i;
2004 next;
a75fecec 2005 } elsif ($test_type eq "patchcheck") {
6c5ee0be
SR
2006 patchcheck $i;
2007 next;
2545eb61 2008 }
2545eb61 2009
7faafbd6
SR
2010 if ($build_type ne "nobuild") {
2011 build $build_type or next;
2545eb61
SR
2012 }
2013
a75fecec
SR
2014 if ($test_type ne "build") {
2015 get_grub_index;
2016 get_version;
2017 install;
5a391fbf 2018
a75fecec
SR
2019 my $failed = 0;
2020 start_monitor;
2021 monitor or $failed = 1;;
2022
2023 if (!$failed && $test_type ne "boot" && defined($run_test)) {
2024 do_run_test or $failed = 1;
2025 }
2026 end_monitor;
2027 next if ($failed);
5a391fbf
SR
2028 }
2029
5f9b6ced 2030 success $i;
2545eb61
SR
2031}
2032
5c42fc5b 2033if ($opt{"POWEROFF_ON_SUCCESS"}) {
75c3fda7 2034 halt;
576f627c 2035} elsif ($opt{"REBOOT_ON_SUCCESS"} && !do_not_reboot) {
75c3fda7 2036 reboot;
5c42fc5b 2037}
75c3fda7 2038
e48c5293
SR
2039doprint "\n $successes of $opt{NUM_TESTS} tests were successful\n\n";
2040
2545eb61 2041exit 0;
This page took 0.130276 seconds and 5 git commands to generate.