| Summary: | NFS file locking fails from Solaris 8 client to FreeBSD server | ||
|---|---|---|---|
| Product: | Base System | Reporter: | Andrew Turner <Andrew> |
| Component: | bin | Assignee: | freebsd-bugs (Nobody) <bugs> |
| Status: | Closed FIXED | ||
| Severity: | Affects Only Me | ||
| Priority: | Normal | ||
| Version: | 4.3-RELEASE | ||
| Hardware: | Any | ||
| OS: | Any | ||
Andrew.P.Lentvorski@FreeBSD.org, "Jr." <buzmeg@hotmail.com> writes: > > >Number: 29191 > >Category: bin > >Synopsis: NFS file locking fails from Solaris 8 client to FreeBSD server ... > >Release: FreeBSD 4.3-RELEASE #0: Sat Apr 21 10:54:49 GMT 2001 IIRC NFS locking isn't implemented in 4.x. State Changed From-To: open->closed feature not implemented and mail to originator bounces On Tue, Jul 24, 2001 at 05:40:02AM -0700, Dima Dorfman wrote:
> The following reply was made to PR bin/29191; it has been noted by GNATS.
>
> From: Dima Dorfman <dima@unixfreak.org>
> To: Andrew.P.Lentvorski@FreeBSD.org, "Jr." <buzmeg@hotmail.com>
> Cc: freebsd-gnats-submit@FreeBSD.org
> Subject: Re: bin/29191: NFS file locking fails from Solaris 8 client to FreeBSD server
> Date: Tue, 24 Jul 2001 05:30:47 -0700
>
> Andrew.P.Lentvorski@FreeBSD.org, "Jr." <buzmeg@hotmail.com> writes:
> >
> > >Number: 29191
> > >Category: bin
> > >Synopsis: NFS file locking fails from Solaris 8 client to FreeBSD server
> ...
> > >Release: FreeBSD 4.3-RELEASE #0: Sat Apr 21 10:54:49 GMT 2001
>
> IIRC NFS locking isn't implemented in 4.x.
Hmm. The 4.3-STABLE rpc.lockd manpage states:
BUGS
The current implementation provides only the server side of the protocol
(ie. clients running other OS types can establish locks on a FreeBSD
fileserver, but there is currently no means for a FreeBSD client to
establish locks).
It seems the discussed setup - Solaris client and FreeBSD server -
should be supported.
G'luck,
Peter
--
Hey, out there - is it *you* reading me, or is it someone else?
State Changed From-To: closed->open It appears that only client side locking is what's unimplemented, so this may indeed be a problem. Upon digging further into this, it appears to be a portmap problem. The
Solaris client is requesting a version 4 NLM via the portmapper which then
replies in the affirmative rather than rejecting the request. Version 4
NLM does not appear to exist on FreeBSD. I believe that there is a proper
request for RPC to reject the call and send the minimum and maximum
version numbers of the requested service.
-a
daffy# rpcinfo -p
program vers proto port
100000 2 tcp 111 portmapper
100000 2 udp 111 portmapper
100005 3 udp 1023 mountd
100005 3 tcp 1023 mountd
100005 1 udp 1023 mountd
100005 1 tcp 1023 mountd
100003 2 udp 2049 nfs
100003 3 udp 2049 nfs
100003 2 tcp 2049 nfs
100003 3 tcp 2049 nfs
100021 1 udp 1010 nlockmgr
100021 3 udp 1010 nlockmgr
100021 1 tcp 1022 nlockmgr
100021 3 tcp 1022 nlockmgr
100024 1 udp 1004 status
100024 1 tcp 1021 status
State Changed From-To: open->closed FreeBSD now supports nlm version 4 locking. |
Attempts to use file locking succeed in native filesystems but fail from a Solaris NFS client to a FreeBSD NFS server. A simple lock test program (included below) results in the following on a native filesystem: bash-2.03# /tmp/locktest f_rdlck,f_wrlck,f_unlck,seek_set,f_setlk=1,2,3,0,6 File handle: 3 Attempting to lock file... lock_val = 0 Attempting to unlock file... lock_val = 0 but the following when run on an NFS filesystem: bash-2.03# /tmp/locktest f_rdlck,f_wrlck,f_unlck,seek_set,f_setlk=1,2,3,0,6 File handle: 3 Attempting to lock file... After trying to lock : Invalid argument lock_val = -1 Attempting to unlock file... After trying to lock : Invalid argument lock_val = -1 A dump from ethereal watching the traffic is as follows: (daffy is the FreeBSD server, foghorn is the Solaris client) No. Time Source Destination Protocol Info 1 0.000000 foghorn daffy NFS V3 GETATTR Call XID 0xc59176e 2 0.000127 daffy foghorn NFS V3 GETATTR Reply XID 0xc59176e 3 0.000487 foghorn daffy NFS V3 LOOKUP Call XID 0xc59176f 4 0.000586 daffy foghorn NFS V3 LOOKUP Reply XID 0xc59176f 5 0.000872 foghorn daffy NFS V3 ACCESS Call XID 0xc591770 6 0.000920 daffy foghorn NFS V3 ACCESS Reply XID 0xc591770 7 0.001324 foghorn daffy Portmap V2 GETPORT Call XID 0xc591771 8 0.001650 daffy foghorn Portmap V2 GETPORT Reply XID 0xc591771 9 0.001875 foghorn daffy NLM V4 LOCK Call XID 0xc591772 10 0.001986 daffy foghorn NLM V4 LOCK Reply XID 0xc591772[Malformed Frame] 11 0.002773 foghorn daffy Portmap V2 GETPORT Call XID 0xc591773 12 0.002985 daffy foghorn Portmap V2 GETPORT Reply XID 0xc591773 13 0.003206 foghorn daffy NLM V4 UNLOCK Call XID 0xc591774 14 0.003295 daffy foghorn NLM V4 UNLOCK Reply XID 0xc591774[Malformed Frame] 15 0.003677 foghorn daffy Portmap V2 GETPORT Call XID 0xc591775 16 0.003865 daffy foghorn Portmap V2 GETPORT Reply XID 0xc591775 17 0.004087 foghorn daffy NLM V4 UNLOCK Call XID 0xc591776 18 0.004171 daffy foghorn NLM V4 UNLOCK Reply XID 0xc591776[Malformed Frame] 19 0.099076 foghorn daffy TCP 1020 > 1022 [ACK] Seq=766665452 Ack=194196698 Win=24820 Len=0 20 0.099099 foghorn daffy TCP 1021 > sunrpc [ACK] Seq=766469072 Ack=173822409 Win=24820 Len=0 21 0.099123 foghorn daffy TCP 1022 > nfsd [ACK] Seq=716857650 Ack=638087445 Win=24820 Len=0 And a dump from the rpcinfo is as follows: daffy# rpcinfo -p program vers proto port 100000 2 tcp 111 portmapper 100000 2 udp 111 portmapper 100003 2 udp 2049 nfs 100003 3 udp 2049 nfs 100003 2 tcp 2049 nfs 100003 3 tcp 2049 nfs 100021 1 udp 1010 nlockmgr 100021 3 udp 1010 nlockmgr 100021 1 tcp 1022 nlockmgr 100021 3 tcp 1022 nlockmgr 100024 1 udp 1004 status 100024 1 tcp 1021 status 100005 3 udp 882 mountd 100005 3 tcp 1002 mountd 100005 1 udp 882 mountd 100005 1 tcp 1002 mountd The problem is easily repeatable by running the program included at the end of this report. This all started when I was trying to get a FreeBSD RAID server to take over our storage tasks. Cadence (a VLSI CAD vendor) tools require fcntl locks to work. If I cannot fix this problem, I will have to dump BSD as a storage solution. Furthermore, I'm on a short timeline to bring everything up. Consequently, if there are flags which I can give to Solaris to make it do the right thing (or even a substitute until FreeBSD is fixed), I would be open to using those as well. Incidentally, FreeBSD -> FreeBSD NFS locking seems to work and Solaris -> Solaris NFS locking also seems to work. Please feel free to contact me if you need any further data. Thanks, -a NFS locking test program: #include <stdio.h> #include <fcntl.h> #include <sys/file.h> #ifndef SEEK_SET #define SEEK_SET 0 #endif main() { int fh, lock_val; struct flock fl; printf("f_rdlck,f_wrlck,f_unlck,seek_set,f_setlk=%d,%d,%d,%d,%d\n", F_RDLCK,F_WRLCK,F_UNLCK,SEEK_SET,F_SETLK); fh = open("cache.file", O_RDWR|O_CREAT, 0644); printf("File handle: %d\n",fh); fl.l_type = F_WRLCK; fl.l_whence = SEEK_SET; fl.l_start = fl.l_len = 0L; printf("Attempting to lock file...\n"); lock_val = fcntl (fh, F_SETLK, &fl); if (lock_val == -1) { perror("After trying to lock "); } printf("lock_val = %d\n",lock_val); printf("Attempting to unlock file...\n"); fl.l_type = F_UNLCK; lock_val = fcntl (fh, F_SETLK, &fl); if (lock_val == -1) { perror("After trying to lock "); } printf("lock_val = %d\n",lock_val); close(fh); } How-To-Repeat: Run the following program in an NFS directory on a Solaris client which has been exported from a FreeBSD server: #include <stdio.h> #include <fcntl.h> #include <sys/file.h> #ifndef SEEK_SET #define SEEK_SET 0 #endif main() { int fh, lock_val; struct flock fl; printf("f_rdlck,f_wrlck,f_unlck,seek_set,f_setlk=%d,%d,%d,%d,%d\n", F_RDLCK,F_WRLCK,F_UNLCK,SEEK_SET,F_SETLK); fh = open("cache.file", O_RDWR|O_CREAT, 0644); printf("File handle: %d\n",fh); fl.l_type = F_WRLCK; fl.l_whence = SEEK_SET; fl.l_start = fl.l_len = 0L; printf("Attempting to lock file...\n"); lock_val = fcntl (fh, F_SETLK, &fl); if (lock_val == -1) { perror("After trying to lock "); } printf("lock_val = %d\n",lock_val); printf("Attempting to unlock file...\n"); fl.l_type = F_UNLCK; lock_val = fcntl (fh, F_SETLK, &fl); if (lock_val == -1) { perror("After trying to lock "); } printf("lock_val = %d\n",lock_val); close(fh); }