Copy open_locked() from tinderbox.pl and use it to optionally acquire a

lock file upon startup.  If this fails, tbmaster will simply terminate.
This commit is contained in:
Dag-Erling Smørgrav 2004-08-20 08:10:30 +00:00
parent d8abb5b00b
commit f95052e5e6
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=134074
2 changed files with 63 additions and 3 deletions

View File

@ -27,7 +27,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd June 21, 2004
.Dd August 18, 2004
.Dt TBMASTER 1
.Os
.Sh NAME
@ -45,7 +45,7 @@ runs, generates log summaries, and mails out failure reports.
.Pp
The following options are recognized:
.Bl -tag -width 12n
.It Fl c Ar CONFIG , Fl -config Ns = Ns Ar CONFIG
.It Fl c Ar NAME , Fl -config Ns = Ns Ar NAME
The name of the configuration to use.
If specified multiple times, all listed configurations will be run in
sequence.
@ -56,6 +56,11 @@ Dumps the configuration and exits without running the tinderbox.
The directory where configuration files are located.
The default is
.Pa $HOME/etc .
.It Fl l Ar FILE
The name of a file to lock upon startup.
If the lock is already held by another process,
.Nm
will terminate immediately rather than block.
.El
.Ss Configuration
The

View File

@ -42,6 +42,8 @@ my $COPYRIGHT = "Copyright (c) 2003 Dag-Erling Sm
my @configs; # Names of requested configations
my $dump; # Dump configuration and exit
my $etcdir; # Configuration directory
my $lockfile; # Lock file name
my $lock; # Lock file descriptor
my %INITIAL_CONFIG = (
'BRANCHES' => [ 'CURRENT' ],
@ -348,6 +350,46 @@ sub tinderbox($$$) {
rename("$logfile.brief.$$", "$logfile.brief");
}
###
### Open and lock a file reliably
###
sub open_locked($;$$) {
my $fn = shift; # File name
my $flags = shift; # Open flags
my $mode = shift; # File mode
local *FILE; # File handle
my (@sb1, @sb2); # File status
for (;; close(FILE)) {
sysopen(FILE, $fn, $flags || O_RDONLY, $mode || 0640)
or last;
if (!(@sb1 = stat(FILE))) {
# Huh? shouldn't happen
warning("$fn: stat(): $!");
last;
}
if (!flock(FILE, LOCK_EX|LOCK_NB)) {
# A failure here means the file can't be locked, or
# something really weird happened, so just give up.
warning("$fn: flock(): $!");
last;
}
if (!(@sb2 = stat($fn))) {
# File was pulled from under our feet, though it may
# reappear in the next pass
next;
}
if ($sb1[0] != $sb2[0] || $sb1[1] != $sb2[1]) {
# File changed under our feet, try again
next;
}
return *FILE{IO};
}
close(FILE);
return undef;
}
###
### Print a usage message and exit
###
@ -363,8 +405,9 @@ Options:
-d, --dump Dump the processed configuration
Parameters:
-c, --config=FILE Configuration name
-c, --config=NAME Configuration name
-e, --etcdir=DIR Configuration directory
-l, --lockfile=FILE Lock file name
Report bugs to <des\@freebsd.org>.
");
@ -448,6 +491,7 @@ MAIN:{
"c|config=s" => \@configs,
"d|dump" => \$dump,
"e|etcdir=s" => \$etcdir,
"l|lockfile=s" => \$lockfile,
) or usage();
if (@ARGV) {
usage();
@ -475,6 +519,17 @@ MAIN:{
$configs[$n] = $1;
}
# Acquire lock
if (defined($lockfile)) {
if ($lockfile !~ m/^([\w\/\.-]+)$/) {
die("invalid lockfile\n");
}
$lockfile = $1;
$lock = open_locked($lockfile, O_CREAT, 0600)
or die("unable to acquire lock on $lockfile");
# Lock will be released upon termination.
}
# Run all specified or implied configurations
foreach my $config (@configs) {
tbmaster($config);