Add -w option to lockf(1).
By default, lockf(1) opens its lock file O_RDONLY|O_EXLOCK. On NFS, if the file already exists, this is split into opening the file read-only and then requesting an exclusive lock -- and the second step fails because NFS does not permit exclusive locking on files which are opened read-only. The new -w option changes the open flags to O_WRONLY|O_EXLOCK, allowing it to work on NFS -- at the cost of not working if the file cannot be opened for writing. (Whether the traditional BSD behaviour of allowing exclusive locks to be obtained on a file which cannot be opened for writing is a good idea is perhaps questionable since it may allow less-privileged users to perform a local denial of service; however this behaviour has been present for a long time and changing it now seems like it would cause problems.) Reviewed by: rmacklem Differential Revision: https://reviews.freebsd.org/D26005
This commit is contained in:
parent
507cf10ad5
commit
437bab4828
@ -1,4 +1,4 @@
|
|||||||
.\"
|
.\"
|
||||||
.\" Copyright (C) 1998 John D. Polstra. All rights reserved.
|
.\" Copyright (C) 1998 John D. Polstra. All rights reserved.
|
||||||
.\"
|
.\"
|
||||||
.\" Redistribution and use in source and binary forms, with or without
|
.\" Redistribution and use in source and binary forms, with or without
|
||||||
@ -24,7 +24,7 @@
|
|||||||
.\"
|
.\"
|
||||||
.\" $FreeBSD$
|
.\" $FreeBSD$
|
||||||
.\"
|
.\"
|
||||||
.Dd June 18, 2020
|
.Dd August 26, 2020
|
||||||
.Dt LOCKF 1
|
.Dt LOCKF 1
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -32,7 +32,7 @@
|
|||||||
.Nd execute a command while holding a file lock
|
.Nd execute a command while holding a file lock
|
||||||
.Sh SYNOPSIS
|
.Sh SYNOPSIS
|
||||||
.Nm
|
.Nm
|
||||||
.Op Fl kns
|
.Op Fl knsw
|
||||||
.Op Fl t Ar seconds
|
.Op Fl t Ar seconds
|
||||||
.Ar file
|
.Ar file
|
||||||
.Ar command
|
.Ar command
|
||||||
@ -121,6 +121,14 @@ When a lock times out,
|
|||||||
is
|
is
|
||||||
.Em not
|
.Em not
|
||||||
executed.
|
executed.
|
||||||
|
.It Fl w
|
||||||
|
Causes
|
||||||
|
.Nm
|
||||||
|
to open
|
||||||
|
.Ar file
|
||||||
|
for writing rather than reading.
|
||||||
|
This is necessary on filesystems (including NFSv4) where a file which
|
||||||
|
has been opened read-only cannot be exclusively locked.
|
||||||
.El
|
.El
|
||||||
.Pp
|
.Pp
|
||||||
In no event will
|
In no event will
|
||||||
|
@ -62,9 +62,9 @@ main(int argc, char **argv)
|
|||||||
pid_t child;
|
pid_t child;
|
||||||
|
|
||||||
silent = keep = 0;
|
silent = keep = 0;
|
||||||
flags = O_CREAT;
|
flags = O_CREAT | O_RDONLY;
|
||||||
waitsec = -1; /* Infinite. */
|
waitsec = -1; /* Infinite. */
|
||||||
while ((ch = getopt(argc, argv, "sknt:")) != -1) {
|
while ((ch = getopt(argc, argv, "sknt:w")) != -1) {
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
case 'k':
|
case 'k':
|
||||||
keep = 1;
|
keep = 1;
|
||||||
@ -84,6 +84,9 @@ main(int argc, char **argv)
|
|||||||
"invalid timeout \"%s\"", optarg);
|
"invalid timeout \"%s\"", optarg);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 'w':
|
||||||
|
flags = (flags & ~O_RDONLY) | O_WRONLY;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
usage();
|
usage();
|
||||||
}
|
}
|
||||||
@ -171,7 +174,7 @@ acquire_lock(const char *name, int flags)
|
|||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
if ((fd = open(name, O_RDONLY|O_EXLOCK|flags, 0666)) == -1) {
|
if ((fd = open(name, O_EXLOCK|flags, 0666)) == -1) {
|
||||||
if (errno == EAGAIN || errno == EINTR)
|
if (errno == EAGAIN || errno == EINTR)
|
||||||
return (-1);
|
return (-1);
|
||||||
else if (errno == ENOENT && (flags & O_CREAT) == 0)
|
else if (errno == ENOENT && (flags & O_CREAT) == 0)
|
||||||
|
Loading…
Reference in New Issue
Block a user