Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/tools/testing/ktest/ktest.pl
26292 views
1
#!/usr/bin/perl -w
2
# SPDX-License-Identifier: GPL-2.0-only
3
#
4
# Copyright 2010 - Steven Rostedt <[email protected]>, Red Hat Inc.
5
#
6
7
use strict;
8
use IPC::Open2;
9
use Fcntl qw(F_GETFL F_SETFL O_NONBLOCK);
10
use File::Path qw(mkpath);
11
use File::Copy qw(cp);
12
use FileHandle;
13
use FindBin;
14
use IO::Handle;
15
16
my $VERSION = "0.2";
17
18
$| = 1;
19
20
my %opt;
21
my %repeat_tests;
22
my %repeats;
23
my %evals;
24
my @command_vars;
25
my %command_tmp_vars;
26
27
#default opts
28
my %default = (
29
"MAILER" => "sendmail", # default mailer
30
"EMAIL_ON_ERROR" => 1,
31
"EMAIL_WHEN_FINISHED" => 1,
32
"EMAIL_WHEN_CANCELED" => 0,
33
"EMAIL_WHEN_STARTED" => 0,
34
"NUM_TESTS" => 1,
35
"TEST_TYPE" => "build",
36
"BUILD_TYPE" => "oldconfig",
37
"MAKE_CMD" => "make",
38
"CLOSE_CONSOLE_SIGNAL" => "INT",
39
"TIMEOUT" => 120,
40
"TMP_DIR" => "/tmp/ktest/\${MACHINE}",
41
"SLEEP_TIME" => 60, # sleep time between tests
42
"BUILD_NOCLEAN" => 0,
43
"REBOOT_ON_ERROR" => 0,
44
"POWEROFF_ON_ERROR" => 0,
45
"REBOOT_ON_SUCCESS" => 1,
46
"POWEROFF_ON_SUCCESS" => 0,
47
"BUILD_OPTIONS" => "",
48
"BISECT_SLEEP_TIME" => 60, # sleep time between bisects
49
"PATCHCHECK_SLEEP_TIME" => 60, # sleep time between patch checks
50
"CLEAR_LOG" => 0,
51
"BISECT_MANUAL" => 0,
52
"BISECT_SKIP" => 1,
53
"BISECT_TRIES" => 1,
54
"MIN_CONFIG_TYPE" => "boot",
55
"SUCCESS_LINE" => "login:",
56
"DETECT_TRIPLE_FAULT" => 1,
57
"NO_INSTALL" => 0,
58
"BOOTED_TIMEOUT" => 1,
59
"DIE_ON_FAILURE" => 1,
60
"SSH_EXEC" => "ssh \$SSH_USER\@\$MACHINE \$SSH_COMMAND",
61
"SCP_TO_TARGET" => "scp \$SRC_FILE \$SSH_USER\@\$MACHINE:\$DST_FILE",
62
"SCP_TO_TARGET_INSTALL" => "\${SCP_TO_TARGET}",
63
"REBOOT" => "ssh \$SSH_USER\@\$MACHINE reboot",
64
"REBOOT_RETURN_CODE" => 255,
65
"STOP_AFTER_SUCCESS" => 10,
66
"STOP_AFTER_FAILURE" => 60,
67
"STOP_TEST_AFTER" => 600,
68
"MAX_MONITOR_WAIT" => 1800,
69
"GRUB_REBOOT" => "grub2-reboot",
70
"GRUB_BLS_GET" => "grubby --info=ALL",
71
"SYSLINUX" => "extlinux",
72
"SYSLINUX_PATH" => "/boot/extlinux",
73
"CONNECT_TIMEOUT" => 25,
74
75
# required, and we will ask users if they don't have them but we keep the default
76
# value something that is common.
77
"REBOOT_TYPE" => "grub",
78
"LOCALVERSION" => "-test",
79
"SSH_USER" => "root",
80
"BUILD_TARGET" => "arch/x86/boot/bzImage",
81
"TARGET_IMAGE" => "/boot/vmlinuz-test",
82
83
"LOG_FILE" => undef,
84
"IGNORE_UNUSED" => 0,
85
);
86
87
my $test_log_start = 0;
88
89
my $ktest_config = "ktest.conf";
90
my $version;
91
my $have_version = 0;
92
my $machine;
93
my $last_machine;
94
my $ssh_user;
95
my $tmpdir;
96
my $builddir;
97
my $outputdir;
98
my $output_config;
99
my $test_type;
100
my $build_type;
101
my $build_options;
102
my $final_post_ktest;
103
my $pre_ktest;
104
my $post_ktest;
105
my $pre_test;
106
my $pre_test_die;
107
my $post_test;
108
my $pre_build;
109
my $post_build;
110
my $pre_build_die;
111
my $post_build_die;
112
my $reboot_type;
113
my $reboot_script;
114
my $power_cycle;
115
my $reboot;
116
my $reboot_return_code;
117
my $reboot_on_error;
118
my $switch_to_good;
119
my $switch_to_test;
120
my $poweroff_on_error;
121
my $reboot_on_success;
122
my $die_on_failure;
123
my $powercycle_after_reboot;
124
my $poweroff_after_halt;
125
my $max_monitor_wait;
126
my $ssh_exec;
127
my $scp_to_target;
128
my $scp_to_target_install;
129
my $power_off;
130
my $grub_menu;
131
my $last_grub_menu;
132
my $grub_file;
133
my $grub_number;
134
my $grub_reboot;
135
my $grub_bls_get;
136
my $syslinux;
137
my $syslinux_path;
138
my $syslinux_label;
139
my $target;
140
my $make;
141
my $pre_install;
142
my $post_install;
143
my $no_install;
144
my $noclean;
145
my $minconfig;
146
my $start_minconfig;
147
my $start_minconfig_defined;
148
my $output_minconfig;
149
my $minconfig_type;
150
my $use_output_minconfig;
151
my $warnings_file;
152
my $ignore_config;
153
my $ignore_errors;
154
my $addconfig;
155
my $in_bisect = 0;
156
my $bisect_bad_commit = "";
157
my $reverse_bisect;
158
my $bisect_manual;
159
my $bisect_skip;
160
my $bisect_tries;
161
my $config_bisect_good;
162
my $bisect_ret_good;
163
my $bisect_ret_bad;
164
my $bisect_ret_skip;
165
my $bisect_ret_abort;
166
my $bisect_ret_default;
167
my $in_patchcheck = 0;
168
my $run_test;
169
my $buildlog;
170
my $testlog;
171
my $dmesg;
172
my $monitor_fp;
173
my $monitor_pid;
174
my $monitor_cnt = 0;
175
my $sleep_time;
176
my $bisect_sleep_time;
177
my $patchcheck_sleep_time;
178
my $ignore_warnings;
179
my $store_failures;
180
my $store_successes;
181
my $test_name;
182
my $timeout;
183
my $run_timeout;
184
my $connect_timeout;
185
my $config_bisect_exec;
186
my $booted_timeout;
187
my $detect_triplefault;
188
my $console;
189
my $close_console_signal;
190
my $reboot_success_line;
191
my $success_line;
192
my $stop_after_success;
193
my $stop_after_failure;
194
my $stop_test_after;
195
my $build_target;
196
my $target_image;
197
my $checkout;
198
my $localversion;
199
my $iteration = 0;
200
my $successes = 0;
201
my $stty_orig;
202
my $run_command_status = 0;
203
204
my $bisect_good;
205
my $bisect_bad;
206
my $bisect_type;
207
my $bisect_start;
208
my $bisect_replay;
209
my $bisect_files;
210
my $bisect_reverse;
211
my $bisect_check;
212
213
my $config_bisect;
214
my $config_bisect_type;
215
my $config_bisect_check;
216
217
my $patchcheck_type;
218
my $patchcheck_start;
219
my $patchcheck_cherry;
220
my $patchcheck_end;
221
my $patchcheck_skip;
222
223
my $build_time;
224
my $install_time;
225
my $reboot_time;
226
my $test_time;
227
228
my $warning_found = 0;
229
230
my $pwd;
231
my $dirname = $FindBin::Bin;
232
233
my $mailto;
234
my $mailer;
235
my $mail_path;
236
my $mail_max_size;
237
my $mail_command;
238
my $email_on_error;
239
my $email_when_finished;
240
my $email_when_started;
241
my $email_when_canceled;
242
243
my $script_start_time = localtime();
244
245
# set when a test is something other that just building or install
246
# which would require more options.
247
my $buildonly = 1;
248
249
# tell build not to worry about warnings, even when WARNINGS_FILE is set
250
my $warnings_ok = 0;
251
252
# set when creating a new config
253
my $newconfig = 0;
254
255
my %entered_configs;
256
my %config_help;
257
my %variable;
258
259
# force_config is the list of configs that we force enabled (or disabled)
260
# in a .config file. The MIN_CONFIG and ADD_CONFIG configs.
261
my %force_config;
262
263
# do not force reboots on config problems
264
my $no_reboot = 1;
265
266
# reboot on success
267
my $reboot_success = 0;
268
269
my %option_map = (
270
"MAILTO" => \$mailto,
271
"MAILER" => \$mailer,
272
"MAIL_PATH" => \$mail_path,
273
"MAIL_MAX_SIZE" => \$mail_max_size,
274
"MAIL_COMMAND" => \$mail_command,
275
"EMAIL_ON_ERROR" => \$email_on_error,
276
"EMAIL_WHEN_FINISHED" => \$email_when_finished,
277
"EMAIL_WHEN_STARTED" => \$email_when_started,
278
"EMAIL_WHEN_CANCELED" => \$email_when_canceled,
279
"MACHINE" => \$machine,
280
"SSH_USER" => \$ssh_user,
281
"TMP_DIR" => \$tmpdir,
282
"OUTPUT_DIR" => \$outputdir,
283
"BUILD_DIR" => \$builddir,
284
"TEST_TYPE" => \$test_type,
285
"PRE_KTEST" => \$pre_ktest,
286
"POST_KTEST" => \$post_ktest,
287
"PRE_TEST" => \$pre_test,
288
"PRE_TEST_DIE" => \$pre_test_die,
289
"POST_TEST" => \$post_test,
290
"BUILD_TYPE" => \$build_type,
291
"BUILD_OPTIONS" => \$build_options,
292
"PRE_BUILD" => \$pre_build,
293
"POST_BUILD" => \$post_build,
294
"PRE_BUILD_DIE" => \$pre_build_die,
295
"POST_BUILD_DIE" => \$post_build_die,
296
"POWER_CYCLE" => \$power_cycle,
297
"REBOOT" => \$reboot,
298
"REBOOT_RETURN_CODE" => \$reboot_return_code,
299
"BUILD_NOCLEAN" => \$noclean,
300
"MIN_CONFIG" => \$minconfig,
301
"OUTPUT_MIN_CONFIG" => \$output_minconfig,
302
"START_MIN_CONFIG" => \$start_minconfig,
303
"MIN_CONFIG_TYPE" => \$minconfig_type,
304
"USE_OUTPUT_MIN_CONFIG" => \$use_output_minconfig,
305
"WARNINGS_FILE" => \$warnings_file,
306
"IGNORE_CONFIG" => \$ignore_config,
307
"TEST" => \$run_test,
308
"ADD_CONFIG" => \$addconfig,
309
"REBOOT_TYPE" => \$reboot_type,
310
"GRUB_MENU" => \$grub_menu,
311
"GRUB_FILE" => \$grub_file,
312
"GRUB_REBOOT" => \$grub_reboot,
313
"GRUB_BLS_GET" => \$grub_bls_get,
314
"SYSLINUX" => \$syslinux,
315
"SYSLINUX_PATH" => \$syslinux_path,
316
"SYSLINUX_LABEL" => \$syslinux_label,
317
"PRE_INSTALL" => \$pre_install,
318
"POST_INSTALL" => \$post_install,
319
"NO_INSTALL" => \$no_install,
320
"REBOOT_SCRIPT" => \$reboot_script,
321
"REBOOT_ON_ERROR" => \$reboot_on_error,
322
"SWITCH_TO_GOOD" => \$switch_to_good,
323
"SWITCH_TO_TEST" => \$switch_to_test,
324
"POWEROFF_ON_ERROR" => \$poweroff_on_error,
325
"REBOOT_ON_SUCCESS" => \$reboot_on_success,
326
"DIE_ON_FAILURE" => \$die_on_failure,
327
"POWER_OFF" => \$power_off,
328
"POWERCYCLE_AFTER_REBOOT" => \$powercycle_after_reboot,
329
"POWEROFF_AFTER_HALT" => \$poweroff_after_halt,
330
"MAX_MONITOR_WAIT" => \$max_monitor_wait,
331
"SLEEP_TIME" => \$sleep_time,
332
"BISECT_SLEEP_TIME" => \$bisect_sleep_time,
333
"PATCHCHECK_SLEEP_TIME" => \$patchcheck_sleep_time,
334
"IGNORE_WARNINGS" => \$ignore_warnings,
335
"IGNORE_ERRORS" => \$ignore_errors,
336
"BISECT_MANUAL" => \$bisect_manual,
337
"BISECT_SKIP" => \$bisect_skip,
338
"BISECT_TRIES" => \$bisect_tries,
339
"CONFIG_BISECT_GOOD" => \$config_bisect_good,
340
"BISECT_RET_GOOD" => \$bisect_ret_good,
341
"BISECT_RET_BAD" => \$bisect_ret_bad,
342
"BISECT_RET_SKIP" => \$bisect_ret_skip,
343
"BISECT_RET_ABORT" => \$bisect_ret_abort,
344
"BISECT_RET_DEFAULT" => \$bisect_ret_default,
345
"STORE_FAILURES" => \$store_failures,
346
"STORE_SUCCESSES" => \$store_successes,
347
"TEST_NAME" => \$test_name,
348
"TIMEOUT" => \$timeout,
349
"RUN_TIMEOUT" => \$run_timeout,
350
"CONNECT_TIMEOUT" => \$connect_timeout,
351
"CONFIG_BISECT_EXEC" => \$config_bisect_exec,
352
"BOOTED_TIMEOUT" => \$booted_timeout,
353
"CONSOLE" => \$console,
354
"CLOSE_CONSOLE_SIGNAL" => \$close_console_signal,
355
"DETECT_TRIPLE_FAULT" => \$detect_triplefault,
356
"SUCCESS_LINE" => \$success_line,
357
"REBOOT_SUCCESS_LINE" => \$reboot_success_line,
358
"STOP_AFTER_SUCCESS" => \$stop_after_success,
359
"STOP_AFTER_FAILURE" => \$stop_after_failure,
360
"STOP_TEST_AFTER" => \$stop_test_after,
361
"BUILD_TARGET" => \$build_target,
362
"SSH_EXEC" => \$ssh_exec,
363
"SCP_TO_TARGET" => \$scp_to_target,
364
"SCP_TO_TARGET_INSTALL" => \$scp_to_target_install,
365
"CHECKOUT" => \$checkout,
366
"TARGET_IMAGE" => \$target_image,
367
"LOCALVERSION" => \$localversion,
368
369
"BISECT_GOOD" => \$bisect_good,
370
"BISECT_BAD" => \$bisect_bad,
371
"BISECT_TYPE" => \$bisect_type,
372
"BISECT_START" => \$bisect_start,
373
"BISECT_REPLAY" => \$bisect_replay,
374
"BISECT_FILES" => \$bisect_files,
375
"BISECT_REVERSE" => \$bisect_reverse,
376
"BISECT_CHECK" => \$bisect_check,
377
378
"CONFIG_BISECT" => \$config_bisect,
379
"CONFIG_BISECT_TYPE" => \$config_bisect_type,
380
"CONFIG_BISECT_CHECK" => \$config_bisect_check,
381
382
"PATCHCHECK_TYPE" => \$patchcheck_type,
383
"PATCHCHECK_START" => \$patchcheck_start,
384
"PATCHCHECK_CHERRY" => \$patchcheck_cherry,
385
"PATCHCHECK_END" => \$patchcheck_end,
386
"PATCHCHECK_SKIP" => \$patchcheck_skip,
387
);
388
389
# Options may be used by other options, record them.
390
my %used_options;
391
392
# default variables that can be used
393
chomp ($variable{"PWD"} = `pwd`);
394
$pwd = $variable{"PWD"};
395
396
$config_help{"MACHINE"} = << "EOF"
397
The machine hostname that you will test.
398
For build only tests, it is still needed to differentiate log files.
399
EOF
400
;
401
$config_help{"SSH_USER"} = << "EOF"
402
The box is expected to have ssh on normal bootup, provide the user
403
(most likely root, since you need privileged operations)
404
EOF
405
;
406
$config_help{"BUILD_DIR"} = << "EOF"
407
The directory that contains the Linux source code (full path).
408
You can use \${PWD} that will be the path where ktest.pl is run, or use
409
\${THIS_DIR} which is assigned \${PWD} but may be changed later.
410
EOF
411
;
412
$config_help{"OUTPUT_DIR"} = << "EOF"
413
The directory that the objects will be built (full path).
414
(can not be same as BUILD_DIR)
415
You can use \${PWD} that will be the path where ktest.pl is run, or use
416
\${THIS_DIR} which is assigned \${PWD} but may be changed later.
417
EOF
418
;
419
$config_help{"BUILD_TARGET"} = << "EOF"
420
The location of the compiled file to copy to the target.
421
(relative to OUTPUT_DIR)
422
EOF
423
;
424
$config_help{"BUILD_OPTIONS"} = << "EOF"
425
Options to add to \"make\" when building.
426
i.e. -j20
427
EOF
428
;
429
$config_help{"TARGET_IMAGE"} = << "EOF"
430
The place to put your image on the test machine.
431
EOF
432
;
433
$config_help{"POWER_CYCLE"} = << "EOF"
434
A script or command to reboot the box.
435
436
Here is a digital loggers power switch example
437
POWER_CYCLE = wget --no-proxy -O /dev/null -q --auth-no-challenge 'http://admin:admin\@power/outlet?5=CCL'
438
439
Here is an example to reboot a virtual box on the current host
440
with the name "Guest".
441
POWER_CYCLE = virsh destroy Guest; sleep 5; virsh start Guest
442
EOF
443
;
444
$config_help{"CONSOLE"} = << "EOF"
445
The script or command that reads the console
446
447
If you use ttywatch server, something like the following would work.
448
CONSOLE = nc -d localhost 3001
449
450
For a virtual machine with guest name "Guest".
451
CONSOLE = virsh console Guest
452
EOF
453
;
454
$config_help{"LOCALVERSION"} = << "EOF"
455
Required version ending to differentiate the test
456
from other linux builds on the system.
457
EOF
458
;
459
$config_help{"REBOOT_TYPE"} = << "EOF"
460
Way to reboot the box to the test kernel.
461
Only valid options so far are "grub", "grub2", "grub2bls", "syslinux", and "script".
462
463
If you specify grub, it will assume grub version 1
464
and will search in /boot/grub/menu.lst for the title \$GRUB_MENU
465
and select that target to reboot to the kernel. If this is not
466
your setup, then specify "script" and have a command or script
467
specified in REBOOT_SCRIPT to boot to the target.
468
469
The entry in /boot/grub/menu.lst must be entered in manually.
470
The test will not modify that file.
471
472
If you specify grub2, then you also need to specify both \$GRUB_MENU
473
and \$GRUB_FILE.
474
475
If you specify grub2bls, then you also need to specify \$GRUB_MENU.
476
477
If you specify syslinux, then you may use SYSLINUX to define the syslinux
478
command (defaults to extlinux), and SYSLINUX_PATH to specify the path to
479
the syslinux install (defaults to /boot/extlinux). But you have to specify
480
SYSLINUX_LABEL to define the label to boot to for the test kernel.
481
EOF
482
;
483
$config_help{"GRUB_MENU"} = << "EOF"
484
The grub title name for the test kernel to boot
485
(Only mandatory if REBOOT_TYPE = grub or grub2)
486
487
Note, ktest.pl will not update the grub menu.lst, you need to
488
manually add an option for the test. ktest.pl will search
489
the grub menu.lst for this option to find what kernel to
490
reboot into.
491
492
For example, if in the /boot/grub/menu.lst the test kernel title has:
493
title Test Kernel
494
kernel vmlinuz-test
495
GRUB_MENU = Test Kernel
496
497
For grub2, a search of \$GRUB_FILE is performed for the lines
498
that begin with "menuentry". It will not detect submenus. The
499
menu must be a non-nested menu. Add the quotes used in the menu
500
to guarantee your selection, as the first menuentry with the content
501
of \$GRUB_MENU that is found will be used.
502
503
For grub2bls, \$GRUB_MENU is searched on the result of \$GRUB_BLS_GET
504
command for the lines that begin with "title".
505
EOF
506
;
507
$config_help{"GRUB_FILE"} = << "EOF"
508
If grub2 is used, the full path for the grub.cfg file is placed
509
here. Use something like /boot/grub2/grub.cfg to search.
510
EOF
511
;
512
$config_help{"SYSLINUX_LABEL"} = << "EOF"
513
If syslinux is used, the label that boots the target kernel must
514
be specified with SYSLINUX_LABEL.
515
EOF
516
;
517
$config_help{"REBOOT_SCRIPT"} = << "EOF"
518
A script to reboot the target into the test kernel
519
(Only mandatory if REBOOT_TYPE = script)
520
EOF
521
;
522
523
# used with process_expression()
524
my $d = 0;
525
526
# defined before get_test_name()
527
my $in_die = 0;
528
529
# defined before process_warning_line()
530
my $check_build_re = ".*:.*(warning|error|Error):.*";
531
my $utf8_quote = "\\x{e2}\\x{80}(\\x{98}|\\x{99})";
532
533
# defined before child_finished()
534
my $child_done;
535
536
# config_ignore holds the configs that were set (or unset) for
537
# a good config and we will ignore these configs for the rest
538
# of a config bisect. These configs stay as they were.
539
my %config_ignore;
540
541
# config_set holds what all configs were set as.
542
my %config_set;
543
544
# config_off holds the set of configs that the bad config had disabled.
545
# We need to record them and set them in the .config when running
546
# olddefconfig, because olddefconfig keeps the defaults.
547
my %config_off;
548
549
# config_off_tmp holds a set of configs to turn off for now
550
my @config_off_tmp;
551
552
# config_list is the set of configs that are being tested
553
my %config_list;
554
my %null_config;
555
556
my %dependency;
557
558
# found above run_config_bisect()
559
my $pass = 1;
560
561
# found above add_dep()
562
563
my %depends;
564
my %depcount;
565
my $iflevel = 0;
566
my @ifdeps;
567
568
# prevent recursion
569
my %read_kconfigs;
570
571
# found above test_this_config()
572
my %min_configs;
573
my %keep_configs;
574
my %save_configs;
575
my %processed_configs;
576
my %nochange_config;
577
578
#
579
# These are first defined here, main function later on
580
#
581
sub run_command;
582
sub start_monitor;
583
sub end_monitor;
584
sub wait_for_monitor;
585
586
sub _logit {
587
if (defined($opt{"LOG_FILE"})) {
588
print LOG @_;
589
}
590
}
591
592
sub logit {
593
if (defined($opt{"LOG_FILE"})) {
594
_logit @_;
595
} else {
596
print @_;
597
}
598
}
599
600
sub doprint {
601
print @_;
602
_logit @_;
603
}
604
605
sub read_prompt {
606
my ($cancel, $prompt) = @_;
607
608
my $ans;
609
610
for (;;) {
611
if ($cancel) {
612
print "$prompt [y/n/C] ";
613
} else {
614
print "$prompt [Y/n] ";
615
}
616
$ans = <STDIN>;
617
chomp $ans;
618
if ($ans =~ /^\s*$/) {
619
if ($cancel) {
620
$ans = "c";
621
} else {
622
$ans = "y";
623
}
624
}
625
last if ($ans =~ /^y$/i || $ans =~ /^n$/i);
626
if ($cancel) {
627
last if ($ans =~ /^c$/i);
628
print "Please answer either 'y', 'n' or 'c'.\n";
629
} else {
630
print "Please answer either 'y' or 'n'.\n";
631
}
632
}
633
if ($ans =~ /^c/i) {
634
exit;
635
}
636
if ($ans !~ /^y$/i) {
637
return 0;
638
}
639
return 1;
640
}
641
642
sub read_yn {
643
my ($prompt) = @_;
644
645
return read_prompt 0, $prompt;
646
}
647
648
sub read_ync {
649
my ($prompt) = @_;
650
651
return read_prompt 1, $prompt;
652
}
653
654
sub get_mandatory_config {
655
my ($config) = @_;
656
my $ans;
657
658
return if (defined($opt{$config}));
659
660
if (defined($config_help{$config})) {
661
print "\n";
662
print $config_help{$config};
663
}
664
665
for (;;) {
666
print "$config = ";
667
if (defined($default{$config}) && length($default{$config})) {
668
print "\[$default{$config}\] ";
669
}
670
$ans = <STDIN>;
671
$ans =~ s/^\s*(.*\S)\s*$/$1/;
672
if ($ans =~ /^\s*$/) {
673
if ($default{$config}) {
674
$ans = $default{$config};
675
} else {
676
print "Your answer can not be blank\n";
677
next;
678
}
679
}
680
$entered_configs{$config} = ${ans};
681
last;
682
}
683
}
684
685
sub show_time {
686
my ($time) = @_;
687
688
my $hours = 0;
689
my $minutes = 0;
690
691
if ($time > 3600) {
692
$hours = int($time / 3600);
693
$time -= $hours * 3600;
694
}
695
if ($time > 60) {
696
$minutes = int($time / 60);
697
$time -= $minutes * 60;
698
}
699
700
if ($hours > 0) {
701
doprint "$hours hour";
702
doprint "s" if ($hours > 1);
703
doprint " ";
704
}
705
706
if ($minutes > 0) {
707
doprint "$minutes minute";
708
doprint "s" if ($minutes > 1);
709
doprint " ";
710
}
711
712
doprint "$time second";
713
doprint "s" if ($time != 1);
714
}
715
716
sub print_times {
717
doprint "\n";
718
if ($build_time) {
719
doprint "Build time: ";
720
show_time($build_time);
721
doprint "\n";
722
}
723
if ($install_time) {
724
doprint "Install time: ";
725
show_time($install_time);
726
doprint "\n";
727
}
728
if ($reboot_time) {
729
doprint "Reboot time: ";
730
show_time($reboot_time);
731
doprint "\n";
732
}
733
if ($test_time) {
734
doprint "Test time: ";
735
show_time($test_time);
736
doprint "\n";
737
}
738
if ($warning_found) {
739
doprint "\n*** WARNING";
740
doprint "S" if ($warning_found > 1);
741
doprint " found in build: $warning_found ***\n\n";
742
}
743
744
# reset for iterations like bisect
745
$build_time = 0;
746
$install_time = 0;
747
$reboot_time = 0;
748
$test_time = 0;
749
$warning_found = 0;
750
}
751
752
sub get_mandatory_configs {
753
get_mandatory_config("MACHINE");
754
get_mandatory_config("BUILD_DIR");
755
get_mandatory_config("OUTPUT_DIR");
756
757
if ($newconfig) {
758
get_mandatory_config("BUILD_OPTIONS");
759
}
760
761
# options required for other than just building a kernel
762
if (!$buildonly) {
763
get_mandatory_config("POWER_CYCLE");
764
get_mandatory_config("CONSOLE");
765
}
766
767
# options required for install and more
768
if ($buildonly != 1) {
769
get_mandatory_config("SSH_USER");
770
get_mandatory_config("BUILD_TARGET");
771
get_mandatory_config("TARGET_IMAGE");
772
}
773
774
get_mandatory_config("LOCALVERSION");
775
776
return if ($buildonly);
777
778
my $rtype = $opt{"REBOOT_TYPE"};
779
780
if (!defined($rtype)) {
781
if (!defined($opt{"GRUB_MENU"})) {
782
get_mandatory_config("REBOOT_TYPE");
783
$rtype = $entered_configs{"REBOOT_TYPE"};
784
} else {
785
$rtype = "grub";
786
}
787
}
788
789
if (($rtype eq "grub") or ($rtype eq "grub2bls")) {
790
get_mandatory_config("GRUB_MENU");
791
}
792
793
if ($rtype eq "grub2") {
794
get_mandatory_config("GRUB_MENU");
795
get_mandatory_config("GRUB_FILE");
796
}
797
798
if ($rtype eq "syslinux") {
799
get_mandatory_config("SYSLINUX_LABEL");
800
}
801
}
802
803
sub process_variables {
804
my ($value, $remove_undef) = @_;
805
my $retval = "";
806
807
# We want to check for '\', and it is just easier
808
# to check the previous character of '$' and not need
809
# to worry if '$' is the first character. By adding
810
# a space to $value, we can just check [^\\]\$ and
811
# it will still work.
812
$value = " $value";
813
814
while ($value =~ /(.*?[^\\])\$\{([^\{]*?)\}(.*)/) {
815
my $begin = $1;
816
my $var = $2;
817
my $end = $3;
818
# append beginning of value to retval
819
$retval = "$retval$begin";
820
if ($var =~ s/^shell\s+//) {
821
$retval = `$var`;
822
if ($?) {
823
doprint "WARNING: $var returned an error\n";
824
} else {
825
chomp $retval;
826
}
827
} elsif (defined($variable{$var})) {
828
$retval = "$retval$variable{$var}";
829
} elsif (defined($remove_undef) && $remove_undef) {
830
# for if statements, any variable that is not defined,
831
# we simple convert to 0
832
$retval = "${retval}0";
833
} else {
834
# put back the origin piece, but with $#### to not reprocess it
835
$retval = "$retval\$####\{$var\}";
836
# This could be an option that is used later, save
837
# it so we don't warn if this option is not one of
838
# ktests options.
839
$used_options{$var} = 1;
840
}
841
$value = "$retval$end";
842
$retval = "";
843
}
844
$retval = $value;
845
846
# Convert the saved variables with $####{var} back to ${var}
847
$retval =~ s/\$####/\$/g;
848
849
# remove the space added in the beginning
850
$retval =~ s/ //;
851
852
return "$retval";
853
}
854
855
sub set_value {
856
my ($lvalue, $rvalue, $override, $overrides, $name) = @_;
857
858
my $prvalue = process_variables($rvalue);
859
860
if ($lvalue =~ /^(TEST|BISECT|CONFIG_BISECT)_TYPE(\[.*\])?$/ &&
861
$prvalue !~ /^(config_|)bisect$/ &&
862
$prvalue !~ /^build$/ &&
863
$prvalue !~ /^make_warnings_file$/ &&
864
$buildonly) {
865
866
# Note if a test is something other than build, then we
867
# will need other mandatory options.
868
if ($prvalue ne "install") {
869
$buildonly = 0;
870
} else {
871
# install still limits some mandatory options.
872
$buildonly = 2;
873
}
874
}
875
876
if (defined($opt{$lvalue})) {
877
if (!$override || defined(${$overrides}{$lvalue})) {
878
my $extra = "";
879
if ($override) {
880
$extra = "In the same override section!\n";
881
}
882
die "$name: $.: Option $lvalue defined more than once!\n$extra";
883
}
884
${$overrides}{$lvalue} = $prvalue;
885
}
886
887
$opt{$lvalue} = $prvalue;
888
}
889
890
sub set_eval {
891
my ($lvalue, $rvalue, $name) = @_;
892
893
my $prvalue = process_variables($rvalue);
894
my $arr;
895
896
if (defined($evals{$lvalue})) {
897
$arr = $evals{$lvalue};
898
} else {
899
$arr = [];
900
$evals{$lvalue} = $arr;
901
}
902
903
push @{$arr}, $rvalue;
904
}
905
906
sub set_variable {
907
my ($lvalue, $rvalue, $command) = @_;
908
909
# Command line variables override all others
910
if (defined($command_tmp_vars{$lvalue})) {
911
return;
912
}
913
if ($rvalue =~ /^\s*$/) {
914
delete $variable{$lvalue};
915
} else {
916
$rvalue = process_variables($rvalue);
917
$variable{$lvalue} = $rvalue;
918
}
919
920
if (defined($command)) {
921
$command_tmp_vars{$lvalue} = 1;
922
}
923
}
924
925
sub process_compare {
926
my ($lval, $cmp, $rval) = @_;
927
928
# remove whitespace
929
930
$lval =~ s/^\s*//;
931
$lval =~ s/\s*$//;
932
933
$rval =~ s/^\s*//;
934
$rval =~ s/\s*$//;
935
936
if ($cmp eq "==") {
937
return $lval eq $rval;
938
} elsif ($cmp eq "!=") {
939
return $lval ne $rval;
940
} elsif ($cmp eq "=~") {
941
return $lval =~ m/$rval/;
942
} elsif ($cmp eq "!~") {
943
return $lval !~ m/$rval/;
944
}
945
946
my $statement = "$lval $cmp $rval";
947
my $ret = eval $statement;
948
949
# $@ stores error of eval
950
if ($@) {
951
return -1;
952
}
953
954
return $ret;
955
}
956
957
sub value_defined {
958
my ($val) = @_;
959
960
return defined($variable{$2}) ||
961
defined($opt{$2});
962
}
963
964
sub process_expression {
965
my ($name, $val) = @_;
966
967
my $c = $d++;
968
969
while ($val =~ s/\(([^\(]*?)\)/\&\&\&\&VAL\&\&\&\&/) {
970
my $express = $1;
971
972
if (process_expression($name, $express)) {
973
$val =~ s/\&\&\&\&VAL\&\&\&\&/ 1 /;
974
} else {
975
$val =~ s/\&\&\&\&VAL\&\&\&\&/ 0 /;
976
}
977
}
978
979
$d--;
980
my $OR = "\\|\\|";
981
my $AND = "\\&\\&";
982
983
while ($val =~ s/^(.*?)($OR|$AND)//) {
984
my $express = $1;
985
my $op = $2;
986
987
if (process_expression($name, $express)) {
988
if ($op eq "||") {
989
return 1;
990
}
991
} else {
992
if ($op eq "&&") {
993
return 0;
994
}
995
}
996
}
997
998
if ($val =~ /(.*)(==|\!=|>=|<=|>|<|=~|\!~)(.*)/) {
999
my $ret = process_compare($1, $2, $3);
1000
if ($ret < 0) {
1001
die "$name: $.: Unable to process comparison\n";
1002
}
1003
return $ret;
1004
}
1005
1006
if ($val =~ /^\s*(NOT\s*)?DEFINED\s+(\S+)\s*$/) {
1007
if (defined $1) {
1008
return !value_defined($2);
1009
} else {
1010
return value_defined($2);
1011
}
1012
}
1013
1014
if ($val =~ s/^\s*NOT\s+(.*)//) {
1015
my $express = $1;
1016
my $ret = process_expression($name, $express);
1017
return !$ret;
1018
}
1019
1020
if ($val =~ /^\s*0\s*$/) {
1021
return 0;
1022
} elsif ($val =~ /^\s*\d+\s*$/) {
1023
return 1;
1024
}
1025
1026
die ("$name: $.: Undefined content $val in if statement\n");
1027
}
1028
1029
sub process_if {
1030
my ($name, $value) = @_;
1031
1032
# Convert variables and replace undefined ones with 0
1033
my $val = process_variables($value, 1);
1034
my $ret = process_expression $name, $val;
1035
1036
return $ret;
1037
}
1038
1039
sub __read_config {
1040
my ($config, $current_test_num) = @_;
1041
1042
my $in;
1043
open($in, $config) || die "can't read file $config";
1044
1045
my $name = $config;
1046
$name =~ s,.*/(.*),$1,;
1047
1048
my $test_num = $$current_test_num;
1049
my $default = 1;
1050
my $repeat = 1;
1051
my $num_tests_set = 0;
1052
my $skip = 0;
1053
my $rest;
1054
my $line;
1055
my $test_case = 0;
1056
my $if = 0;
1057
my $if_set = 0;
1058
my $override = 0;
1059
1060
my %overrides;
1061
1062
while (<$in>) {
1063
1064
# ignore blank lines and comments
1065
next if (/^\s*$/ || /\s*\#/);
1066
1067
if (/^\s*(TEST_START|DEFAULTS)\b(.*)/) {
1068
1069
my $type = $1;
1070
$rest = $2;
1071
$line = $2;
1072
1073
my $old_test_num;
1074
my $old_repeat;
1075
$override = 0;
1076
1077
if ($type eq "TEST_START") {
1078
if ($num_tests_set) {
1079
die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
1080
}
1081
1082
$old_test_num = $test_num;
1083
$old_repeat = $repeat;
1084
1085
$test_num += $repeat;
1086
$default = 0;
1087
$repeat = 1;
1088
} else {
1089
$default = 1;
1090
}
1091
1092
# If SKIP is anywhere in the line, the command will be skipped
1093
if ($rest =~ s/\s+SKIP\b//) {
1094
$skip = 1;
1095
} else {
1096
$test_case = 1;
1097
$skip = 0;
1098
}
1099
1100
if ($rest =~ s/\sELSE\b//) {
1101
if (!$if) {
1102
die "$name: $.: ELSE found with out matching IF section\n$_";
1103
}
1104
$if = 0;
1105
1106
if ($if_set) {
1107
$skip = 1;
1108
} else {
1109
$skip = 0;
1110
}
1111
}
1112
1113
if ($rest =~ s/\sIF\s+(.*)//) {
1114
if (process_if($name, $1)) {
1115
$if_set = 1;
1116
} else {
1117
$skip = 1;
1118
}
1119
$if = 1;
1120
} else {
1121
$if = 0;
1122
$if_set = 0;
1123
}
1124
1125
if (!$skip) {
1126
if ($type eq "TEST_START") {
1127
if ($rest =~ s/\s+ITERATE\s+(\d+)//) {
1128
$repeat = $1;
1129
$repeat_tests{"$test_num"} = $repeat;
1130
}
1131
} elsif ($rest =~ s/\sOVERRIDE\b//) {
1132
# DEFAULT only
1133
$override = 1;
1134
# Clear previous overrides
1135
%overrides = ();
1136
}
1137
}
1138
1139
if (!$skip && $rest !~ /^\s*$/) {
1140
die "$name: $.: Garbage found after $type\n$_";
1141
}
1142
1143
if ($skip && $type eq "TEST_START") {
1144
$test_num = $old_test_num;
1145
$repeat = $old_repeat;
1146
}
1147
} elsif (/^\s*ELSE\b(.*)$/) {
1148
if (!$if) {
1149
die "$name: $.: ELSE found with out matching IF section\n$_";
1150
}
1151
$rest = $1;
1152
if ($if_set) {
1153
$skip = 1;
1154
$rest = "";
1155
} else {
1156
$skip = 0;
1157
1158
if ($rest =~ /\sIF\s+(.*)/) {
1159
# May be a ELSE IF section.
1160
if (process_if($name, $1)) {
1161
$if_set = 1;
1162
} else {
1163
$skip = 1;
1164
}
1165
$rest = "";
1166
} else {
1167
$if = 0;
1168
}
1169
}
1170
1171
if ($rest !~ /^\s*$/) {
1172
die "$name: $.: Garbage found after DEFAULTS\n$_";
1173
}
1174
1175
} elsif (/^\s*INCLUDE\s+(\S+)/) {
1176
1177
next if ($skip);
1178
1179
if (!$default) {
1180
die "$name: $.: INCLUDE can only be done in default sections\n$_";
1181
}
1182
1183
my $file = process_variables($1);
1184
1185
if ($file !~ m,^/,) {
1186
# check the path of the config file first
1187
if ($config =~ m,(.*)/,) {
1188
if (-f "$1/$file") {
1189
$file = "$1/$file";
1190
}
1191
}
1192
}
1193
1194
if ( ! -r $file ) {
1195
die "$name: $.: Can't read file $file\n$_";
1196
}
1197
1198
if (__read_config($file, \$test_num)) {
1199
$test_case = 1;
1200
}
1201
1202
} elsif (/^\s*([A-Z_\[\]\d]+)\s*=~\s*(.*?)\s*$/) {
1203
1204
next if ($skip);
1205
1206
my $lvalue = $1;
1207
my $rvalue = $2;
1208
1209
if ($default || $lvalue =~ /\[\d+\]$/) {
1210
set_eval($lvalue, $rvalue, $name);
1211
} else {
1212
my $val = "$lvalue\[$test_num\]";
1213
set_eval($val, $rvalue, $name);
1214
}
1215
1216
} elsif (/^\s*([A-Z_\[\]\d]+)\s*=\s*(.*?)\s*$/) {
1217
1218
next if ($skip);
1219
1220
my $lvalue = $1;
1221
my $rvalue = $2;
1222
1223
if (!$default &&
1224
($lvalue eq "NUM_TESTS" ||
1225
$lvalue eq "LOG_FILE" ||
1226
$lvalue eq "CLEAR_LOG")) {
1227
die "$name: $.: $lvalue must be set in DEFAULTS section\n";
1228
}
1229
1230
if ($lvalue eq "NUM_TESTS") {
1231
if ($test_num) {
1232
die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
1233
}
1234
if (!$default) {
1235
die "$name: $.: NUM_TESTS must be set in default section\n";
1236
}
1237
$num_tests_set = 1;
1238
}
1239
1240
if ($default || $lvalue =~ /\[\d+\]$/) {
1241
set_value($lvalue, $rvalue, $override, \%overrides, $name);
1242
} else {
1243
my $val = "$lvalue\[$test_num\]";
1244
set_value($val, $rvalue, $override, \%overrides, $name);
1245
1246
if ($repeat > 1) {
1247
$repeats{$val} = $repeat;
1248
}
1249
}
1250
} elsif (/^\s*([A-Z_\[\]\d]+)\s*:=\s*(.*?)\s*$/) {
1251
next if ($skip);
1252
1253
my $lvalue = $1;
1254
my $rvalue = $2;
1255
1256
# process config variables.
1257
# Config variables are only active while reading the
1258
# config and can be defined anywhere. They also ignore
1259
# TEST_START and DEFAULTS, but are skipped if they are in
1260
# one of these sections that have SKIP defined.
1261
# The save variable can be
1262
# defined multiple times and the new one simply overrides
1263
# the previous one.
1264
set_variable($lvalue, $rvalue);
1265
1266
} else {
1267
die "$name: $.: Garbage found in config\n$_";
1268
}
1269
}
1270
1271
if ($test_num) {
1272
$test_num += $repeat - 1;
1273
$opt{"NUM_TESTS"} = $test_num;
1274
}
1275
1276
close($in);
1277
1278
$$current_test_num = $test_num;
1279
1280
return $test_case;
1281
}
1282
1283
sub get_test_case {
1284
print "What test case would you like to run?\n";
1285
print " (build, install or boot)\n";
1286
print " Other tests are available but require editing ktest.conf\n";
1287
print " (see tools/testing/ktest/sample.conf)\n";
1288
my $ans = <STDIN>;
1289
chomp $ans;
1290
$default{"TEST_TYPE"} = $ans;
1291
}
1292
1293
sub read_config {
1294
my ($config) = @_;
1295
1296
my $test_case;
1297
my $test_num = 0;
1298
1299
$test_case = __read_config $config, \$test_num;
1300
1301
foreach my $val (@command_vars) {
1302
chomp $val;
1303
my %command_overrides;
1304
if ($val =~ m/^\s*([A-Z_\[\]\d]+)\s*=\s*(.*?)\s*$/) {
1305
my $lvalue = $1;
1306
my $rvalue = $2;
1307
1308
set_value($lvalue, $rvalue, 1, \%command_overrides, "COMMAND LINE");
1309
} else {
1310
die "Invalid option definition '$val'\n";
1311
}
1312
}
1313
1314
# make sure we have all mandatory configs
1315
get_mandatory_configs;
1316
1317
# was a test specified?
1318
if (!$test_case) {
1319
print "No test case specified.\n";
1320
get_test_case;
1321
}
1322
1323
# set any defaults
1324
1325
foreach my $default (keys %default) {
1326
if (!defined($opt{$default})) {
1327
$opt{$default} = $default{$default};
1328
}
1329
}
1330
1331
if ($opt{"IGNORE_UNUSED"} == 1) {
1332
return;
1333
}
1334
1335
my %not_used;
1336
1337
# check if there are any stragglers (typos?)
1338
foreach my $option (keys %opt) {
1339
my $op = $option;
1340
# remove per test labels.
1341
$op =~ s/\[.*\]//;
1342
if (!exists($option_map{$op}) &&
1343
!exists($default{$op}) &&
1344
!exists($used_options{$op})) {
1345
$not_used{$op} = 1;
1346
}
1347
}
1348
1349
if (%not_used) {
1350
my $s = "s are";
1351
$s = " is" if (keys %not_used == 1);
1352
print "The following option$s not used; could be a typo:\n";
1353
foreach my $option (keys %not_used) {
1354
print "$option\n";
1355
}
1356
print "Set IGNORE_UNUSED = 1 to have ktest ignore unused variables\n";
1357
if (!read_yn "Do you want to continue?") {
1358
exit -1;
1359
}
1360
}
1361
}
1362
1363
sub __eval_option {
1364
my ($name, $option, $i) = @_;
1365
1366
# Add space to evaluate the character before $
1367
$option = " $option";
1368
my $retval = "";
1369
my $repeated = 0;
1370
my $parent = 0;
1371
1372
foreach my $test (keys %repeat_tests) {
1373
if ($i >= $test &&
1374
$i < $test + $repeat_tests{$test}) {
1375
1376
$repeated = 1;
1377
$parent = $test;
1378
last;
1379
}
1380
}
1381
1382
while ($option =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) {
1383
my $start = $1;
1384
my $var = $2;
1385
my $end = $3;
1386
1387
# Append beginning of line
1388
$retval = "$retval$start";
1389
1390
# If the iteration option OPT[$i] exists, then use that.
1391
# otherwise see if the default OPT (without [$i]) exists.
1392
1393
my $o = "$var\[$i\]";
1394
my $parento = "$var\[$parent\]";
1395
1396
# If a variable contains itself, use the default var
1397
if (($var eq $name) && defined($opt{$var})) {
1398
$o = $opt{$var};
1399
# Only append if the default doesn't contain itself
1400
if ($o !~ m/\$\{$var\}/) {
1401
$retval = "$retval$o";
1402
}
1403
} elsif (defined($opt{$o})) {
1404
$o = $opt{$o};
1405
$retval = "$retval$o";
1406
} elsif ($repeated && defined($opt{$parento})) {
1407
$o = $opt{$parento};
1408
$retval = "$retval$o";
1409
} elsif (defined($opt{$var})) {
1410
$o = $opt{$var};
1411
$retval = "$retval$o";
1412
} elsif ($var eq "KERNEL_VERSION" && defined($make)) {
1413
# special option KERNEL_VERSION uses kernel version
1414
get_version();
1415
$retval = "$retval$version";
1416
} else {
1417
$retval = "$retval\$\{$var\}";
1418
}
1419
1420
$option = $end;
1421
}
1422
1423
$retval = "$retval$option";
1424
1425
$retval =~ s/^ //;
1426
1427
return $retval;
1428
}
1429
1430
sub process_evals {
1431
my ($name, $option, $i) = @_;
1432
1433
my $option_name = "$name\[$i\]";
1434
my $ev;
1435
1436
my $old_option = $option;
1437
1438
if (defined($evals{$option_name})) {
1439
$ev = $evals{$option_name};
1440
} elsif (defined($evals{$name})) {
1441
$ev = $evals{$name};
1442
} else {
1443
return $option;
1444
}
1445
1446
for my $e (@{$ev}) {
1447
eval "\$option =~ $e";
1448
}
1449
1450
if ($option ne $old_option) {
1451
doprint("$name changed from '$old_option' to '$option'\n");
1452
}
1453
1454
return $option;
1455
}
1456
1457
sub eval_option {
1458
my ($name, $option, $i) = @_;
1459
1460
my $prev = "";
1461
1462
# Since an option can evaluate to another option,
1463
# keep iterating until we do not evaluate any more
1464
# options.
1465
my $r = 0;
1466
while ($prev ne $option) {
1467
# Check for recursive evaluations.
1468
# 100 deep should be more than enough.
1469
if ($r++ > 100) {
1470
die "Over 100 evaluations occurred with $option\n" .
1471
"Check for recursive variables\n";
1472
}
1473
$prev = $option;
1474
$option = __eval_option($name, $option, $i);
1475
}
1476
1477
$option = process_evals($name, $option, $i);
1478
1479
return $option;
1480
}
1481
1482
sub reboot {
1483
my ($time) = @_;
1484
my $powercycle = 0;
1485
1486
# test if the machine can be connected to within a few seconds
1487
my $stat = run_ssh("echo check machine status", $connect_timeout);
1488
if (!$stat) {
1489
doprint("power cycle\n");
1490
$powercycle = 1;
1491
}
1492
1493
if ($powercycle) {
1494
run_command "$power_cycle";
1495
1496
start_monitor;
1497
# flush out current monitor
1498
# May contain the reboot success line
1499
wait_for_monitor 1;
1500
1501
} else {
1502
# Make sure everything has been written to disk
1503
run_ssh("sync", 10);
1504
1505
if (defined($time)) {
1506
start_monitor;
1507
# flush out current monitor
1508
# May contain the reboot success line
1509
wait_for_monitor 1;
1510
}
1511
1512
# try to reboot normally
1513
if (run_command $reboot) {
1514
if (defined($powercycle_after_reboot)) {
1515
sleep $powercycle_after_reboot;
1516
run_command "$power_cycle";
1517
}
1518
} else {
1519
# nope? power cycle it.
1520
run_command "$power_cycle";
1521
}
1522
}
1523
1524
if (defined($time)) {
1525
1526
# We only want to get to the new kernel, don't fail
1527
# if we stumble over a call trace.
1528
my $save_ignore_errors = $ignore_errors;
1529
$ignore_errors = 1;
1530
1531
# Look for the good kernel to boot
1532
if (wait_for_monitor($time, "Linux version")) {
1533
# reboot got stuck?
1534
doprint "Reboot did not finish. Forcing power cycle\n";
1535
run_command "$power_cycle";
1536
}
1537
1538
$ignore_errors = $save_ignore_errors;
1539
1540
# Still need to wait for the reboot to finish
1541
wait_for_monitor($time, $reboot_success_line);
1542
}
1543
if ($powercycle || $time) {
1544
end_monitor;
1545
}
1546
}
1547
1548
sub reboot_to_good {
1549
my ($time) = @_;
1550
1551
if (defined($switch_to_good)) {
1552
run_command $switch_to_good;
1553
}
1554
1555
reboot $time;
1556
}
1557
1558
sub do_not_reboot {
1559
my $i = $iteration;
1560
1561
return $test_type eq "build" || $no_reboot ||
1562
($test_type eq "patchcheck" && $opt{"PATCHCHECK_TYPE[$i]"} eq "build") ||
1563
($test_type eq "bisect" && $opt{"BISECT_TYPE[$i]"} eq "build") ||
1564
($test_type eq "config_bisect" && $opt{"CONFIG_BISECT_TYPE[$i]"} eq "build");
1565
}
1566
1567
sub get_test_name() {
1568
my $name;
1569
1570
if (defined($test_name)) {
1571
$name = "$test_name:$test_type";
1572
} else {
1573
$name = $test_type;
1574
}
1575
return $name;
1576
}
1577
1578
sub dodie {
1579
# avoid recursion
1580
return if ($in_die);
1581
$in_die = 1;
1582
1583
if ($monitor_cnt) {
1584
# restore terminal settings
1585
system("stty $stty_orig");
1586
}
1587
1588
my $i = $iteration;
1589
1590
doprint "CRITICAL FAILURE... [TEST $i] ", @_, "\n";
1591
1592
if ($reboot_on_error && !do_not_reboot) {
1593
doprint "REBOOTING\n";
1594
reboot_to_good;
1595
} elsif ($poweroff_on_error && defined($power_off)) {
1596
doprint "POWERING OFF\n";
1597
`$power_off`;
1598
}
1599
1600
if (defined($opt{"LOG_FILE"})) {
1601
print " See $opt{LOG_FILE} for more info.\n";
1602
}
1603
1604
if ($email_on_error) {
1605
my $name = get_test_name;
1606
my $log_file;
1607
1608
if (defined($opt{"LOG_FILE"})) {
1609
my $whence = 2; # End of file
1610
my $log_size = tell LOG;
1611
my $size = $log_size - $test_log_start;
1612
1613
if (defined($mail_max_size)) {
1614
if ($size > $mail_max_size) {
1615
$size = $mail_max_size;
1616
}
1617
}
1618
my $pos = - $size;
1619
$log_file = "$tmpdir/log";
1620
open (L, "$opt{LOG_FILE}") or die "Can't open $opt{LOG_FILE} to read)";
1621
open (O, "> $tmpdir/log") or die "Can't open $tmpdir/log\n";
1622
seek(L, $pos, $whence);
1623
while (<L>) {
1624
print O;
1625
}
1626
close O;
1627
close L;
1628
}
1629
1630
send_email("KTEST: critical failure for test $i [$name]",
1631
"Your test started at $script_start_time has failed with:\n@_\n", $log_file);
1632
}
1633
1634
if (defined($post_test)) {
1635
run_command $post_test;
1636
}
1637
1638
die @_, "\n";
1639
}
1640
1641
sub create_pty {
1642
my ($ptm, $pts) = @_;
1643
my $tmp;
1644
my $TIOCSPTLCK = 0x40045431;
1645
my $TIOCGPTN = 0x80045430;
1646
1647
sysopen($ptm, "/dev/ptmx", O_RDWR | O_NONBLOCK) or
1648
dodie "Can't open /dev/ptmx";
1649
1650
# unlockpt()
1651
$tmp = pack("i", 0);
1652
ioctl($ptm, $TIOCSPTLCK, $tmp) or
1653
dodie "ioctl TIOCSPTLCK for /dev/ptmx failed";
1654
1655
# ptsname()
1656
ioctl($ptm, $TIOCGPTN, $tmp) or
1657
dodie "ioctl TIOCGPTN for /dev/ptmx failed";
1658
$tmp = unpack("i", $tmp);
1659
1660
sysopen($pts, "/dev/pts/$tmp", O_RDWR | O_NONBLOCK) or
1661
dodie "Can't open /dev/pts/$tmp";
1662
}
1663
1664
sub exec_console {
1665
my ($ptm, $pts) = @_;
1666
1667
close($ptm);
1668
1669
close(\*STDIN);
1670
close(\*STDOUT);
1671
close(\*STDERR);
1672
1673
open(\*STDIN, '<&', $pts);
1674
open(\*STDOUT, '>&', $pts);
1675
open(\*STDERR, '>&', $pts);
1676
1677
close($pts);
1678
1679
exec $console or
1680
dodie "Can't open console $console";
1681
}
1682
1683
sub open_console {
1684
my ($ptm) = @_;
1685
my $pts = \*PTSFD;
1686
my $pid;
1687
1688
# save terminal settings
1689
$stty_orig = `stty -g`;
1690
1691
# place terminal in cbreak mode so that stdin can be read one character at
1692
# a time without having to wait for a newline
1693
system("stty -icanon -echo -icrnl");
1694
1695
create_pty($ptm, $pts);
1696
1697
$pid = fork;
1698
1699
if (!$pid) {
1700
# child
1701
exec_console($ptm, $pts)
1702
}
1703
1704
# parent
1705
close($pts);
1706
1707
return $pid;
1708
1709
open(PTSFD, "Stop perl from warning about single use of PTSFD");
1710
}
1711
1712
sub close_console {
1713
my ($fp, $pid) = @_;
1714
1715
doprint "kill child process $pid\n";
1716
kill $close_console_signal, $pid;
1717
1718
doprint "wait for child process $pid to exit\n";
1719
waitpid($pid, 0);
1720
1721
print "closing!\n";
1722
close($fp);
1723
1724
# restore terminal settings
1725
system("stty $stty_orig");
1726
}
1727
1728
sub start_monitor {
1729
if ($monitor_cnt++) {
1730
return;
1731
}
1732
$monitor_fp = \*MONFD;
1733
$monitor_pid = open_console $monitor_fp;
1734
1735
return;
1736
1737
open(MONFD, "Stop perl from warning about single use of MONFD");
1738
}
1739
1740
sub end_monitor {
1741
return if (!defined $console);
1742
if (--$monitor_cnt) {
1743
return;
1744
}
1745
close_console($monitor_fp, $monitor_pid);
1746
}
1747
1748
sub wait_for_monitor {
1749
my ($time, $stop) = @_;
1750
my $full_line = "";
1751
my $line;
1752
my $booted = 0;
1753
my $start_time = time;
1754
my $skip_call_trace = 0;
1755
my $bug = 0;
1756
my $bug_ignored = 0;
1757
my $now;
1758
1759
doprint "** Wait for monitor to settle down **\n";
1760
1761
# read the monitor and wait for the system to calm down
1762
while (!$booted) {
1763
$line = wait_for_input($monitor_fp, $time);
1764
last if (!defined($line));
1765
print "$line";
1766
$full_line .= $line;
1767
1768
if (defined($stop) && $full_line =~ /$stop/) {
1769
doprint "wait for monitor detected $stop\n";
1770
$booted = 1;
1771
}
1772
1773
if ($full_line =~ /\[ backtrace testing \]/) {
1774
$skip_call_trace = 1;
1775
}
1776
1777
if ($full_line =~ /call trace:/i) {
1778
if (!$bug && !$skip_call_trace) {
1779
if ($ignore_errors) {
1780
$bug_ignored = 1;
1781
} else {
1782
$bug = 1;
1783
}
1784
}
1785
}
1786
1787
if ($full_line =~ /\[ end of backtrace testing \]/) {
1788
$skip_call_trace = 0;
1789
}
1790
1791
if ($full_line =~ /Kernel panic -/) {
1792
$bug = 1;
1793
}
1794
1795
if ($line =~ /\n/) {
1796
$full_line = "";
1797
}
1798
$now = time;
1799
if ($now - $start_time >= $max_monitor_wait) {
1800
doprint "Exiting monitor flush due to hitting MAX_MONITOR_WAIT\n";
1801
return 1;
1802
}
1803
}
1804
print "** Monitor flushed **\n";
1805
1806
# if stop is defined but wasn't hit, return error
1807
# used by reboot (which wants to see a reboot)
1808
if (defined($stop) && !$booted) {
1809
$bug = 1;
1810
}
1811
return $bug;
1812
}
1813
1814
sub save_logs {
1815
my ($result, $basedir) = @_;
1816
my @t = localtime;
1817
my $date = sprintf "%04d%02d%02d%02d%02d%02d",
1818
1900+$t[5],$t[4],$t[3],$t[2],$t[1],$t[0];
1819
1820
my $type = $build_type;
1821
if ($type =~ /useconfig/) {
1822
$type = "useconfig";
1823
}
1824
1825
my $dir = "$machine-$test_type-$type-$result-$date";
1826
1827
$dir = "$basedir/$dir";
1828
1829
if (!-d $dir) {
1830
mkpath($dir) or
1831
dodie "can't create $dir";
1832
}
1833
1834
my %files = (
1835
"config" => $output_config,
1836
"buildlog" => $buildlog,
1837
"dmesg" => $dmesg,
1838
"testlog" => $testlog,
1839
);
1840
1841
while (my ($name, $source) = each(%files)) {
1842
if (-f "$source") {
1843
cp "$source", "$dir/$name" or
1844
dodie "failed to copy $source";
1845
}
1846
}
1847
1848
doprint "*** Saved info to $dir ***\n";
1849
}
1850
1851
sub fail {
1852
1853
if ($die_on_failure) {
1854
dodie @_;
1855
}
1856
1857
doprint "FAILED\n";
1858
1859
my $i = $iteration;
1860
1861
# no need to reboot for just building.
1862
if (!do_not_reboot) {
1863
doprint "REBOOTING\n";
1864
reboot_to_good $sleep_time;
1865
}
1866
1867
my $name = "";
1868
1869
if (defined($test_name)) {
1870
$name = " ($test_name)";
1871
}
1872
1873
print_times;
1874
1875
doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
1876
doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
1877
doprint "KTEST RESULT: TEST $i$name Failed: ", @_, "\n";
1878
doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
1879
doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
1880
1881
if (defined($store_failures)) {
1882
save_logs "fail", $store_failures;
1883
}
1884
1885
if (defined($post_test)) {
1886
run_command $post_test;
1887
}
1888
1889
return 1;
1890
}
1891
1892
sub run_command {
1893
my ($command, $redirect, $timeout) = @_;
1894
my $start_time;
1895
my $end_time;
1896
my $dolog = 0;
1897
my $dord = 0;
1898
my $dostdout = 0;
1899
my $pid;
1900
my $command_orig = $command;
1901
1902
$command =~ s/\$SSH_USER/$ssh_user/g;
1903
$command =~ s/\$MACHINE/$machine/g;
1904
1905
if (!defined($timeout)) {
1906
$timeout = $run_timeout;
1907
}
1908
1909
if (!defined($timeout)) {
1910
$timeout = -1; # tell wait_for_input to wait indefinitely
1911
}
1912
1913
doprint("$command ... ");
1914
$start_time = time;
1915
1916
$pid = open(CMD, "$command 2>&1 |") or
1917
(fail "unable to exec $command" and return 0);
1918
1919
if (defined($opt{"LOG_FILE"})) {
1920
$dolog = 1;
1921
}
1922
1923
if (defined($redirect)) {
1924
if ($redirect eq 1) {
1925
$dostdout = 1;
1926
# Have the output of the command on its own line
1927
doprint "\n";
1928
} else {
1929
open (RD, ">$redirect") or
1930
dodie "failed to write to redirect $redirect";
1931
$dord = 1;
1932
}
1933
}
1934
1935
my $hit_timeout = 0;
1936
1937
while (1) {
1938
my $fp = \*CMD;
1939
my $line = wait_for_input($fp, $timeout);
1940
if (!defined($line)) {
1941
my $now = time;
1942
if ($timeout >= 0 && (($now - $start_time) >= $timeout)) {
1943
doprint "Hit timeout of $timeout, killing process\n";
1944
$hit_timeout = 1;
1945
kill 9, $pid;
1946
}
1947
last;
1948
}
1949
print LOG $line if ($dolog);
1950
print RD $line if ($dord);
1951
print $line if ($dostdout);
1952
}
1953
1954
waitpid($pid, 0);
1955
# shift 8 for real exit status
1956
$run_command_status = $? >> 8;
1957
1958
if ($command_orig eq $default{REBOOT} &&
1959
$run_command_status == $reboot_return_code) {
1960
$run_command_status = 0;
1961
}
1962
1963
close(CMD);
1964
close(RD) if ($dord);
1965
1966
$end_time = time;
1967
my $delta = $end_time - $start_time;
1968
1969
if ($delta == 1) {
1970
doprint "[1 second] ";
1971
} else {
1972
doprint "[$delta seconds] ";
1973
}
1974
1975
if ($hit_timeout) {
1976
$run_command_status = 1;
1977
}
1978
1979
if ($run_command_status) {
1980
doprint "FAILED!\n";
1981
} else {
1982
doprint "SUCCESS\n";
1983
}
1984
1985
return !$run_command_status;
1986
}
1987
1988
sub run_ssh {
1989
my ($cmd, $timeout) = @_;
1990
my $cp_exec = $ssh_exec;
1991
1992
$cp_exec =~ s/\$SSH_COMMAND/$cmd/g;
1993
return run_command "$cp_exec", undef , $timeout;
1994
}
1995
1996
sub run_scp {
1997
my ($src, $dst, $cp_scp) = @_;
1998
1999
$cp_scp =~ s/\$SRC_FILE/$src/g;
2000
$cp_scp =~ s/\$DST_FILE/$dst/g;
2001
2002
return run_command "$cp_scp";
2003
}
2004
2005
sub run_scp_install {
2006
my ($src, $dst) = @_;
2007
2008
my $cp_scp = $scp_to_target_install;
2009
2010
return run_scp($src, $dst, $cp_scp);
2011
}
2012
2013
sub run_scp_mod {
2014
my ($src, $dst) = @_;
2015
2016
my $cp_scp = $scp_to_target;
2017
2018
return run_scp($src, $dst, $cp_scp);
2019
}
2020
2021
sub _get_grub_index {
2022
2023
my ($command, $target, $skip, $submenu) = @_;
2024
2025
return if (defined($grub_number) && defined($last_grub_menu) &&
2026
$last_grub_menu eq $grub_menu && defined($last_machine) &&
2027
$last_machine eq $machine);
2028
2029
doprint "Find $reboot_type menu ... ";
2030
$grub_number = -1;
2031
2032
my $ssh_grub = $ssh_exec;
2033
$ssh_grub =~ s,\$SSH_COMMAND,$command,g;
2034
2035
open(IN, "$ssh_grub |") or
2036
dodie "unable to execute $command";
2037
2038
my $found = 0;
2039
2040
my $submenu_number = 0;
2041
2042
while (<IN>) {
2043
if (/$target/) {
2044
$grub_number++;
2045
$found = 1;
2046
last;
2047
} elsif (defined($submenu) && /$submenu/) {
2048
$submenu_number++;
2049
$grub_number = -1;
2050
} elsif (/$skip/) {
2051
$grub_number++;
2052
}
2053
}
2054
close(IN);
2055
2056
dodie "Could not find '$grub_menu' through $command on $machine"
2057
if (!$found);
2058
if ($submenu_number > 0) {
2059
$grub_number = "$submenu_number>$grub_number";
2060
}
2061
doprint "$grub_number\n";
2062
$last_grub_menu = $grub_menu;
2063
$last_machine = $machine;
2064
}
2065
2066
sub get_grub_index {
2067
2068
my $command;
2069
my $target;
2070
my $skip;
2071
my $submenu;
2072
my $grub_menu_qt;
2073
2074
if ($reboot_type !~ /^grub/) {
2075
return;
2076
}
2077
2078
$grub_menu_qt = quotemeta($grub_menu);
2079
2080
if ($reboot_type eq "grub") {
2081
$command = "cat /boot/grub/menu.lst";
2082
$target = '^\s*title\s+' . $grub_menu_qt . '\s*$';
2083
$skip = '^\s*title\s';
2084
} elsif ($reboot_type eq "grub2") {
2085
$command = "cat $grub_file";
2086
$target = '^\s*menuentry.*' . $grub_menu_qt;
2087
$skip = '^\s*menuentry\s';
2088
$submenu = '^\s*submenu\s';
2089
} elsif ($reboot_type eq "grub2bls") {
2090
$command = $grub_bls_get;
2091
$target = '^title=.*' . $grub_menu_qt;
2092
$skip = '^title=';
2093
} else {
2094
return;
2095
}
2096
2097
_get_grub_index($command, $target, $skip, $submenu);
2098
}
2099
2100
sub wait_for_input {
2101
my ($fp, $time) = @_;
2102
my $start_time;
2103
my $rin;
2104
my $rout;
2105
my $nr;
2106
my $buf;
2107
my $line;
2108
my $ch;
2109
2110
if (!defined($time)) {
2111
$time = $timeout;
2112
}
2113
2114
if ($time < 0) {
2115
# Negative number means wait indefinitely
2116
undef $time;
2117
}
2118
2119
$rin = '';
2120
vec($rin, fileno($fp), 1) = 1;
2121
vec($rin, fileno(\*STDIN), 1) = 1;
2122
2123
$start_time = time;
2124
2125
while (1) {
2126
$nr = select($rout=$rin, undef, undef, $time);
2127
2128
last if ($nr <= 0);
2129
2130
# copy data from stdin to the console
2131
if (vec($rout, fileno(\*STDIN), 1) == 1) {
2132
$nr = sysread(\*STDIN, $buf, 1000);
2133
syswrite($fp, $buf, $nr) if ($nr > 0);
2134
}
2135
2136
# The timeout is based on time waiting for the fp data
2137
if (vec($rout, fileno($fp), 1) != 1) {
2138
last if (defined($time) && (time - $start_time > $time));
2139
next;
2140
}
2141
2142
$line = "";
2143
2144
# try to read one char at a time
2145
while (sysread $fp, $ch, 1) {
2146
$line .= $ch;
2147
last if ($ch eq "\n");
2148
}
2149
2150
last if (!length($line));
2151
2152
return $line;
2153
}
2154
return undef;
2155
}
2156
2157
sub reboot_to {
2158
if (defined($switch_to_test)) {
2159
run_command $switch_to_test;
2160
}
2161
2162
if ($reboot_type eq "grub") {
2163
run_ssh "'(echo \"savedefault --default=$grub_number --once\" | grub --batch)'";
2164
} elsif (($reboot_type eq "grub2") or ($reboot_type eq "grub2bls")) {
2165
run_ssh "$grub_reboot \"'$grub_number'\"";
2166
} elsif ($reboot_type eq "syslinux") {
2167
run_ssh "$syslinux --once \\\"$syslinux_label\\\" $syslinux_path";
2168
} elsif (defined $reboot_script) {
2169
run_command "$reboot_script";
2170
}
2171
reboot;
2172
}
2173
2174
sub get_sha1 {
2175
my ($commit) = @_;
2176
2177
doprint "git rev-list --max-count=1 $commit ... ";
2178
my $sha1 = `git rev-list --max-count=1 $commit`;
2179
my $ret = $?;
2180
2181
logit $sha1;
2182
2183
if ($ret) {
2184
doprint "FAILED\n";
2185
dodie "Failed to get git $commit";
2186
}
2187
2188
print "SUCCESS\n";
2189
2190
chomp $sha1;
2191
2192
return $sha1;
2193
}
2194
2195
sub monitor {
2196
my $booted = 0;
2197
my $bug = 0;
2198
my $bug_ignored = 0;
2199
my $skip_call_trace = 0;
2200
my $loops;
2201
2202
my $start_time = time;
2203
2204
wait_for_monitor 5;
2205
2206
my $line;
2207
my $full_line = "";
2208
2209
open(DMESG, "> $dmesg") or
2210
dodie "unable to write to $dmesg";
2211
2212
reboot_to;
2213
2214
my $success_start;
2215
my $failure_start;
2216
my $monitor_start = time;
2217
my $done = 0;
2218
my $version_found = 0;
2219
2220
while (!$done) {
2221
if ($bug && defined($stop_after_failure) &&
2222
$stop_after_failure >= 0) {
2223
my $time = $stop_after_failure - (time - $failure_start);
2224
$line = wait_for_input($monitor_fp, $time);
2225
if (!defined($line)) {
2226
doprint "bug timed out after $booted_timeout seconds\n";
2227
doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
2228
last;
2229
}
2230
} elsif ($booted) {
2231
$line = wait_for_input($monitor_fp, $booted_timeout);
2232
if (!defined($line)) {
2233
my $s = $booted_timeout == 1 ? "" : "s";
2234
doprint "Successful boot found: break after $booted_timeout second$s\n";
2235
last;
2236
}
2237
} else {
2238
$line = wait_for_input($monitor_fp);
2239
if (!defined($line)) {
2240
my $s = $timeout == 1 ? "" : "s";
2241
doprint "Timed out after $timeout second$s\n";
2242
last;
2243
}
2244
}
2245
2246
doprint $line;
2247
print DMESG $line;
2248
2249
# we are not guaranteed to get a full line
2250
$full_line .= $line;
2251
2252
if ($full_line =~ /$success_line/) {
2253
$booted = 1;
2254
$success_start = time;
2255
}
2256
2257
if ($booted && defined($stop_after_success) &&
2258
$stop_after_success >= 0) {
2259
my $now = time;
2260
if ($now - $success_start >= $stop_after_success) {
2261
doprint "Test forced to stop after $stop_after_success seconds after success\n";
2262
last;
2263
}
2264
}
2265
2266
if ($full_line =~ /\[ backtrace testing \]/) {
2267
$skip_call_trace = 1;
2268
}
2269
2270
if ($full_line =~ /call trace:/i) {
2271
if (!$bug && !$skip_call_trace) {
2272
if ($ignore_errors) {
2273
$bug_ignored = 1;
2274
} else {
2275
$bug = 1;
2276
$failure_start = time;
2277
}
2278
}
2279
}
2280
2281
if ($bug && defined($stop_after_failure) &&
2282
$stop_after_failure >= 0) {
2283
my $now = time;
2284
if ($now - $failure_start >= $stop_after_failure) {
2285
doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
2286
last;
2287
}
2288
}
2289
2290
if ($full_line =~ /\[ end of backtrace testing \]/) {
2291
$skip_call_trace = 0;
2292
}
2293
2294
if ($full_line =~ /Kernel panic -/) {
2295
$failure_start = time;
2296
$bug = 1;
2297
}
2298
2299
# Detect triple faults by testing the banner
2300
if ($full_line =~ /\bLinux version (\S+).*\n/) {
2301
if ($1 eq $version) {
2302
$version_found = 1;
2303
} elsif ($version_found && $detect_triplefault) {
2304
# We already booted into the kernel we are testing,
2305
# but now we booted into another kernel?
2306
# Consider this a triple fault.
2307
doprint "Already booted in Linux kernel $version, but now\n";
2308
doprint "we booted into Linux kernel $1.\n";
2309
doprint "Assuming that this is a triple fault.\n";
2310
doprint "To disable this: set DETECT_TRIPLE_FAULT to 0\n";
2311
last;
2312
}
2313
}
2314
2315
if ($line =~ /\n/) {
2316
$full_line = "";
2317
}
2318
2319
if ($stop_test_after > 0 && !$booted && !$bug) {
2320
if (time - $monitor_start > $stop_test_after) {
2321
doprint "STOP_TEST_AFTER ($stop_test_after seconds) timed out\n";
2322
$done = 1;
2323
}
2324
}
2325
}
2326
2327
my $end_time = time;
2328
$reboot_time = $end_time - $start_time;
2329
2330
close(DMESG);
2331
2332
if ($bug) {
2333
return 0 if ($in_bisect);
2334
fail "failed - got a bug report" and return 0;
2335
}
2336
2337
if (!$booted) {
2338
return 0 if ($in_bisect);
2339
fail "failed - never got a boot prompt." and return 0;
2340
}
2341
2342
if ($bug_ignored) {
2343
doprint "WARNING: Call Trace detected but ignored due to IGNORE_ERRORS=1\n";
2344
}
2345
2346
return 1;
2347
}
2348
2349
sub eval_kernel_version {
2350
my ($option) = @_;
2351
2352
$option =~ s/\$KERNEL_VERSION/$version/g;
2353
2354
return $option;
2355
}
2356
2357
sub do_post_install {
2358
2359
return if (!defined($post_install));
2360
2361
my $cp_post_install = eval_kernel_version $post_install;
2362
run_command "$cp_post_install" or
2363
dodie "Failed to run post install";
2364
}
2365
2366
# Sometimes the reboot fails, and will hang. We try to ssh to the box
2367
# and if we fail, we force another reboot, that should powercycle it.
2368
sub test_booted {
2369
if (!run_ssh "echo testing connection") {
2370
reboot $sleep_time;
2371
}
2372
}
2373
2374
sub install {
2375
2376
return if ($no_install);
2377
2378
my $start_time = time;
2379
2380
if (defined($pre_install)) {
2381
my $cp_pre_install = eval_kernel_version $pre_install;
2382
run_command "$cp_pre_install" or
2383
dodie "Failed to run pre install";
2384
}
2385
2386
my $cp_target = eval_kernel_version $target_image;
2387
2388
test_booted;
2389
2390
run_scp_install "$outputdir/$build_target", "$cp_target" or
2391
dodie "failed to copy image";
2392
2393
my $install_mods = 0;
2394
2395
# should we process modules?
2396
$install_mods = 0;
2397
open(IN, "$output_config") or dodie("Can't read config file");
2398
while (<IN>) {
2399
if (/CONFIG_MODULES(=y)?/) {
2400
if (defined($1)) {
2401
$install_mods = 1;
2402
last;
2403
}
2404
}
2405
}
2406
close(IN);
2407
2408
if (!$install_mods) {
2409
do_post_install;
2410
doprint "No modules needed\n";
2411
my $end_time = time;
2412
$install_time = $end_time - $start_time;
2413
return;
2414
}
2415
2416
run_command "$make INSTALL_MOD_STRIP=1 INSTALL_MOD_PATH=$tmpdir modules_install" or
2417
dodie "Failed to install modules";
2418
2419
my $modlib = "/lib/modules/$version";
2420
my $modtar = "ktest-mods.tar.bz2";
2421
2422
run_ssh "rm -rf $modlib" or
2423
dodie "failed to remove old mods: $modlib";
2424
2425
# would be nice if scp -r did not follow symbolic links
2426
run_command "cd $tmpdir && tar -cjf $modtar lib/modules/$version" or
2427
dodie "making tarball";
2428
2429
run_scp_mod "$tmpdir/$modtar", "/tmp" or
2430
dodie "failed to copy modules";
2431
2432
unlink "$tmpdir/$modtar";
2433
2434
run_ssh "'(cd / && tar xjf /tmp/$modtar)'" or
2435
dodie "failed to tar modules";
2436
2437
run_ssh "rm -f /tmp/$modtar";
2438
2439
do_post_install;
2440
2441
my $end_time = time;
2442
$install_time = $end_time - $start_time;
2443
}
2444
2445
sub get_version {
2446
# get the release name
2447
return if ($have_version);
2448
doprint "$make kernelrelease ... ";
2449
$version = `$make -s kernelrelease | tail -1`;
2450
if (!length($version)) {
2451
run_command "$make allnoconfig" or return 0;
2452
doprint "$make kernelrelease ... ";
2453
$version = `$make -s kernelrelease | tail -1`;
2454
}
2455
chomp($version);
2456
doprint "$version\n";
2457
$have_version = 1;
2458
}
2459
2460
sub start_monitor_and_install {
2461
# Make sure the stable kernel has finished booting
2462
2463
# Install bisects, don't need console
2464
if (defined $console) {
2465
start_monitor;
2466
wait_for_monitor 5;
2467
end_monitor;
2468
}
2469
2470
get_grub_index;
2471
get_version;
2472
install;
2473
2474
start_monitor if (defined $console);
2475
return monitor;
2476
}
2477
2478
sub process_warning_line {
2479
my ($line) = @_;
2480
2481
chomp $line;
2482
2483
# for distcc heterogeneous systems, some compilers
2484
# do things differently causing warning lines
2485
# to be slightly different. This makes an attempt
2486
# to fixe those issues.
2487
2488
# chop off the index into the line
2489
# using distcc, some compilers give different indexes
2490
# depending on white space
2491
$line =~ s/^(\s*\S+:\d+:)\d+/$1/;
2492
2493
# Some compilers use UTF-8 extended for quotes and some don't.
2494
$line =~ s/$utf8_quote/'/g;
2495
2496
return $line;
2497
}
2498
2499
# Read buildlog and check against warnings file for any
2500
# new warnings.
2501
#
2502
# Returns 1 if OK
2503
# 0 otherwise
2504
sub check_buildlog {
2505
my %warnings_list;
2506
2507
# Failed builds should not reboot the target
2508
my $save_no_reboot = $no_reboot;
2509
$no_reboot = 1;
2510
2511
if (-f $warnings_file) {
2512
open(IN, $warnings_file) or
2513
dodie "Error opening $warnings_file";
2514
2515
while (<IN>) {
2516
if (/$check_build_re/) {
2517
my $warning = process_warning_line $_;
2518
2519
$warnings_list{$warning} = 1;
2520
}
2521
}
2522
close(IN);
2523
}
2524
2525
open(IN, $buildlog) or dodie "Can't open $buildlog";
2526
while (<IN>) {
2527
if (/$check_build_re/) {
2528
my $warning = process_warning_line $_;
2529
2530
if (!defined $warnings_list{$warning}) {
2531
$warning_found++;
2532
2533
# If warnings file didn't exist, and WARNINGS_FILE exist,
2534
# then we fail on any warning!
2535
if (defined $warnings_file) {
2536
fail "New warning found (not in $warnings_file)\n$_\n";
2537
$no_reboot = $save_no_reboot;
2538
return 0;
2539
}
2540
}
2541
}
2542
}
2543
$no_reboot = $save_no_reboot;
2544
close(IN);
2545
}
2546
2547
sub check_patch_buildlog {
2548
my ($patch) = @_;
2549
2550
my @files = `git show $patch | diffstat -l`;
2551
2552
foreach my $file (@files) {
2553
chomp $file;
2554
}
2555
2556
open(IN, "git show $patch |") or
2557
dodie "failed to show $patch";
2558
while (<IN>) {
2559
if (m,^--- a/(.*),) {
2560
chomp $1;
2561
$files[$#files] = $1;
2562
}
2563
}
2564
close(IN);
2565
2566
open(IN, $buildlog) or dodie "Can't open $buildlog";
2567
while (<IN>) {
2568
if (/^\s*(.*?):.*(warning|error)/) {
2569
my $err = $1;
2570
foreach my $file (@files) {
2571
my $fullpath = "$builddir/$file";
2572
if ($file eq $err || $fullpath eq $err) {
2573
fail "$file built with warnings" and return 0;
2574
}
2575
}
2576
}
2577
}
2578
close(IN);
2579
2580
return 1;
2581
}
2582
2583
sub apply_min_config {
2584
my $outconfig = "$output_config.new";
2585
2586
# Read the config file and remove anything that
2587
# is in the force_config hash (from minconfig and others)
2588
# then add the force config back.
2589
2590
doprint "Applying minimum configurations into $output_config.new\n";
2591
2592
open (OUT, ">$outconfig") or
2593
dodie "Can't create $outconfig";
2594
2595
if (-f $output_config) {
2596
open (IN, $output_config) or
2597
dodie "Failed to open $output_config";
2598
while (<IN>) {
2599
if (/^(# )?(CONFIG_[^\s=]*)/) {
2600
next if (defined($force_config{$2}));
2601
}
2602
print OUT;
2603
}
2604
close IN;
2605
}
2606
foreach my $config (keys %force_config) {
2607
print OUT "$force_config{$config}\n";
2608
}
2609
close OUT;
2610
2611
run_command "mv $outconfig $output_config";
2612
}
2613
2614
sub make_oldconfig {
2615
2616
my @force_list = keys %force_config;
2617
2618
if ($#force_list >= 0) {
2619
apply_min_config;
2620
}
2621
2622
if (!run_command "$make olddefconfig") {
2623
# Perhaps olddefconfig doesn't exist in this version of the kernel
2624
# try oldnoconfig
2625
doprint "olddefconfig failed, trying make oldnoconfig\n";
2626
if (!run_command "$make oldnoconfig") {
2627
doprint "oldnoconfig failed, trying yes '' | make oldconfig\n";
2628
# try a yes '' | oldconfig
2629
run_command "yes '' | $make oldconfig" or
2630
dodie "failed make config oldconfig";
2631
}
2632
}
2633
}
2634
2635
# read a config file and use this to force new configs.
2636
sub load_force_config {
2637
my ($config) = @_;
2638
2639
doprint "Loading force configs from $config\n";
2640
open(IN, $config) or
2641
dodie "failed to read $config";
2642
while (<IN>) {
2643
chomp;
2644
if (/^(CONFIG[^\s=]*)(\s*=.*)/) {
2645
$force_config{$1} = $_;
2646
} elsif (/^# (CONFIG_\S*) is not set/) {
2647
$force_config{$1} = $_;
2648
}
2649
}
2650
close IN;
2651
}
2652
2653
sub build {
2654
my ($type) = @_;
2655
2656
unlink $buildlog;
2657
2658
my $start_time = time;
2659
2660
# Failed builds should not reboot the target
2661
my $save_no_reboot = $no_reboot;
2662
$no_reboot = 1;
2663
2664
# Calculate a new version from here.
2665
$have_version = 0;
2666
2667
if (defined($pre_build)) {
2668
my $ret = run_command $pre_build;
2669
if (!$ret && defined($pre_build_die) &&
2670
$pre_build_die) {
2671
dodie "failed to pre_build\n";
2672
}
2673
}
2674
2675
if ($type =~ /^useconfig:(.*)/) {
2676
run_command "cp $1 $output_config" or
2677
dodie "could not copy $1 to .config";
2678
2679
$type = "oldconfig";
2680
}
2681
2682
# old config can ask questions
2683
if ($type eq "oldconfig") {
2684
$type = "olddefconfig";
2685
2686
# allow for empty configs
2687
run_command "touch $output_config";
2688
2689
if (!$noclean) {
2690
run_command "mv $output_config $outputdir/config_temp" or
2691
dodie "moving .config";
2692
2693
run_command "$make mrproper" or dodie "make mrproper";
2694
2695
run_command "mv $outputdir/config_temp $output_config" or
2696
dodie "moving config_temp";
2697
}
2698
} elsif (!$noclean) {
2699
unlink "$output_config";
2700
run_command "$make mrproper" or
2701
dodie "make mrproper";
2702
}
2703
2704
# add something to distinguish this build
2705
open(OUT, "> $outputdir/localversion") or dodie("Can't make localversion file");
2706
print OUT "$localversion\n";
2707
close(OUT);
2708
2709
if (defined($minconfig)) {
2710
load_force_config($minconfig);
2711
}
2712
2713
if ($type ne "olddefconfig") {
2714
run_command "$make $type" or
2715
dodie "failed make config";
2716
}
2717
# Run old config regardless, to enforce min configurations
2718
make_oldconfig;
2719
2720
if (not defined($build_options)){
2721
$build_options = "";
2722
}
2723
my $build_ret = run_command "$make $build_options", $buildlog;
2724
2725
if (defined($post_build)) {
2726
# Because a post build may change the kernel version
2727
# do it now.
2728
get_version;
2729
my $ret = run_command $post_build;
2730
if (!$ret && defined($post_build_die) &&
2731
$post_build_die) {
2732
dodie "failed to post_build\n";
2733
}
2734
}
2735
2736
if (!$build_ret) {
2737
# bisect may need this to pass
2738
if ($in_bisect) {
2739
$no_reboot = $save_no_reboot;
2740
return 0;
2741
}
2742
fail "failed build" and return 0;
2743
}
2744
2745
$no_reboot = $save_no_reboot;
2746
2747
my $end_time = time;
2748
$build_time = $end_time - $start_time;
2749
2750
return 1;
2751
}
2752
2753
sub halt {
2754
if (!run_ssh "halt" or defined($power_off)) {
2755
if (defined($poweroff_after_halt)) {
2756
sleep $poweroff_after_halt;
2757
run_command "$power_off";
2758
}
2759
} else {
2760
# nope? the zap it!
2761
run_command "$power_off";
2762
}
2763
}
2764
2765
sub success {
2766
my ($i) = @_;
2767
2768
$successes++;
2769
2770
my $name = "";
2771
2772
if (defined($test_name)) {
2773
$name = " ($test_name)";
2774
}
2775
2776
print_times;
2777
2778
doprint "\n\n";
2779
doprint "*******************************************\n";
2780
doprint "*******************************************\n";
2781
doprint "KTEST RESULT: TEST $i$name SUCCESS!!!! **\n";
2782
doprint "*******************************************\n";
2783
doprint "*******************************************\n";
2784
2785
if (defined($store_successes)) {
2786
save_logs "success", $store_successes;
2787
}
2788
2789
if ($i != $opt{"NUM_TESTS"} && !do_not_reboot) {
2790
doprint "Reboot and wait $sleep_time seconds\n";
2791
reboot_to_good $sleep_time;
2792
}
2793
2794
if (defined($post_test)) {
2795
run_command $post_test;
2796
}
2797
}
2798
2799
sub answer_bisect {
2800
for (;;) {
2801
doprint "Pass, fail, or skip? [p/f/s]";
2802
my $ans = <STDIN>;
2803
chomp $ans;
2804
if ($ans eq "p" || $ans eq "P") {
2805
return 1;
2806
} elsif ($ans eq "f" || $ans eq "F") {
2807
return 0;
2808
} elsif ($ans eq "s" || $ans eq "S") {
2809
return -1;
2810
} else {
2811
print "Please answer 'p', 'f', or 's'\n";
2812
}
2813
}
2814
}
2815
2816
sub child_run_test {
2817
2818
# child should have no power
2819
$reboot_on_error = 0;
2820
$poweroff_on_error = 0;
2821
$die_on_failure = 1;
2822
2823
run_command $run_test, $testlog;
2824
2825
exit $run_command_status;
2826
}
2827
2828
sub child_finished {
2829
$child_done = 1;
2830
}
2831
2832
sub do_run_test {
2833
my $child_pid;
2834
my $child_exit;
2835
my $line;
2836
my $full_line;
2837
my $bug = 0;
2838
my $bug_ignored = 0;
2839
2840
my $start_time = time;
2841
2842
wait_for_monitor 1;
2843
2844
doprint "run test $run_test\n";
2845
2846
$child_done = 0;
2847
2848
$SIG{CHLD} = qw(child_finished);
2849
2850
$child_pid = fork;
2851
2852
child_run_test if (!$child_pid);
2853
2854
$full_line = "";
2855
2856
do {
2857
$line = wait_for_input($monitor_fp, 1);
2858
if (defined($line)) {
2859
2860
# we are not guaranteed to get a full line
2861
$full_line .= $line;
2862
doprint $line;
2863
2864
if ($full_line =~ /call trace:/i) {
2865
if ($ignore_errors) {
2866
$bug_ignored = 1;
2867
} else {
2868
$bug = 1;
2869
}
2870
}
2871
2872
if ($full_line =~ /Kernel panic -/) {
2873
$bug = 1;
2874
}
2875
2876
if ($line =~ /\n/) {
2877
$full_line = "";
2878
}
2879
}
2880
} while (!$child_done && !$bug);
2881
2882
if (!$bug && $bug_ignored) {
2883
doprint "WARNING: Call Trace detected but ignored due to IGNORE_ERRORS=1\n";
2884
}
2885
2886
if ($bug) {
2887
my $failure_start = time;
2888
my $now;
2889
do {
2890
$line = wait_for_input($monitor_fp, 1);
2891
if (defined($line)) {
2892
doprint $line;
2893
}
2894
$now = time;
2895
if ($now - $failure_start >= $stop_after_failure) {
2896
last;
2897
}
2898
} while (defined($line));
2899
2900
doprint "Detected kernel crash!\n";
2901
# kill the child with extreme prejudice
2902
kill 9, $child_pid;
2903
}
2904
2905
waitpid $child_pid, 0;
2906
$child_exit = $? >> 8;
2907
2908
my $end_time = time;
2909
$test_time = $end_time - $start_time;
2910
2911
if (!$bug && $in_bisect) {
2912
if (defined($bisect_ret_good)) {
2913
if ($child_exit == $bisect_ret_good) {
2914
return 1;
2915
}
2916
}
2917
if (defined($bisect_ret_skip)) {
2918
if ($child_exit == $bisect_ret_skip) {
2919
return -1;
2920
}
2921
}
2922
if (defined($bisect_ret_abort)) {
2923
if ($child_exit == $bisect_ret_abort) {
2924
fail "test abort" and return -2;
2925
}
2926
}
2927
if (defined($bisect_ret_bad)) {
2928
if ($child_exit == $bisect_ret_skip) {
2929
return 0;
2930
}
2931
}
2932
if (defined($bisect_ret_default)) {
2933
if ($bisect_ret_default eq "good") {
2934
return 1;
2935
} elsif ($bisect_ret_default eq "bad") {
2936
return 0;
2937
} elsif ($bisect_ret_default eq "skip") {
2938
return -1;
2939
} elsif ($bisect_ret_default eq "abort") {
2940
return -2;
2941
} else {
2942
fail "unknown default action: $bisect_ret_default"
2943
and return -2;
2944
}
2945
}
2946
}
2947
2948
if ($bug || $child_exit) {
2949
return 0 if $in_bisect;
2950
fail "test failed" and return 0;
2951
}
2952
return 1;
2953
}
2954
2955
sub run_git_bisect {
2956
my ($command) = @_;
2957
2958
doprint "$command ... ";
2959
2960
my $output = `$command 2>&1`;
2961
my $ret = $?;
2962
2963
logit $output;
2964
2965
if ($ret) {
2966
doprint "FAILED\n";
2967
dodie "Failed to git bisect";
2968
}
2969
2970
doprint "SUCCESS\n";
2971
if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\))\s+\[([[:xdigit:]]+)\]/) {
2972
doprint "$1 [$2]\n";
2973
} elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) {
2974
$bisect_bad_commit = $1;
2975
doprint "Found bad commit... $1\n";
2976
return 0;
2977
} else {
2978
# we already logged it, just print it now.
2979
print $output;
2980
}
2981
2982
return 1;
2983
}
2984
2985
sub bisect_reboot {
2986
doprint "Reboot and sleep $bisect_sleep_time seconds\n";
2987
reboot_to_good $bisect_sleep_time;
2988
}
2989
2990
# returns 1 on success, 0 on failure, -1 on skip
2991
sub run_bisect_test {
2992
my ($type, $buildtype) = @_;
2993
2994
my $failed = 0;
2995
my $result;
2996
2997
$in_bisect = 1;
2998
2999
build $buildtype or $failed = 1;
3000
3001
if ($type ne "build") {
3002
if ($failed && $bisect_skip) {
3003
$in_bisect = 0;
3004
return -1;
3005
}
3006
dodie "Failed on build" if $failed;
3007
3008
# Now boot the box
3009
start_monitor_and_install or $failed = 1;
3010
3011
if ($type ne "boot") {
3012
if ($failed && $bisect_skip) {
3013
end_monitor;
3014
bisect_reboot;
3015
$in_bisect = 0;
3016
return -1;
3017
}
3018
dodie "Failed on boot" if $failed;
3019
3020
do_run_test or $failed = 1;
3021
}
3022
end_monitor;
3023
}
3024
3025
if ($failed) {
3026
$result = 0;
3027
} else {
3028
$result = 1;
3029
}
3030
3031
# reboot the box to a kernel we can ssh to
3032
if ($type ne "build") {
3033
bisect_reboot;
3034
}
3035
$in_bisect = 0;
3036
3037
return $result;
3038
}
3039
3040
sub run_bisect {
3041
my ($type) = @_;
3042
my $buildtype = "oldconfig";
3043
3044
# We should have a minconfig to use?
3045
if (defined($minconfig)) {
3046
$buildtype = "useconfig:$minconfig";
3047
}
3048
3049
# If the user sets bisect_tries to less than 1, then no tries
3050
# is a success.
3051
my $ret = 1;
3052
3053
# Still let the user manually decide that though.
3054
if ($bisect_tries < 1 && $bisect_manual) {
3055
$ret = answer_bisect;
3056
}
3057
3058
for (my $i = 0; $i < $bisect_tries; $i++) {
3059
if ($bisect_tries > 1) {
3060
my $t = $i + 1;
3061
doprint("Running bisect trial $t of $bisect_tries:\n");
3062
}
3063
$ret = run_bisect_test $type, $buildtype;
3064
3065
if ($bisect_manual) {
3066
$ret = answer_bisect;
3067
}
3068
3069
last if (!$ret);
3070
}
3071
3072
# Are we looking for where it worked, not failed?
3073
if ($reverse_bisect && $ret >= 0) {
3074
$ret = !$ret;
3075
}
3076
3077
if ($ret > 0) {
3078
return "good";
3079
} elsif ($ret == 0) {
3080
return "bad";
3081
} elsif ($bisect_skip) {
3082
doprint "HIT A BAD COMMIT ... SKIPPING\n";
3083
return "skip";
3084
}
3085
}
3086
3087
sub update_bisect_replay {
3088
my $tmp_log = "$tmpdir/ktest_bisect_log";
3089
run_command "git bisect log > $tmp_log" or
3090
dodie "can't create bisect log";
3091
return $tmp_log;
3092
}
3093
3094
sub bisect {
3095
my ($i) = @_;
3096
3097
my $result;
3098
3099
dodie "BISECT_GOOD[$i] not defined\n" if (!defined($bisect_good));
3100
dodie "BISECT_BAD[$i] not defined\n" if (!defined($bisect_bad));
3101
dodie "BISECT_TYPE[$i] not defined\n" if (!defined($bisect_type));
3102
3103
my $good = $bisect_good;
3104
my $bad = $bisect_bad;
3105
my $type = $bisect_type;
3106
my $start = $bisect_start;
3107
my $replay = $bisect_replay;
3108
my $start_files = $bisect_files;
3109
3110
if (defined($start_files)) {
3111
$start_files = " -- " . $start_files;
3112
} else {
3113
$start_files = "";
3114
}
3115
3116
# convert to true sha1's
3117
$good = get_sha1($good);
3118
$bad = get_sha1($bad);
3119
3120
if (defined($bisect_reverse) && $bisect_reverse == 1) {
3121
doprint "Performing a reverse bisect (bad is good, good is bad!)\n";
3122
$reverse_bisect = 1;
3123
} else {
3124
$reverse_bisect = 0;
3125
}
3126
3127
# Can't have a test without having a test to run
3128
if ($type eq "test" && !defined($run_test)) {
3129
$type = "boot";
3130
}
3131
3132
# Check if a bisect was running
3133
my $bisect_start_file = "$builddir/.git/BISECT_START";
3134
3135
my $check = $bisect_check;
3136
my $do_check = defined($check) && $check ne "0";
3137
3138
if ( -f $bisect_start_file ) {
3139
print "Bisect in progress found\n";
3140
if ($do_check) {
3141
print " If you say yes, then no checks of good or bad will be done\n";
3142
}
3143
if (defined($replay)) {
3144
print "** BISECT_REPLAY is defined in config file **";
3145
print " Ignore config option and perform new git bisect log?\n";
3146
if (read_ync " (yes, no, or cancel) ") {
3147
$replay = update_bisect_replay;
3148
$do_check = 0;
3149
}
3150
} elsif (read_yn "read git log and continue?") {
3151
$replay = update_bisect_replay;
3152
$do_check = 0;
3153
}
3154
}
3155
3156
if ($do_check) {
3157
# get current HEAD
3158
my $head = get_sha1("HEAD");
3159
3160
if ($check ne "good") {
3161
doprint "TESTING BISECT BAD [$bad]\n";
3162
run_command "git checkout $bad" or
3163
dodie "Failed to checkout $bad";
3164
3165
$result = run_bisect $type;
3166
3167
if ($result ne "bad") {
3168
fail "Tested BISECT_BAD [$bad] and it succeeded" and return 0;
3169
}
3170
}
3171
3172
if ($check ne "bad") {
3173
doprint "TESTING BISECT GOOD [$good]\n";
3174
run_command "git checkout $good" or
3175
dodie "Failed to checkout $good";
3176
3177
$result = run_bisect $type;
3178
3179
if ($result ne "good") {
3180
fail "Tested BISECT_GOOD [$good] and it failed" and return 0;
3181
}
3182
}
3183
3184
# checkout where we started
3185
run_command "git checkout $head" or
3186
dodie "Failed to checkout $head";
3187
}
3188
3189
run_command "git bisect start$start_files" or
3190
dodie "could not start bisect";
3191
3192
if (defined($replay)) {
3193
run_command "git bisect replay $replay" or
3194
dodie "failed to run replay";
3195
} else {
3196
run_command "git bisect good $good" or
3197
dodie "could not set bisect good to $good";
3198
3199
run_git_bisect "git bisect bad $bad" or
3200
dodie "could not set bisect bad to $bad";
3201
}
3202
3203
if (defined($start)) {
3204
run_command "git checkout $start" or
3205
dodie "failed to checkout $start";
3206
}
3207
3208
my $test;
3209
do {
3210
$result = run_bisect $type;
3211
$test = run_git_bisect "git bisect $result";
3212
print_times;
3213
} while ($test);
3214
3215
run_command "git bisect log" or
3216
dodie "could not capture git bisect log";
3217
3218
run_command "git bisect reset" or
3219
dodie "could not reset git bisect";
3220
3221
doprint "Bad commit was [$bisect_bad_commit]\n";
3222
3223
success $i;
3224
}
3225
3226
sub assign_configs {
3227
my ($hash, $config) = @_;
3228
3229
doprint "Reading configs from $config\n";
3230
3231
open (IN, $config) or
3232
dodie "Failed to read $config";
3233
3234
while (<IN>) {
3235
chomp;
3236
if (/^((CONFIG\S*)=.*)/) {
3237
${$hash}{$2} = $1;
3238
} elsif (/^(# (CONFIG\S*) is not set)/) {
3239
${$hash}{$2} = $1;
3240
}
3241
}
3242
3243
close(IN);
3244
}
3245
3246
sub process_config_ignore {
3247
my ($config) = @_;
3248
3249
assign_configs \%config_ignore, $config;
3250
}
3251
3252
sub get_dependencies {
3253
my ($config) = @_;
3254
3255
my $arr = $dependency{$config};
3256
if (!defined($arr)) {
3257
return ();
3258
}
3259
3260
my @deps = @{$arr};
3261
3262
foreach my $dep (@{$arr}) {
3263
print "ADD DEP $dep\n";
3264
@deps = (@deps, get_dependencies $dep);
3265
}
3266
3267
return @deps;
3268
}
3269
3270
sub save_config {
3271
my ($pc, $file) = @_;
3272
3273
my %configs = %{$pc};
3274
3275
doprint "Saving configs into $file\n";
3276
3277
open(OUT, ">$file") or dodie "Can not write to $file";
3278
3279
foreach my $config (keys %configs) {
3280
print OUT "$configs{$config}\n";
3281
}
3282
close(OUT);
3283
}
3284
3285
sub create_config {
3286
my ($name, $pc) = @_;
3287
3288
doprint "Creating old config from $name configs\n";
3289
3290
save_config $pc, $output_config;
3291
3292
make_oldconfig;
3293
}
3294
3295
sub run_config_bisect_test {
3296
my ($type) = @_;
3297
3298
my $ret = run_bisect_test $type, "oldconfig";
3299
3300
if ($bisect_manual) {
3301
$ret = answer_bisect;
3302
}
3303
3304
return $ret;
3305
}
3306
3307
sub config_bisect_end {
3308
my ($good, $bad) = @_;
3309
my $diffexec = "diff -u";
3310
3311
if (-f "$builddir/scripts/diffconfig") {
3312
$diffexec = "$builddir/scripts/diffconfig";
3313
}
3314
doprint "\n\n***************************************\n";
3315
doprint "No more config bisecting possible.\n";
3316
run_command "$diffexec $good $bad", 1;
3317
doprint "***************************************\n\n";
3318
}
3319
3320
sub run_config_bisect {
3321
my ($good, $bad, $last_result) = @_;
3322
my $reset = "";
3323
my $cmd;
3324
my $ret;
3325
3326
if (!length($last_result)) {
3327
$reset = "-r";
3328
}
3329
run_command "$config_bisect_exec $reset -b $outputdir $good $bad $last_result", 1;
3330
3331
# config-bisect returns:
3332
# 0 if there is more to bisect
3333
# 1 for finding a good config
3334
# 2 if it can not find any more configs
3335
# -1 (255) on error
3336
if ($run_command_status) {
3337
return $run_command_status;
3338
}
3339
3340
$ret = run_config_bisect_test $config_bisect_type;
3341
if ($ret) {
3342
doprint "NEW GOOD CONFIG ($pass)\n";
3343
system("cp $output_config $tmpdir/good_config.tmp.$pass");
3344
$pass++;
3345
# Return 3 for good config
3346
return 3;
3347
} else {
3348
doprint "NEW BAD CONFIG ($pass)\n";
3349
system("cp $output_config $tmpdir/bad_config.tmp.$pass");
3350
$pass++;
3351
# Return 4 for bad config
3352
return 4;
3353
}
3354
}
3355
3356
sub config_bisect {
3357
my ($i) = @_;
3358
3359
my $good_config;
3360
my $bad_config;
3361
3362
my $type = $config_bisect_type;
3363
my $ret;
3364
3365
$bad_config = $config_bisect;
3366
3367
if (defined($config_bisect_good)) {
3368
$good_config = $config_bisect_good;
3369
} elsif (defined($minconfig)) {
3370
$good_config = $minconfig;
3371
} else {
3372
doprint "No config specified, checking if defconfig works";
3373
$ret = run_bisect_test $type, "defconfig";
3374
if (!$ret) {
3375
fail "Have no good config to compare with, please set CONFIG_BISECT_GOOD";
3376
return 1;
3377
}
3378
$good_config = $output_config;
3379
}
3380
3381
if (!defined($config_bisect_exec)) {
3382
# First check the location that ktest.pl ran
3383
my @locations = (
3384
"$pwd/config-bisect.pl",
3385
"$dirname/config-bisect.pl",
3386
"$builddir/tools/testing/ktest/config-bisect.pl",
3387
undef );
3388
foreach my $loc (@locations) {
3389
doprint "loc = $loc\n";
3390
$config_bisect_exec = $loc;
3391
last if (defined($config_bisect_exec && -x $config_bisect_exec));
3392
}
3393
if (!defined($config_bisect_exec)) {
3394
fail "Could not find an executable config-bisect.pl\n",
3395
" Set CONFIG_BISECT_EXEC to point to config-bisect.pl";
3396
return 1;
3397
}
3398
}
3399
3400
# we don't want min configs to cause issues here.
3401
doprint "Disabling 'MIN_CONFIG' for this test\n";
3402
undef $minconfig;
3403
3404
my %good_configs;
3405
my %bad_configs;
3406
my %tmp_configs;
3407
3408
if (-f "$tmpdir/good_config.tmp" || -f "$tmpdir/bad_config.tmp") {
3409
if (read_yn "Interrupted config-bisect. Continue (n - will start new)?") {
3410
if (-f "$tmpdir/good_config.tmp") {
3411
$good_config = "$tmpdir/good_config.tmp";
3412
} else {
3413
$good_config = "$tmpdir/good_config";
3414
}
3415
if (-f "$tmpdir/bad_config.tmp") {
3416
$bad_config = "$tmpdir/bad_config.tmp";
3417
} else {
3418
$bad_config = "$tmpdir/bad_config";
3419
}
3420
}
3421
}
3422
doprint "Run good configs through make oldconfig\n";
3423
assign_configs \%tmp_configs, $good_config;
3424
create_config "$good_config", \%tmp_configs;
3425
$good_config = "$tmpdir/good_config";
3426
system("cp $output_config $good_config") == 0 or dodie "cp good config";
3427
3428
doprint "Run bad configs through make oldconfig\n";
3429
assign_configs \%tmp_configs, $bad_config;
3430
create_config "$bad_config", \%tmp_configs;
3431
$bad_config = "$tmpdir/bad_config";
3432
system("cp $output_config $bad_config") == 0 or dodie "cp bad config";
3433
3434
if (defined($config_bisect_check) && $config_bisect_check ne "0") {
3435
if ($config_bisect_check ne "good") {
3436
doprint "Testing bad config\n";
3437
3438
$ret = run_bisect_test $type, "useconfig:$bad_config";
3439
if ($ret) {
3440
fail "Bad config succeeded when expected to fail!";
3441
return 0;
3442
}
3443
}
3444
if ($config_bisect_check ne "bad") {
3445
doprint "Testing good config\n";
3446
3447
$ret = run_bisect_test $type, "useconfig:$good_config";
3448
if (!$ret) {
3449
fail "Good config failed when expected to succeed!";
3450
return 0;
3451
}
3452
}
3453
}
3454
3455
my $last_run = "";
3456
3457
do {
3458
$ret = run_config_bisect $good_config, $bad_config, $last_run;
3459
if ($ret == 3) {
3460
$last_run = "good";
3461
} elsif ($ret == 4) {
3462
$last_run = "bad";
3463
}
3464
print_times;
3465
} while ($ret == 3 || $ret == 4);
3466
3467
if ($ret == 2) {
3468
config_bisect_end "$good_config.tmp", "$bad_config.tmp";
3469
}
3470
3471
return $ret if ($ret < 0);
3472
3473
success $i;
3474
}
3475
3476
sub patchcheck_reboot {
3477
doprint "Reboot and sleep $patchcheck_sleep_time seconds\n";
3478
reboot_to_good $patchcheck_sleep_time;
3479
}
3480
3481
sub patchcheck {
3482
my ($i) = @_;
3483
3484
dodie "PATCHCHECK_START[$i] not defined\n"
3485
if (!defined($patchcheck_start));
3486
dodie "PATCHCHECK_TYPE[$i] not defined\n"
3487
if (!defined($patchcheck_type));
3488
3489
my $start = $patchcheck_start;
3490
3491
my $cherry = $patchcheck_cherry;
3492
if (!defined($cherry)) {
3493
$cherry = 0;
3494
}
3495
3496
my $end = "HEAD";
3497
if (defined($patchcheck_end)) {
3498
$end = $patchcheck_end;
3499
} elsif ($cherry) {
3500
dodie "PATCHCHECK_END must be defined with PATCHCHECK_CHERRY\n";
3501
}
3502
3503
# Get the true sha1's since we can use things like HEAD~3
3504
$start = get_sha1($start);
3505
$end = get_sha1($end);
3506
3507
my $type = $patchcheck_type;
3508
3509
# Can't have a test without having a test to run
3510
if ($type eq "test" && !defined($run_test)) {
3511
$type = "boot";
3512
}
3513
3514
if ($cherry) {
3515
open (IN, "git cherry -v $start $end|") or
3516
dodie "could not get git list";
3517
} else {
3518
open (IN, "git log --pretty=oneline $end|") or
3519
dodie "could not get git list";
3520
}
3521
3522
my @list;
3523
3524
while (<IN>) {
3525
chomp;
3526
# git cherry adds a '+' we want to remove
3527
s/^\+ //;
3528
$list[$#list+1] = $_;
3529
last if (/^$start/);
3530
}
3531
close(IN);
3532
3533
if (!$cherry) {
3534
if ($list[$#list] !~ /^$start/) {
3535
fail "SHA1 $start not found";
3536
}
3537
3538
# go backwards in the list
3539
@list = reverse @list;
3540
}
3541
3542
my %skip_list;
3543
my $will_skip = 0;
3544
3545
if (defined($patchcheck_skip)) {
3546
foreach my $s (split /\s+/, $patchcheck_skip) {
3547
$s = `git log --pretty=oneline $s~1..$s`;
3548
$s =~ s/^(\S+).*/$1/;
3549
chomp $s;
3550
$skip_list{$s} = 1;
3551
$will_skip++;
3552
}
3553
}
3554
3555
doprint("Going to test the following commits:\n");
3556
foreach my $l (@list) {
3557
my $sha1 = $l;
3558
$sha1 =~ s/^([[:xdigit:]]+).*/$1/;
3559
next if (defined($skip_list{$sha1}));
3560
doprint "$l\n";
3561
}
3562
3563
if ($will_skip) {
3564
doprint("\nSkipping the following commits:\n");
3565
foreach my $l (@list) {
3566
my $sha1 = $l;
3567
$sha1 =~ s/^([[:xdigit:]]+).*/$1/;
3568
next if (!defined($skip_list{$sha1}));
3569
doprint "$l\n";
3570
}
3571
}
3572
3573
my $save_clean = $noclean;
3574
my %ignored_warnings;
3575
3576
if (defined($ignore_warnings)) {
3577
foreach my $sha1 (split /\s+/, $ignore_warnings) {
3578
$ignored_warnings{$sha1} = 1;
3579
}
3580
}
3581
3582
$in_patchcheck = 1;
3583
foreach my $item (@list) {
3584
my $sha1 = $item;
3585
$sha1 =~ s/^([[:xdigit:]]+).*/$1/;
3586
3587
if (defined($skip_list{$sha1})) {
3588
doprint "\nSkipping \"$item\"\n\n";
3589
next;
3590
}
3591
3592
doprint "\nProcessing commit \"$item\"\n\n";
3593
3594
run_command "git checkout $sha1" or
3595
dodie "Failed to checkout $sha1";
3596
3597
# only clean on the first and last patch
3598
if ($item eq $list[0] ||
3599
$item eq $list[$#list]) {
3600
$noclean = $save_clean;
3601
} else {
3602
$noclean = 1;
3603
}
3604
3605
if (defined($minconfig)) {
3606
build "useconfig:$minconfig" or return 0;
3607
} else {
3608
# ?? no config to use?
3609
build "oldconfig" or return 0;
3610
}
3611
3612
# No need to do per patch checking if warnings file exists
3613
if (!defined($warnings_file) && !defined($ignored_warnings{$sha1})) {
3614
check_patch_buildlog $sha1 or return 0;
3615
}
3616
3617
check_buildlog or return 0;
3618
3619
next if ($type eq "build");
3620
3621
my $failed = 0;
3622
3623
start_monitor_and_install or $failed = 1;
3624
3625
if (!$failed && $type ne "boot"){
3626
do_run_test or $failed = 1;
3627
}
3628
end_monitor;
3629
if ($failed) {
3630
print_times;
3631
return 0;
3632
}
3633
patchcheck_reboot;
3634
print_times;
3635
}
3636
$in_patchcheck = 0;
3637
success $i;
3638
3639
return 1;
3640
}
3641
3642
sub add_dep {
3643
# $config depends on $dep
3644
my ($config, $dep) = @_;
3645
3646
if (defined($depends{$config})) {
3647
$depends{$config} .= " " . $dep;
3648
} else {
3649
$depends{$config} = $dep;
3650
}
3651
3652
# record the number of configs depending on $dep
3653
if (defined $depcount{$dep}) {
3654
$depcount{$dep}++;
3655
} else {
3656
$depcount{$dep} = 1;
3657
}
3658
}
3659
3660
# taken from streamline_config.pl
3661
sub read_kconfig {
3662
my ($kconfig) = @_;
3663
3664
my $state = "NONE";
3665
my $config;
3666
my @kconfigs;
3667
3668
my $cont = 0;
3669
my $line;
3670
3671
if (! -f $kconfig) {
3672
doprint "file $kconfig does not exist, skipping\n";
3673
return;
3674
}
3675
3676
open(KIN, "$kconfig")
3677
or dodie "Can't open $kconfig";
3678
while (<KIN>) {
3679
chomp;
3680
3681
# Make sure that lines ending with \ continue
3682
if ($cont) {
3683
$_ = $line . " " . $_;
3684
}
3685
3686
if (s/\\$//) {
3687
$cont = 1;
3688
$line = $_;
3689
next;
3690
}
3691
3692
$cont = 0;
3693
3694
# collect any Kconfig sources
3695
if (/^source\s*"(.*)"/) {
3696
$kconfigs[$#kconfigs+1] = $1;
3697
}
3698
3699
# configs found
3700
if (/^\s*(menu)?config\s+(\S+)\s*$/) {
3701
$state = "NEW";
3702
$config = $2;
3703
3704
for (my $i = 0; $i < $iflevel; $i++) {
3705
add_dep $config, $ifdeps[$i];
3706
}
3707
3708
# collect the depends for the config
3709
} elsif ($state eq "NEW" && /^\s*depends\s+on\s+(.*)$/) {
3710
3711
add_dep $config, $1;
3712
3713
# Get the configs that select this config
3714
} elsif ($state eq "NEW" && /^\s*select\s+(\S+)/) {
3715
3716
# selected by depends on config
3717
add_dep $1, $config;
3718
3719
# Check for if statements
3720
} elsif (/^if\s+(.*\S)\s*$/) {
3721
my $deps = $1;
3722
# remove beginning and ending non text
3723
$deps =~ s/^[^a-zA-Z0-9_]*//;
3724
$deps =~ s/[^a-zA-Z0-9_]*$//;
3725
3726
my @deps = split /[^a-zA-Z0-9_]+/, $deps;
3727
3728
$ifdeps[$iflevel++] = join ':', @deps;
3729
3730
} elsif (/^endif/) {
3731
3732
$iflevel-- if ($iflevel);
3733
3734
# stop on "help"
3735
} elsif (/^\s*help\s*$/) {
3736
$state = "NONE";
3737
}
3738
}
3739
close(KIN);
3740
3741
# read in any configs that were found.
3742
foreach $kconfig (@kconfigs) {
3743
if (!defined($read_kconfigs{$kconfig})) {
3744
$read_kconfigs{$kconfig} = 1;
3745
read_kconfig("$builddir/$kconfig");
3746
}
3747
}
3748
}
3749
3750
sub read_depends {
3751
# find out which arch this is by the kconfig file
3752
open (IN, $output_config) or
3753
dodie "Failed to read $output_config";
3754
my $arch;
3755
while (<IN>) {
3756
if (m,Linux/(\S+)\s+\S+\s+Kernel Configuration,) {
3757
$arch = $1;
3758
last;
3759
}
3760
}
3761
close IN;
3762
3763
if (!defined($arch)) {
3764
doprint "Could not find arch from config file\n";
3765
doprint "no dependencies used\n";
3766
return;
3767
}
3768
3769
# arch is really the subarch, we need to know
3770
# what directory to look at.
3771
if ($arch eq "i386" || $arch eq "x86_64") {
3772
$arch = "x86";
3773
}
3774
3775
my $kconfig = "$builddir/arch/$arch/Kconfig";
3776
3777
if (! -f $kconfig && $arch =~ /\d$/) {
3778
my $orig = $arch;
3779
# some subarchs have numbers, truncate them
3780
$arch =~ s/\d*$//;
3781
$kconfig = "$builddir/arch/$arch/Kconfig";
3782
if (! -f $kconfig) {
3783
doprint "No idea what arch dir $orig is for\n";
3784
doprint "no dependencies used\n";
3785
return;
3786
}
3787
}
3788
3789
read_kconfig($kconfig);
3790
}
3791
3792
sub make_new_config {
3793
my @configs = @_;
3794
3795
open (OUT, ">$output_config")
3796
or dodie "Failed to write $output_config";
3797
3798
foreach my $config (@configs) {
3799
print OUT "$config\n";
3800
}
3801
close OUT;
3802
}
3803
3804
sub chomp_config {
3805
my ($config) = @_;
3806
3807
$config =~ s/CONFIG_//;
3808
3809
return $config;
3810
}
3811
3812
sub get_depends {
3813
my ($dep) = @_;
3814
3815
my $kconfig = chomp_config $dep;
3816
3817
$dep = $depends{"$kconfig"};
3818
3819
# the dep string we have saves the dependencies as they
3820
# were found, including expressions like ! && ||. We
3821
# want to split this out into just an array of configs.
3822
3823
my $valid = "A-Za-z_0-9";
3824
3825
my @configs;
3826
3827
while ($dep =~ /[$valid]/) {
3828
if ($dep =~ /^[^$valid]*([$valid]+)/) {
3829
my $conf = "CONFIG_" . $1;
3830
3831
$configs[$#configs + 1] = $conf;
3832
3833
$dep =~ s/^[^$valid]*[$valid]+//;
3834
} else {
3835
dodie "this should never happen";
3836
}
3837
}
3838
3839
return @configs;
3840
}
3841
3842
sub test_this_config {
3843
my ($config) = @_;
3844
3845
my $found;
3846
3847
# if we already processed this config, skip it
3848
if (defined($processed_configs{$config})) {
3849
return undef;
3850
}
3851
$processed_configs{$config} = 1;
3852
3853
# if this config failed during this round, skip it
3854
if (defined($nochange_config{$config})) {
3855
return undef;
3856
}
3857
3858
my $kconfig = chomp_config $config;
3859
3860
# Test dependencies first
3861
if (defined($depends{"$kconfig"})) {
3862
my @parents = get_depends $config;
3863
foreach my $parent (@parents) {
3864
# if the parent is in the min config, check it first
3865
next if (!defined($min_configs{$parent}));
3866
$found = test_this_config($parent);
3867
if (defined($found)) {
3868
return $found;
3869
}
3870
}
3871
}
3872
3873
# Remove this config from the list of configs
3874
# do a make olddefconfig and then read the resulting
3875
# .config to make sure it is missing the config that
3876
# we had before
3877
my %configs = %min_configs;
3878
$configs{$config} = "# $config is not set";
3879
make_new_config ((values %configs), (values %keep_configs));
3880
make_oldconfig;
3881
delete $configs{$config};
3882
undef %configs;
3883
assign_configs \%configs, $output_config;
3884
3885
if (!defined($configs{$config}) || $configs{$config} =~ /^#/) {
3886
return $config;
3887
}
3888
3889
doprint "disabling config $config did not change .config\n";
3890
3891
$nochange_config{$config} = 1;
3892
3893
return undef;
3894
}
3895
3896
sub make_min_config {
3897
my ($i) = @_;
3898
3899
my $type = $minconfig_type;
3900
if ($type ne "boot" && $type ne "test") {
3901
fail "Invalid MIN_CONFIG_TYPE '$minconfig_type'\n" .
3902
" make_min_config works only with 'boot' and 'test'\n" and return;
3903
}
3904
3905
if (!defined($output_minconfig)) {
3906
fail "OUTPUT_MIN_CONFIG not defined" and return;
3907
}
3908
3909
# If output_minconfig exists, and the start_minconfig
3910
# came from min_config, than ask if we should use
3911
# that instead.
3912
if (-f $output_minconfig && !$start_minconfig_defined) {
3913
print "$output_minconfig exists\n";
3914
if (!defined($use_output_minconfig)) {
3915
if (read_yn " Use it as minconfig?") {
3916
$start_minconfig = $output_minconfig;
3917
}
3918
} elsif ($use_output_minconfig > 0) {
3919
doprint "Using $output_minconfig as MIN_CONFIG\n";
3920
$start_minconfig = $output_minconfig;
3921
} else {
3922
doprint "Set to still use MIN_CONFIG as starting point\n";
3923
}
3924
}
3925
3926
if (!defined($start_minconfig)) {
3927
fail "START_MIN_CONFIG or MIN_CONFIG not defined" and return;
3928
}
3929
3930
my $temp_config = "$tmpdir/temp_config";
3931
3932
# First things first. We build an allnoconfig to find
3933
# out what the defaults are that we can't touch.
3934
# Some are selections, but we really can't handle selections.
3935
3936
my $save_minconfig = $minconfig;
3937
undef $minconfig;
3938
3939
run_command "$make allnoconfig" or return 0;
3940
3941
read_depends;
3942
3943
process_config_ignore $output_config;
3944
3945
undef %save_configs;
3946
undef %min_configs;
3947
3948
if (defined($ignore_config)) {
3949
# make sure the file exists
3950
`touch $ignore_config`;
3951
assign_configs \%save_configs, $ignore_config;
3952
}
3953
3954
%keep_configs = %save_configs;
3955
3956
doprint "Load initial configs from $start_minconfig\n";
3957
3958
# Look at the current min configs, and save off all the
3959
# ones that were set via the allnoconfig
3960
assign_configs \%min_configs, $start_minconfig;
3961
3962
my @config_keys = keys %min_configs;
3963
3964
# All configs need a depcount
3965
foreach my $config (@config_keys) {
3966
my $kconfig = chomp_config $config;
3967
if (!defined $depcount{$kconfig}) {
3968
$depcount{$kconfig} = 0;
3969
}
3970
}
3971
3972
# Remove anything that was set by the make allnoconfig
3973
# we shouldn't need them as they get set for us anyway.
3974
foreach my $config (@config_keys) {
3975
# Remove anything in the ignore_config
3976
if (defined($keep_configs{$config})) {
3977
my $file = $ignore_config;
3978
$file =~ s,.*/(.*?)$,$1,;
3979
doprint "$config set by $file ... ignored\n";
3980
delete $min_configs{$config};
3981
next;
3982
}
3983
# But make sure the settings are the same. If a min config
3984
# sets a selection, we do not want to get rid of it if
3985
# it is not the same as what we have. Just move it into
3986
# the keep configs.
3987
if (defined($config_ignore{$config})) {
3988
if ($config_ignore{$config} ne $min_configs{$config}) {
3989
doprint "$config is in allnoconfig as '$config_ignore{$config}'";
3990
doprint " but it is '$min_configs{$config}' in minconfig .. keeping\n";
3991
$keep_configs{$config} = $min_configs{$config};
3992
} else {
3993
doprint "$config set by allnoconfig ... ignored\n";
3994
}
3995
delete $min_configs{$config};
3996
}
3997
}
3998
3999
my $done = 0;
4000
my $take_two = 0;
4001
4002
while (!$done) {
4003
my $config;
4004
my $found;
4005
4006
# Now disable each config one by one and do a make oldconfig
4007
# till we find a config that changes our list.
4008
4009
my @test_configs = keys %min_configs;
4010
4011
# Sort keys by who is most dependent on
4012
@test_configs = sort { $depcount{chomp_config($b)} <=> $depcount{chomp_config($a)} }
4013
@test_configs ;
4014
4015
# Put configs that did not modify the config at the end.
4016
my $reset = 1;
4017
for (my $i = 0; $i < $#test_configs; $i++) {
4018
if (!defined($nochange_config{$test_configs[0]})) {
4019
$reset = 0;
4020
last;
4021
}
4022
# This config didn't change the .config last time.
4023
# Place it at the end
4024
my $config = shift @test_configs;
4025
push @test_configs, $config;
4026
}
4027
4028
# if every test config has failed to modify the .config file
4029
# in the past, then reset and start over.
4030
if ($reset) {
4031
undef %nochange_config;
4032
}
4033
4034
undef %processed_configs;
4035
4036
foreach my $config (@test_configs) {
4037
4038
$found = test_this_config $config;
4039
4040
last if (defined($found));
4041
4042
# oh well, try another config
4043
}
4044
4045
if (!defined($found)) {
4046
# we could have failed due to the nochange_config hash
4047
# reset and try again
4048
if (!$take_two) {
4049
undef %nochange_config;
4050
$take_two = 1;
4051
next;
4052
}
4053
doprint "No more configs found that we can disable\n";
4054
$done = 1;
4055
last;
4056
}
4057
$take_two = 0;
4058
4059
$config = $found;
4060
4061
doprint "Test with $config disabled\n";
4062
4063
# set in_bisect to keep build and monitor from dieing
4064
$in_bisect = 1;
4065
4066
my $failed = 0;
4067
build "oldconfig" or $failed = 1;
4068
if (!$failed) {
4069
start_monitor_and_install or $failed = 1;
4070
4071
if ($type eq "test" && !$failed) {
4072
do_run_test or $failed = 1;
4073
}
4074
4075
end_monitor;
4076
}
4077
4078
$in_bisect = 0;
4079
4080
if ($failed) {
4081
doprint "$min_configs{$config} is needed to boot the box... keeping\n";
4082
# this config is needed, add it to the ignore list.
4083
$keep_configs{$config} = $min_configs{$config};
4084
$save_configs{$config} = $min_configs{$config};
4085
delete $min_configs{$config};
4086
4087
# update new ignore configs
4088
if (defined($ignore_config)) {
4089
open (OUT, ">$temp_config") or
4090
dodie "Can't write to $temp_config";
4091
foreach my $config (keys %save_configs) {
4092
print OUT "$save_configs{$config}\n";
4093
}
4094
close OUT;
4095
run_command "mv $temp_config $ignore_config" or
4096
dodie "failed to copy update to $ignore_config";
4097
}
4098
4099
} else {
4100
# We booted without this config, remove it from the minconfigs.
4101
doprint "$config is not needed, disabling\n";
4102
4103
delete $min_configs{$config};
4104
4105
# Also disable anything that is not enabled in this config
4106
my %configs;
4107
assign_configs \%configs, $output_config;
4108
my @config_keys = keys %min_configs;
4109
foreach my $config (@config_keys) {
4110
if (!defined($configs{$config})) {
4111
doprint "$config is not set, disabling\n";
4112
delete $min_configs{$config};
4113
}
4114
}
4115
4116
# Save off all the current mandatory configs
4117
open (OUT, ">$temp_config") or
4118
dodie "Can't write to $temp_config";
4119
foreach my $config (keys %keep_configs) {
4120
print OUT "$keep_configs{$config}\n";
4121
}
4122
foreach my $config (keys %min_configs) {
4123
print OUT "$min_configs{$config}\n";
4124
}
4125
close OUT;
4126
4127
run_command "mv $temp_config $output_minconfig" or
4128
dodie "failed to copy update to $output_minconfig";
4129
}
4130
4131
doprint "Reboot and wait $sleep_time seconds\n";
4132
reboot_to_good $sleep_time;
4133
}
4134
4135
success $i;
4136
return 1;
4137
}
4138
4139
sub make_warnings_file {
4140
my ($i) = @_;
4141
4142
if (!defined($warnings_file)) {
4143
dodie "Must define WARNINGS_FILE for make_warnings_file test";
4144
}
4145
4146
if ($build_type eq "nobuild") {
4147
dodie "BUILD_TYPE can not be 'nobuild' for make_warnings_file test";
4148
}
4149
4150
build $build_type or dodie "Failed to build";
4151
4152
open(OUT, ">$warnings_file") or dodie "Can't create $warnings_file";
4153
4154
open(IN, $buildlog) or dodie "Can't open $buildlog";
4155
while (<IN>) {
4156
# Some compilers use UTF-8 extended for quotes
4157
# for distcc heterogeneous systems, this causes issues
4158
s/$utf8_quote/'/g;
4159
4160
if (/$check_build_re/) {
4161
print OUT;
4162
}
4163
}
4164
close(IN);
4165
4166
close(OUT);
4167
4168
success $i;
4169
}
4170
4171
sub option_defined {
4172
my ($option) = @_;
4173
4174
if (defined($opt{$option}) && $opt{$option} !~ /^\s*$/) {
4175
return 1;
4176
}
4177
4178
return 0;
4179
}
4180
4181
sub __set_test_option {
4182
my ($name, $i) = @_;
4183
4184
my $option = "$name\[$i\]";
4185
4186
if (option_defined($option)) {
4187
return $opt{$option};
4188
}
4189
4190
foreach my $test (keys %repeat_tests) {
4191
if ($i >= $test &&
4192
$i < $test + $repeat_tests{$test}) {
4193
$option = "$name\[$test\]";
4194
if (option_defined($option)) {
4195
return $opt{$option};
4196
}
4197
}
4198
}
4199
4200
if (option_defined($name)) {
4201
return $opt{$name};
4202
}
4203
4204
return undef;
4205
}
4206
4207
sub set_test_option {
4208
my ($name, $i) = @_;
4209
4210
my $option = __set_test_option($name, $i);
4211
return $option if (!defined($option));
4212
4213
return eval_option($name, $option, $i);
4214
}
4215
4216
sub find_mailer {
4217
my ($mailer) = @_;
4218
4219
my @paths = split /:/, $ENV{PATH};
4220
4221
# sendmail is usually in /usr/sbin
4222
$paths[$#paths + 1] = "/usr/sbin";
4223
4224
foreach my $path (@paths) {
4225
if (-x "$path/$mailer") {
4226
return $path;
4227
}
4228
}
4229
4230
return undef;
4231
}
4232
4233
sub do_send_mail {
4234
my ($subject, $message, $file) = @_;
4235
4236
if (!defined($mail_path)) {
4237
# find the mailer
4238
$mail_path = find_mailer $mailer;
4239
if (!defined($mail_path)) {
4240
die "\nCan not find $mailer in PATH\n";
4241
}
4242
}
4243
4244
my $header_file = "$tmpdir/header";
4245
open (HEAD, ">$header_file") or die "Can not create $header_file\n";
4246
print HEAD "To: $mailto\n";
4247
print HEAD "Subject: $subject\n\n";
4248
print HEAD "$message\n";
4249
close HEAD;
4250
4251
if (!defined($mail_command)) {
4252
if ($mailer eq "mail" || $mailer eq "mailx") {
4253
$mail_command = "cat \$HEADER_FILE \$BODY_FILE | \$MAIL_PATH/\$MAILER -s \'\$SUBJECT\' \$MAILTO";
4254
} elsif ($mailer eq "sendmail" ) {
4255
$mail_command = "cat \$HEADER_FILE \$BODY_FILE | \$MAIL_PATH/\$MAILER -t \$MAILTO";
4256
} else {
4257
die "\nYour mailer: $mailer is not supported.\n";
4258
}
4259
}
4260
4261
if (defined($file)) {
4262
$mail_command =~ s/\$BODY_FILE/$file/g;
4263
} else {
4264
$mail_command =~ s/\$BODY_FILE//g;
4265
}
4266
4267
$mail_command =~ s/\$HEADER_FILE/$header_file/g;
4268
$mail_command =~ s/\$MAILER/$mailer/g;
4269
$mail_command =~ s/\$MAIL_PATH/$mail_path/g;
4270
$mail_command =~ s/\$MAILTO/$mailto/g;
4271
$mail_command =~ s/\$SUBJECT/$subject/g;
4272
$mail_command =~ s/\$MESSAGE/$message/g;
4273
4274
my $ret = run_command $mail_command;
4275
if (!$ret && defined($file)) {
4276
# try again without the file
4277
$message .= "\n\n*** FAILED TO SEND LOG ***\n\n";
4278
do_send_email($subject, $message);
4279
}
4280
}
4281
4282
sub send_email {
4283
if (defined($mailto)) {
4284
if (!defined($mailer)) {
4285
doprint "No email sent: email or mailer not specified in config.\n";
4286
return;
4287
}
4288
do_send_mail @_;
4289
}
4290
}
4291
4292
sub cancel_test {
4293
if ($monitor_cnt) {
4294
end_monitor;
4295
}
4296
if ($email_when_canceled) {
4297
my $name = get_test_name;
4298
send_email("KTEST: Your [$name] test was cancelled",
4299
"Your test started at $script_start_time was cancelled: sig int");
4300
}
4301
die "\nCaught Sig Int, test interrupted: $!\n"
4302
}
4303
4304
sub die_usage {
4305
die << "EOF"
4306
ktest.pl version: $VERSION
4307
usage: ktest.pl [options] [config-file]
4308
[options]:
4309
-D value: Where value can act as an option override.
4310
-D BUILD_NOCLEAN=1
4311
Sets global BUILD_NOCLEAN to 1
4312
-D TEST_TYPE[2]=build
4313
Sets TEST_TYPE of test 2 to "build"
4314
4315
It can also override all temp variables.
4316
-D USE_TEMP_DIR:=1
4317
Will override all variables that use
4318
"USE_TEMP_DIR="
4319
4320
EOF
4321
;
4322
}
4323
4324
while ( $#ARGV >= 0 ) {
4325
if ( $ARGV[0] eq "-D" ) {
4326
shift;
4327
die_usage if ($#ARGV < 1);
4328
my $val = shift;
4329
4330
if ($val =~ m/(.*?):=(.*)$/) {
4331
set_variable($1, $2, 1);
4332
} else {
4333
$command_vars[$#command_vars + 1] = $val;
4334
}
4335
4336
} elsif ( $ARGV[0] =~ m/^-D(.*)/) {
4337
my $val = $1;
4338
shift;
4339
4340
if ($val =~ m/(.*?):=(.*)$/) {
4341
set_variable($1, $2, 1);
4342
} else {
4343
$command_vars[$#command_vars + 1] = $val;
4344
}
4345
} elsif ( $ARGV[0] eq "-h" ) {
4346
die_usage;
4347
} else {
4348
last;
4349
}
4350
}
4351
4352
$#ARGV < 1 or die_usage;
4353
if ($#ARGV == 0) {
4354
$ktest_config = $ARGV[0];
4355
if (! -f $ktest_config) {
4356
print "$ktest_config does not exist.\n";
4357
if (!read_yn "Create it?") {
4358
exit 0;
4359
}
4360
}
4361
}
4362
4363
if (! -f $ktest_config) {
4364
$newconfig = 1;
4365
get_test_case;
4366
open(OUT, ">$ktest_config") or die "Can not create $ktest_config";
4367
print OUT << "EOF"
4368
# Generated by ktest.pl
4369
#
4370
4371
# PWD is a ktest.pl variable that will result in the process working
4372
# directory that ktest.pl is executed in.
4373
4374
# THIS_DIR is automatically assigned the PWD of the path that generated
4375
# the config file. It is best to use this variable when assigning other
4376
# directory paths within this directory. This allows you to easily
4377
# move the test cases to other locations or to other machines.
4378
#
4379
THIS_DIR := $variable{"PWD"}
4380
4381
# Define each test with TEST_START
4382
# The config options below it will override the defaults
4383
TEST_START
4384
TEST_TYPE = $default{"TEST_TYPE"}
4385
4386
DEFAULTS
4387
EOF
4388
;
4389
close(OUT);
4390
}
4391
read_config $ktest_config;
4392
4393
if (defined($opt{"LOG_FILE"})) {
4394
$opt{"LOG_FILE"} = eval_option("LOG_FILE", $opt{"LOG_FILE"}, -1);
4395
}
4396
4397
# Append any configs entered in manually to the config file.
4398
my @new_configs = keys %entered_configs;
4399
if ($#new_configs >= 0) {
4400
print "\nAppending entered in configs to $ktest_config\n";
4401
open(OUT, ">>$ktest_config") or die "Can not append to $ktest_config";
4402
foreach my $config (@new_configs) {
4403
print OUT "$config = $entered_configs{$config}\n";
4404
$opt{$config} = process_variables($entered_configs{$config});
4405
}
4406
}
4407
4408
if (defined($opt{"LOG_FILE"})) {
4409
if ($opt{"CLEAR_LOG"}) {
4410
unlink $opt{"LOG_FILE"};
4411
}
4412
4413
if (! -e $opt{"LOG_FILE"} && $opt{"LOG_FILE"} =~ m,^(.*/),) {
4414
my $dir = $1;
4415
if (! -d $dir) {
4416
mkpath($dir) or die "Failed to create directories '$dir': $!";
4417
print "\nThe log directory $dir did not exist, so it was created.\n";
4418
}
4419
}
4420
open(LOG, ">> $opt{LOG_FILE}") or die "Can't write to $opt{LOG_FILE}";
4421
LOG->autoflush(1);
4422
}
4423
4424
doprint "\n\nSTARTING AUTOMATED TESTS\n\n";
4425
4426
for (my $i = 0, my $repeat = 1; $i <= $opt{"NUM_TESTS"}; $i += $repeat) {
4427
4428
if (!$i) {
4429
doprint "DEFAULT OPTIONS:\n";
4430
} else {
4431
doprint "\nTEST $i OPTIONS";
4432
if (defined($repeat_tests{$i})) {
4433
$repeat = $repeat_tests{$i};
4434
doprint " ITERATE $repeat";
4435
}
4436
doprint "\n";
4437
}
4438
4439
foreach my $option (sort keys %opt) {
4440
if ($option =~ /\[(\d+)\]$/) {
4441
next if ($i != $1);
4442
} else {
4443
next if ($i);
4444
}
4445
4446
doprint "$option = $opt{$option}\n";
4447
}
4448
}
4449
4450
$SIG{INT} = qw(cancel_test);
4451
4452
# First we need to do is the builds
4453
for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
4454
4455
# Do not reboot on failing test options
4456
$no_reboot = 1;
4457
$reboot_success = 0;
4458
4459
$have_version = 0;
4460
4461
$iteration = $i;
4462
4463
$build_time = 0;
4464
$install_time = 0;
4465
$reboot_time = 0;
4466
$test_time = 0;
4467
4468
undef %force_config;
4469
4470
my $makecmd = set_test_option("MAKE_CMD", $i);
4471
4472
$outputdir = set_test_option("OUTPUT_DIR", $i);
4473
$builddir = set_test_option("BUILD_DIR", $i);
4474
4475
chdir $builddir || dodie "can't change directory to $builddir";
4476
4477
if (!-d $outputdir) {
4478
mkpath($outputdir) or
4479
dodie "can't create $outputdir";
4480
}
4481
4482
$make = "$makecmd O=$outputdir";
4483
4484
# Load all the options into their mapped variable names
4485
foreach my $opt (keys %option_map) {
4486
${$option_map{$opt}} = set_test_option($opt, $i);
4487
}
4488
4489
$start_minconfig_defined = 1;
4490
4491
# The first test may override the PRE_KTEST option
4492
if ($i == 1) {
4493
if (defined($pre_ktest)) {
4494
doprint "\n";
4495
run_command $pre_ktest;
4496
}
4497
if ($email_when_started) {
4498
my $name = get_test_name;
4499
send_email("KTEST: Your [$name] test was started",
4500
"Your test was started on $script_start_time");
4501
}
4502
}
4503
4504
# Any test can override the POST_KTEST option
4505
# The last test takes precedence.
4506
if (defined($post_ktest)) {
4507
$final_post_ktest = $post_ktest;
4508
}
4509
4510
if (!defined($start_minconfig)) {
4511
$start_minconfig_defined = 0;
4512
$start_minconfig = $minconfig;
4513
}
4514
4515
if (!-d $tmpdir) {
4516
mkpath($tmpdir) or
4517
dodie "can't create $tmpdir";
4518
}
4519
4520
$ENV{"SSH_USER"} = $ssh_user;
4521
$ENV{"MACHINE"} = $machine;
4522
4523
$buildlog = "$tmpdir/buildlog-$machine";
4524
$testlog = "$tmpdir/testlog-$machine";
4525
$dmesg = "$tmpdir/dmesg-$machine";
4526
$output_config = "$outputdir/.config";
4527
4528
if (!$buildonly) {
4529
$target = "$ssh_user\@$machine";
4530
if (($reboot_type eq "grub") or ($reboot_type eq "grub2bls")) {
4531
dodie "GRUB_MENU not defined" if (!defined($grub_menu));
4532
} elsif ($reboot_type eq "grub2") {
4533
dodie "GRUB_MENU not defined" if (!defined($grub_menu));
4534
dodie "GRUB_FILE not defined" if (!defined($grub_file));
4535
} elsif ($reboot_type eq "syslinux") {
4536
dodie "SYSLINUX_LABEL not defined" if (!defined($syslinux_label));
4537
}
4538
}
4539
4540
my $run_type = $build_type;
4541
if ($test_type eq "patchcheck") {
4542
$run_type = $patchcheck_type;
4543
} elsif ($test_type eq "bisect") {
4544
$run_type = $bisect_type;
4545
} elsif ($test_type eq "config_bisect") {
4546
$run_type = $config_bisect_type;
4547
} elsif ($test_type eq "make_min_config") {
4548
$run_type = "";
4549
} elsif ($test_type eq "make_warnings_file") {
4550
$run_type = "";
4551
}
4552
4553
# mistake in config file?
4554
if (!defined($run_type)) {
4555
$run_type = "ERROR";
4556
}
4557
4558
my $installme = "";
4559
$installme = " no_install" if ($no_install);
4560
4561
my $name = "";
4562
4563
if (defined($test_name)) {
4564
$name = " ($test_name)";
4565
}
4566
4567
doprint "\n\n";
4568
4569
if (defined($opt{"LOG_FILE"})) {
4570
$test_log_start = tell(LOG);
4571
}
4572
4573
doprint "RUNNING TEST $i of $opt{NUM_TESTS}$name with option $test_type $run_type$installme\n\n";
4574
4575
# Always show which build directory and output directory is being used
4576
doprint "BUILD_DIR=$builddir\n";
4577
doprint "OUTPUT_DIR=$outputdir\n\n";
4578
4579
if (defined($pre_test)) {
4580
my $ret = run_command $pre_test;
4581
if (!$ret && defined($pre_test_die) &&
4582
$pre_test_die) {
4583
dodie "failed to pre_test\n";
4584
}
4585
}
4586
4587
unlink $dmesg;
4588
unlink $buildlog;
4589
unlink $testlog;
4590
4591
if (defined($addconfig)) {
4592
my $min = $minconfig;
4593
if (!defined($minconfig)) {
4594
$min = "";
4595
}
4596
run_command "cat $addconfig $min > $tmpdir/add_config" or
4597
dodie "Failed to create temp config";
4598
$minconfig = "$tmpdir/add_config";
4599
}
4600
4601
if (defined($checkout)) {
4602
run_command "git checkout $checkout" or
4603
dodie "failed to checkout $checkout";
4604
}
4605
4606
$no_reboot = 0;
4607
4608
# A test may opt to not reboot the box
4609
if ($reboot_on_success) {
4610
$reboot_success = 1;
4611
}
4612
4613
if ($test_type eq "bisect") {
4614
bisect $i;
4615
next;
4616
} elsif ($test_type eq "config_bisect") {
4617
config_bisect $i;
4618
next;
4619
} elsif ($test_type eq "patchcheck") {
4620
patchcheck $i;
4621
next;
4622
} elsif ($test_type eq "make_min_config") {
4623
make_min_config $i;
4624
next;
4625
} elsif ($test_type eq "make_warnings_file") {
4626
$no_reboot = 1;
4627
make_warnings_file $i;
4628
next;
4629
}
4630
4631
if ($build_type ne "nobuild") {
4632
build $build_type or next;
4633
check_buildlog or next;
4634
}
4635
4636
if ($test_type eq "install") {
4637
get_version;
4638
install;
4639
success $i;
4640
next;
4641
}
4642
4643
if ($test_type ne "build") {
4644
my $failed = 0;
4645
start_monitor_and_install or $failed = 1;
4646
4647
if (!$failed && $test_type ne "boot" && defined($run_test)) {
4648
do_run_test or $failed = 1;
4649
}
4650
end_monitor;
4651
if ($failed) {
4652
print_times;
4653
next;
4654
}
4655
}
4656
4657
print_times;
4658
4659
success $i;
4660
}
4661
4662
if (defined($final_post_ktest)) {
4663
4664
my $cp_final_post_ktest = eval_kernel_version $final_post_ktest;
4665
run_command $cp_final_post_ktest;
4666
}
4667
4668
if ($opt{"POWEROFF_ON_SUCCESS"}) {
4669
halt;
4670
} elsif ($opt{"REBOOT_ON_SUCCESS"} && !do_not_reboot && $reboot_success) {
4671
reboot_to_good;
4672
} elsif (defined($switch_to_good)) {
4673
# still need to get to the good kernel
4674
run_command $switch_to_good;
4675
}
4676
4677
doprint "\n $successes of $opt{NUM_TESTS} tests were successful\n\n";
4678
4679
if ($email_when_finished) {
4680
send_email("KTEST: Your test has finished!",
4681
"$successes of $opt{NUM_TESTS} tests started at $script_start_time were successful!");
4682
}
4683
4684
if (defined($opt{"LOG_FILE"})) {
4685
print "\n See $opt{LOG_FILE} for the record of results.\n\n";
4686
close LOG;
4687
}
4688
4689
exit 0;
4690
4691
##
4692
# The following are here to standardize tabs/spaces/etc across the most likely editors
4693
###
4694
4695
# Local Variables:
4696
# mode: perl
4697
# End:
4698
# vim: softtabstop=4
4699
4700