tools: flock: add NFSv4 compatibility

This patch fixes the LEDE build on mounted NFSv4 shares.

The lock file cannot be opened in read-write mode by default, because
then we cannot use flock(1) to lock executable files.

The read-write mode for lock files is necessary on NFSv4 where
flock(2) is emulated by by fcntl() -- this situation is possible to
detect by flock(2) EBADF error.

The patch consist of the following util-linux/flock commits

http://git.kernel.org/cgit/utils/util-linux/util-linux.git/commit/?id=eb742a1f66d5e3a7c5b43efce741c113f51bef3b

http://git.kernel.org/cgit/utils/util-linux/util-linux.git/commit/?id=caf1ba11a367ad702fb774653daf9ebdcca49d7b

without including the pre kernel 3.4 support.

Signed-off-by: Mathias Kresin <dev@kresin.me>
Signed-off-by: Felix Fietkau <nbd@nbd.name> [minor cleanup]
master
Mathias Kresin 9 years ago committed by Felix Fietkau
parent 360fd10ac9
commit 5d0b180f79
  1. 16
      tools/flock/src/flock.c

@ -133,6 +133,7 @@ int main(int argc, char *argv[])
int do_close = 0; int do_close = 0;
int err; int err;
int status; int status;
int open_flags = 0;
char *eon; char *eon;
char **cmd_argv = NULL, *sh_c_argv[4]; char **cmd_argv = NULL, *sh_c_argv[4];
const char *filename = NULL; const char *filename = NULL;
@ -266,6 +267,21 @@ int main(int argc, char *argv[])
if ( timeout_expired ) if ( timeout_expired )
exit(1); /* -w option set and failed to lock */ exit(1); /* -w option set and failed to lock */
continue; /* otherwise try again */ continue; /* otherwise try again */
case EBADF: /* since Linux 3.4 (commit 55725513) */
/* Probably NFSv4 where flock() is emulated by fcntl().
* Let's try to reopen in read-write mode.
*/
if (!(open_flags & O_RDWR) &&
type != LOCK_SH &&
filename &&
access(filename, R_OK | W_OK) == 0) {
close(fd);
open_flags = O_RDWR;
fd = open(filename, open_flags);
break;
}
/* go through */
default: /* Other errors */ default: /* Other errors */
if ( filename ) if ( filename )
fprintf(stderr, "%s: %s: %s\n", program, filename, strerror(err)); fprintf(stderr, "%s: %s: %s\n", program, filename, strerror(err));

Loading…
Cancel
Save