Re: nfs server issues
Rick Macklem <[email protected]> Tue, 7 Jul 2026 07:01:06 -0700
| Newsgroups | gmane.os.freebsd.devel.file-systems |
|---|---|
| Message-ID | <CAM5tNy7VXOcr65sW_MJZ52-WgrkD1dskptfZZ6-3atOwfLRv0w@mail.gmail.com> |
On Tue, Jul 7, 2026 at 5:30 AM Paul Barker <[email protected]> wrote: > > On Tue, 2026-07-07 at 14:29 +0300, Konstantin Belousov wrote: > > On Tue, Jul 07, 2026 at 12:18:21PM +0100, Paul Barker wrote: > > > On Tue, 2026-07-07 at 09:52 +0100, Richard Purdie wrote: > > > > On Sat, 2026-07-04 at 12:41 -0700, Rick Macklem wrote: > > > > > On Sat, Jul 4, 2026 at 1:05 AM Richard Purdie > > > > > <[email protected]> wrote: > > > > > > > > > > > > nfsstat -E -s > > > > > > Server Info: > > > > > > Getattr Setattr Lookup Readlink Read Write > > > > > > 17354100116 1674996998 5136769057 40544 18429670397 986443058 > > > > > > Create Remove Rename Link Symlink Mkdir > > > > > > 0 98646613 119865835 17071853 0 0 > > > > > > Rmdir Readdir RdirPlus Access Mknod Fsstat > > > > > > 0 1655544711 0 4129535844 0 0 > > > > > > FSinfo pathConf Commit LookupP SetClId SetClIdCf > > > > > > 0 0 8723436 0 0 0 > > > > > One more thing to note. The # of Commits is much smaller than the # of Writes > > > > > on the top line. This "hints" that a lot of the Writes are being done File_sync. > > > > > (To check that, you'd need to capture packets and look at them in wireshark.) > > > > > > > > > > If a lot of the Writes are File_sync (which means the server must commit the > > > > > data/metadata changes to stable storage before replying), doing the "mirrored > > > > > pair of storage devices dedicated to the ZIL" could be what you need to get > > > > > writes to work well. (As I mentioned, the "cheat" alternative is to > > > > > set "sync=disabled", > > > > > but that runs a risk of data loss when the NFS server crashes/reboots.) > > > > > > > > I was able to find a way to increase the Open/Lock counts on the > > > > server. Most of the locking we do on the clients is from a tool called > > > > Bitbake and the locking is isolated to specific function. I maintain > > > > Bitbake and wrote/maintain the locking code over the <too many> years. > > > > I copied and pasted the relevant code straight from bitbake into a test > > > > script: > > > > > > > > https://valkyrie.yocto.io/pub/non-release/rptest/testlock.py > > > > > > > > (code is from > > > > https://git.openembedded.org/bitbake/tree/lib/bb/utils.py) > > > > > > > > Obviously it could easily be simplified more but I wanted to test our > > > > actual code. The lock file name/path is hardcoded at the end of the > > > > script but easily changed. > > > > > > > > I ran that script on three of the NFS clients for around 5 minutes. On > > > > the server, the counts went from: > > > > > > > > nfsdumpstate | egrep 'fd01:172:16::242:2157|fd01:172:16::12|fd01:172:16:1::11 ' > > > > CB 2 6307 55 55 0 0 fd01:172:16::242:2157 4c696e7578204e465376342e322064656269616e31322d766b2d31 > > > > CB 3 6543 77 77 0 0 fd01:172:16::12 4c696e7578204e465376342e322064656269616e31322d766b2d33 > > > > CB 2 6571 83 83 0 0 fd01:172:16:1::11 4c696e7578204e465376342e322064656269616e31322d766b2d32 > > > > > > > > to: > > > > > > > > nfsdumpstate | egrep 'fd01:172:16::242:2157|fd01:172:16::12|fd01:172:16:1::11 ' > > > > CB 2 6462 65 65 0 0 fd01:172:16::242:2157 4c696e7578204e465376342e322064656269616e31322d766b2d31 > > > > CB 3 6679 83 83 0 0 fd01:172:16::12 4c696e7578204e465376342e322064656269616e31322d766b2d33 > > > > CB 2 6691 88 88 0 0 fd01:172:16:1::11 4c696e7578204e465376342e322064656269616e31322d766b2d32 > > > > > > > > I've then stopped the scripts and waited and the counts just stayed > > > > there. > > > > > > > > I'd be very interested if someone else could reproduce that and if so, > > > > explain what is happening and if it is an issue? > > > > > > > > I can't prove the write hangs are related to the counts but it does > > > > seem there is some issue there regardless as they don't make sense. > > > > > > Hi all, > > > > > > This is a long one... > > > > > > I've looked into this issue with the Yocto Project autobuilder cluster > > > alongside Richard. I've used Claude to help me navigate the Linux and > > > FreeBSD source trees, along with manually checking some of the key > > > findings, so this is in the territory of a "working theory" as to what's > > > going on. Some input from folks more familiar with the FreeBSD NFS > > > server code would definitely be helpful to confirm I'm on the right > > > track. > > > > > > The issue we're seeing is probably triggered by the following sequence > > > of events: > > > > > > 1) Client A opens a file on the FreeBSD server via an NFS mount. Even if > > > the client immediately closes the file, Linux's NFS client code will > > > keep the file handle cached for a short while before sending a CLOSE > > > to the server. > > > > > > 2) During this window, client B deletes or replaces the file. This sends > > > a REMOVE or RENAME message to the server. The FreeBSD NFS server code > > > unlinks the underlying file immediately. > > > > > > 3) Client A now releases the file, either explicitly or due to cache > > > timing out. At this point it sends a PUTFH/CLOSE compound message to > > > the NFS server, as CLOSE acts on the current file handle the PUTFH is > > > needed to select which file is being closed. However, the file handle > > > is now stale due to the removal from another client so the PUTFH > > > operation fails with ESTALE. The CLOSE operation is never reached, so > > > no resource cleanup occurs. The file handle has now leaked and will > > > not be released unless the client session which owns it terminates. > > > > > > I've confirmed that the file becomes stale with a simple experiment: > > > > > > 1) Open a file via a Python shell on client A. Leave this Python shell > > > running. > > > > > > >>> fh = open("/srv/autobuilder/valkyrie.yocto.io/pub/non-release/testfile.txt", "r") > > > > > > 2) Remove the file from client B: > > > > > > $ rm /srv/autobuilder/valkyrie.yocto.io/pub/non-release/testfile.txt > > > > > > 3) Now attempt to read the file via the open handle on client A: > > > > > > >>> fh.read() > > > Traceback (most recent call last): > > > File "<python-input-2>", line 1, in <module> > > > fh.read() > > > ~~~~~~~^^ > > > OSError: [Errno 116] Stale file handle > > > > > > I've also looked at the NFS server code myself on the freebsd-src > > > stable/14 branch. In nfsrvd_compound(), case NFSV4OP_PUTFH calls > > > nfsd_fhtovp(), which calls nfsvno_fhtovp() to resolve the file handle. > > > This sets nd->nd_repstat to ESTALE if the file has been unlinked. This > > > causes a break from the main loop in nfsrvd_compound() to return the > > > error to the client, so the CLOSE operation is never processed. And if > > > CLOSE is never processed, the open file handle leaks. > > > > > > This causes us two kinds of problems: > > > > > > 1) The hash table of open file handles grows. With >400k file handles in > > > the hash table we see the CPU load over 5000%. There is one file > > > handle table in the NFS server, with one lock, and all stateful > > > operations seem to need to take this lock to lookup a file handle, so > > > this leads to thrashing. > > > > > > Linux may interpret timeouts waiting for a server response as > > > EREMOTEIO. > > > > > > This can be somewhat ameliorated by increasing vfs.nfsd.fhhashsize to > > > spread the open handles across more buckets in the hash table, but > > > that just delays the load issues, it doesn't resolve them. > > > > > > 2) When the total number of open file handles + open locks hits 500,000, > > > we hit the default v4statelimit. This causes the server to reply to > > > operations with NFSERR_RESOURCE which Linux also interprets as > > > EREMOTEIO. > > > > > > The ~483,000 open file handles in Richard's original message is > > > consistent with the 500k limit being reached before a few clients > > > were disconnected (zeroing out their open counts and reducing the > > > overall total). > > > > > > We could increase vfs.nfsd.v4statelimit, but again this is just > > > delaying the inevitable issues. If we're leaking ~500k open file > > > handles in less than a week then no limit will last very long. > > > > > > So, essentially we would need to avoid the leak in the first place. > > > Should the error handling for PUTFH on a stale file handle free the > > > associated state? Or should a REMOVE/RENAME operation leave the file > > > handle intact until all consumers have released the file handle (this is > > > what a Linux NFS server seems to do)? > > > > > > Thank you for bearing with that long explanation! If I've misunderstood > > > anything then please let me know and I'll take another look. > > > > Does the FreeBSD NFS server still reference the vnode for the deleted file > > in your situation? If yes, then c041b82c59e885d106f45454302bad3d9dcc58a7 > > might already help. > > Hi Konstantin, thanks for the info. I sadly don't think this patch will > help, we're using ZFS as the backing store for these NFS shares and that > commit only changes UFS/FFS code. I also don't think the NFS server > holds a vnode reference for each open stateid but I may be wrong, I'm > not really familiar with the code base. You are correct. The Open/Lock structures hold file handles (no vnodes or file descriptors). --> This does imply that the code does not know if/when a file is deleted, so the Opens/Locks can persist after the file is deleted. My understanding is that the NFSv4 client is responsible for doing LockU/Close operations. (You could argue that there should be some sort of garbage collection running in background to get rid of Opens/Locks that exist after the file has been deleted, but the current code does not do that. The counter argument is that the client should be doing LockU/Close and the structures are pretty harmless.) Btw, I believe the Linux knfsd server does hold some sort of reference to the file for Opens/Locks and since the Linux client mainly gets tested against the Linux knfsd, they might have found that LockU/Close's are not needed for the Linux knfsd. (This is just conjecture.) rick > > Best regards, > > -- > Paul Barker >