From d30e0e242e82870de06848cc5351dab48165e280 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dag-Erling=20Sm=C3=B8rgrav?= Date: Mon, 21 Jun 2004 14:49:22 +0000 Subject: [PATCH] Add a timeout after which tinderbox(1) will kill its children and exit. --- tools/tools/tinderbox/tbmaster.1 | 6 +++++- tools/tools/tinderbox/tbmaster.pl | 3 +++ tools/tools/tinderbox/tinderbox.1 | 5 ++++- tools/tools/tinderbox/tinderbox.pl | 25 ++++++++++++++++++++++++- 4 files changed, 36 insertions(+), 3 deletions(-) diff --git a/tools/tools/tinderbox/tbmaster.1 b/tools/tools/tinderbox/tbmaster.1 index 64d824d63882..96d90e3da6df 100644 --- a/tools/tools/tinderbox/tbmaster.1 +++ b/tools/tools/tinderbox/tbmaster.1 @@ -27,7 +27,7 @@ .\" .\" $FreeBSD$ .\" -.Dd June 14, 2004 +.Dd June 21, 2004 .Dt TBMASTER 1 .Os .Sh NAME @@ -238,6 +238,10 @@ A list of targets (commands) to specify to the script. The default is .Dq world . +.It TIMEOUT +The number of seconds after which each tinderbox invocation will time +out. +No default value. .It TINDERBOX The location of the .Xr tinderbox(1) diff --git a/tools/tools/tinderbox/tbmaster.pl b/tools/tools/tinderbox/tbmaster.pl index 2e92a96d7f47..687d940214de 100644 --- a/tools/tools/tinderbox/tbmaster.pl +++ b/tools/tools/tinderbox/tbmaster.pl @@ -63,6 +63,7 @@ my %INITIAL_CONFIG = ( 'SENDER' => '', 'SUBJECT' => 'Tinderbox failure on %%arch%%/%%machine%%', 'TARGETS' => [ 'update', 'world' ], + 'TIMEOUT' => '', 'TINDERBOX' => '%%HOME%%/tinderbox', ); my %CONFIG; @@ -254,6 +255,8 @@ sub tinderbox($$$) { if ($CONFIG{'PATCH'}); push(@args, "--jobs=" . expand('JOBS')) if ($CONFIG{'JOBS'}); + push(@args, "--timeout=" . expand('TIMEOUT')) + if ($CONFIG{'TIMEOUT'}); push(@args, @{$CONFIG{'TARGETS'}}); push(@args, @{$CONFIG{'ENV'}}); push(@args, "CFLAGS=" . expand('CFLAGS')) diff --git a/tools/tools/tinderbox/tinderbox.1 b/tools/tools/tinderbox/tinderbox.1 index b5546cff01ac..ea1f193e7f03 100644 --- a/tools/tools/tinderbox/tinderbox.1 +++ b/tools/tools/tinderbox/tinderbox.1 @@ -27,7 +27,7 @@ .\" .\" $FreeBSD$ .\" -.Dd March 15, 2004 +.Dd June 21, 2004 .Dt TINDERBOX 1 .Os .Sh NAME @@ -139,6 +139,9 @@ The default is The location of the sandbox in which the builds are to take place. This directory should reside on a reasonably fast disk with at least 1.5 GB available (3 GB if building a release). +.It Fl t Ar NUM , Fl -timeout Ns = Ns Ar NUM +The maximum wall-time duration of the run, in seconds. +The default is to continue until all targets are completed. .It Fl v , Fl -verbose Enable additional debugging output. .El diff --git a/tools/tools/tinderbox/tinderbox.pl b/tools/tools/tinderbox/tinderbox.pl index 6433d078e984..97bd180b861a 100644 --- a/tools/tools/tinderbox/tinderbox.pl +++ b/tools/tools/tinderbox/tinderbox.pl @@ -50,8 +50,11 @@ my $machine; # Target machine my $patch; # Patch to apply before building my $repository; # Location of CVS repository my $sandbox; # Location of sandbox +my $timeout; # Timeout in seconds my $verbose; # Verbose mode +my %children; + my %userenv; my %cmds = ( @@ -199,7 +202,10 @@ sub spawn($@) { exec($cmd, @args); die("child: exec(): $!\n"); } - if (waitpid($pid, 0) == -1) { + $children{$pid} = $pid; + my $ret = waitpid($pid, 0); + delete $children{$pid}; + if ($ret == -1) { return warning("waitpid(): $!\n"); } elsif ($? & 0xff) { return warning("$cmd caught signal ", $? & 0x7f, "\n"); @@ -236,6 +242,13 @@ sub sigdie { exit(1); } +sub timeout() { + kill(15, keys(%children)) + if (%children); + error("timed out after $timeout seconds"); + exit(1); +} + sub usage() { print(STDERR "This is the FreeBSD tinderbox script, version $VERSION. @@ -307,12 +320,16 @@ MAIN:{ "p|patch=s" => \$patch, "r|repository=s" => \$repository, "s|sandbox=s" => \$sandbox, + "t|timeout=i" => \$timeout, "v|verbose+" => \$verbose, ) or usage(); if ($jobs < 0) { error("invalid number of jobs"); } + if ($timeout < 0) { + error("invalid timeout"); + } if ($branch !~ m|^(\w+)$|) { error("invalid source branch"); } @@ -342,6 +359,12 @@ MAIN:{ usage(); } + # Set up a timeout + if ($timeout > 0) { + $SIG{ALRM} = \&timeout; + alarm($timeout); + } + # Find out what we're expected to do foreach my $cmd (@ARGV) { if ($cmd =~ m/^([0-9A-Z_]+)=(.*)\s*$/) {