Closed jaraco closed 1 year ago
Sure thing! I've not tried running the server itself on Mac OS, but IIRC when I was testing mounting from Mac OS I used something to the effect of sudo mount -t nfs server_ip:/mount_path /Users/user/some_mount_point
, I didn't use Finder.
I don't think there's anything in there that should preclude it from working on Mac OS, I'll take a look today.
Yep, there looks to be an issue binding UDP sockets under Mac OS, thanks for raising this!
Since RPCBind / PortMapper run on port 111 by convention, you can verify that they're not correctly bound by running lsof -iUDP -Pn | grep 111
. Similarly, when you run one of the NFS examples, $ showmount 127.0.0.1 -e
should return something like
Export list for 127.0.0.1:
/tmp/nfs2 *
but just times out under Mac OS, due to the server port not being bound.
I'll take a look at this, my guess is it's some weirdo asyncio thing with how I'm binding the UDP server socket.
I was able to run the example server and mount it on my macOS Sonoma system using:
mount_nfs -o nolock localhost:/tmp/nfs2 ~/mnt
Hmmm, that makes sense, thanks! I didn't implement any of the NFS 3 locking service because I largely use per-mount filesystems, that might be forcing it down the UDP path on new macOS. I'll see if fixing UDP + implementing a stub lock service deals with the issue.
@rgmisra Your pointer was really helpful, looks like this was actually due to a new check in XNU's NFS code that checks if statd is provided by PortMapper before allowing the mount if locks were enabled (the default.) https://github.com/apple/darwin-xnu/blob/2ff845c2e033bd0ff64b5b6aa6063a1f8f65aa32/bsd/nfs/nfs_vfsops.c#L4622-L4655 . It doesn't actually call statd, it just checks if it's there, I can't see the exact rational since I don't have access to the referenced ticket.
@jaraco Could you check if the current HEAD
works for you without extra options? It looks like XNU will automatically disable locking mode when it notices that NLM isn't provided later on, and everything seems to work on my laptop, but I'm not entirely sure.
It's working great! I launched the daemon:
ShenanigaNFS master @ pip-run . -- examples/nfsserverexample.py
Mounted '127.0.0.1': 926155170949658851, b'/tmp/nfs2'
2 <function NFSV3Service.LOOKUP at 0x105682340> (<shenaniganfs.nfs3.NFSV3Service object at 0x105685c10>, <shenaniganfs.transport.CallContext object at 0x104c8b080>, LOOKUP3Args(what=DiropArgs3(dir_handle=b'Q\xa8\xbe\xff\xe88\x06\t\xe9\x95\xa8\xeaN\xf7\x10f\xac@\x87\xba\xca\xd5\x8c\xb0NM@\t\x13\x84\xc9U\x00\x00\x00\x00\x00\x00\x00\x02\x0c\xda]8\x93Xx\xe3', name=b'._.')))
2 <function NFSV3Service.LOOKUP at 0x105682340> (<shenaniganfs.nfs3.NFSV3Service object at 0x105685c10>, <shenaniganfs.transport.CallContext object at 0x104c8b080>, LOOKUP3Args(what=DiropArgs3(dir_handle=b'Q\xa8\xbe\xff\xe88\x06\t\xe9\x95\xa8\xeaN\xf7\x10f\xac@\x87\xba\xca\xd5\x8c\xb0NM@\t\x13\x84\xc9U\x00\x00\x00\x00\x00\x00\x00\x02\x0c\xda]8\x93Xx\xe3', name=b'DCIM')))
2 <function NFSV3Service.LOOKUP at 0x105682340> (<shenaniganfs.nfs3.NFSV3Service object at 0x105685c10>, <shenaniganfs.transport.CallContext object at 0x1047c4140>, LOOKUP3Args(what=DiropArgs3(dir_handle=b'Q\xa8\xbe\xff\xe88\x06\t\xe9\x95\xa8\xeaN\xf7\x10f\xac@\x87\xba\xca\xd5\x8c\xb0NM@\t\x13\x84\xc9U\x00\x00\x00\x00\x00\x00\x00\x02\x0c\xda]8\x93Xx\xe3', name=b'.metadata_never_index_unless_rootfs')))
2 <function NFSV3Service.LOOKUP at 0x105682340> (<shenaniganfs.nfs3.NFSV3Service object at 0x105685c10>, <shenaniganfs.transport.CallContext object at 0x104c8b080>, LOOKUP3Args(what=DiropArgs3(dir_handle=b'Q\xa8\xbe\xff\xe88\x06\t\xe9\x95\xa8\xeaN\xf7\x10f\xac@\x87\xba\xca\xd5\x8c\xb0NM@\t\x13\x84\xc9U\x00\x00\x00\x00\x00\x00\x00\x02\x0c\xda]8\x93Xx\xe3', name=b'.metadata_never_index')))
2 <function NFSV3Service.LOOKUP at 0x105682340> (<shenaniganfs.nfs3.NFSV3Service object at 0x105685c10>, <shenaniganfs.transport.CallContext object at 0x1047c4140>, LOOKUP3Args(what=DiropArgs3(dir_handle=b'Q\xa8\xbe\xff\xe88\x06\t\xe9\x95\xa8\xeaN\xf7\x10f\xac@\x87\xba\xca\xd5\x8c\xb0NM@\t\x13\x84\xc9U\x00\x00\x00\x00\x00\x00\x00\x02\x0c\xda]8\x93Xx\xe3', name=b'.metadata_direct_scope_only')))
2 <function NFSV3Service.LOOKUP at 0x105682340> (<shenaniganfs.nfs3.NFSV3Service object at 0x105685c10>, <shenaniganfs.transport.CallContext object at 0x104c8b080>, LOOKUP3Args(what=DiropArgs3(dir_handle=b'Q\xa8\xbe\xff\xe88\x06\t\xe9\x95\xa8\xeaN\xf7\x10f\xac@\x87\xba\xca\xd5\x8c\xb0NM@\t\x13\x84\xc9U\x00\x00\x00\x00\x00\x00\x00\x02\x0c\xda]8\x93Xx\xe3', name=b'.Spotlight-V100')))
And mounted the example:
ShenanigaNFS master @ mkdir /tmp/test
ShenanigaNFS master @ sudo mount -t nfs localhost:/tmp/nfs2 /tmp/test
Password:
ShenanigaNFS master @ ls /tmp/test
testfile.txt
ShenanigaNFS master @ cat /tmp/test/testfile.txt
test
Thanks for investigating and making the fix!
I know it should be obvious, but when I tried, I failed.
I ran the example server, then tried mounting it using macOS Finder.
Are there known limitations (like it runs on Linux only)? Can you share some step-by-step instructions that demonstrate how one could utilize the server? Next, I'll probably try mounting in Linux instead of macOS, so may be able to answer the question myself, but any advice would be appreciated.