Date: Wed, 26 Sep 2007 22:14:52 GMT From: Zach Loafman <zachary.loafman@isilon.com> To: freebsd-gnats-submit@FreeBSD.org Subject: kern/116679: lockd replies with DENIED for blocking lock if held by underlying FS Message-ID: <200709262214.l8QMEqVt000224@www.freebsd.org> Resent-Message-ID: <200709262220.l8QMK25s029071@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 116679 >Category: kern >Synopsis: lockd replies with DENIED for blocking lock if held by underlying FS >Confidential: no >Severity: serious >Priority: low >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Wed Sep 26 22:20:02 GMT 2007 >Closed-Date: >Last-Modified: >Originator: Zach Loafman >Release: 6.1-RELEASE >Organization: Isilon Systems >Environment: FreeBSD you.dont.care 6.1-RELEASE FreeBSD 6.1-RELEASE #0: Sun May 7 04:32:43 UTC 2006 root@opus.cse.buffalo.edu:/usr/obj/usr/src/sys/GENERIC i386 >Description: If lockd gets a request to an NLM request to lock a file but the non-blocking lockf() call on the exported file system fails, lockd will reply with NLM4_DENIED. In this situation, lockd needs to return NLM4_BLOCKED and actually set up some sort of structure to deal with it (however, there exists no way for the FS to notify lockd that the lock could be acquired). The result of this is that an NFS client may try for a blocking lock, but still get EAGAIN ("Resource temporarily unavailable"), which is counter-intuitive. >How-To-Repeat: # cat > locker_two_path.c <<EOF #include <sys/types.h> #include <sys/stat.h> #include <sys/file.h> #include <assert.h> #include <errno.h> #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include <unistd.h> static void do_lock(int fd, int exclusive, int waitok) { int rc; time_t start_time; struct flock flock; start_time = time(0); flock.l_start = 0; flock.l_len = 0; flock.l_type = exclusive ? F_WRLCK : F_RDLCK; flock.l_whence = SEEK_SET; rc = fcntl(fd, waitok ? F_SETLKW : F_SETLK, &flock); if (rc < 0) { perror("fcntl lock"); exit(1); } printf("%d: waited %d seconds for lock\n", getpid(), time(0) - start_time); } int main(int argc, char *argv[]) { int local_fd, nfs_fd; if (argc != 3) { printf("usage: %s <local path> <nfs path>", argv[0]); exit(1); } local_fd = open(argv[1], O_RDWR|O_CREAT, 0666); if (local_fd < 0) { perror("open"); exit(1); } nfs_fd = open(argv[2], O_RDWR|O_CREAT, 0666); if (nfs_fd < 0) { perror("open"); exit(1); } do_lock(local_fd, 1, 1); do_lock(nfs_fd, 1, 1); return 0; } EOF # cc -Wall -o locker_two_path locker_two_path.c # mount -otcp,intr localhost:/local /mnt/test # ./locker_two_path /local/foobar /mnt/test/foobar 99086: waited 0 seconds for lock fcntl lock: Resource temporarily unavailable >Fix: Serious work. >Release-Note: >Audit-Trail: >Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200709262214.l8QMEqVt000224>