blob: 0a5f6cb007af004766bc0a355120f021aac67580 [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 Rostedt2545eb62010-11-02 15:01:32 -040021
22#default opts
Steven Rostedt4f43e0d2011-12-22 21:32:05 -050023my %default = (
24 "NUM_TESTS" => 1,
25 "TEST_TYPE" => "build",
26 "BUILD_TYPE" => "randconfig",
27 "MAKE_CMD" => "make",
28 "TIMEOUT" => 120,
29 "TMP_DIR" => "/tmp/ktest/\${MACHINE}",
30 "SLEEP_TIME" => 60, # sleep time between tests
31 "BUILD_NOCLEAN" => 0,
32 "REBOOT_ON_ERROR" => 0,
33 "POWEROFF_ON_ERROR" => 0,
34 "REBOOT_ON_SUCCESS" => 1,
35 "POWEROFF_ON_SUCCESS" => 0,
36 "BUILD_OPTIONS" => "",
37 "BISECT_SLEEP_TIME" => 60, # sleep time between bisects
38 "PATCHCHECK_SLEEP_TIME" => 60, # sleep time between patch checks
39 "CLEAR_LOG" => 0,
40 "BISECT_MANUAL" => 0,
41 "BISECT_SKIP" => 1,
42 "SUCCESS_LINE" => "login:",
43 "DETECT_TRIPLE_FAULT" => 1,
44 "NO_INSTALL" => 0,
45 "BOOTED_TIMEOUT" => 1,
46 "DIE_ON_FAILURE" => 1,
47 "SSH_EXEC" => "ssh \$SSH_USER\@\$MACHINE \$SSH_COMMAND",
48 "SCP_TO_TARGET" => "scp \$SRC_FILE \$SSH_USER\@\$MACHINE:\$DST_FILE",
49 "REBOOT" => "ssh \$SSH_USER\@\$MACHINE reboot",
50 "STOP_AFTER_SUCCESS" => 10,
51 "STOP_AFTER_FAILURE" => 60,
52 "STOP_TEST_AFTER" => 600,
Steven Rostedt600bbf02011-11-21 20:12:04 -050053
54# required, and we will ask users if they don't have them but we keep the default
55# value something that is common.
Steven Rostedt4f43e0d2011-12-22 21:32:05 -050056 "REBOOT_TYPE" => "grub",
57 "LOCALVERSION" => "-test",
58 "SSH_USER" => "root",
59 "BUILD_TARGET" => "arch/x86/boot/bzImage",
60 "TARGET_IMAGE" => "/boot/vmlinuz-test",
Steven Rostedt9cc9e092011-12-22 21:37:22 -050061
62 "LOG_FILE" => undef,
63 "IGNORE_UNUSED" => 0,
Steven Rostedt4f43e0d2011-12-22 21:32:05 -050064);
Steven Rostedt2545eb62010-11-02 15:01:32 -040065
Steven Rostedt8d1491b2010-11-18 15:39:48 -050066my $ktest_config;
Steven Rostedt2545eb62010-11-02 15:01:32 -040067my $version;
Steven Rostedta75fece2010-11-02 14:58:27 -040068my $machine;
Steven Rostedte48c5292010-11-02 14:35:37 -040069my $ssh_user;
Steven Rostedta75fece2010-11-02 14:58:27 -040070my $tmpdir;
71my $builddir;
72my $outputdir;
Steven Rostedt51ad1dd2010-11-08 16:43:21 -050073my $output_config;
Steven Rostedta75fece2010-11-02 14:58:27 -040074my $test_type;
Steven Rostedt7faafbd2010-11-02 14:58:22 -040075my $build_type;
Steven Rostedta75fece2010-11-02 14:58:27 -040076my $build_options;
Steven Rostedt0bd6c1a2011-06-14 20:39:31 -040077my $pre_build;
78my $post_build;
79my $pre_build_die;
80my $post_build_die;
Steven Rostedta75fece2010-11-02 14:58:27 -040081my $reboot_type;
82my $reboot_script;
83my $power_cycle;
Steven Rostedte48c5292010-11-02 14:35:37 -040084my $reboot;
Steven Rostedta75fece2010-11-02 14:58:27 -040085my $reboot_on_error;
Steven Rostedtbc7c5802011-12-22 16:29:10 -050086my $switch_to_good;
87my $switch_to_test;
Steven Rostedta75fece2010-11-02 14:58:27 -040088my $poweroff_on_error;
89my $die_on_failure;
Steven Rostedt576f6272010-11-02 14:58:38 -040090my $powercycle_after_reboot;
91my $poweroff_after_halt;
Steven Rostedte48c5292010-11-02 14:35:37 -040092my $ssh_exec;
93my $scp_to_target;
Steven Rostedta75fece2010-11-02 14:58:27 -040094my $power_off;
95my $grub_menu;
Steven Rostedt2545eb62010-11-02 15:01:32 -040096my $grub_number;
97my $target;
98my $make;
Steven Rostedt8b37ca82010-11-02 14:58:33 -040099my $post_install;
Steven Rostedte0a87422011-09-30 17:50:48 -0400100my $no_install;
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400101my $noclean;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400102my $minconfig;
Steven Rostedt4c4ab122011-07-15 21:16:17 -0400103my $start_minconfig;
Steven Rostedt35ce5952011-07-15 21:57:25 -0400104my $start_minconfig_defined;
Steven Rostedt4c4ab122011-07-15 21:16:17 -0400105my $output_minconfig;
106my $ignore_config;
Steven Rostedtbe405f92012-01-04 21:51:59 -0500107my $ignore_errors;
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400108my $addconfig;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400109my $in_bisect = 0;
Steven Rostedtb5f4aea2011-12-22 21:33:55 -0500110my $bisect_bad_commit = "";
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400111my $reverse_bisect;
Steven Rostedtc960bb92011-03-08 09:22:39 -0500112my $bisect_manual;
Steven Rostedtc23dca72011-03-08 09:26:31 -0500113my $bisect_skip;
Steven Rostedt30f75da2011-06-13 10:35:35 -0400114my $config_bisect_good;
Steven Rostedtc5dacb82011-12-22 12:43:57 -0500115my $bisect_ret_good;
116my $bisect_ret_bad;
117my $bisect_ret_skip;
118my $bisect_ret_abort;
119my $bisect_ret_default;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -0400120my $in_patchcheck = 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -0400121my $run_test;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -0400122my $redirect;
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400123my $buildlog;
Rabin Vincenta9dd5d62011-11-18 17:05:29 +0530124my $testlog;
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400125my $dmesg;
126my $monitor_fp;
127my $monitor_pid;
128my $monitor_cnt = 0;
Steven Rostedta75fece2010-11-02 14:58:27 -0400129my $sleep_time;
130my $bisect_sleep_time;
Steven Rostedt27d934b2011-05-20 09:18:18 -0400131my $patchcheck_sleep_time;
Steven Rostedt19902072011-06-14 20:46:25 -0400132my $ignore_warnings;
Steven Rostedta75fece2010-11-02 14:58:27 -0400133my $store_failures;
Rabin Vincentde5b6e32011-11-18 17:05:31 +0530134my $store_successes;
Steven Rostedt9064af52011-06-13 10:38:48 -0400135my $test_name;
Steven Rostedta75fece2010-11-02 14:58:27 -0400136my $timeout;
137my $booted_timeout;
Steven Rostedtf1a5b962011-06-13 10:30:00 -0400138my $detect_triplefault;
Steven Rostedta75fece2010-11-02 14:58:27 -0400139my $console;
Steven Rostedt2b803362011-09-30 18:00:23 -0400140my $reboot_success_line;
Steven Rostedta75fece2010-11-02 14:58:27 -0400141my $success_line;
Steven Rostedt1c8a6172010-11-09 12:55:40 -0500142my $stop_after_success;
143my $stop_after_failure;
Steven Rostedt2d01b262011-03-08 09:47:54 -0500144my $stop_test_after;
Steven Rostedta75fece2010-11-02 14:58:27 -0400145my $build_target;
146my $target_image;
Steven Rostedtb5f4aea2011-12-22 21:33:55 -0500147my $checkout;
Steven Rostedta75fece2010-11-02 14:58:27 -0400148my $localversion;
Steven Rostedt576f6272010-11-02 14:58:38 -0400149my $iteration = 0;
Steven Rostedte48c5292010-11-02 14:35:37 -0400150my $successes = 0;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400151
Steven Rostedtb5f4aea2011-12-22 21:33:55 -0500152my $bisect_good;
153my $bisect_bad;
154my $bisect_type;
155my $bisect_start;
156my $bisect_replay;
157my $bisect_files;
158my $bisect_reverse;
159my $bisect_check;
160
161my $config_bisect;
162my $config_bisect_type;
163
164my $patchcheck_type;
165my $patchcheck_start;
166my $patchcheck_end;
167
Steven Rostedt165708b2011-11-26 20:56:52 -0500168# set when a test is something other that just building or install
Steven Rostedtbb8474b2011-11-23 15:58:00 -0500169# which would require more options.
170my $buildonly = 1;
171
Steven Rostedtdbd37832011-11-23 16:00:48 -0500172# set when creating a new config
173my $newconfig = 0;
174
Steven Rostedt8d1491b2010-11-18 15:39:48 -0500175my %entered_configs;
176my %config_help;
Steven Rostedt77d942c2011-05-20 13:36:58 -0400177my %variable;
Steven Rostedtfcb3f162011-06-13 10:40:58 -0400178my %force_config;
Steven Rostedt8d1491b2010-11-18 15:39:48 -0500179
Steven Rostedt4ab1cce2011-09-30 18:12:20 -0400180# do not force reboots on config problems
181my $no_reboot = 1;
182
Steven Rostedt9cc9e092011-12-22 21:37:22 -0500183my %option_map = (
184 "MACHINE" => \$machine,
185 "SSH_USER" => \$ssh_user,
186 "TMP_DIR" => \$tmpdir,
187 "OUTPUT_DIR" => \$outputdir,
188 "BUILD_DIR" => \$builddir,
189 "TEST_TYPE" => \$test_type,
190 "BUILD_TYPE" => \$build_type,
191 "BUILD_OPTIONS" => \$build_options,
192 "PRE_BUILD" => \$pre_build,
193 "POST_BUILD" => \$post_build,
194 "PRE_BUILD_DIE" => \$pre_build_die,
195 "POST_BUILD_DIE" => \$post_build_die,
196 "POWER_CYCLE" => \$power_cycle,
197 "REBOOT" => \$reboot,
198 "BUILD_NOCLEAN" => \$noclean,
199 "MIN_CONFIG" => \$minconfig,
200 "OUTPUT_MIN_CONFIG" => \$output_minconfig,
201 "START_MIN_CONFIG" => \$start_minconfig,
202 "IGNORE_CONFIG" => \$ignore_config,
203 "TEST" => \$run_test,
204 "ADD_CONFIG" => \$addconfig,
205 "REBOOT_TYPE" => \$reboot_type,
206 "GRUB_MENU" => \$grub_menu,
207 "POST_INSTALL" => \$post_install,
208 "NO_INSTALL" => \$no_install,
209 "REBOOT_SCRIPT" => \$reboot_script,
210 "REBOOT_ON_ERROR" => \$reboot_on_error,
211 "SWITCH_TO_GOOD" => \$switch_to_good,
212 "SWITCH_TO_TEST" => \$switch_to_test,
213 "POWEROFF_ON_ERROR" => \$poweroff_on_error,
214 "DIE_ON_FAILURE" => \$die_on_failure,
215 "POWER_OFF" => \$power_off,
216 "POWERCYCLE_AFTER_REBOOT" => \$powercycle_after_reboot,
217 "POWEROFF_AFTER_HALT" => \$poweroff_after_halt,
218 "SLEEP_TIME" => \$sleep_time,
219 "BISECT_SLEEP_TIME" => \$bisect_sleep_time,
220 "PATCHCHECK_SLEEP_TIME" => \$patchcheck_sleep_time,
221 "IGNORE_WARNINGS" => \$ignore_warnings,
Steven Rostedtbe405f92012-01-04 21:51:59 -0500222 "IGNORE_ERRORS" => \$ignore_errors,
Steven Rostedt9cc9e092011-12-22 21:37:22 -0500223 "BISECT_MANUAL" => \$bisect_manual,
224 "BISECT_SKIP" => \$bisect_skip,
225 "CONFIG_BISECT_GOOD" => \$config_bisect_good,
226 "BISECT_RET_GOOD" => \$bisect_ret_good,
227 "BISECT_RET_BAD" => \$bisect_ret_bad,
228 "BISECT_RET_SKIP" => \$bisect_ret_skip,
229 "BISECT_RET_ABORT" => \$bisect_ret_abort,
230 "BISECT_RET_DEFAULT" => \$bisect_ret_default,
231 "STORE_FAILURES" => \$store_failures,
232 "STORE_SUCCESSES" => \$store_successes,
233 "TEST_NAME" => \$test_name,
234 "TIMEOUT" => \$timeout,
235 "BOOTED_TIMEOUT" => \$booted_timeout,
236 "CONSOLE" => \$console,
237 "DETECT_TRIPLE_FAULT" => \$detect_triplefault,
238 "SUCCESS_LINE" => \$success_line,
239 "REBOOT_SUCCESS_LINE" => \$reboot_success_line,
240 "STOP_AFTER_SUCCESS" => \$stop_after_success,
241 "STOP_AFTER_FAILURE" => \$stop_after_failure,
242 "STOP_TEST_AFTER" => \$stop_test_after,
243 "BUILD_TARGET" => \$build_target,
244 "SSH_EXEC" => \$ssh_exec,
245 "SCP_TO_TARGET" => \$scp_to_target,
246 "CHECKOUT" => \$checkout,
247 "TARGET_IMAGE" => \$target_image,
248 "LOCALVERSION" => \$localversion,
249
250 "BISECT_GOOD" => \$bisect_good,
251 "BISECT_BAD" => \$bisect_bad,
252 "BISECT_TYPE" => \$bisect_type,
253 "BISECT_START" => \$bisect_start,
254 "BISECT_REPLAY" => \$bisect_replay,
255 "BISECT_FILES" => \$bisect_files,
256 "BISECT_REVERSE" => \$bisect_reverse,
257 "BISECT_CHECK" => \$bisect_check,
258
259 "CONFIG_BISECT" => \$config_bisect,
260 "CONFIG_BISECT_TYPE" => \$config_bisect_type,
261
262 "PATCHCHECK_TYPE" => \$patchcheck_type,
263 "PATCHCHECK_START" => \$patchcheck_start,
264 "PATCHCHECK_END" => \$patchcheck_end,
265);
266
267# Options may be used by other options, record them.
268my %used_options;
269
Steven Rostedt7bf51072011-10-22 09:07:03 -0400270# default variables that can be used
271chomp ($variable{"PWD"} = `pwd`);
272
Steven Rostedt8d1491b2010-11-18 15:39:48 -0500273$config_help{"MACHINE"} = << "EOF"
274 The machine hostname that you will test.
Steven Rostedtbb8474b2011-11-23 15:58:00 -0500275 For build only tests, it is still needed to differentiate log files.
Steven Rostedt8d1491b2010-11-18 15:39:48 -0500276EOF
277 ;
278$config_help{"SSH_USER"} = << "EOF"
279 The box is expected to have ssh on normal bootup, provide the user
280 (most likely root, since you need privileged operations)
281EOF
282 ;
283$config_help{"BUILD_DIR"} = << "EOF"
284 The directory that contains the Linux source code (full path).
Steven Rostedt0e7a22d2011-11-21 20:39:33 -0500285 You can use \${PWD} that will be the path where ktest.pl is run, or use
286 \${THIS_DIR} which is assigned \${PWD} but may be changed later.
Steven Rostedt8d1491b2010-11-18 15:39:48 -0500287EOF
288 ;
289$config_help{"OUTPUT_DIR"} = << "EOF"
290 The directory that the objects will be built (full path).
291 (can not be same as BUILD_DIR)
Steven Rostedt0e7a22d2011-11-21 20:39:33 -0500292 You can use \${PWD} that will be the path where ktest.pl is run, or use
293 \${THIS_DIR} which is assigned \${PWD} but may be changed later.
Steven Rostedt8d1491b2010-11-18 15:39:48 -0500294EOF
295 ;
296$config_help{"BUILD_TARGET"} = << "EOF"
297 The location of the compiled file to copy to the target.
298 (relative to OUTPUT_DIR)
299EOF
300 ;
Steven Rostedtdbd37832011-11-23 16:00:48 -0500301$config_help{"BUILD_OPTIONS"} = << "EOF"
302 Options to add to \"make\" when building.
303 i.e. -j20
304EOF
305 ;
Steven Rostedt8d1491b2010-11-18 15:39:48 -0500306$config_help{"TARGET_IMAGE"} = << "EOF"
307 The place to put your image on the test machine.
308EOF
309 ;
310$config_help{"POWER_CYCLE"} = << "EOF"
311 A script or command to reboot the box.
312
313 Here is a digital loggers power switch example
314 POWER_CYCLE = wget --no-proxy -O /dev/null -q --auth-no-challenge 'http://admin:admin\@power/outlet?5=CCL'
315
316 Here is an example to reboot a virtual box on the current host
317 with the name "Guest".
318 POWER_CYCLE = virsh destroy Guest; sleep 5; virsh start Guest
319EOF
320 ;
321$config_help{"CONSOLE"} = << "EOF"
322 The script or command that reads the console
323
324 If you use ttywatch server, something like the following would work.
325CONSOLE = nc -d localhost 3001
326
327 For a virtual machine with guest name "Guest".
328CONSOLE = virsh console Guest
329EOF
330 ;
331$config_help{"LOCALVERSION"} = << "EOF"
332 Required version ending to differentiate the test
333 from other linux builds on the system.
334EOF
335 ;
336$config_help{"REBOOT_TYPE"} = << "EOF"
337 Way to reboot the box to the test kernel.
338 Only valid options so far are "grub" and "script".
339
340 If you specify grub, it will assume grub version 1
341 and will search in /boot/grub/menu.lst for the title \$GRUB_MENU
342 and select that target to reboot to the kernel. If this is not
343 your setup, then specify "script" and have a command or script
344 specified in REBOOT_SCRIPT to boot to the target.
345
346 The entry in /boot/grub/menu.lst must be entered in manually.
347 The test will not modify that file.
348EOF
349 ;
350$config_help{"GRUB_MENU"} = << "EOF"
351 The grub title name for the test kernel to boot
352 (Only mandatory if REBOOT_TYPE = grub)
353
354 Note, ktest.pl will not update the grub menu.lst, you need to
355 manually add an option for the test. ktest.pl will search
356 the grub menu.lst for this option to find what kernel to
357 reboot into.
358
359 For example, if in the /boot/grub/menu.lst the test kernel title has:
360 title Test Kernel
361 kernel vmlinuz-test
362 GRUB_MENU = Test Kernel
363EOF
364 ;
365$config_help{"REBOOT_SCRIPT"} = << "EOF"
366 A script to reboot the target into the test kernel
367 (Only mandatory if REBOOT_TYPE = script)
368EOF
369 ;
370
Steven Rostedtdad98752011-11-22 20:48:57 -0500371sub read_prompt {
372 my ($cancel, $prompt) = @_;
Steven Rostedt35ce5952011-07-15 21:57:25 -0400373
374 my $ans;
375
376 for (;;) {
Steven Rostedtdad98752011-11-22 20:48:57 -0500377 if ($cancel) {
378 print "$prompt [y/n/C] ";
379 } else {
380 print "$prompt [Y/n] ";
381 }
Steven Rostedt35ce5952011-07-15 21:57:25 -0400382 $ans = <STDIN>;
383 chomp $ans;
384 if ($ans =~ /^\s*$/) {
Steven Rostedtdad98752011-11-22 20:48:57 -0500385 if ($cancel) {
386 $ans = "c";
387 } else {
388 $ans = "y";
389 }
Steven Rostedt35ce5952011-07-15 21:57:25 -0400390 }
391 last if ($ans =~ /^y$/i || $ans =~ /^n$/i);
Steven Rostedtdad98752011-11-22 20:48:57 -0500392 if ($cancel) {
393 last if ($ans =~ /^c$/i);
394 print "Please answer either 'y', 'n' or 'c'.\n";
395 } else {
396 print "Please answer either 'y' or 'n'.\n";
397 }
398 }
399 if ($ans =~ /^c/i) {
400 exit;
Steven Rostedt35ce5952011-07-15 21:57:25 -0400401 }
402 if ($ans !~ /^y$/i) {
403 return 0;
404 }
405 return 1;
406}
Steven Rostedt8d1491b2010-11-18 15:39:48 -0500407
Steven Rostedtdad98752011-11-22 20:48:57 -0500408sub read_yn {
409 my ($prompt) = @_;
410
411 return read_prompt 0, $prompt;
412}
413
414sub read_ync {
415 my ($prompt) = @_;
416
417 return read_prompt 1, $prompt;
418}
419
Steven Rostedt8d1491b2010-11-18 15:39:48 -0500420sub get_ktest_config {
421 my ($config) = @_;
Steven Rostedt815e2bd2011-10-28 07:01:40 -0400422 my $ans;
Steven Rostedt8d1491b2010-11-18 15:39:48 -0500423
424 return if (defined($opt{$config}));
425
426 if (defined($config_help{$config})) {
427 print "\n";
428 print $config_help{$config};
429 }
430
431 for (;;) {
432 print "$config = ";
Steven Rostedtdbd37832011-11-23 16:00:48 -0500433 if (defined($default{$config}) && length($default{$config})) {
Steven Rostedt8d1491b2010-11-18 15:39:48 -0500434 print "\[$default{$config}\] ";
435 }
Steven Rostedt815e2bd2011-10-28 07:01:40 -0400436 $ans = <STDIN>;
437 $ans =~ s/^\s*(.*\S)\s*$/$1/;
438 if ($ans =~ /^\s*$/) {
Steven Rostedt8d1491b2010-11-18 15:39:48 -0500439 if ($default{$config}) {
Steven Rostedt815e2bd2011-10-28 07:01:40 -0400440 $ans = $default{$config};
Steven Rostedt8d1491b2010-11-18 15:39:48 -0500441 } else {
442 print "Your answer can not be blank\n";
443 next;
444 }
445 }
Steven Rostedt0e7a22d2011-11-21 20:39:33 -0500446 $entered_configs{$config} = ${ans};
Steven Rostedt8d1491b2010-11-18 15:39:48 -0500447 last;
448 }
449}
450
451sub get_ktest_configs {
452 get_ktest_config("MACHINE");
Steven Rostedt8d1491b2010-11-18 15:39:48 -0500453 get_ktest_config("BUILD_DIR");
454 get_ktest_config("OUTPUT_DIR");
Steven Rostedtbb8474b2011-11-23 15:58:00 -0500455
Steven Rostedtdbd37832011-11-23 16:00:48 -0500456 if ($newconfig) {
457 get_ktest_config("BUILD_OPTIONS");
458 }
459
Steven Rostedtbb8474b2011-11-23 15:58:00 -0500460 # options required for other than just building a kernel
461 if (!$buildonly) {
Steven Rostedt165708b2011-11-26 20:56:52 -0500462 get_ktest_config("POWER_CYCLE");
463 get_ktest_config("CONSOLE");
464 }
465
466 # options required for install and more
467 if ($buildonly != 1) {
Steven Rostedtbb8474b2011-11-23 15:58:00 -0500468 get_ktest_config("SSH_USER");
469 get_ktest_config("BUILD_TARGET");
470 get_ktest_config("TARGET_IMAGE");
Steven Rostedtbb8474b2011-11-23 15:58:00 -0500471 }
472
Steven Rostedt8d1491b2010-11-18 15:39:48 -0500473 get_ktest_config("LOCALVERSION");
474
Steven Rostedtbb8474b2011-11-23 15:58:00 -0500475 return if ($buildonly);
476
Steven Rostedt8d1491b2010-11-18 15:39:48 -0500477 my $rtype = $opt{"REBOOT_TYPE"};
478
479 if (!defined($rtype)) {
480 if (!defined($opt{"GRUB_MENU"})) {
481 get_ktest_config("REBOOT_TYPE");
482 $rtype = $entered_configs{"REBOOT_TYPE"};
483 } else {
484 $rtype = "grub";
485 }
486 }
487
488 if ($rtype eq "grub") {
489 get_ktest_config("GRUB_MENU");
Steven Rostedt8d1491b2010-11-18 15:39:48 -0500490 }
491}
492
Steven Rostedt77d942c2011-05-20 13:36:58 -0400493sub process_variables {
Steven Rostedt8d735212011-10-17 11:36:44 -0400494 my ($value, $remove_undef) = @_;
Steven Rostedt77d942c2011-05-20 13:36:58 -0400495 my $retval = "";
496
497 # We want to check for '\', and it is just easier
498 # to check the previous characet of '$' and not need
499 # to worry if '$' is the first character. By adding
500 # a space to $value, we can just check [^\\]\$ and
501 # it will still work.
502 $value = " $value";
503
504 while ($value =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) {
505 my $begin = $1;
506 my $var = $2;
507 my $end = $3;
508 # append beginning of value to retval
509 $retval = "$retval$begin";
510 if (defined($variable{$var})) {
511 $retval = "$retval$variable{$var}";
Steven Rostedt8d735212011-10-17 11:36:44 -0400512 } elsif (defined($remove_undef) && $remove_undef) {
513 # for if statements, any variable that is not defined,
514 # we simple convert to 0
515 $retval = "${retval}0";
Steven Rostedt77d942c2011-05-20 13:36:58 -0400516 } else {
517 # put back the origin piece.
518 $retval = "$retval\$\{$var\}";
Steven Rostedt9cc9e092011-12-22 21:37:22 -0500519 # This could be an option that is used later, save
520 # it so we don't warn if this option is not one of
521 # ktests options.
522 $used_options{$var} = 1;
Steven Rostedt77d942c2011-05-20 13:36:58 -0400523 }
524 $value = $end;
525 }
526 $retval = "$retval$value";
527
528 # remove the space added in the beginning
529 $retval =~ s/ //;
530
531 return "$retval"
532}
533
Steven Rostedta57419b2010-11-02 15:13:54 -0400534sub set_value {
Steven Rostedt3d1cc412011-09-30 22:14:21 -0400535 my ($lvalue, $rvalue, $override, $overrides, $name) = @_;
Steven Rostedta57419b2010-11-02 15:13:54 -0400536
Steven Rostedtcad96662011-12-22 11:32:52 -0500537 my $prvalue = process_variables($rvalue);
538
539 if ($buildonly && $lvalue =~ /^TEST_TYPE(\[.*\])?$/ && $prvalue ne "build") {
Steven Rostedtbb8474b2011-11-23 15:58:00 -0500540 # Note if a test is something other than build, then we
541 # will need other manditory options.
Steven Rostedtcad96662011-12-22 11:32:52 -0500542 if ($prvalue ne "install") {
Steven Rostedt165708b2011-11-26 20:56:52 -0500543 $buildonly = 0;
544 } else {
545 # install still limits some manditory options.
546 $buildonly = 2;
547 }
Steven Rostedtbb8474b2011-11-23 15:58:00 -0500548 }
549
Steven Rostedta57419b2010-11-02 15:13:54 -0400550 if (defined($opt{$lvalue})) {
Steven Rostedt3d1cc412011-09-30 22:14:21 -0400551 if (!$override || defined(${$overrides}{$lvalue})) {
552 my $extra = "";
553 if ($override) {
554 $extra = "In the same override section!\n";
555 }
556 die "$name: $.: Option $lvalue defined more than once!\n$extra";
557 }
Steven Rostedtcad96662011-12-22 11:32:52 -0500558 ${$overrides}{$lvalue} = $prvalue;
Steven Rostedta57419b2010-11-02 15:13:54 -0400559 }
Steven Rostedt21a96792010-11-08 16:45:50 -0500560 if ($rvalue =~ /^\s*$/) {
561 delete $opt{$lvalue};
562 } else {
Steven Rostedtcad96662011-12-22 11:32:52 -0500563 $opt{$lvalue} = $prvalue;
Steven Rostedt21a96792010-11-08 16:45:50 -0500564 }
Steven Rostedta57419b2010-11-02 15:13:54 -0400565}
566
Steven Rostedt77d942c2011-05-20 13:36:58 -0400567sub set_variable {
568 my ($lvalue, $rvalue) = @_;
569
570 if ($rvalue =~ /^\s*$/) {
571 delete $variable{$lvalue};
572 } else {
573 $rvalue = process_variables($rvalue);
574 $variable{$lvalue} = $rvalue;
575 }
576}
577
Steven Rostedtab7a3f52011-09-30 20:24:07 -0400578sub process_compare {
579 my ($lval, $cmp, $rval) = @_;
580
581 # remove whitespace
582
583 $lval =~ s/^\s*//;
584 $lval =~ s/\s*$//;
585
586 $rval =~ s/^\s*//;
587 $rval =~ s/\s*$//;
588
589 if ($cmp eq "==") {
590 return $lval eq $rval;
591 } elsif ($cmp eq "!=") {
592 return $lval ne $rval;
593 }
594
595 my $statement = "$lval $cmp $rval";
596 my $ret = eval $statement;
597
598 # $@ stores error of eval
599 if ($@) {
600 return -1;
601 }
602
603 return $ret;
604}
605
Steven Rostedt9900b5d2011-09-30 22:41:14 -0400606sub value_defined {
607 my ($val) = @_;
608
609 return defined($variable{$2}) ||
610 defined($opt{$2});
611}
612
Steven Rostedt8d735212011-10-17 11:36:44 -0400613my $d = 0;
614sub process_expression {
615 my ($name, $val) = @_;
Steven Rostedt45d73a52011-09-30 19:44:53 -0400616
Steven Rostedt8d735212011-10-17 11:36:44 -0400617 my $c = $d++;
618
619 while ($val =~ s/\(([^\(]*?)\)/\&\&\&\&VAL\&\&\&\&/) {
620 my $express = $1;
621
622 if (process_expression($name, $express)) {
623 $val =~ s/\&\&\&\&VAL\&\&\&\&/ 1 /;
624 } else {
625 $val =~ s/\&\&\&\&VAL\&\&\&\&/ 0 /;
626 }
627 }
628
629 $d--;
630 my $OR = "\\|\\|";
631 my $AND = "\\&\\&";
632
633 while ($val =~ s/^(.*?)($OR|$AND)//) {
634 my $express = $1;
635 my $op = $2;
636
637 if (process_expression($name, $express)) {
638 if ($op eq "||") {
639 return 1;
640 }
641 } else {
642 if ($op eq "&&") {
643 return 0;
644 }
645 }
646 }
Steven Rostedt45d73a52011-09-30 19:44:53 -0400647
Steven Rostedtab7a3f52011-09-30 20:24:07 -0400648 if ($val =~ /(.*)(==|\!=|>=|<=|>|<)(.*)/) {
649 my $ret = process_compare($1, $2, $3);
650 if ($ret < 0) {
651 die "$name: $.: Unable to process comparison\n";
652 }
653 return $ret;
654 }
655
Steven Rostedt9900b5d2011-09-30 22:41:14 -0400656 if ($val =~ /^\s*(NOT\s*)?DEFINED\s+(\S+)\s*$/) {
657 if (defined $1) {
658 return !value_defined($2);
659 } else {
660 return value_defined($2);
661 }
662 }
663
Steven Rostedt45d73a52011-09-30 19:44:53 -0400664 if ($val =~ /^\s*0\s*$/) {
665 return 0;
666 } elsif ($val =~ /^\s*\d+\s*$/) {
667 return 1;
668 }
669
Steven Rostedt9900b5d2011-09-30 22:41:14 -0400670 die ("$name: $.: Undefined content $val in if statement\n");
Steven Rostedt8d735212011-10-17 11:36:44 -0400671}
672
673sub process_if {
674 my ($name, $value) = @_;
675
676 # Convert variables and replace undefined ones with 0
677 my $val = process_variables($value, 1);
678 my $ret = process_expression $name, $val;
679
680 return $ret;
Steven Rostedt45d73a52011-09-30 19:44:53 -0400681}
682
Steven Rostedt2ed3b162011-09-30 21:00:00 -0400683sub __read_config {
684 my ($config, $current_test_num) = @_;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400685
Steven Rostedt2ed3b162011-09-30 21:00:00 -0400686 my $in;
687 open($in, $config) || die "can't read file $config";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400688
Steven Rostedta57419b2010-11-02 15:13:54 -0400689 my $name = $config;
690 $name =~ s,.*/(.*),$1,;
691
Steven Rostedt2ed3b162011-09-30 21:00:00 -0400692 my $test_num = $$current_test_num;
Steven Rostedta57419b2010-11-02 15:13:54 -0400693 my $default = 1;
694 my $repeat = 1;
695 my $num_tests_set = 0;
696 my $skip = 0;
697 my $rest;
Steven Rostedta9f84422011-10-17 11:06:29 -0400698 my $line;
Steven Rostedt0df213c2011-06-14 20:51:37 -0400699 my $test_case = 0;
Steven Rostedt45d73a52011-09-30 19:44:53 -0400700 my $if = 0;
701 my $if_set = 0;
Steven Rostedt3d1cc412011-09-30 22:14:21 -0400702 my $override = 0;
703
704 my %overrides;
Steven Rostedta57419b2010-11-02 15:13:54 -0400705
Steven Rostedt2ed3b162011-09-30 21:00:00 -0400706 while (<$in>) {
Steven Rostedt2545eb62010-11-02 15:01:32 -0400707
708 # ignore blank lines and comments
709 next if (/^\s*$/ || /\s*\#/);
710
Steven Rostedt0050b6b2011-09-30 21:10:30 -0400711 if (/^\s*(TEST_START|DEFAULTS)\b(.*)/) {
Steven Rostedta57419b2010-11-02 15:13:54 -0400712
Steven Rostedt0050b6b2011-09-30 21:10:30 -0400713 my $type = $1;
714 $rest = $2;
Steven Rostedta9f84422011-10-17 11:06:29 -0400715 $line = $2;
Steven Rostedta57419b2010-11-02 15:13:54 -0400716
Steven Rostedt0050b6b2011-09-30 21:10:30 -0400717 my $old_test_num;
718 my $old_repeat;
Steven Rostedt3d1cc412011-09-30 22:14:21 -0400719 $override = 0;
Steven Rostedt0050b6b2011-09-30 21:10:30 -0400720
721 if ($type eq "TEST_START") {
722
723 if ($num_tests_set) {
724 die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
725 }
726
727 $old_test_num = $test_num;
728 $old_repeat = $repeat;
729
730 $test_num += $repeat;
731 $default = 0;
732 $repeat = 1;
733 } else {
734 $default = 1;
Steven Rostedta57419b2010-11-02 15:13:54 -0400735 }
736
Steven Rostedta9f84422011-10-17 11:06:29 -0400737 # If SKIP is anywhere in the line, the command will be skipped
738 if ($rest =~ s/\s+SKIP\b//) {
Steven Rostedta57419b2010-11-02 15:13:54 -0400739 $skip = 1;
740 } else {
Steven Rostedt0df213c2011-06-14 20:51:37 -0400741 $test_case = 1;
Steven Rostedta57419b2010-11-02 15:13:54 -0400742 $skip = 0;
743 }
744
Steven Rostedta9f84422011-10-17 11:06:29 -0400745 if ($rest =~ s/\sELSE\b//) {
746 if (!$if) {
747 die "$name: $.: ELSE found with out matching IF section\n$_";
748 }
749 $if = 0;
750
751 if ($if_set) {
752 $skip = 1;
753 } else {
754 $skip = 0;
Steven Rostedt3d1cc412011-09-30 22:14:21 -0400755 }
Steven Rostedta57419b2010-11-02 15:13:54 -0400756 }
757
Steven Rostedta9f84422011-10-17 11:06:29 -0400758 if ($rest =~ s/\sIF\s+(.*)//) {
Steven Rostedt45d73a52011-09-30 19:44:53 -0400759 if (process_if($name, $1)) {
760 $if_set = 1;
761 } else {
762 $skip = 1;
763 }
764 $if = 1;
765 } else {
766 $if = 0;
Steven Rostedta9f84422011-10-17 11:06:29 -0400767 $if_set = 0;
Steven Rostedta57419b2010-11-02 15:13:54 -0400768 }
769
Steven Rostedta9f84422011-10-17 11:06:29 -0400770 if (!$skip) {
771 if ($type eq "TEST_START") {
772 if ($rest =~ s/\s+ITERATE\s+(\d+)//) {
773 $repeat = $1;
774 $repeat_tests{"$test_num"} = $repeat;
775 }
776 } elsif ($rest =~ s/\sOVERRIDE\b//) {
777 # DEFAULT only
778 $override = 1;
779 # Clear previous overrides
780 %overrides = ();
781 }
782 }
783
784 if (!$skip && $rest !~ /^\s*$/) {
Steven Rostedt0050b6b2011-09-30 21:10:30 -0400785 die "$name: $.: Gargbage found after $type\n$_";
Steven Rostedta57419b2010-11-02 15:13:54 -0400786 }
787
Steven Rostedt0050b6b2011-09-30 21:10:30 -0400788 if ($skip && $type eq "TEST_START") {
Steven Rostedta57419b2010-11-02 15:13:54 -0400789 $test_num = $old_test_num;
Steven Rostedte48c5292010-11-02 14:35:37 -0400790 $repeat = $old_repeat;
Steven Rostedta57419b2010-11-02 15:13:54 -0400791 }
792
Steven Rostedtab7a3f52011-09-30 20:24:07 -0400793 } elsif (/^\s*ELSE\b(.*)$/) {
Steven Rostedt45d73a52011-09-30 19:44:53 -0400794 if (!$if) {
795 die "$name: $.: ELSE found with out matching IF section\n$_";
796 }
797 $rest = $1;
798 if ($if_set) {
799 $skip = 1;
Steven Rostedtab7a3f52011-09-30 20:24:07 -0400800 $rest = "";
Steven Rostedt45d73a52011-09-30 19:44:53 -0400801 } else {
802 $skip = 0;
803
Steven Rostedtab7a3f52011-09-30 20:24:07 -0400804 if ($rest =~ /\sIF\s+(.*)/) {
Steven Rostedt45d73a52011-09-30 19:44:53 -0400805 # May be a ELSE IF section.
806 if (!process_if($name, $1)) {
807 $skip = 1;
808 }
Steven Rostedtab7a3f52011-09-30 20:24:07 -0400809 $rest = "";
Steven Rostedt45d73a52011-09-30 19:44:53 -0400810 } else {
811 $if = 0;
812 }
813 }
814
Steven Rostedtab7a3f52011-09-30 20:24:07 -0400815 if ($rest !~ /^\s*$/) {
816 die "$name: $.: Gargbage found after DEFAULTS\n$_";
817 }
818
Steven Rostedt2ed3b162011-09-30 21:00:00 -0400819 } elsif (/^\s*INCLUDE\s+(\S+)/) {
820
821 next if ($skip);
822
823 if (!$default) {
824 die "$name: $.: INCLUDE can only be done in default sections\n$_";
825 }
826
827 my $file = process_variables($1);
828
829 if ($file !~ m,^/,) {
830 # check the path of the config file first
831 if ($config =~ m,(.*)/,) {
832 if (-f "$1/$file") {
833 $file = "$1/$file";
834 }
835 }
836 }
837
838 if ( ! -r $file ) {
839 die "$name: $.: Can't read file $file\n$_";
840 }
841
842 if (__read_config($file, \$test_num)) {
843 $test_case = 1;
844 }
845
Steven Rostedta57419b2010-11-02 15:13:54 -0400846 } elsif (/^\s*([A-Z_\[\]\d]+)\s*=\s*(.*?)\s*$/) {
847
848 next if ($skip);
849
Steven Rostedt2545eb62010-11-02 15:01:32 -0400850 my $lvalue = $1;
851 my $rvalue = $2;
852
Steven Rostedta57419b2010-11-02 15:13:54 -0400853 if (!$default &&
854 ($lvalue eq "NUM_TESTS" ||
855 $lvalue eq "LOG_FILE" ||
856 $lvalue eq "CLEAR_LOG")) {
857 die "$name: $.: $lvalue must be set in DEFAULTS section\n";
Steven Rostedta75fece2010-11-02 14:58:27 -0400858 }
Steven Rostedta57419b2010-11-02 15:13:54 -0400859
860 if ($lvalue eq "NUM_TESTS") {
861 if ($test_num) {
862 die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
863 }
864 if (!$default) {
865 die "$name: $.: NUM_TESTS must be set in default section\n";
866 }
867 $num_tests_set = 1;
868 }
869
870 if ($default || $lvalue =~ /\[\d+\]$/) {
Steven Rostedt3d1cc412011-09-30 22:14:21 -0400871 set_value($lvalue, $rvalue, $override, \%overrides, $name);
Steven Rostedta57419b2010-11-02 15:13:54 -0400872 } else {
873 my $val = "$lvalue\[$test_num\]";
Steven Rostedt3d1cc412011-09-30 22:14:21 -0400874 set_value($val, $rvalue, $override, \%overrides, $name);
Steven Rostedta57419b2010-11-02 15:13:54 -0400875
876 if ($repeat > 1) {
877 $repeats{$val} = $repeat;
878 }
879 }
Steven Rostedt77d942c2011-05-20 13:36:58 -0400880 } elsif (/^\s*([A-Z_\[\]\d]+)\s*:=\s*(.*?)\s*$/) {
881 next if ($skip);
882
883 my $lvalue = $1;
884 my $rvalue = $2;
885
886 # process config variables.
887 # Config variables are only active while reading the
888 # config and can be defined anywhere. They also ignore
889 # TEST_START and DEFAULTS, but are skipped if they are in
890 # on of these sections that have SKIP defined.
891 # The save variable can be
892 # defined multiple times and the new one simply overrides
893 # the prevous one.
894 set_variable($lvalue, $rvalue);
895
Steven Rostedta57419b2010-11-02 15:13:54 -0400896 } else {
897 die "$name: $.: Garbage found in config\n$_";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400898 }
899 }
900
Steven Rostedta57419b2010-11-02 15:13:54 -0400901 if ($test_num) {
902 $test_num += $repeat - 1;
903 $opt{"NUM_TESTS"} = $test_num;
904 }
905
Steven Rostedt2ed3b162011-09-30 21:00:00 -0400906 close($in);
907
908 $$current_test_num = $test_num;
909
910 return $test_case;
911}
912
Steven Rostedtc4261d02011-11-23 13:41:18 -0500913sub get_test_case {
914 print "What test case would you like to run?\n";
915 print " (build, install or boot)\n";
916 print " Other tests are available but require editing the config file\n";
917 my $ans = <STDIN>;
918 chomp $ans;
919 $default{"TEST_TYPE"} = $ans;
920}
921
Steven Rostedt2ed3b162011-09-30 21:00:00 -0400922sub read_config {
923 my ($config) = @_;
924
925 my $test_case;
926 my $test_num = 0;
927
928 $test_case = __read_config $config, \$test_num;
929
Steven Rostedt8d1491b2010-11-18 15:39:48 -0500930 # make sure we have all mandatory configs
931 get_ktest_configs;
932
Steven Rostedt0df213c2011-06-14 20:51:37 -0400933 # was a test specified?
934 if (!$test_case) {
935 print "No test case specified.\n";
Steven Rostedtc4261d02011-11-23 13:41:18 -0500936 get_test_case;
Steven Rostedt0df213c2011-06-14 20:51:37 -0400937 }
938
Steven Rostedta75fece2010-11-02 14:58:27 -0400939 # set any defaults
940
941 foreach my $default (keys %default) {
942 if (!defined($opt{$default})) {
943 $opt{$default} = $default{$default};
944 }
945 }
Steven Rostedt9cc9e092011-12-22 21:37:22 -0500946
947 if ($opt{"IGNORE_UNUSED"} == 1) {
948 return;
949 }
950
951 my %not_used;
952
953 # check if there are any stragglers (typos?)
954 foreach my $option (keys %opt) {
955 my $op = $option;
956 # remove per test labels.
957 $op =~ s/\[.*\]//;
958 if (!exists($option_map{$op}) &&
959 !exists($default{$op}) &&
960 !exists($used_options{$op})) {
961 $not_used{$op} = 1;
962 }
963 }
964
965 if (%not_used) {
966 my $s = "s are";
967 $s = " is" if (keys %not_used == 1);
968 print "The following option$s not used; could be a typo:\n";
969 foreach my $option (keys %not_used) {
970 print "$option\n";
971 }
972 print "Set IGRNORE_UNUSED = 1 to have ktest ignore unused variables\n";
973 if (!read_yn "Do you want to continue?") {
974 exit -1;
975 }
976 }
Steven Rostedt2545eb62010-11-02 15:01:32 -0400977}
978
Steven Rostedt23715c3c2011-06-13 11:03:34 -0400979sub __eval_option {
980 my ($option, $i) = @_;
981
982 # Add space to evaluate the character before $
983 $option = " $option";
984 my $retval = "";
Rabin Vincentf9dfb652011-11-18 17:05:30 +0530985 my $repeated = 0;
986 my $parent = 0;
987
988 foreach my $test (keys %repeat_tests) {
989 if ($i >= $test &&
990 $i < $test + $repeat_tests{$test}) {
991
992 $repeated = 1;
993 $parent = $test;
994 last;
995 }
996 }
Steven Rostedt23715c3c2011-06-13 11:03:34 -0400997
998 while ($option =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) {
999 my $start = $1;
1000 my $var = $2;
1001 my $end = $3;
1002
1003 # Append beginning of line
1004 $retval = "$retval$start";
1005
1006 # If the iteration option OPT[$i] exists, then use that.
1007 # otherwise see if the default OPT (without [$i]) exists.
1008
1009 my $o = "$var\[$i\]";
Rabin Vincentf9dfb652011-11-18 17:05:30 +05301010 my $parento = "$var\[$parent\]";
Steven Rostedt23715c3c2011-06-13 11:03:34 -04001011
1012 if (defined($opt{$o})) {
1013 $o = $opt{$o};
1014 $retval = "$retval$o";
Rabin Vincentf9dfb652011-11-18 17:05:30 +05301015 } elsif ($repeated && defined($opt{$parento})) {
1016 $o = $opt{$parento};
1017 $retval = "$retval$o";
Steven Rostedt23715c3c2011-06-13 11:03:34 -04001018 } elsif (defined($opt{$var})) {
1019 $o = $opt{$var};
1020 $retval = "$retval$o";
1021 } else {
1022 $retval = "$retval\$\{$var\}";
1023 }
1024
1025 $option = $end;
1026 }
1027
1028 $retval = "$retval$option";
1029
1030 $retval =~ s/^ //;
1031
1032 return $retval;
1033}
1034
1035sub eval_option {
1036 my ($option, $i) = @_;
1037
1038 my $prev = "";
1039
1040 # Since an option can evaluate to another option,
1041 # keep iterating until we do not evaluate any more
1042 # options.
1043 my $r = 0;
1044 while ($prev ne $option) {
1045 # Check for recursive evaluations.
1046 # 100 deep should be more than enough.
1047 if ($r++ > 100) {
1048 die "Over 100 evaluations accurred with $option\n" .
1049 "Check for recursive variables\n";
1050 }
1051 $prev = $option;
1052 $option = __eval_option($option, $i);
1053 }
1054
1055 return $option;
1056}
1057
Steven Rostedtd1e2f222010-11-08 16:39:57 -05001058sub _logit {
Steven Rostedt2545eb62010-11-02 15:01:32 -04001059 if (defined($opt{"LOG_FILE"})) {
1060 open(OUT, ">> $opt{LOG_FILE}") or die "Can't write to $opt{LOG_FILE}";
1061 print OUT @_;
1062 close(OUT);
1063 }
1064}
1065
Steven Rostedtd1e2f222010-11-08 16:39:57 -05001066sub logit {
1067 if (defined($opt{"LOG_FILE"})) {
1068 _logit @_;
1069 } else {
1070 print @_;
1071 }
1072}
1073
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001074sub doprint {
1075 print @_;
Steven Rostedtd1e2f222010-11-08 16:39:57 -05001076 _logit @_;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001077}
1078
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001079sub run_command;
Andrew Jones2728be42011-08-12 15:32:05 +02001080sub start_monitor;
1081sub end_monitor;
1082sub wait_for_monitor;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001083
1084sub reboot {
Andrew Jones2728be42011-08-12 15:32:05 +02001085 my ($time) = @_;
1086
Steven Rostedt2b803362011-09-30 18:00:23 -04001087 if (defined($time)) {
1088 start_monitor;
1089 # flush out current monitor
1090 # May contain the reboot success line
1091 wait_for_monitor 1;
1092 }
1093
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001094 # try to reboot normally
Steven Rostedte48c5292010-11-02 14:35:37 -04001095 if (run_command $reboot) {
Steven Rostedt576f6272010-11-02 14:58:38 -04001096 if (defined($powercycle_after_reboot)) {
1097 sleep $powercycle_after_reboot;
1098 run_command "$power_cycle";
1099 }
1100 } else {
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001101 # nope? power cycle it.
Steven Rostedta75fece2010-11-02 14:58:27 -04001102 run_command "$power_cycle";
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001103 }
Andrew Jones2728be42011-08-12 15:32:05 +02001104
1105 if (defined($time)) {
Steven Rostedt2b803362011-09-30 18:00:23 -04001106 wait_for_monitor($time, $reboot_success_line);
Andrew Jones2728be42011-08-12 15:32:05 +02001107 end_monitor;
1108 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001109}
1110
Steven Rostedtbc7c5802011-12-22 16:29:10 -05001111sub reboot_to_good {
1112 my ($time) = @_;
1113
1114 if (defined($switch_to_good)) {
1115 run_command $switch_to_good;
1116 return;
1117 }
1118
1119 reboot $time;
1120}
1121
Steven Rostedt576f6272010-11-02 14:58:38 -04001122sub do_not_reboot {
1123 my $i = $iteration;
1124
Steven Rostedt4ab1cce2011-09-30 18:12:20 -04001125 return $test_type eq "build" || $no_reboot ||
Steven Rostedt576f6272010-11-02 14:58:38 -04001126 ($test_type eq "patchcheck" && $opt{"PATCHCHECK_TYPE[$i]"} eq "build") ||
1127 ($test_type eq "bisect" && $opt{"BISECT_TYPE[$i]"} eq "build");
1128}
1129
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001130sub dodie {
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001131 doprint "CRITICAL FAILURE... ", @_, "\n";
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001132
Steven Rostedt576f6272010-11-02 14:58:38 -04001133 my $i = $iteration;
1134
1135 if ($reboot_on_error && !do_not_reboot) {
1136
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001137 doprint "REBOOTING\n";
Steven Rostedtbc7c5802011-12-22 16:29:10 -05001138 reboot_to_good;
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001139
Steven Rostedta75fece2010-11-02 14:58:27 -04001140 } elsif ($poweroff_on_error && defined($power_off)) {
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001141 doprint "POWERING OFF\n";
Steven Rostedta75fece2010-11-02 14:58:27 -04001142 `$power_off`;
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001143 }
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001144
Steven Rostedtf80802c2011-03-07 13:18:47 -05001145 if (defined($opt{"LOG_FILE"})) {
1146 print " See $opt{LOG_FILE} for more info.\n";
1147 }
1148
Steven Rostedt576f6272010-11-02 14:58:38 -04001149 die @_, "\n";
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001150}
1151
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001152sub open_console {
1153 my ($fp) = @_;
1154
1155 my $flags;
1156
Steven Rostedta75fece2010-11-02 14:58:27 -04001157 my $pid = open($fp, "$console|") or
1158 dodie "Can't open console $console";
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001159
1160 $flags = fcntl($fp, F_GETFL, 0) or
Steven Rostedt576f6272010-11-02 14:58:38 -04001161 dodie "Can't get flags for the socket: $!";
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001162 $flags = fcntl($fp, F_SETFL, $flags | O_NONBLOCK) or
Steven Rostedt576f6272010-11-02 14:58:38 -04001163 dodie "Can't set flags for the socket: $!";
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001164
1165 return $pid;
1166}
1167
1168sub close_console {
1169 my ($fp, $pid) = @_;
1170
1171 doprint "kill child process $pid\n";
1172 kill 2, $pid;
1173
1174 print "closing!\n";
1175 close($fp);
1176}
1177
1178sub start_monitor {
1179 if ($monitor_cnt++) {
1180 return;
1181 }
1182 $monitor_fp = \*MONFD;
1183 $monitor_pid = open_console $monitor_fp;
Steven Rostedta75fece2010-11-02 14:58:27 -04001184
1185 return;
1186
1187 open(MONFD, "Stop perl from warning about single use of MONFD");
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001188}
1189
1190sub end_monitor {
1191 if (--$monitor_cnt) {
1192 return;
1193 }
1194 close_console($monitor_fp, $monitor_pid);
1195}
1196
1197sub wait_for_monitor {
Steven Rostedt2b803362011-09-30 18:00:23 -04001198 my ($time, $stop) = @_;
1199 my $full_line = "";
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001200 my $line;
Steven Rostedt2b803362011-09-30 18:00:23 -04001201 my $booted = 0;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001202
Steven Rostedta75fece2010-11-02 14:58:27 -04001203 doprint "** Wait for monitor to settle down **\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001204
1205 # read the monitor and wait for the system to calm down
Steven Rostedt2b803362011-09-30 18:00:23 -04001206 while (!$booted) {
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001207 $line = wait_for_input($monitor_fp, $time);
Steven Rostedt2b803362011-09-30 18:00:23 -04001208 last if (!defined($line));
1209 print "$line";
1210 $full_line .= $line;
1211
1212 if (defined($stop) && $full_line =~ /$stop/) {
1213 doprint "wait for monitor detected $stop\n";
1214 $booted = 1;
1215 }
1216
1217 if ($line =~ /\n/) {
1218 $full_line = "";
1219 }
1220 }
Steven Rostedta75fece2010-11-02 14:58:27 -04001221 print "** Monitor flushed **\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001222}
1223
Rabin Vincentde5b6e32011-11-18 17:05:31 +05301224sub save_logs {
1225 my ($result, $basedir) = @_;
1226 my @t = localtime;
1227 my $date = sprintf "%04d%02d%02d%02d%02d%02d",
1228 1900+$t[5],$t[4],$t[3],$t[2],$t[1],$t[0];
1229
1230 my $type = $build_type;
1231 if ($type =~ /useconfig/) {
1232 $type = "useconfig";
1233 }
1234
1235 my $dir = "$machine-$test_type-$type-$result-$date";
1236
1237 $dir = "$basedir/$dir";
1238
1239 if (!-d $dir) {
1240 mkpath($dir) or
1241 die "can't create $dir";
1242 }
1243
1244 my %files = (
1245 "config" => $output_config,
1246 "buildlog" => $buildlog,
1247 "dmesg" => $dmesg,
1248 "testlog" => $testlog,
1249 );
1250
1251 while (my ($name, $source) = each(%files)) {
1252 if (-f "$source") {
1253 cp "$source", "$dir/$name" or
1254 die "failed to copy $source";
1255 }
1256 }
1257
1258 doprint "*** Saved info to $dir ***\n";
1259}
1260
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001261sub fail {
1262
Steven Rostedta75fece2010-11-02 14:58:27 -04001263 if ($die_on_failure) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001264 dodie @_;
1265 }
1266
Steven Rostedta75fece2010-11-02 14:58:27 -04001267 doprint "FAILED\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001268
Steven Rostedt576f6272010-11-02 14:58:38 -04001269 my $i = $iteration;
1270
Steven Rostedta75fece2010-11-02 14:58:27 -04001271 # no need to reboot for just building.
Steven Rostedt576f6272010-11-02 14:58:38 -04001272 if (!do_not_reboot) {
Steven Rostedta75fece2010-11-02 14:58:27 -04001273 doprint "REBOOTING\n";
Steven Rostedtbc7c5802011-12-22 16:29:10 -05001274 reboot_to_good $sleep_time;
Steven Rostedta75fece2010-11-02 14:58:27 -04001275 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001276
Steven Rostedt9064af52011-06-13 10:38:48 -04001277 my $name = "";
1278
1279 if (defined($test_name)) {
1280 $name = " ($test_name)";
1281 }
1282
Steven Rostedt576f6272010-11-02 14:58:38 -04001283 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
1284 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
Steven Rostedt9064af52011-06-13 10:38:48 -04001285 doprint "KTEST RESULT: TEST $i$name Failed: ", @_, "\n";
Steven Rostedt576f6272010-11-02 14:58:38 -04001286 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
1287 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
Steven Rostedta75fece2010-11-02 14:58:27 -04001288
Rabin Vincentde5b6e32011-11-18 17:05:31 +05301289 if (defined($store_failures)) {
1290 save_logs "fail", $store_failures;
1291 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001292
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001293 return 1;
1294}
1295
Steven Rostedt2545eb62010-11-02 15:01:32 -04001296sub run_command {
1297 my ($command) = @_;
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04001298 my $dolog = 0;
1299 my $dord = 0;
1300 my $pid;
1301
Steven Rostedte48c5292010-11-02 14:35:37 -04001302 $command =~ s/\$SSH_USER/$ssh_user/g;
1303 $command =~ s/\$MACHINE/$machine/g;
1304
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04001305 doprint("$command ... ");
1306
1307 $pid = open(CMD, "$command 2>&1 |") or
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001308 (fail "unable to exec $command" and return 0);
Steven Rostedt2545eb62010-11-02 15:01:32 -04001309
1310 if (defined($opt{"LOG_FILE"})) {
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04001311 open(LOG, ">>$opt{LOG_FILE}") or
1312 dodie "failed to write to log";
1313 $dolog = 1;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001314 }
1315
1316 if (defined($redirect)) {
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04001317 open (RD, ">$redirect") or
1318 dodie "failed to write to redirect $redirect";
1319 $dord = 1;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001320 }
1321
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04001322 while (<CMD>) {
1323 print LOG if ($dolog);
1324 print RD if ($dord);
1325 }
Steven Rostedt2545eb62010-11-02 15:01:32 -04001326
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04001327 waitpid($pid, 0);
Steven Rostedt2545eb62010-11-02 15:01:32 -04001328 my $failed = $?;
1329
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04001330 close(CMD);
1331 close(LOG) if ($dolog);
1332 close(RD) if ($dord);
1333
Steven Rostedt2545eb62010-11-02 15:01:32 -04001334 if ($failed) {
1335 doprint "FAILED!\n";
1336 } else {
1337 doprint "SUCCESS\n";
1338 }
1339
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001340 return !$failed;
1341}
1342
Steven Rostedte48c5292010-11-02 14:35:37 -04001343sub run_ssh {
1344 my ($cmd) = @_;
1345 my $cp_exec = $ssh_exec;
1346
1347 $cp_exec =~ s/\$SSH_COMMAND/$cmd/g;
1348 return run_command "$cp_exec";
1349}
1350
1351sub run_scp {
1352 my ($src, $dst) = @_;
1353 my $cp_scp = $scp_to_target;
1354
1355 $cp_scp =~ s/\$SRC_FILE/$src/g;
1356 $cp_scp =~ s/\$DST_FILE/$dst/g;
1357
1358 return run_command "$cp_scp";
1359}
1360
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001361sub get_grub_index {
1362
Steven Rostedta75fece2010-11-02 14:58:27 -04001363 if ($reboot_type ne "grub") {
1364 return;
1365 }
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001366 return if (defined($grub_number));
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001367
1368 doprint "Find grub menu ... ";
1369 $grub_number = -1;
Steven Rostedte48c5292010-11-02 14:35:37 -04001370
1371 my $ssh_grub = $ssh_exec;
1372 $ssh_grub =~ s,\$SSH_COMMAND,cat /boot/grub/menu.lst,g;
1373
1374 open(IN, "$ssh_grub |")
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001375 or die "unable to get menu.lst";
Steven Rostedte48c5292010-11-02 14:35:37 -04001376
Steven Rostedteaa1fe22011-09-14 17:20:39 -04001377 my $found = 0;
1378
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001379 while (<IN>) {
Steven Rostedta75fece2010-11-02 14:58:27 -04001380 if (/^\s*title\s+$grub_menu\s*$/) {
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001381 $grub_number++;
Steven Rostedteaa1fe22011-09-14 17:20:39 -04001382 $found = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001383 last;
1384 } elsif (/^\s*title\s/) {
1385 $grub_number++;
1386 }
1387 }
1388 close(IN);
1389
Steven Rostedta75fece2010-11-02 14:58:27 -04001390 die "Could not find '$grub_menu' in /boot/grub/menu on $machine"
Steven Rostedteaa1fe22011-09-14 17:20:39 -04001391 if (!$found);
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001392 doprint "$grub_number\n";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001393}
1394
Steven Rostedt2545eb62010-11-02 15:01:32 -04001395sub wait_for_input
1396{
1397 my ($fp, $time) = @_;
1398 my $rin;
1399 my $ready;
1400 my $line;
1401 my $ch;
1402
1403 if (!defined($time)) {
1404 $time = $timeout;
1405 }
1406
1407 $rin = '';
1408 vec($rin, fileno($fp), 1) = 1;
1409 $ready = select($rin, undef, undef, $time);
1410
1411 $line = "";
1412
1413 # try to read one char at a time
1414 while (sysread $fp, $ch, 1) {
1415 $line .= $ch;
1416 last if ($ch eq "\n");
1417 }
1418
1419 if (!length($line)) {
1420 return undef;
1421 }
1422
1423 return $line;
1424}
1425
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001426sub reboot_to {
Steven Rostedtbc7c5802011-12-22 16:29:10 -05001427 if (defined($switch_to_test)) {
1428 run_command $switch_to_test;
1429 }
1430
Steven Rostedta75fece2010-11-02 14:58:27 -04001431 if ($reboot_type eq "grub") {
Steven Rostedtc54367f2011-10-20 09:56:41 -04001432 run_ssh "'(echo \"savedefault --default=$grub_number --once\" | grub --batch)'";
Steven Rostedt96f6a0d2011-12-23 00:24:51 -05001433 } elsif (defined $reboot_script) {
1434 run_command "$reboot_script";
Steven Rostedta75fece2010-11-02 14:58:27 -04001435 }
Steven Rostedt96f6a0d2011-12-23 00:24:51 -05001436 reboot;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001437}
1438
Steven Rostedta57419b2010-11-02 15:13:54 -04001439sub get_sha1 {
1440 my ($commit) = @_;
1441
1442 doprint "git rev-list --max-count=1 $commit ... ";
1443 my $sha1 = `git rev-list --max-count=1 $commit`;
1444 my $ret = $?;
1445
1446 logit $sha1;
1447
1448 if ($ret) {
1449 doprint "FAILED\n";
1450 dodie "Failed to get git $commit";
1451 }
1452
1453 print "SUCCESS\n";
1454
1455 chomp $sha1;
1456
1457 return $sha1;
1458}
1459
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001460sub monitor {
Steven Rostedt2545eb62010-11-02 15:01:32 -04001461 my $booted = 0;
1462 my $bug = 0;
Steven Rostedt6ca996c2012-03-21 08:18:35 -04001463 my $bug_ignored = 0;
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001464 my $skip_call_trace = 0;
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001465 my $loops;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001466
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001467 wait_for_monitor 5;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001468
1469 my $line;
1470 my $full_line = "";
1471
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001472 open(DMESG, "> $dmesg") or
1473 die "unable to write to $dmesg";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001474
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001475 reboot_to;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001476
Steven Rostedt1c8a6172010-11-09 12:55:40 -05001477 my $success_start;
1478 my $failure_start;
Steven Rostedt2d01b262011-03-08 09:47:54 -05001479 my $monitor_start = time;
1480 my $done = 0;
Steven Rostedtf1a5b962011-06-13 10:30:00 -04001481 my $version_found = 0;
Steven Rostedt1c8a6172010-11-09 12:55:40 -05001482
Steven Rostedt2d01b262011-03-08 09:47:54 -05001483 while (!$done) {
Steven Rostedt2545eb62010-11-02 15:01:32 -04001484
Steven Rostedtecaf8e52011-06-13 10:48:10 -04001485 if ($bug && defined($stop_after_failure) &&
1486 $stop_after_failure >= 0) {
1487 my $time = $stop_after_failure - (time - $failure_start);
1488 $line = wait_for_input($monitor_fp, $time);
1489 if (!defined($line)) {
1490 doprint "bug timed out after $booted_timeout seconds\n";
1491 doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
1492 last;
1493 }
1494 } elsif ($booted) {
Steven Rostedta75fece2010-11-02 14:58:27 -04001495 $line = wait_for_input($monitor_fp, $booted_timeout);
Steven Rostedtcd4f1d52011-06-13 10:26:27 -04001496 if (!defined($line)) {
1497 my $s = $booted_timeout == 1 ? "" : "s";
1498 doprint "Successful boot found: break after $booted_timeout second$s\n";
1499 last;
1500 }
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001501 } else {
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001502 $line = wait_for_input($monitor_fp);
Steven Rostedtcd4f1d52011-06-13 10:26:27 -04001503 if (!defined($line)) {
1504 my $s = $timeout == 1 ? "" : "s";
1505 doprint "Timed out after $timeout second$s\n";
1506 last;
1507 }
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001508 }
Steven Rostedt2545eb62010-11-02 15:01:32 -04001509
Steven Rostedt2545eb62010-11-02 15:01:32 -04001510 doprint $line;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001511 print DMESG $line;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001512
1513 # we are not guaranteed to get a full line
1514 $full_line .= $line;
1515
Steven Rostedta75fece2010-11-02 14:58:27 -04001516 if ($full_line =~ /$success_line/) {
Steven Rostedt2545eb62010-11-02 15:01:32 -04001517 $booted = 1;
Steven Rostedt1c8a6172010-11-09 12:55:40 -05001518 $success_start = time;
1519 }
1520
1521 if ($booted && defined($stop_after_success) &&
1522 $stop_after_success >= 0) {
1523 my $now = time;
1524 if ($now - $success_start >= $stop_after_success) {
1525 doprint "Test forced to stop after $stop_after_success seconds after success\n";
1526 last;
1527 }
Steven Rostedt2545eb62010-11-02 15:01:32 -04001528 }
1529
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001530 if ($full_line =~ /\[ backtrace testing \]/) {
1531 $skip_call_trace = 1;
1532 }
1533
Steven Rostedt2545eb62010-11-02 15:01:32 -04001534 if ($full_line =~ /call trace:/i) {
Steven Rostedt6ca996c2012-03-21 08:18:35 -04001535 if (!$bug && !$skip_call_trace) {
1536 if ($ignore_errors) {
1537 $bug_ignored = 1;
1538 } else {
1539 $bug = 1;
1540 $failure_start = time;
1541 }
Steven Rostedt1c8a6172010-11-09 12:55:40 -05001542 }
1543 }
1544
1545 if ($bug && defined($stop_after_failure) &&
1546 $stop_after_failure >= 0) {
1547 my $now = time;
1548 if ($now - $failure_start >= $stop_after_failure) {
1549 doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
1550 last;
1551 }
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001552 }
1553
1554 if ($full_line =~ /\[ end of backtrace testing \]/) {
1555 $skip_call_trace = 0;
1556 }
1557
1558 if ($full_line =~ /Kernel panic -/) {
Steven Rostedt10abf112011-03-07 13:21:00 -05001559 $failure_start = time;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001560 $bug = 1;
1561 }
1562
Steven Rostedtf1a5b962011-06-13 10:30:00 -04001563 # Detect triple faults by testing the banner
1564 if ($full_line =~ /\bLinux version (\S+).*\n/) {
1565 if ($1 eq $version) {
1566 $version_found = 1;
1567 } elsif ($version_found && $detect_triplefault) {
1568 # We already booted into the kernel we are testing,
1569 # but now we booted into another kernel?
1570 # Consider this a triple fault.
1571 doprint "Aleady booted in Linux kernel $version, but now\n";
1572 doprint "we booted into Linux kernel $1.\n";
1573 doprint "Assuming that this is a triple fault.\n";
1574 doprint "To disable this: set DETECT_TRIPLE_FAULT to 0\n";
1575 last;
1576 }
1577 }
1578
Steven Rostedt2545eb62010-11-02 15:01:32 -04001579 if ($line =~ /\n/) {
1580 $full_line = "";
1581 }
Steven Rostedt2d01b262011-03-08 09:47:54 -05001582
1583 if ($stop_test_after > 0 && !$booted && !$bug) {
1584 if (time - $monitor_start > $stop_test_after) {
Steven Rostedt4d62bf52011-05-20 09:14:35 -04001585 doprint "STOP_TEST_AFTER ($stop_test_after seconds) timed out\n";
Steven Rostedt2d01b262011-03-08 09:47:54 -05001586 $done = 1;
1587 }
1588 }
Steven Rostedt2545eb62010-11-02 15:01:32 -04001589 }
1590
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001591 close(DMESG);
Steven Rostedt2545eb62010-11-02 15:01:32 -04001592
Steven Rostedt2545eb62010-11-02 15:01:32 -04001593 if ($bug) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001594 return 0 if ($in_bisect);
Steven Rostedt576f6272010-11-02 14:58:38 -04001595 fail "failed - got a bug report" and return 0;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001596 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001597
Steven Rostedta75fece2010-11-02 14:58:27 -04001598 if (!$booted) {
1599 return 0 if ($in_bisect);
Steven Rostedt576f6272010-11-02 14:58:38 -04001600 fail "failed - never got a boot prompt." and return 0;
Steven Rostedta75fece2010-11-02 14:58:27 -04001601 }
1602
Steven Rostedt6ca996c2012-03-21 08:18:35 -04001603 if ($bug_ignored) {
1604 doprint "WARNING: Call Trace detected but ignored due to IGNORE_ERRORS=1\n";
1605 }
1606
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001607 return 1;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001608}
1609
Steven Rostedt2b29b2f2011-12-22 11:25:46 -05001610sub eval_kernel_version {
1611 my ($option) = @_;
1612
1613 $option =~ s/\$KERNEL_VERSION/$version/g;
1614
1615 return $option;
1616}
1617
Steven Rostedtdb05cfe2011-06-13 11:09:22 -04001618sub do_post_install {
1619
1620 return if (!defined($post_install));
1621
Steven Rostedt2b29b2f2011-12-22 11:25:46 -05001622 my $cp_post_install = eval_kernel_version $post_install;
Steven Rostedtdb05cfe2011-06-13 11:09:22 -04001623 run_command "$cp_post_install" or
1624 dodie "Failed to run post install";
1625}
1626
Steven Rostedt2545eb62010-11-02 15:01:32 -04001627sub install {
1628
Steven Rostedte0a87422011-09-30 17:50:48 -04001629 return if ($no_install);
1630
Steven Rostedt2b29b2f2011-12-22 11:25:46 -05001631 my $cp_target = eval_kernel_version $target_image;
1632
1633 run_scp "$outputdir/$build_target", "$cp_target" or
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001634 dodie "failed to copy image";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001635
1636 my $install_mods = 0;
1637
1638 # should we process modules?
1639 $install_mods = 0;
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05001640 open(IN, "$output_config") or dodie("Can't read config file");
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001641 while (<IN>) {
1642 if (/CONFIG_MODULES(=y)?/) {
1643 $install_mods = 1 if (defined($1));
1644 last;
1645 }
1646 }
1647 close(IN);
1648
1649 if (!$install_mods) {
Steven Rostedtdb05cfe2011-06-13 11:09:22 -04001650 do_post_install;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001651 doprint "No modules needed\n";
1652 return;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001653 }
1654
Steven Rostedt627977d2012-03-21 08:16:15 -04001655 run_command "$make INSTALL_MOD_STRIP=1 INSTALL_MOD_PATH=$tmpdir modules_install" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001656 dodie "Failed to install modules";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001657
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001658 my $modlib = "/lib/modules/$version";
Steven Rostedta57419b2010-11-02 15:13:54 -04001659 my $modtar = "ktest-mods.tar.bz2";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001660
Steven Rostedte48c5292010-11-02 14:35:37 -04001661 run_ssh "rm -rf $modlib" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001662 dodie "failed to remove old mods: $modlib";
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001663
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001664 # would be nice if scp -r did not follow symbolic links
Steven Rostedta75fece2010-11-02 14:58:27 -04001665 run_command "cd $tmpdir && tar -cjf $modtar lib/modules/$version" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001666 dodie "making tarball";
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001667
Steven Rostedte48c5292010-11-02 14:35:37 -04001668 run_scp "$tmpdir/$modtar", "/tmp" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001669 dodie "failed to copy modules";
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001670
Steven Rostedta75fece2010-11-02 14:58:27 -04001671 unlink "$tmpdir/$modtar";
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001672
Steven Rostedte7b13442011-06-14 20:44:36 -04001673 run_ssh "'(cd / && tar xjf /tmp/$modtar)'" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001674 dodie "failed to tar modules";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001675
Steven Rostedte48c5292010-11-02 14:35:37 -04001676 run_ssh "rm -f /tmp/$modtar";
Steven Rostedt8b37ca82010-11-02 14:58:33 -04001677
Steven Rostedtdb05cfe2011-06-13 11:09:22 -04001678 do_post_install;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001679}
1680
Steven Rostedtddf607e2011-06-14 20:49:13 -04001681sub get_version {
1682 # get the release name
1683 doprint "$make kernelrelease ... ";
1684 $version = `$make kernelrelease | tail -1`;
1685 chomp($version);
1686 doprint "$version\n";
1687}
1688
1689sub start_monitor_and_boot {
Steven Rostedt9f7424c2011-10-22 08:58:19 -04001690 # Make sure the stable kernel has finished booting
1691 start_monitor;
1692 wait_for_monitor 5;
1693 end_monitor;
1694
Steven Rostedtddf607e2011-06-14 20:49:13 -04001695 get_grub_index;
1696 get_version;
1697 install;
1698
1699 start_monitor;
1700 return monitor;
1701}
1702
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001703sub check_buildlog {
1704 my ($patch) = @_;
1705
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001706 my @files = `git show $patch | diffstat -l`;
1707
1708 open(IN, "git show $patch |") or
1709 dodie "failed to show $patch";
1710 while (<IN>) {
1711 if (m,^--- a/(.*),) {
1712 chomp $1;
1713 $files[$#files] = $1;
1714 }
1715 }
1716 close(IN);
1717
1718 open(IN, $buildlog) or dodie "Can't open $buildlog";
1719 while (<IN>) {
1720 if (/^\s*(.*?):.*(warning|error)/) {
1721 my $err = $1;
1722 foreach my $file (@files) {
Steven Rostedta75fece2010-11-02 14:58:27 -04001723 my $fullpath = "$builddir/$file";
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001724 if ($file eq $err || $fullpath eq $err) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001725 fail "$file built with warnings" and return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001726 }
1727 }
1728 }
1729 }
1730 close(IN);
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001731
1732 return 1;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001733}
1734
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001735sub apply_min_config {
1736 my $outconfig = "$output_config.new";
Steven Rostedt612b9e92011-03-07 13:27:43 -05001737
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001738 # Read the config file and remove anything that
1739 # is in the force_config hash (from minconfig and others)
1740 # then add the force config back.
1741
1742 doprint "Applying minimum configurations into $output_config.new\n";
1743
1744 open (OUT, ">$outconfig") or
1745 dodie "Can't create $outconfig";
1746
1747 if (-f $output_config) {
1748 open (IN, $output_config) or
1749 dodie "Failed to open $output_config";
1750 while (<IN>) {
1751 if (/^(# )?(CONFIG_[^\s=]*)/) {
1752 next if (defined($force_config{$2}));
1753 }
1754 print OUT;
1755 }
1756 close IN;
1757 }
1758 foreach my $config (keys %force_config) {
1759 print OUT "$force_config{$config}\n";
1760 }
1761 close OUT;
1762
1763 run_command "mv $outconfig $output_config";
1764}
1765
1766sub make_oldconfig {
1767
Steven Rostedt4c4ab122011-07-15 21:16:17 -04001768 my @force_list = keys %force_config;
1769
1770 if ($#force_list >= 0) {
1771 apply_min_config;
1772 }
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001773
1774 if (!run_command "$make oldnoconfig") {
Steven Rostedt612b9e92011-03-07 13:27:43 -05001775 # Perhaps oldnoconfig doesn't exist in this version of the kernel
1776 # try a yes '' | oldconfig
1777 doprint "oldnoconfig failed, trying yes '' | make oldconfig\n";
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001778 run_command "yes '' | $make oldconfig" or
Steven Rostedt612b9e92011-03-07 13:27:43 -05001779 dodie "failed make config oldconfig";
1780 }
1781}
1782
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001783# read a config file and use this to force new configs.
1784sub load_force_config {
1785 my ($config) = @_;
1786
1787 open(IN, $config) or
1788 dodie "failed to read $config";
1789 while (<IN>) {
1790 chomp;
1791 if (/^(CONFIG[^\s=]*)(\s*=.*)/) {
1792 $force_config{$1} = $_;
1793 } elsif (/^# (CONFIG_\S*) is not set/) {
1794 $force_config{$1} = $_;
1795 }
1796 }
1797 close IN;
1798}
1799
Steven Rostedt2545eb62010-11-02 15:01:32 -04001800sub build {
1801 my ($type) = @_;
1802
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001803 unlink $buildlog;
1804
Steven Rostedt4ab1cce2011-09-30 18:12:20 -04001805 # Failed builds should not reboot the target
1806 my $save_no_reboot = $no_reboot;
1807 $no_reboot = 1;
1808
Steven Rostedt0bd6c1a2011-06-14 20:39:31 -04001809 if (defined($pre_build)) {
1810 my $ret = run_command $pre_build;
1811 if (!$ret && defined($pre_build_die) &&
1812 $pre_build_die) {
1813 dodie "failed to pre_build\n";
1814 }
1815 }
1816
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001817 if ($type =~ /^useconfig:(.*)/) {
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05001818 run_command "cp $1 $output_config" or
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001819 dodie "could not copy $1 to .config";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001820
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001821 $type = "oldconfig";
1822 }
1823
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001824 # old config can ask questions
1825 if ($type eq "oldconfig") {
Steven Rostedt9386c6a2010-11-08 16:35:48 -05001826 $type = "oldnoconfig";
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001827
1828 # allow for empty configs
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05001829 run_command "touch $output_config";
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001830
Andrew Jones13488232011-08-12 15:32:04 +02001831 if (!$noclean) {
1832 run_command "mv $output_config $outputdir/config_temp" or
1833 dodie "moving .config";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001834
Andrew Jones13488232011-08-12 15:32:04 +02001835 run_command "$make mrproper" or dodie "make mrproper";
1836
1837 run_command "mv $outputdir/config_temp $output_config" or
1838 dodie "moving config_temp";
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001839 }
1840
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001841 } elsif (!$noclean) {
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05001842 unlink "$output_config";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001843 run_command "$make mrproper" or
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001844 dodie "make mrproper";
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001845 }
Steven Rostedt2545eb62010-11-02 15:01:32 -04001846
1847 # add something to distinguish this build
Steven Rostedta75fece2010-11-02 14:58:27 -04001848 open(OUT, "> $outputdir/localversion") or dodie("Can't make localversion file");
1849 print OUT "$localversion\n";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001850 close(OUT);
1851
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001852 if (defined($minconfig)) {
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001853 load_force_config($minconfig);
Steven Rostedt2545eb62010-11-02 15:01:32 -04001854 }
1855
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001856 if ($type ne "oldnoconfig") {
1857 run_command "$make $type" or
Steven Rostedt612b9e92011-03-07 13:27:43 -05001858 dodie "failed make config";
1859 }
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001860 # Run old config regardless, to enforce min configurations
1861 make_oldconfig;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001862
Steven Rostedta75fece2010-11-02 14:58:27 -04001863 $redirect = "$buildlog";
Steven Rostedt0bd6c1a2011-06-14 20:39:31 -04001864 my $build_ret = run_command "$make $build_options";
1865 undef $redirect;
1866
1867 if (defined($post_build)) {
1868 my $ret = run_command $post_build;
1869 if (!$ret && defined($post_build_die) &&
1870 $post_build_die) {
1871 dodie "failed to post_build\n";
1872 }
1873 }
1874
1875 if (!$build_ret) {
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001876 # bisect may need this to pass
Steven Rostedt4ab1cce2011-09-30 18:12:20 -04001877 if ($in_bisect) {
1878 $no_reboot = $save_no_reboot;
1879 return 0;
1880 }
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001881 fail "failed build" and return 0;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001882 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001883
Steven Rostedt4ab1cce2011-09-30 18:12:20 -04001884 $no_reboot = $save_no_reboot;
1885
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001886 return 1;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001887}
1888
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001889sub halt {
Steven Rostedte48c5292010-11-02 14:35:37 -04001890 if (!run_ssh "halt" or defined($power_off)) {
Steven Rostedt576f6272010-11-02 14:58:38 -04001891 if (defined($poweroff_after_halt)) {
1892 sleep $poweroff_after_halt;
1893 run_command "$power_off";
1894 }
1895 } else {
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001896 # nope? the zap it!
Steven Rostedta75fece2010-11-02 14:58:27 -04001897 run_command "$power_off";
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001898 }
1899}
1900
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001901sub success {
1902 my ($i) = @_;
1903
Steven Rostedte48c5292010-11-02 14:35:37 -04001904 $successes++;
1905
Steven Rostedt9064af52011-06-13 10:38:48 -04001906 my $name = "";
1907
1908 if (defined($test_name)) {
1909 $name = " ($test_name)";
1910 }
1911
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001912 doprint "\n\n*******************************************\n";
1913 doprint "*******************************************\n";
Steven Rostedt9064af52011-06-13 10:38:48 -04001914 doprint "KTEST RESULT: TEST $i$name SUCCESS!!!! **\n";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001915 doprint "*******************************************\n";
1916 doprint "*******************************************\n";
1917
Rabin Vincentde5b6e32011-11-18 17:05:31 +05301918 if (defined($store_successes)) {
1919 save_logs "success", $store_successes;
1920 }
1921
Steven Rostedt576f6272010-11-02 14:58:38 -04001922 if ($i != $opt{"NUM_TESTS"} && !do_not_reboot) {
Steven Rostedta75fece2010-11-02 14:58:27 -04001923 doprint "Reboot and wait $sleep_time seconds\n";
Steven Rostedtbc7c5802011-12-22 16:29:10 -05001924 reboot_to_good $sleep_time;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001925 }
1926}
1927
Steven Rostedtc960bb92011-03-08 09:22:39 -05001928sub answer_bisect {
1929 for (;;) {
1930 doprint "Pass or fail? [p/f]";
1931 my $ans = <STDIN>;
1932 chomp $ans;
1933 if ($ans eq "p" || $ans eq "P") {
1934 return 1;
1935 } elsif ($ans eq "f" || $ans eq "F") {
1936 return 0;
1937 } else {
1938 print "Please answer 'P' or 'F'\n";
1939 }
1940 }
1941}
1942
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001943sub child_run_test {
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001944 my $failed = 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001945
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001946 # child should have no power
Steven Rostedta75fece2010-11-02 14:58:27 -04001947 $reboot_on_error = 0;
1948 $poweroff_on_error = 0;
1949 $die_on_failure = 1;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001950
Rabin Vincenta9dd5d62011-11-18 17:05:29 +05301951 $redirect = "$testlog";
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001952 run_command $run_test or $failed = 1;
Rabin Vincenta9dd5d62011-11-18 17:05:29 +05301953 undef $redirect;
1954
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001955 exit $failed;
1956}
1957
1958my $child_done;
1959
1960sub child_finished {
1961 $child_done = 1;
1962}
1963
1964sub do_run_test {
1965 my $child_pid;
1966 my $child_exit;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001967 my $line;
1968 my $full_line;
1969 my $bug = 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001970
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001971 wait_for_monitor 1;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001972
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001973 doprint "run test $run_test\n";
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001974
1975 $child_done = 0;
1976
1977 $SIG{CHLD} = qw(child_finished);
1978
1979 $child_pid = fork;
1980
1981 child_run_test if (!$child_pid);
1982
1983 $full_line = "";
1984
1985 do {
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001986 $line = wait_for_input($monitor_fp, 1);
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001987 if (defined($line)) {
1988
1989 # we are not guaranteed to get a full line
1990 $full_line .= $line;
Steven Rostedt8ea0e062011-03-08 09:44:35 -05001991 doprint $line;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001992
1993 if ($full_line =~ /call trace:/i) {
1994 $bug = 1;
1995 }
1996
1997 if ($full_line =~ /Kernel panic -/) {
1998 $bug = 1;
1999 }
2000
2001 if ($line =~ /\n/) {
2002 $full_line = "";
2003 }
2004 }
2005 } while (!$child_done && !$bug);
2006
2007 if ($bug) {
Steven Rostedt8ea0e062011-03-08 09:44:35 -05002008 my $failure_start = time;
2009 my $now;
2010 do {
2011 $line = wait_for_input($monitor_fp, 1);
2012 if (defined($line)) {
2013 doprint $line;
2014 }
2015 $now = time;
2016 if ($now - $failure_start >= $stop_after_failure) {
2017 last;
2018 }
2019 } while (defined($line));
2020
Steven Rostedt5a391fb2010-11-02 14:57:43 -04002021 doprint "Detected kernel crash!\n";
2022 # kill the child with extreme prejudice
2023 kill 9, $child_pid;
2024 }
2025
2026 waitpid $child_pid, 0;
2027 $child_exit = $?;
2028
Steven Rostedtc5dacb82011-12-22 12:43:57 -05002029 if (!$bug && $in_bisect) {
2030 if (defined($bisect_ret_good)) {
2031 if ($child_exit == $bisect_ret_good) {
2032 return 1;
2033 }
2034 }
2035 if (defined($bisect_ret_skip)) {
2036 if ($child_exit == $bisect_ret_skip) {
2037 return -1;
2038 }
2039 }
2040 if (defined($bisect_ret_abort)) {
2041 if ($child_exit == $bisect_ret_abort) {
2042 fail "test abort" and return -2;
2043 }
2044 }
2045 if (defined($bisect_ret_bad)) {
2046 if ($child_exit == $bisect_ret_skip) {
2047 return 0;
2048 }
2049 }
2050 if (defined($bisect_ret_default)) {
2051 if ($bisect_ret_default eq "good") {
2052 return 1;
2053 } elsif ($bisect_ret_default eq "bad") {
2054 return 0;
2055 } elsif ($bisect_ret_default eq "skip") {
2056 return -1;
2057 } elsif ($bisect_ret_default eq "abort") {
2058 return -2;
2059 } else {
2060 fail "unknown default action: $bisect_ret_default"
2061 and return -2;
2062 }
2063 }
2064 }
2065
Steven Rostedt5a391fb2010-11-02 14:57:43 -04002066 if ($bug || $child_exit) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002067 return 0 if $in_bisect;
2068 fail "test failed" and return 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04002069 }
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002070 return 1;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04002071}
2072
Steven Rostedta75fece2010-11-02 14:58:27 -04002073sub run_git_bisect {
2074 my ($command) = @_;
2075
2076 doprint "$command ... ";
2077
2078 my $output = `$command 2>&1`;
2079 my $ret = $?;
2080
2081 logit $output;
2082
2083 if ($ret) {
2084 doprint "FAILED\n";
2085 dodie "Failed to git bisect";
2086 }
2087
2088 doprint "SUCCESS\n";
2089 if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\))\s+\[([[:xdigit:]]+)\]/) {
2090 doprint "$1 [$2]\n";
2091 } elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) {
Steven Rostedtb5f4aea2011-12-22 21:33:55 -05002092 $bisect_bad_commit = $1;
Steven Rostedta75fece2010-11-02 14:58:27 -04002093 doprint "Found bad commit... $1\n";
2094 return 0;
2095 } else {
2096 # we already logged it, just print it now.
2097 print $output;
2098 }
2099
2100 return 1;
2101}
2102
Steven Rostedtc23dca72011-03-08 09:26:31 -05002103sub bisect_reboot {
2104 doprint "Reboot and sleep $bisect_sleep_time seconds\n";
Steven Rostedtbc7c5802011-12-22 16:29:10 -05002105 reboot_to_good $bisect_sleep_time;
Steven Rostedtc23dca72011-03-08 09:26:31 -05002106}
2107
2108# returns 1 on success, 0 on failure, -1 on skip
Steven Rostedt0a05c762010-11-08 11:14:10 -05002109sub run_bisect_test {
2110 my ($type, $buildtype) = @_;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04002111
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002112 my $failed = 0;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04002113 my $result;
2114 my $output;
2115 my $ret;
2116
Steven Rostedt0a05c762010-11-08 11:14:10 -05002117 $in_bisect = 1;
2118
2119 build $buildtype or $failed = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04002120
2121 if ($type ne "build") {
Steven Rostedtc23dca72011-03-08 09:26:31 -05002122 if ($failed && $bisect_skip) {
2123 $in_bisect = 0;
2124 return -1;
2125 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -04002126 dodie "Failed on build" if $failed;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04002127
2128 # Now boot the box
Steven Rostedtddf607e2011-06-14 20:49:13 -04002129 start_monitor_and_boot or $failed = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04002130
2131 if ($type ne "boot") {
Steven Rostedtc23dca72011-03-08 09:26:31 -05002132 if ($failed && $bisect_skip) {
2133 end_monitor;
2134 bisect_reboot;
2135 $in_bisect = 0;
2136 return -1;
2137 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -04002138 dodie "Failed on boot" if $failed;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04002139
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002140 do_run_test or $failed = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04002141 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -04002142 end_monitor;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04002143 }
2144
2145 if ($failed) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05002146 $result = 0;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04002147 } else {
Steven Rostedt0a05c762010-11-08 11:14:10 -05002148 $result = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04002149 }
Steven Rostedt4025bc62011-05-20 09:16:29 -04002150
2151 # reboot the box to a kernel we can ssh to
2152 if ($type ne "build") {
2153 bisect_reboot;
2154 }
Steven Rostedt0a05c762010-11-08 11:14:10 -05002155 $in_bisect = 0;
2156
2157 return $result;
2158}
2159
2160sub run_bisect {
2161 my ($type) = @_;
2162 my $buildtype = "oldconfig";
2163
2164 # We should have a minconfig to use?
2165 if (defined($minconfig)) {
2166 $buildtype = "useconfig:$minconfig";
2167 }
2168
2169 my $ret = run_bisect_test $type, $buildtype;
2170
Steven Rostedtc960bb92011-03-08 09:22:39 -05002171 if ($bisect_manual) {
2172 $ret = answer_bisect;
2173 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04002174
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04002175 # Are we looking for where it worked, not failed?
2176 if ($reverse_bisect) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05002177 $ret = !$ret;
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04002178 }
2179
Steven Rostedtc23dca72011-03-08 09:26:31 -05002180 if ($ret > 0) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05002181 return "good";
Steven Rostedtc23dca72011-03-08 09:26:31 -05002182 } elsif ($ret == 0) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05002183 return "bad";
Steven Rostedtc23dca72011-03-08 09:26:31 -05002184 } elsif ($bisect_skip) {
2185 doprint "HIT A BAD COMMIT ... SKIPPING\n";
2186 return "skip";
Steven Rostedt0a05c762010-11-08 11:14:10 -05002187 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04002188}
2189
Steven Rostedtdad98752011-11-22 20:48:57 -05002190sub update_bisect_replay {
2191 my $tmp_log = "$tmpdir/ktest_bisect_log";
2192 run_command "git bisect log > $tmp_log" or
2193 die "can't create bisect log";
2194 return $tmp_log;
2195}
2196
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04002197sub bisect {
2198 my ($i) = @_;
2199
2200 my $result;
2201
Steven Rostedtb5f4aea2011-12-22 21:33:55 -05002202 die "BISECT_GOOD[$i] not defined\n" if (!defined($bisect_good));
2203 die "BISECT_BAD[$i] not defined\n" if (!defined($bisect_bad));
2204 die "BISECT_TYPE[$i] not defined\n" if (!defined($bisect_type));
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04002205
Steven Rostedtb5f4aea2011-12-22 21:33:55 -05002206 my $good = $bisect_good;
2207 my $bad = $bisect_bad;
2208 my $type = $bisect_type;
2209 my $start = $bisect_start;
2210 my $replay = $bisect_replay;
2211 my $start_files = $bisect_files;
Steven Rostedt3410f6f2011-03-08 09:38:12 -05002212
2213 if (defined($start_files)) {
2214 $start_files = " -- " . $start_files;
2215 } else {
2216 $start_files = "";
2217 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04002218
Steven Rostedta57419b2010-11-02 15:13:54 -04002219 # convert to true sha1's
2220 $good = get_sha1($good);
2221 $bad = get_sha1($bad);
2222
Steven Rostedtb5f4aea2011-12-22 21:33:55 -05002223 if (defined($bisect_reverse) && $bisect_reverse == 1) {
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04002224 doprint "Performing a reverse bisect (bad is good, good is bad!)\n";
2225 $reverse_bisect = 1;
2226 } else {
2227 $reverse_bisect = 0;
2228 }
2229
Steven Rostedt5a391fb2010-11-02 14:57:43 -04002230 # Can't have a test without having a test to run
2231 if ($type eq "test" && !defined($run_test)) {
2232 $type = "boot";
2233 }
2234
Steven Rostedtdad98752011-11-22 20:48:57 -05002235 # Check if a bisect was running
2236 my $bisect_start_file = "$builddir/.git/BISECT_START";
2237
Steven Rostedtb5f4aea2011-12-22 21:33:55 -05002238 my $check = $bisect_check;
Steven Rostedtdad98752011-11-22 20:48:57 -05002239 my $do_check = defined($check) && $check ne "0";
2240
2241 if ( -f $bisect_start_file ) {
2242 print "Bisect in progress found\n";
2243 if ($do_check) {
2244 print " If you say yes, then no checks of good or bad will be done\n";
2245 }
2246 if (defined($replay)) {
2247 print "** BISECT_REPLAY is defined in config file **";
2248 print " Ignore config option and perform new git bisect log?\n";
2249 if (read_ync " (yes, no, or cancel) ") {
2250 $replay = update_bisect_replay;
2251 $do_check = 0;
2252 }
2253 } elsif (read_yn "read git log and continue?") {
2254 $replay = update_bisect_replay;
2255 $do_check = 0;
2256 }
2257 }
2258
2259 if ($do_check) {
Steven Rostedta75fece2010-11-02 14:58:27 -04002260
2261 # get current HEAD
Steven Rostedta57419b2010-11-02 15:13:54 -04002262 my $head = get_sha1("HEAD");
Steven Rostedta75fece2010-11-02 14:58:27 -04002263
2264 if ($check ne "good") {
2265 doprint "TESTING BISECT BAD [$bad]\n";
2266 run_command "git checkout $bad" or
2267 die "Failed to checkout $bad";
2268
2269 $result = run_bisect $type;
2270
2271 if ($result ne "bad") {
2272 fail "Tested BISECT_BAD [$bad] and it succeeded" and return 0;
2273 }
2274 }
2275
2276 if ($check ne "bad") {
2277 doprint "TESTING BISECT GOOD [$good]\n";
2278 run_command "git checkout $good" or
2279 die "Failed to checkout $good";
2280
2281 $result = run_bisect $type;
2282
2283 if ($result ne "good") {
2284 fail "Tested BISECT_GOOD [$good] and it failed" and return 0;
2285 }
2286 }
2287
2288 # checkout where we started
2289 run_command "git checkout $head" or
2290 die "Failed to checkout $head";
2291 }
2292
Steven Rostedt3410f6f2011-03-08 09:38:12 -05002293 run_command "git bisect start$start_files" or
Steven Rostedta75fece2010-11-02 14:58:27 -04002294 dodie "could not start bisect";
2295
2296 run_command "git bisect good $good" or
2297 dodie "could not set bisect good to $good";
2298
2299 run_git_bisect "git bisect bad $bad" or
2300 dodie "could not set bisect bad to $bad";
2301
2302 if (defined($replay)) {
2303 run_command "git bisect replay $replay" or
2304 dodie "failed to run replay";
2305 }
2306
2307 if (defined($start)) {
2308 run_command "git checkout $start" or
2309 dodie "failed to checkout $start";
2310 }
2311
2312 my $test;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04002313 do {
2314 $result = run_bisect $type;
Steven Rostedta75fece2010-11-02 14:58:27 -04002315 $test = run_git_bisect "git bisect $result";
2316 } while ($test);
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04002317
2318 run_command "git bisect log" or
2319 dodie "could not capture git bisect log";
2320
2321 run_command "git bisect reset" or
2322 dodie "could not reset git bisect";
2323
Steven Rostedtb5f4aea2011-12-22 21:33:55 -05002324 doprint "Bad commit was [$bisect_bad_commit]\n";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04002325
Steven Rostedt0a05c762010-11-08 11:14:10 -05002326 success $i;
2327}
2328
2329my %config_ignore;
2330my %config_set;
2331
2332my %config_list;
2333my %null_config;
2334
2335my %dependency;
2336
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002337sub assign_configs {
2338 my ($hash, $config) = @_;
Steven Rostedt0a05c762010-11-08 11:14:10 -05002339
2340 open (IN, $config)
2341 or dodie "Failed to read $config";
2342
2343 while (<IN>) {
Steven Rostedt9bf71742011-06-01 23:27:19 -04002344 if (/^((CONFIG\S*)=.*)/) {
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002345 ${$hash}{$2} = $1;
Steven Rostedt0a05c762010-11-08 11:14:10 -05002346 }
2347 }
2348
2349 close(IN);
2350}
2351
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002352sub process_config_ignore {
2353 my ($config) = @_;
2354
2355 assign_configs \%config_ignore, $config;
2356}
2357
Steven Rostedt0a05c762010-11-08 11:14:10 -05002358sub read_current_config {
2359 my ($config_ref) = @_;
2360
2361 %{$config_ref} = ();
2362 undef %{$config_ref};
2363
2364 my @key = keys %{$config_ref};
2365 if ($#key >= 0) {
2366 print "did not delete!\n";
2367 exit;
2368 }
2369 open (IN, "$output_config");
2370
2371 while (<IN>) {
2372 if (/^(CONFIG\S+)=(.*)/) {
2373 ${$config_ref}{$1} = $2;
2374 }
2375 }
2376 close(IN);
2377}
2378
2379sub get_dependencies {
2380 my ($config) = @_;
2381
2382 my $arr = $dependency{$config};
2383 if (!defined($arr)) {
2384 return ();
2385 }
2386
2387 my @deps = @{$arr};
2388
2389 foreach my $dep (@{$arr}) {
2390 print "ADD DEP $dep\n";
2391 @deps = (@deps, get_dependencies $dep);
2392 }
2393
2394 return @deps;
2395}
2396
2397sub create_config {
2398 my @configs = @_;
2399
2400 open(OUT, ">$output_config") or dodie "Can not write to $output_config";
2401
2402 foreach my $config (@configs) {
2403 print OUT "$config_set{$config}\n";
2404 my @deps = get_dependencies $config;
2405 foreach my $dep (@deps) {
2406 print OUT "$config_set{$dep}\n";
2407 }
2408 }
2409
2410 foreach my $config (keys %config_ignore) {
2411 print OUT "$config_ignore{$config}\n";
2412 }
2413 close(OUT);
2414
2415# exit;
Steven Rostedtfcb3f162011-06-13 10:40:58 -04002416 make_oldconfig;
Steven Rostedt0a05c762010-11-08 11:14:10 -05002417}
2418
2419sub compare_configs {
2420 my (%a, %b) = @_;
2421
2422 foreach my $item (keys %a) {
2423 if (!defined($b{$item})) {
2424 print "diff $item\n";
2425 return 1;
2426 }
2427 delete $b{$item};
2428 }
2429
2430 my @keys = keys %b;
2431 if ($#keys) {
2432 print "diff2 $keys[0]\n";
2433 }
2434 return -1 if ($#keys >= 0);
2435
2436 return 0;
2437}
2438
2439sub run_config_bisect_test {
2440 my ($type) = @_;
2441
2442 return run_bisect_test $type, "oldconfig";
2443}
2444
2445sub process_passed {
2446 my (%configs) = @_;
2447
2448 doprint "These configs had no failure: (Enabling them for further compiles)\n";
2449 # Passed! All these configs are part of a good compile.
2450 # Add them to the min options.
2451 foreach my $config (keys %configs) {
2452 if (defined($config_list{$config})) {
2453 doprint " removing $config\n";
2454 $config_ignore{$config} = $config_list{$config};
2455 delete $config_list{$config};
2456 }
2457 }
Steven Rostedtf1a27852010-11-11 11:34:38 -05002458 doprint "config copied to $outputdir/config_good\n";
2459 run_command "cp -f $output_config $outputdir/config_good";
Steven Rostedt0a05c762010-11-08 11:14:10 -05002460}
2461
2462sub process_failed {
2463 my ($config) = @_;
2464
2465 doprint "\n\n***************************************\n";
2466 doprint "Found bad config: $config\n";
2467 doprint "***************************************\n\n";
2468}
2469
2470sub run_config_bisect {
2471
2472 my @start_list = keys %config_list;
2473
2474 if ($#start_list < 0) {
2475 doprint "No more configs to test!!!\n";
2476 return -1;
2477 }
2478
2479 doprint "***** RUN TEST ***\n";
Steven Rostedtb5f4aea2011-12-22 21:33:55 -05002480 my $type = $config_bisect_type;
Steven Rostedt0a05c762010-11-08 11:14:10 -05002481 my $ret;
2482 my %current_config;
2483
2484 my $count = $#start_list + 1;
2485 doprint " $count configs to test\n";
2486
2487 my $half = int($#start_list / 2);
2488
2489 do {
2490 my @tophalf = @start_list[0 .. $half];
2491
2492 create_config @tophalf;
2493 read_current_config \%current_config;
2494
2495 $count = $#tophalf + 1;
2496 doprint "Testing $count configs\n";
2497 my $found = 0;
2498 # make sure we test something
2499 foreach my $config (@tophalf) {
2500 if (defined($current_config{$config})) {
2501 logit " $config\n";
2502 $found = 1;
2503 }
2504 }
2505 if (!$found) {
2506 # try the other half
2507 doprint "Top half produced no set configs, trying bottom half\n";
Steven Rostedt4c8cc552011-06-01 23:22:30 -04002508 @tophalf = @start_list[$half + 1 .. $#start_list];
Steven Rostedt0a05c762010-11-08 11:14:10 -05002509 create_config @tophalf;
2510 read_current_config \%current_config;
2511 foreach my $config (@tophalf) {
2512 if (defined($current_config{$config})) {
2513 logit " $config\n";
2514 $found = 1;
2515 }
2516 }
2517 if (!$found) {
2518 doprint "Failed: Can't make new config with current configs\n";
2519 foreach my $config (@start_list) {
2520 doprint " CONFIG: $config\n";
2521 }
2522 return -1;
2523 }
2524 $count = $#tophalf + 1;
2525 doprint "Testing $count configs\n";
2526 }
2527
2528 $ret = run_config_bisect_test $type;
Steven Rostedtc960bb92011-03-08 09:22:39 -05002529 if ($bisect_manual) {
2530 $ret = answer_bisect;
2531 }
Steven Rostedt0a05c762010-11-08 11:14:10 -05002532 if ($ret) {
2533 process_passed %current_config;
2534 return 0;
2535 }
2536
2537 doprint "This config had a failure.\n";
2538 doprint "Removing these configs that were not set in this config:\n";
Steven Rostedtf1a27852010-11-11 11:34:38 -05002539 doprint "config copied to $outputdir/config_bad\n";
2540 run_command "cp -f $output_config $outputdir/config_bad";
Steven Rostedt0a05c762010-11-08 11:14:10 -05002541
2542 # A config exists in this group that was bad.
2543 foreach my $config (keys %config_list) {
2544 if (!defined($current_config{$config})) {
2545 doprint " removing $config\n";
2546 delete $config_list{$config};
2547 }
2548 }
2549
2550 @start_list = @tophalf;
2551
2552 if ($#start_list == 0) {
2553 process_failed $start_list[0];
2554 return 1;
2555 }
2556
2557 # remove half the configs we are looking at and see if
2558 # they are good.
2559 $half = int($#start_list / 2);
Steven Rostedt4c8cc552011-06-01 23:22:30 -04002560 } while ($#start_list > 0);
Steven Rostedt0a05c762010-11-08 11:14:10 -05002561
Steven Rostedtc960bb92011-03-08 09:22:39 -05002562 # we found a single config, try it again unless we are running manually
2563
2564 if ($bisect_manual) {
2565 process_failed $start_list[0];
2566 return 1;
2567 }
2568
Steven Rostedt0a05c762010-11-08 11:14:10 -05002569 my @tophalf = @start_list[0 .. 0];
2570
2571 $ret = run_config_bisect_test $type;
2572 if ($ret) {
2573 process_passed %current_config;
2574 return 0;
2575 }
2576
2577 process_failed $start_list[0];
2578 return 1;
2579}
2580
2581sub config_bisect {
2582 my ($i) = @_;
2583
Steven Rostedtb5f4aea2011-12-22 21:33:55 -05002584 my $start_config = $config_bisect;
Steven Rostedt0a05c762010-11-08 11:14:10 -05002585
2586 my $tmpconfig = "$tmpdir/use_config";
2587
Steven Rostedt30f75da2011-06-13 10:35:35 -04002588 if (defined($config_bisect_good)) {
2589 process_config_ignore $config_bisect_good;
2590 }
2591
Steven Rostedt0a05c762010-11-08 11:14:10 -05002592 # Make the file with the bad config and the min config
2593 if (defined($minconfig)) {
2594 # read the min config for things to ignore
2595 run_command "cp $minconfig $tmpconfig" or
2596 dodie "failed to copy $minconfig to $tmpconfig";
2597 } else {
2598 unlink $tmpconfig;
2599 }
2600
Steven Rostedt0a05c762010-11-08 11:14:10 -05002601 if (-f $tmpconfig) {
Steven Rostedtfcb3f162011-06-13 10:40:58 -04002602 load_force_config($tmpconfig);
Steven Rostedt0a05c762010-11-08 11:14:10 -05002603 process_config_ignore $tmpconfig;
2604 }
2605
2606 # now process the start config
2607 run_command "cp $start_config $output_config" or
2608 dodie "failed to copy $start_config to $output_config";
2609
2610 # read directly what we want to check
2611 my %config_check;
2612 open (IN, $output_config)
2613 or dodie "faied to open $output_config";
2614
2615 while (<IN>) {
2616 if (/^((CONFIG\S*)=.*)/) {
2617 $config_check{$2} = $1;
2618 }
2619 }
2620 close(IN);
2621
Steven Rostedt250bae82011-07-15 22:05:59 -04002622 # Now run oldconfig with the minconfig
Steven Rostedtfcb3f162011-06-13 10:40:58 -04002623 make_oldconfig;
Steven Rostedt0a05c762010-11-08 11:14:10 -05002624
2625 # check to see what we lost (or gained)
2626 open (IN, $output_config)
2627 or dodie "Failed to read $start_config";
2628
2629 my %removed_configs;
2630 my %added_configs;
2631
2632 while (<IN>) {
2633 if (/^((CONFIG\S*)=.*)/) {
2634 # save off all options
2635 $config_set{$2} = $1;
2636 if (defined($config_check{$2})) {
2637 if (defined($config_ignore{$2})) {
2638 $removed_configs{$2} = $1;
2639 } else {
2640 $config_list{$2} = $1;
2641 }
2642 } elsif (!defined($config_ignore{$2})) {
2643 $added_configs{$2} = $1;
2644 $config_list{$2} = $1;
2645 }
2646 }
2647 }
2648 close(IN);
2649
2650 my @confs = keys %removed_configs;
2651 if ($#confs >= 0) {
2652 doprint "Configs overridden by default configs and removed from check:\n";
2653 foreach my $config (@confs) {
2654 doprint " $config\n";
2655 }
2656 }
2657 @confs = keys %added_configs;
2658 if ($#confs >= 0) {
2659 doprint "Configs appearing in make oldconfig and added:\n";
2660 foreach my $config (@confs) {
2661 doprint " $config\n";
2662 }
2663 }
2664
2665 my %config_test;
2666 my $once = 0;
2667
2668 # Sometimes kconfig does weird things. We must make sure
2669 # that the config we autocreate has everything we need
2670 # to test, otherwise we may miss testing configs, or
2671 # may not be able to create a new config.
2672 # Here we create a config with everything set.
2673 create_config (keys %config_list);
2674 read_current_config \%config_test;
2675 foreach my $config (keys %config_list) {
2676 if (!defined($config_test{$config})) {
2677 if (!$once) {
2678 $once = 1;
2679 doprint "Configs not produced by kconfig (will not be checked):\n";
2680 }
2681 doprint " $config\n";
2682 delete $config_list{$config};
2683 }
2684 }
2685 my $ret;
2686 do {
2687 $ret = run_config_bisect;
2688 } while (!$ret);
2689
2690 return $ret if ($ret < 0);
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04002691
2692 success $i;
2693}
2694
Steven Rostedt27d934b2011-05-20 09:18:18 -04002695sub patchcheck_reboot {
2696 doprint "Reboot and sleep $patchcheck_sleep_time seconds\n";
Steven Rostedtbc7c5802011-12-22 16:29:10 -05002697 reboot_to_good $patchcheck_sleep_time;
Steven Rostedt27d934b2011-05-20 09:18:18 -04002698}
2699
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002700sub patchcheck {
2701 my ($i) = @_;
2702
2703 die "PATCHCHECK_START[$i] not defined\n"
Steven Rostedtb5f4aea2011-12-22 21:33:55 -05002704 if (!defined($patchcheck_start));
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002705 die "PATCHCHECK_TYPE[$i] not defined\n"
Steven Rostedtb5f4aea2011-12-22 21:33:55 -05002706 if (!defined($patchcheck_type));
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002707
Steven Rostedtb5f4aea2011-12-22 21:33:55 -05002708 my $start = $patchcheck_start;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002709
2710 my $end = "HEAD";
Steven Rostedtb5f4aea2011-12-22 21:33:55 -05002711 if (defined($patchcheck_end)) {
2712 $end = $patchcheck_end;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002713 }
2714
Steven Rostedta57419b2010-11-02 15:13:54 -04002715 # Get the true sha1's since we can use things like HEAD~3
2716 $start = get_sha1($start);
2717 $end = get_sha1($end);
2718
Steven Rostedtb5f4aea2011-12-22 21:33:55 -05002719 my $type = $patchcheck_type;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002720
2721 # Can't have a test without having a test to run
2722 if ($type eq "test" && !defined($run_test)) {
2723 $type = "boot";
2724 }
2725
2726 open (IN, "git log --pretty=oneline $end|") or
2727 dodie "could not get git list";
2728
2729 my @list;
2730
2731 while (<IN>) {
2732 chomp;
2733 $list[$#list+1] = $_;
2734 last if (/^$start/);
2735 }
2736 close(IN);
2737
2738 if ($list[$#list] !~ /^$start/) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002739 fail "SHA1 $start not found";
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002740 }
2741
2742 # go backwards in the list
2743 @list = reverse @list;
2744
2745 my $save_clean = $noclean;
Steven Rostedt19902072011-06-14 20:46:25 -04002746 my %ignored_warnings;
2747
2748 if (defined($ignore_warnings)) {
2749 foreach my $sha1 (split /\s+/, $ignore_warnings) {
2750 $ignored_warnings{$sha1} = 1;
2751 }
2752 }
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002753
2754 $in_patchcheck = 1;
2755 foreach my $item (@list) {
2756 my $sha1 = $item;
2757 $sha1 =~ s/^([[:xdigit:]]+).*/$1/;
2758
2759 doprint "\nProcessing commit $item\n\n";
2760
2761 run_command "git checkout $sha1" or
2762 die "Failed to checkout $sha1";
2763
2764 # only clean on the first and last patch
2765 if ($item eq $list[0] ||
2766 $item eq $list[$#list]) {
2767 $noclean = $save_clean;
2768 } else {
2769 $noclean = 1;
2770 }
2771
2772 if (defined($minconfig)) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002773 build "useconfig:$minconfig" or return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002774 } else {
2775 # ?? no config to use?
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002776 build "oldconfig" or return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002777 }
2778
Steven Rostedt19902072011-06-14 20:46:25 -04002779
2780 if (!defined($ignored_warnings{$sha1})) {
2781 check_buildlog $sha1 or return 0;
2782 }
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002783
2784 next if ($type eq "build");
2785
Steven Rostedt7faafbd2010-11-02 14:58:22 -04002786 my $failed = 0;
2787
Steven Rostedtddf607e2011-06-14 20:49:13 -04002788 start_monitor_and_boot or $failed = 1;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04002789
2790 if (!$failed && $type ne "boot"){
2791 do_run_test or $failed = 1;
2792 }
2793 end_monitor;
2794 return 0 if ($failed);
2795
Steven Rostedt27d934b2011-05-20 09:18:18 -04002796 patchcheck_reboot;
2797
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002798 }
2799 $in_patchcheck = 0;
2800 success $i;
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002801
2802 return 1;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002803}
2804
Steven Rostedtb9066f62011-07-15 21:25:24 -04002805my %depends;
Steven Rostedtac6974c2011-10-04 09:40:17 -04002806my %depcount;
Steven Rostedtb9066f62011-07-15 21:25:24 -04002807my $iflevel = 0;
2808my @ifdeps;
2809
2810# prevent recursion
2811my %read_kconfigs;
2812
Steven Rostedtac6974c2011-10-04 09:40:17 -04002813sub add_dep {
2814 # $config depends on $dep
2815 my ($config, $dep) = @_;
2816
2817 if (defined($depends{$config})) {
2818 $depends{$config} .= " " . $dep;
2819 } else {
2820 $depends{$config} = $dep;
2821 }
2822
2823 # record the number of configs depending on $dep
2824 if (defined $depcount{$dep}) {
2825 $depcount{$dep}++;
2826 } else {
2827 $depcount{$dep} = 1;
2828 }
2829}
2830
Steven Rostedtb9066f62011-07-15 21:25:24 -04002831# taken from streamline_config.pl
2832sub read_kconfig {
2833 my ($kconfig) = @_;
2834
2835 my $state = "NONE";
2836 my $config;
2837 my @kconfigs;
2838
2839 my $cont = 0;
2840 my $line;
2841
2842
2843 if (! -f $kconfig) {
2844 doprint "file $kconfig does not exist, skipping\n";
2845 return;
2846 }
2847
2848 open(KIN, "$kconfig")
2849 or die "Can't open $kconfig";
2850 while (<KIN>) {
2851 chomp;
2852
2853 # Make sure that lines ending with \ continue
2854 if ($cont) {
2855 $_ = $line . " " . $_;
2856 }
2857
2858 if (s/\\$//) {
2859 $cont = 1;
2860 $line = $_;
2861 next;
2862 }
2863
2864 $cont = 0;
2865
2866 # collect any Kconfig sources
2867 if (/^source\s*"(.*)"/) {
2868 $kconfigs[$#kconfigs+1] = $1;
2869 }
2870
2871 # configs found
2872 if (/^\s*(menu)?config\s+(\S+)\s*$/) {
2873 $state = "NEW";
2874 $config = $2;
2875
2876 for (my $i = 0; $i < $iflevel; $i++) {
Steven Rostedtac6974c2011-10-04 09:40:17 -04002877 add_dep $config, $ifdeps[$i];
Steven Rostedtb9066f62011-07-15 21:25:24 -04002878 }
2879
2880 # collect the depends for the config
2881 } elsif ($state eq "NEW" && /^\s*depends\s+on\s+(.*)$/) {
2882
Steven Rostedtac6974c2011-10-04 09:40:17 -04002883 add_dep $config, $1;
Steven Rostedtb9066f62011-07-15 21:25:24 -04002884
2885 # Get the configs that select this config
Steven Rostedtac6974c2011-10-04 09:40:17 -04002886 } elsif ($state eq "NEW" && /^\s*select\s+(\S+)/) {
2887
2888 # selected by depends on config
2889 add_dep $1, $config;
Steven Rostedtb9066f62011-07-15 21:25:24 -04002890
2891 # Check for if statements
2892 } elsif (/^if\s+(.*\S)\s*$/) {
2893 my $deps = $1;
2894 # remove beginning and ending non text
2895 $deps =~ s/^[^a-zA-Z0-9_]*//;
2896 $deps =~ s/[^a-zA-Z0-9_]*$//;
2897
2898 my @deps = split /[^a-zA-Z0-9_]+/, $deps;
2899
2900 $ifdeps[$iflevel++] = join ':', @deps;
2901
2902 } elsif (/^endif/) {
2903
2904 $iflevel-- if ($iflevel);
2905
2906 # stop on "help"
2907 } elsif (/^\s*help\s*$/) {
2908 $state = "NONE";
2909 }
2910 }
2911 close(KIN);
2912
2913 # read in any configs that were found.
2914 foreach $kconfig (@kconfigs) {
2915 if (!defined($read_kconfigs{$kconfig})) {
2916 $read_kconfigs{$kconfig} = 1;
2917 read_kconfig("$builddir/$kconfig");
2918 }
2919 }
2920}
2921
2922sub read_depends {
2923 # find out which arch this is by the kconfig file
2924 open (IN, $output_config)
2925 or dodie "Failed to read $output_config";
2926 my $arch;
2927 while (<IN>) {
2928 if (m,Linux/(\S+)\s+\S+\s+Kernel Configuration,) {
2929 $arch = $1;
2930 last;
2931 }
2932 }
2933 close IN;
2934
2935 if (!defined($arch)) {
2936 doprint "Could not find arch from config file\n";
2937 doprint "no dependencies used\n";
2938 return;
2939 }
2940
2941 # arch is really the subarch, we need to know
2942 # what directory to look at.
2943 if ($arch eq "i386" || $arch eq "x86_64") {
2944 $arch = "x86";
2945 } elsif ($arch =~ /^tile/) {
2946 $arch = "tile";
2947 }
2948
2949 my $kconfig = "$builddir/arch/$arch/Kconfig";
2950
2951 if (! -f $kconfig && $arch =~ /\d$/) {
2952 my $orig = $arch;
2953 # some subarchs have numbers, truncate them
2954 $arch =~ s/\d*$//;
2955 $kconfig = "$builddir/arch/$arch/Kconfig";
2956 if (! -f $kconfig) {
2957 doprint "No idea what arch dir $orig is for\n";
2958 doprint "no dependencies used\n";
2959 return;
2960 }
2961 }
2962
2963 read_kconfig($kconfig);
2964}
2965
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002966sub read_config_list {
2967 my ($config) = @_;
2968
2969 open (IN, $config)
2970 or dodie "Failed to read $config";
2971
2972 while (<IN>) {
2973 if (/^((CONFIG\S*)=.*)/) {
2974 if (!defined($config_ignore{$2})) {
2975 $config_list{$2} = $1;
2976 }
2977 }
2978 }
2979
2980 close(IN);
2981}
2982
2983sub read_output_config {
2984 my ($config) = @_;
2985
2986 assign_configs \%config_ignore, $config;
2987}
2988
2989sub make_new_config {
2990 my @configs = @_;
2991
2992 open (OUT, ">$output_config")
2993 or dodie "Failed to write $output_config";
2994
2995 foreach my $config (@configs) {
2996 print OUT "$config\n";
2997 }
2998 close OUT;
2999}
3000
Steven Rostedtac6974c2011-10-04 09:40:17 -04003001sub chomp_config {
3002 my ($config) = @_;
3003
3004 $config =~ s/CONFIG_//;
3005
3006 return $config;
3007}
3008
Steven Rostedtb9066f62011-07-15 21:25:24 -04003009sub get_depends {
3010 my ($dep) = @_;
3011
Steven Rostedtac6974c2011-10-04 09:40:17 -04003012 my $kconfig = chomp_config $dep;
Steven Rostedtb9066f62011-07-15 21:25:24 -04003013
3014 $dep = $depends{"$kconfig"};
3015
3016 # the dep string we have saves the dependencies as they
3017 # were found, including expressions like ! && ||. We
3018 # want to split this out into just an array of configs.
3019
3020 my $valid = "A-Za-z_0-9";
3021
3022 my @configs;
3023
3024 while ($dep =~ /[$valid]/) {
3025
3026 if ($dep =~ /^[^$valid]*([$valid]+)/) {
3027 my $conf = "CONFIG_" . $1;
3028
3029 $configs[$#configs + 1] = $conf;
3030
3031 $dep =~ s/^[^$valid]*[$valid]+//;
3032 } else {
3033 die "this should never happen";
3034 }
3035 }
3036
3037 return @configs;
3038}
3039
3040my %min_configs;
3041my %keep_configs;
Steven Rostedt43d1b652011-07-15 22:01:56 -04003042my %save_configs;
Steven Rostedtb9066f62011-07-15 21:25:24 -04003043my %processed_configs;
3044my %nochange_config;
3045
3046sub test_this_config {
3047 my ($config) = @_;
3048
3049 my $found;
3050
3051 # if we already processed this config, skip it
3052 if (defined($processed_configs{$config})) {
3053 return undef;
3054 }
3055 $processed_configs{$config} = 1;
3056
3057 # if this config failed during this round, skip it
3058 if (defined($nochange_config{$config})) {
3059 return undef;
3060 }
3061
Steven Rostedtac6974c2011-10-04 09:40:17 -04003062 my $kconfig = chomp_config $config;
Steven Rostedtb9066f62011-07-15 21:25:24 -04003063
3064 # Test dependencies first
3065 if (defined($depends{"$kconfig"})) {
3066 my @parents = get_depends $config;
3067 foreach my $parent (@parents) {
3068 # if the parent is in the min config, check it first
3069 next if (!defined($min_configs{$parent}));
3070 $found = test_this_config($parent);
3071 if (defined($found)) {
3072 return $found;
3073 }
3074 }
3075 }
3076
3077 # Remove this config from the list of configs
3078 # do a make oldnoconfig and then read the resulting
3079 # .config to make sure it is missing the config that
3080 # we had before
3081 my %configs = %min_configs;
3082 delete $configs{$config};
3083 make_new_config ((values %configs), (values %keep_configs));
3084 make_oldconfig;
3085 undef %configs;
3086 assign_configs \%configs, $output_config;
3087
3088 return $config if (!defined($configs{$config}));
3089
3090 doprint "disabling config $config did not change .config\n";
3091
3092 $nochange_config{$config} = 1;
3093
3094 return undef;
3095}
3096
Steven Rostedt4c4ab122011-07-15 21:16:17 -04003097sub make_min_config {
3098 my ($i) = @_;
3099
3100 if (!defined($output_minconfig)) {
3101 fail "OUTPUT_MIN_CONFIG not defined" and return;
3102 }
Steven Rostedt35ce5952011-07-15 21:57:25 -04003103
3104 # If output_minconfig exists, and the start_minconfig
3105 # came from min_config, than ask if we should use
3106 # that instead.
3107 if (-f $output_minconfig && !$start_minconfig_defined) {
3108 print "$output_minconfig exists\n";
3109 if (read_yn " Use it as minconfig?") {
3110 $start_minconfig = $output_minconfig;
3111 }
3112 }
3113
Steven Rostedt4c4ab122011-07-15 21:16:17 -04003114 if (!defined($start_minconfig)) {
3115 fail "START_MIN_CONFIG or MIN_CONFIG not defined" and return;
3116 }
3117
Steven Rostedt35ce5952011-07-15 21:57:25 -04003118 my $temp_config = "$tmpdir/temp_config";
3119
Steven Rostedt4c4ab122011-07-15 21:16:17 -04003120 # First things first. We build an allnoconfig to find
3121 # out what the defaults are that we can't touch.
3122 # Some are selections, but we really can't handle selections.
3123
3124 my $save_minconfig = $minconfig;
3125 undef $minconfig;
3126
3127 run_command "$make allnoconfig" or return 0;
3128
Steven Rostedtb9066f62011-07-15 21:25:24 -04003129 read_depends;
3130
Steven Rostedt4c4ab122011-07-15 21:16:17 -04003131 process_config_ignore $output_config;
Steven Rostedtb9066f62011-07-15 21:25:24 -04003132
Steven Rostedt43d1b652011-07-15 22:01:56 -04003133 undef %save_configs;
Steven Rostedtb9066f62011-07-15 21:25:24 -04003134 undef %min_configs;
Steven Rostedt4c4ab122011-07-15 21:16:17 -04003135
3136 if (defined($ignore_config)) {
3137 # make sure the file exists
3138 `touch $ignore_config`;
Steven Rostedt43d1b652011-07-15 22:01:56 -04003139 assign_configs \%save_configs, $ignore_config;
Steven Rostedt4c4ab122011-07-15 21:16:17 -04003140 }
3141
Steven Rostedt43d1b652011-07-15 22:01:56 -04003142 %keep_configs = %save_configs;
3143
Steven Rostedt4c4ab122011-07-15 21:16:17 -04003144 doprint "Load initial configs from $start_minconfig\n";
3145
3146 # Look at the current min configs, and save off all the
3147 # ones that were set via the allnoconfig
Steven Rostedt4c4ab122011-07-15 21:16:17 -04003148 assign_configs \%min_configs, $start_minconfig;
3149
3150 my @config_keys = keys %min_configs;
3151
Steven Rostedtac6974c2011-10-04 09:40:17 -04003152 # All configs need a depcount
3153 foreach my $config (@config_keys) {
3154 my $kconfig = chomp_config $config;
3155 if (!defined $depcount{$kconfig}) {
3156 $depcount{$kconfig} = 0;
3157 }
3158 }
3159
Steven Rostedt4c4ab122011-07-15 21:16:17 -04003160 # Remove anything that was set by the make allnoconfig
3161 # we shouldn't need them as they get set for us anyway.
3162 foreach my $config (@config_keys) {
3163 # Remove anything in the ignore_config
3164 if (defined($keep_configs{$config})) {
3165 my $file = $ignore_config;
3166 $file =~ s,.*/(.*?)$,$1,;
3167 doprint "$config set by $file ... ignored\n";
3168 delete $min_configs{$config};
3169 next;
3170 }
3171 # But make sure the settings are the same. If a min config
3172 # sets a selection, we do not want to get rid of it if
3173 # it is not the same as what we have. Just move it into
3174 # the keep configs.
3175 if (defined($config_ignore{$config})) {
3176 if ($config_ignore{$config} ne $min_configs{$config}) {
3177 doprint "$config is in allnoconfig as '$config_ignore{$config}'";
3178 doprint " but it is '$min_configs{$config}' in minconfig .. keeping\n";
3179 $keep_configs{$config} = $min_configs{$config};
3180 } else {
3181 doprint "$config set by allnoconfig ... ignored\n";
3182 }
3183 delete $min_configs{$config};
3184 }
3185 }
3186
Steven Rostedt4c4ab122011-07-15 21:16:17 -04003187 my $done = 0;
Steven Rostedtb9066f62011-07-15 21:25:24 -04003188 my $take_two = 0;
Steven Rostedt4c4ab122011-07-15 21:16:17 -04003189
3190 while (!$done) {
3191
3192 my $config;
3193 my $found;
3194
3195 # Now disable each config one by one and do a make oldconfig
3196 # till we find a config that changes our list.
3197
Steven Rostedt4c4ab122011-07-15 21:16:17 -04003198 my @test_configs = keys %min_configs;
Steven Rostedtac6974c2011-10-04 09:40:17 -04003199
3200 # Sort keys by who is most dependent on
3201 @test_configs = sort { $depcount{chomp_config($b)} <=> $depcount{chomp_config($a)} }
3202 @test_configs ;
3203
3204 # Put configs that did not modify the config at the end.
Steven Rostedt4c4ab122011-07-15 21:16:17 -04003205 my $reset = 1;
3206 for (my $i = 0; $i < $#test_configs; $i++) {
3207 if (!defined($nochange_config{$test_configs[0]})) {
3208 $reset = 0;
3209 last;
3210 }
3211 # This config didn't change the .config last time.
3212 # Place it at the end
3213 my $config = shift @test_configs;
3214 push @test_configs, $config;
3215 }
3216
3217 # if every test config has failed to modify the .config file
3218 # in the past, then reset and start over.
3219 if ($reset) {
3220 undef %nochange_config;
3221 }
3222
Steven Rostedtb9066f62011-07-15 21:25:24 -04003223 undef %processed_configs;
3224
Steven Rostedt4c4ab122011-07-15 21:16:17 -04003225 foreach my $config (@test_configs) {
3226
Steven Rostedtb9066f62011-07-15 21:25:24 -04003227 $found = test_this_config $config;
Steven Rostedt4c4ab122011-07-15 21:16:17 -04003228
Steven Rostedtb9066f62011-07-15 21:25:24 -04003229 last if (defined($found));
Steven Rostedt4c4ab122011-07-15 21:16:17 -04003230
3231 # oh well, try another config
Steven Rostedt4c4ab122011-07-15 21:16:17 -04003232 }
3233
3234 if (!defined($found)) {
Steven Rostedtb9066f62011-07-15 21:25:24 -04003235 # we could have failed due to the nochange_config hash
3236 # reset and try again
3237 if (!$take_two) {
3238 undef %nochange_config;
3239 $take_two = 1;
3240 next;
3241 }
Steven Rostedt4c4ab122011-07-15 21:16:17 -04003242 doprint "No more configs found that we can disable\n";
3243 $done = 1;
3244 last;
3245 }
Steven Rostedtb9066f62011-07-15 21:25:24 -04003246 $take_two = 0;
Steven Rostedt4c4ab122011-07-15 21:16:17 -04003247
3248 $config = $found;
3249
3250 doprint "Test with $config disabled\n";
3251
3252 # set in_bisect to keep build and monitor from dieing
3253 $in_bisect = 1;
3254
3255 my $failed = 0;
Steven Rostedtbf1c95a2012-02-27 13:58:49 -05003256 build "oldconfig" or $failed = 1;
3257 if (!$failed) {
3258 start_monitor_and_boot or $failed = 1;
3259 end_monitor;
3260 }
Steven Rostedt4c4ab122011-07-15 21:16:17 -04003261
3262 $in_bisect = 0;
3263
3264 if ($failed) {
Steven Rostedtb9066f62011-07-15 21:25:24 -04003265 doprint "$min_configs{$config} is needed to boot the box... keeping\n";
Steven Rostedt4c4ab122011-07-15 21:16:17 -04003266 # this config is needed, add it to the ignore list.
3267 $keep_configs{$config} = $min_configs{$config};
Steven Rostedt43d1b652011-07-15 22:01:56 -04003268 $save_configs{$config} = $min_configs{$config};
Steven Rostedt4c4ab122011-07-15 21:16:17 -04003269 delete $min_configs{$config};
Steven Rostedt35ce5952011-07-15 21:57:25 -04003270
3271 # update new ignore configs
3272 if (defined($ignore_config)) {
3273 open (OUT, ">$temp_config")
3274 or die "Can't write to $temp_config";
Steven Rostedt43d1b652011-07-15 22:01:56 -04003275 foreach my $config (keys %save_configs) {
3276 print OUT "$save_configs{$config}\n";
Steven Rostedt35ce5952011-07-15 21:57:25 -04003277 }
3278 close OUT;
3279 run_command "mv $temp_config $ignore_config" or
3280 dodie "failed to copy update to $ignore_config";
3281 }
3282
Steven Rostedt4c4ab122011-07-15 21:16:17 -04003283 } else {
3284 # We booted without this config, remove it from the minconfigs.
3285 doprint "$config is not needed, disabling\n";
3286
3287 delete $min_configs{$config};
3288
3289 # Also disable anything that is not enabled in this config
3290 my %configs;
3291 assign_configs \%configs, $output_config;
3292 my @config_keys = keys %min_configs;
3293 foreach my $config (@config_keys) {
3294 if (!defined($configs{$config})) {
3295 doprint "$config is not set, disabling\n";
3296 delete $min_configs{$config};
3297 }
3298 }
3299
3300 # Save off all the current mandidory configs
Steven Rostedt35ce5952011-07-15 21:57:25 -04003301 open (OUT, ">$temp_config")
3302 or die "Can't write to $temp_config";
Steven Rostedt4c4ab122011-07-15 21:16:17 -04003303 foreach my $config (keys %keep_configs) {
3304 print OUT "$keep_configs{$config}\n";
3305 }
3306 foreach my $config (keys %min_configs) {
3307 print OUT "$min_configs{$config}\n";
3308 }
3309 close OUT;
Steven Rostedt35ce5952011-07-15 21:57:25 -04003310
3311 run_command "mv $temp_config $output_minconfig" or
3312 dodie "failed to copy update to $output_minconfig";
Steven Rostedt4c4ab122011-07-15 21:16:17 -04003313 }
3314
3315 doprint "Reboot and wait $sleep_time seconds\n";
Steven Rostedtbc7c5802011-12-22 16:29:10 -05003316 reboot_to_good $sleep_time;
Steven Rostedt4c4ab122011-07-15 21:16:17 -04003317 }
3318
3319 success $i;
3320 return 1;
3321}
3322
Steven Rostedt8d1491b2010-11-18 15:39:48 -05003323$#ARGV < 1 or die "ktest.pl version: $VERSION\n usage: ktest.pl config-file\n";
Steven Rostedt2545eb62010-11-02 15:01:32 -04003324
Steven Rostedt8d1491b2010-11-18 15:39:48 -05003325if ($#ARGV == 0) {
3326 $ktest_config = $ARGV[0];
3327 if (! -f $ktest_config) {
3328 print "$ktest_config does not exist.\n";
Steven Rostedt35ce5952011-07-15 21:57:25 -04003329 if (!read_yn "Create it?") {
Steven Rostedt8d1491b2010-11-18 15:39:48 -05003330 exit 0;
3331 }
3332 }
3333} else {
3334 $ktest_config = "ktest.conf";
3335}
3336
3337if (! -f $ktest_config) {
Steven Rostedtdbd37832011-11-23 16:00:48 -05003338 $newconfig = 1;
Steven Rostedtc4261d02011-11-23 13:41:18 -05003339 get_test_case;
Steven Rostedt8d1491b2010-11-18 15:39:48 -05003340 open(OUT, ">$ktest_config") or die "Can not create $ktest_config";
3341 print OUT << "EOF"
3342# Generated by ktest.pl
3343#
Steven Rostedt0e7a22d2011-11-21 20:39:33 -05003344
3345# PWD is a ktest.pl variable that will result in the process working
3346# directory that ktest.pl is executed in.
3347
3348# THIS_DIR is automatically assigned the PWD of the path that generated
3349# the config file. It is best to use this variable when assigning other
3350# directory paths within this directory. This allows you to easily
3351# move the test cases to other locations or to other machines.
3352#
3353THIS_DIR := $variable{"PWD"}
3354
Steven Rostedt8d1491b2010-11-18 15:39:48 -05003355# Define each test with TEST_START
3356# The config options below it will override the defaults
3357TEST_START
Steven Rostedtc4261d02011-11-23 13:41:18 -05003358TEST_TYPE = $default{"TEST_TYPE"}
Steven Rostedt8d1491b2010-11-18 15:39:48 -05003359
3360DEFAULTS
3361EOF
3362;
3363 close(OUT);
3364}
3365read_config $ktest_config;
3366
Steven Rostedt23715c3c2011-06-13 11:03:34 -04003367if (defined($opt{"LOG_FILE"})) {
3368 $opt{"LOG_FILE"} = eval_option($opt{"LOG_FILE"}, -1);
3369}
3370
Steven Rostedt8d1491b2010-11-18 15:39:48 -05003371# Append any configs entered in manually to the config file.
3372my @new_configs = keys %entered_configs;
3373if ($#new_configs >= 0) {
3374 print "\nAppending entered in configs to $ktest_config\n";
3375 open(OUT, ">>$ktest_config") or die "Can not append to $ktest_config";
3376 foreach my $config (@new_configs) {
3377 print OUT "$config = $entered_configs{$config}\n";
Steven Rostedt0e7a22d2011-11-21 20:39:33 -05003378 $opt{$config} = process_variables($entered_configs{$config});
Steven Rostedt8d1491b2010-11-18 15:39:48 -05003379 }
3380}
Steven Rostedt2545eb62010-11-02 15:01:32 -04003381
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04003382if ($opt{"CLEAR_LOG"} && defined($opt{"LOG_FILE"})) {
3383 unlink $opt{"LOG_FILE"};
3384}
Steven Rostedt2545eb62010-11-02 15:01:32 -04003385
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04003386doprint "\n\nSTARTING AUTOMATED TESTS\n\n";
3387
Steven Rostedta57419b2010-11-02 15:13:54 -04003388for (my $i = 0, my $repeat = 1; $i <= $opt{"NUM_TESTS"}; $i += $repeat) {
3389
3390 if (!$i) {
3391 doprint "DEFAULT OPTIONS:\n";
3392 } else {
3393 doprint "\nTEST $i OPTIONS";
3394 if (defined($repeat_tests{$i})) {
3395 $repeat = $repeat_tests{$i};
3396 doprint " ITERATE $repeat";
3397 }
3398 doprint "\n";
3399 }
3400
3401 foreach my $option (sort keys %opt) {
3402
3403 if ($option =~ /\[(\d+)\]$/) {
3404 next if ($i != $1);
3405 } else {
3406 next if ($i);
3407 }
3408
3409 doprint "$option = $opt{$option}\n";
3410 }
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04003411}
Steven Rostedt2545eb62010-11-02 15:01:32 -04003412
Steven Rostedt2a625122011-05-20 15:48:59 -04003413sub __set_test_option {
Steven Rostedt5a391fb2010-11-02 14:57:43 -04003414 my ($name, $i) = @_;
3415
3416 my $option = "$name\[$i\]";
3417
3418 if (defined($opt{$option})) {
3419 return $opt{$option};
3420 }
3421
Steven Rostedta57419b2010-11-02 15:13:54 -04003422 foreach my $test (keys %repeat_tests) {
3423 if ($i >= $test &&
3424 $i < $test + $repeat_tests{$test}) {
3425 $option = "$name\[$test\]";
3426 if (defined($opt{$option})) {
3427 return $opt{$option};
3428 }
3429 }
3430 }
3431
Steven Rostedt5a391fb2010-11-02 14:57:43 -04003432 if (defined($opt{$name})) {
3433 return $opt{$name};
3434 }
3435
3436 return undef;
3437}
3438
Steven Rostedt2a625122011-05-20 15:48:59 -04003439sub set_test_option {
3440 my ($name, $i) = @_;
3441
3442 my $option = __set_test_option($name, $i);
3443 return $option if (!defined($option));
3444
Steven Rostedt23715c3c2011-06-13 11:03:34 -04003445 return eval_option($option, $i);
Steven Rostedt2a625122011-05-20 15:48:59 -04003446}
3447
Steven Rostedt2545eb62010-11-02 15:01:32 -04003448# First we need to do is the builds
Steven Rostedta75fece2010-11-02 14:58:27 -04003449for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
Steven Rostedt2545eb62010-11-02 15:01:32 -04003450
Steven Rostedt4ab1cce2011-09-30 18:12:20 -04003451 # Do not reboot on failing test options
3452 $no_reboot = 1;
3453
Steven Rostedt576f6272010-11-02 14:58:38 -04003454 $iteration = $i;
3455
Steven Rostedta75fece2010-11-02 14:58:27 -04003456 my $makecmd = set_test_option("MAKE_CMD", $i);
3457
Steven Rostedt9cc9e092011-12-22 21:37:22 -05003458 # Load all the options into their mapped variable names
3459 foreach my $opt (keys %option_map) {
3460 ${$option_map{$opt}} = set_test_option($opt, $i);
3461 }
Steven Rostedtb5f4aea2011-12-22 21:33:55 -05003462
Steven Rostedt35ce5952011-07-15 21:57:25 -04003463 $start_minconfig_defined = 1;
3464
Steven Rostedt4c4ab122011-07-15 21:16:17 -04003465 if (!defined($start_minconfig)) {
Steven Rostedt35ce5952011-07-15 21:57:25 -04003466 $start_minconfig_defined = 0;
Steven Rostedt4c4ab122011-07-15 21:16:17 -04003467 $start_minconfig = $minconfig;
3468 }
3469
Steven Rostedta75fece2010-11-02 14:58:27 -04003470 chdir $builddir || die "can't change directory to $builddir";
3471
Andrew Jonesa908a662011-08-12 15:32:03 +02003472 foreach my $dir ($tmpdir, $outputdir) {
3473 if (!-d $dir) {
3474 mkpath($dir) or
3475 die "can't create $dir";
3476 }
Steven Rostedta75fece2010-11-02 14:58:27 -04003477 }
3478
Steven Rostedte48c5292010-11-02 14:35:37 -04003479 $ENV{"SSH_USER"} = $ssh_user;
3480 $ENV{"MACHINE"} = $machine;
3481
Steven Rostedta75fece2010-11-02 14:58:27 -04003482 $buildlog = "$tmpdir/buildlog-$machine";
Rabin Vincenta9dd5d62011-11-18 17:05:29 +05303483 $testlog = "$tmpdir/testlog-$machine";
Steven Rostedta75fece2010-11-02 14:58:27 -04003484 $dmesg = "$tmpdir/dmesg-$machine";
3485 $make = "$makecmd O=$outputdir";
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05003486 $output_config = "$outputdir/.config";
Steven Rostedta75fece2010-11-02 14:58:27 -04003487
Steven Rostedtbb8474b2011-11-23 15:58:00 -05003488 if (!$buildonly) {
3489 $target = "$ssh_user\@$machine";
3490 if ($reboot_type eq "grub") {
3491 dodie "GRUB_MENU not defined" if (!defined($grub_menu));
Steven Rostedtbb8474b2011-11-23 15:58:00 -05003492 }
Steven Rostedta75fece2010-11-02 14:58:27 -04003493 }
3494
3495 my $run_type = $build_type;
3496 if ($test_type eq "patchcheck") {
Steven Rostedtb5f4aea2011-12-22 21:33:55 -05003497 $run_type = $patchcheck_type;
Steven Rostedta75fece2010-11-02 14:58:27 -04003498 } elsif ($test_type eq "bisect") {
Steven Rostedtb5f4aea2011-12-22 21:33:55 -05003499 $run_type = $bisect_type;
Steven Rostedt0a05c762010-11-08 11:14:10 -05003500 } elsif ($test_type eq "config_bisect") {
Steven Rostedtb5f4aea2011-12-22 21:33:55 -05003501 $run_type = $config_bisect_type;
Steven Rostedta75fece2010-11-02 14:58:27 -04003502 }
3503
Steven Rostedt4c4ab122011-07-15 21:16:17 -04003504 if ($test_type eq "make_min_config") {
3505 $run_type = "";
3506 }
3507
Steven Rostedta75fece2010-11-02 14:58:27 -04003508 # mistake in config file?
3509 if (!defined($run_type)) {
3510 $run_type = "ERROR";
3511 }
Steven Rostedt2545eb62010-11-02 15:01:32 -04003512
Steven Rostedte0a87422011-09-30 17:50:48 -04003513 my $installme = "";
3514 $installme = " no_install" if ($no_install);
3515
Steven Rostedt2545eb62010-11-02 15:01:32 -04003516 doprint "\n\n";
Steven Rostedte0a87422011-09-30 17:50:48 -04003517 doprint "RUNNING TEST $i of $opt{NUM_TESTS} with option $test_type $run_type$installme\n\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -04003518
3519 unlink $dmesg;
3520 unlink $buildlog;
Rabin Vincenta9dd5d62011-11-18 17:05:29 +05303521 unlink $testlog;
Steven Rostedt2545eb62010-11-02 15:01:32 -04003522
Steven Rostedt250bae82011-07-15 22:05:59 -04003523 if (defined($addconfig)) {
3524 my $min = $minconfig;
3525 if (!defined($minconfig)) {
3526 $min = "";
3527 }
3528 run_command "cat $addconfig $min > $tmpdir/add_config" or
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04003529 dodie "Failed to create temp config";
Steven Rostedt9be2e6b2010-11-09 12:20:21 -05003530 $minconfig = "$tmpdir/add_config";
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04003531 }
3532
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04003533 if (defined($checkout)) {
3534 run_command "git checkout $checkout" or
3535 die "failed to checkout $checkout";
3536 }
3537
Steven Rostedt4ab1cce2011-09-30 18:12:20 -04003538 $no_reboot = 0;
3539
3540
Steven Rostedta75fece2010-11-02 14:58:27 -04003541 if ($test_type eq "bisect") {
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04003542 bisect $i;
3543 next;
Steven Rostedt0a05c762010-11-08 11:14:10 -05003544 } elsif ($test_type eq "config_bisect") {
3545 config_bisect $i;
3546 next;
Steven Rostedta75fece2010-11-02 14:58:27 -04003547 } elsif ($test_type eq "patchcheck") {
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04003548 patchcheck $i;
3549 next;
Steven Rostedt4c4ab122011-07-15 21:16:17 -04003550 } elsif ($test_type eq "make_min_config") {
3551 make_min_config $i;
3552 next;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04003553 }
3554
Steven Rostedt7faafbd2010-11-02 14:58:22 -04003555 if ($build_type ne "nobuild") {
3556 build $build_type or next;
Steven Rostedt2545eb62010-11-02 15:01:32 -04003557 }
3558
Steven Rostedtcd8e3682011-08-18 16:35:44 -04003559 if ($test_type eq "install") {
3560 get_version;
3561 install;
3562 success $i;
3563 next;
3564 }
3565
Steven Rostedta75fece2010-11-02 14:58:27 -04003566 if ($test_type ne "build") {
Steven Rostedta75fece2010-11-02 14:58:27 -04003567 my $failed = 0;
Steven Rostedtddf607e2011-06-14 20:49:13 -04003568 start_monitor_and_boot or $failed = 1;
Steven Rostedta75fece2010-11-02 14:58:27 -04003569
3570 if (!$failed && $test_type ne "boot" && defined($run_test)) {
3571 do_run_test or $failed = 1;
3572 }
3573 end_monitor;
3574 next if ($failed);
Steven Rostedt5a391fb2010-11-02 14:57:43 -04003575 }
3576
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04003577 success $i;
Steven Rostedt2545eb62010-11-02 15:01:32 -04003578}
3579
Steven Rostedt5c42fc52010-11-02 14:57:01 -04003580if ($opt{"POWEROFF_ON_SUCCESS"}) {
Steven Rostedt75c3fda72010-11-02 14:57:21 -04003581 halt;
Steven Rostedt576f6272010-11-02 14:58:38 -04003582} elsif ($opt{"REBOOT_ON_SUCCESS"} && !do_not_reboot) {
Steven Rostedtbc7c5802011-12-22 16:29:10 -05003583 reboot_to_good;
Steven Rostedt5c42fc52010-11-02 14:57:01 -04003584}
Steven Rostedt75c3fda72010-11-02 14:57:21 -04003585
Steven Rostedte48c5292010-11-02 14:35:37 -04003586doprint "\n $successes of $opt{NUM_TESTS} tests were successful\n\n";
3587
Steven Rostedt2545eb62010-11-02 15:01:32 -04003588exit 0;