summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authordes <des@FreeBSD.org>2004-08-20 08:10:30 +0000
committerdes <des@FreeBSD.org>2004-08-20 08:10:30 +0000
commita05183855a89c8bbabbcc5df71978ffebe9c9201 (patch)
tree83382a9018b29d4e9d60f8e24f18471baf11173c /tools
parent3dc1409438a3f87a0faafa8d709f7b4eb33738d9 (diff)
downloadFreeBSD-src-a05183855a89c8bbabbcc5df71978ffebe9c9201.zip
FreeBSD-src-a05183855a89c8bbabbcc5df71978ffebe9c9201.tar.gz
Copy open_locked() from tinderbox.pl and use it to optionally acquire a
lock file upon startup. If this fails, tbmaster will simply terminate.
Diffstat (limited to 'tools')
-rw-r--r--tools/tools/tinderbox/tbmaster.19
-rw-r--r--tools/tools/tinderbox/tbmaster.pl57
2 files changed, 63 insertions, 3 deletions
diff --git a/tools/tools/tinderbox/tbmaster.1 b/tools/tools/tinderbox/tbmaster.1
index 96d90e3..d8001d5 100644
--- a/tools/tools/tinderbox/tbmaster.1
+++ b/tools/tools/tinderbox/tbmaster.1
@@ -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
diff --git a/tools/tools/tinderbox/tbmaster.pl b/tools/tools/tinderbox/tbmaster.pl
index 687d940..fbba91e7 100644
--- a/tools/tools/tinderbox/tbmaster.pl
+++ b/tools/tools/tinderbox/tbmaster.pl
@@ -42,6 +42,8 @@ my $COPYRIGHT = "Copyright (c) 2003 Dag-Erling Smørgrav. " .
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' ],
@@ -349,6 +351,46 @@ sub tinderbox($$$) {
}
###
+### 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
###
sub usage() {
@@ -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);
OpenPOWER on IntegriCloud