* [RFC PATCH 1/2] common/nfs: add management helpers
2026-09-07 16:40 [RFC PATCH 0/2] quota evasion test and nfs helpers cem
@ 2026-09-07 16:40 ` cem
2026-09-08 14:22 ` Darrick J. Wong
2026-09-07 16:40 ` [RFC PATCH 2/2] generic: add test for quota enforcement via a nfs share cem
` (2 subsequent siblings)
3 siblings, 1 reply; 13+ messages in thread
From: cem @ 2026-09-07 16:40 UTC (permalink / raw)
To: zlang; +Cc: djwong, hch, linux-xfs, fstests, jack
From: Carlos Maiolino <cem@kernel.org>
This adds a few new helpers to manage local nfs client/servers. These
can be used to exercise bugs which happens through a nfs share.
Signed-off-by: Carlos Maiolino <cmaiolino@redhat.com>
---
common/nfs | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 55 insertions(+)
diff --git a/common/nfs b/common/nfs
index a03eaf48e1c0..4508a8a2e494 100644
--- a/common/nfs
+++ b/common/nfs
@@ -33,3 +33,58 @@ _require_scratch_nfs_version()
fi
_scratch_unmount
}
+
+# Start rpcbind if it is not already running.
+_start_rpcbind()
+{
+ rpcinfo -p localhost > /dev/null 2>&1 && return 0
+ rpcbind 2>> $seqres.full || _notrun "Cannot start rpcbind"
+ /usr/sbin/rpc.statd 2>> $seqres.full || _notrun "Cannot start rpc.statd"
+ /usr/sbin/rpc.idmapd 2>> $seqres.full || _notrun "Cannot start rpc.idmapd"
+ /usr/sbin/nfsdcld 2>> $seqres.full || _notrun "Cannot start nfsdcld"
+
+}
+
+# Stop rpcbind.
+_stop_rpcbind()
+{
+ pkill rpcbind 2>/dev/null
+}
+
+# Start the NFS server if not already running.
+_start_nfsd()
+{
+ rpcinfo -p localhost 2>/dev/null | grep -q nfs && return 0
+ rpc.nfsd 2>> $seqres.full || _notrun "Cannot start rpc.nfsd"
+ rpc.mountd 2>> $seqres.full || _notrun "Cannot start rpc.mountd"
+}
+
+# Stop the NFS server.
+_stop_nfsd()
+{
+ rpc.nfsd 0 2>/dev/null
+ pkill rpc.mountd 2>/dev/null
+}
+
+# Require a NFS server to be available and start rpcbind and nfsd if they are
+# not already running.
+_require_nfs_server()
+{
+ type -P exportfs > /dev/null 2>&1 || \
+ _notrun "exportfs utility required, skipped this test"
+ type -P rpc.nfsd > /dev/null 2>&1 || \
+ _notrun "rpc.nfsd utility required, skipped this test"
+ type -P rpc.mountd > /dev/null 2>&1 || \
+ _notrun "rpc.mountd utility required, skipped this test"
+ _start_rpcbind
+ _start_nfsd
+}
+
+# Require a NFS client to be available.
+_require_nfs_client()
+{
+ grep -q nfs /proc/filesystems 2>/dev/null || \
+ _notrun "Kernel does not support NFS client"
+ type -P mount.nfs > /dev/null 2>&1 || \
+ _notrun "mount.nfs utility required, skipped this test"
+}
--
2.55.0
^ permalink raw reply related [flat|nested] 13+ messages in thread* Re: [RFC PATCH 1/2] common/nfs: add management helpers
2026-09-07 16:40 ` [RFC PATCH 1/2] common/nfs: add management helpers cem
@ 2026-09-08 14:22 ` Darrick J. Wong
2026-09-09 6:12 ` Christoph Hellwig
0 siblings, 1 reply; 13+ messages in thread
From: Darrick J. Wong @ 2026-09-08 14:22 UTC (permalink / raw)
To: cem; +Cc: zlang, hch, linux-xfs, fstests, jack
On Mon, Sep 07, 2026 at 06:40:47PM +0200, cem@kernel.org wrote:
> From: Carlos Maiolino <cem@kernel.org>
>
> This adds a few new helpers to manage local nfs client/servers. These
> can be used to exercise bugs which happens through a nfs share.
>
> Signed-off-by: Carlos Maiolino <cmaiolino@redhat.com>
> ---
> common/nfs | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 55 insertions(+)
>
> diff --git a/common/nfs b/common/nfs
> index a03eaf48e1c0..4508a8a2e494 100644
> --- a/common/nfs
> +++ b/common/nfs
> @@ -33,3 +33,58 @@ _require_scratch_nfs_version()
> fi
> _scratch_unmount
> }
> +
> +# Start rpcbind if it is not already running.
> +_start_rpcbind()
> +{
> + rpcinfo -p localhost > /dev/null 2>&1 && return 0
> + rpcbind 2>> $seqres.full || _notrun "Cannot start rpcbind"
> + /usr/sbin/rpc.statd 2>> $seqres.full || _notrun "Cannot start rpc.statd"
> + /usr/sbin/rpc.idmapd 2>> $seqres.full || _notrun "Cannot start rpc.idmapd"
> + /usr/sbin/nfsdcld 2>> $seqres.full || _notrun "Cannot start nfsdcld"
Aren't these daemons usually configured as system services?
# service rpcbind start
etc?
> +}
> +
> +# Stop rpcbind.
> +_stop_rpcbind()
> +{
> + pkill rpcbind 2>/dev/null
> +}
> +
> +# Start the NFS server if not already running.
> +_start_nfsd()
> +{
> + rpcinfo -p localhost 2>/dev/null | grep -q nfs && return 0
> + rpc.nfsd 2>> $seqres.full || _notrun "Cannot start rpc.nfsd"
> + rpc.mountd 2>> $seqres.full || _notrun "Cannot start rpc.mountd"
> +}
> +
> +# Stop the NFS server.
> +_stop_nfsd()
> +{
> + rpc.nfsd 0 2>/dev/null
> + pkill rpc.mountd 2>/dev/null
If the system under test has nfs filesystems mounted, won't killing
those daemons also break the mounts?
I think that might break testing of nfs itself, and nfs-booted testing
nodes as well?
--D
> +}
> +
> +# Require a NFS server to be available and start rpcbind and nfsd if they are
> +# not already running.
> +_require_nfs_server()
> +{
> + type -P exportfs > /dev/null 2>&1 || \
> + _notrun "exportfs utility required, skipped this test"
> + type -P rpc.nfsd > /dev/null 2>&1 || \
> + _notrun "rpc.nfsd utility required, skipped this test"
> + type -P rpc.mountd > /dev/null 2>&1 || \
> + _notrun "rpc.mountd utility required, skipped this test"
> + _start_rpcbind
> + _start_nfsd
> +}
> +
> +# Require a NFS client to be available.
> +_require_nfs_client()
> +{
> + grep -q nfs /proc/filesystems 2>/dev/null || \
> + _notrun "Kernel does not support NFS client"
> + type -P mount.nfs > /dev/null 2>&1 || \
> + _notrun "mount.nfs utility required, skipped this test"
> +}
> --
> 2.55.0
>
>
^ permalink raw reply [flat|nested] 13+ messages in thread* Re: [RFC PATCH 1/2] common/nfs: add management helpers
2026-09-08 14:22 ` Darrick J. Wong
@ 2026-09-09 6:12 ` Christoph Hellwig
2026-09-09 16:13 ` Darrick J. Wong
2026-09-10 11:30 ` Jeff Layton
0 siblings, 2 replies; 13+ messages in thread
From: Christoph Hellwig @ 2026-09-09 6:12 UTC (permalink / raw)
To: Darrick J. Wong
Cc: cem, zlang, linux-xfs, fstests, jack, Chuck Lever, Jeff Layton,
linux-nfs
On Tue, Sep 08, 2026 at 07:22:26AM -0700, Darrick J. Wong wrote:
> > +# Start rpcbind if it is not already running.
> > +_start_rpcbind()
> > +{
> > + rpcinfo -p localhost > /dev/null 2>&1 && return 0
> > + rpcbind 2>> $seqres.full || _notrun "Cannot start rpcbind"
> > + /usr/sbin/rpc.statd 2>> $seqres.full || _notrun "Cannot start rpc.statd"
> > + /usr/sbin/rpc.idmapd 2>> $seqres.full || _notrun "Cannot start rpc.idmapd"
> > + /usr/sbin/nfsdcld 2>> $seqres.full || _notrun "Cannot start nfsdcld"
>
> Aren't these daemons usually configured as system services?
>
> # service rpcbind start
>
> etc?
They usually are, but doing that as part of a test feels wrong.
Adding the relevant maintainers and list.
>
> > +}
> > +
> > +# Stop rpcbind.
> > +_stop_rpcbind()
> > +{
> > + pkill rpcbind 2>/dev/null
> > +}
> > +
> > +# Start the NFS server if not already running.
> > +_start_nfsd()
> > +{
> > + rpcinfo -p localhost 2>/dev/null | grep -q nfs && return 0
> > + rpc.nfsd 2>> $seqres.full || _notrun "Cannot start rpc.nfsd"
> > + rpc.mountd 2>> $seqres.full || _notrun "Cannot start rpc.mountd"
> > +}
> > +
> > +# Stop the NFS server.
> > +_stop_nfsd()
> > +{
> > + rpc.nfsd 0 2>/dev/null
> > + pkill rpc.mountd 2>/dev/null
>
> If the system under test has nfs filesystems mounted, won't killing
> those daemons also break the mounts?
>
> I think that might break testing of nfs itself, and nfs-booted testing
> nodes as well?
Possibly. I guess if we want to save we need to launch a container
or at least a network namespace this is bound too.
^ permalink raw reply [flat|nested] 13+ messages in thread* Re: [RFC PATCH 1/2] common/nfs: add management helpers
2026-09-09 6:12 ` Christoph Hellwig
@ 2026-09-09 16:13 ` Darrick J. Wong
2026-09-10 9:45 ` Carlos Maiolino
2026-09-10 11:30 ` Jeff Layton
1 sibling, 1 reply; 13+ messages in thread
From: Darrick J. Wong @ 2026-09-09 16:13 UTC (permalink / raw)
To: Christoph Hellwig
Cc: cem, zlang, linux-xfs, fstests, jack, Chuck Lever, Jeff Layton,
linux-nfs
On Tue, Sep 08, 2026 at 11:12:28PM -0700, Christoph Hellwig wrote:
> On Tue, Sep 08, 2026 at 07:22:26AM -0700, Darrick J. Wong wrote:
> > > +# Start rpcbind if it is not already running.
> > > +_start_rpcbind()
> > > +{
> > > + rpcinfo -p localhost > /dev/null 2>&1 && return 0
> > > + rpcbind 2>> $seqres.full || _notrun "Cannot start rpcbind"
> > > + /usr/sbin/rpc.statd 2>> $seqres.full || _notrun "Cannot start rpc.statd"
> > > + /usr/sbin/rpc.idmapd 2>> $seqres.full || _notrun "Cannot start rpc.idmapd"
> > > + /usr/sbin/nfsdcld 2>> $seqres.full || _notrun "Cannot start nfsdcld"
> >
> > Aren't these daemons usually configured as system services?
> >
> > # service rpcbind start
> >
> > etc?
>
> They usually are, but doing that as part of a test feels wrong.
> Adding the relevant maintainers and list.
<nod> I guess for this test we actually want to launch our own nfs
daemons in a separate pid / network namespace so that they don't
interfere with nfs operations outside of the test (e.g. testing nfs
itself, nfsboot, etc)
> >
> > > +}
> > > +
> > > +# Stop rpcbind.
> > > +_stop_rpcbind()
> > > +{
> > > + pkill rpcbind 2>/dev/null
> > > +}
> > > +
> > > +# Start the NFS server if not already running.
> > > +_start_nfsd()
> > > +{
> > > + rpcinfo -p localhost 2>/dev/null | grep -q nfs && return 0
> > > + rpc.nfsd 2>> $seqres.full || _notrun "Cannot start rpc.nfsd"
> > > + rpc.mountd 2>> $seqres.full || _notrun "Cannot start rpc.mountd"
> > > +}
> > > +
> > > +# Stop the NFS server.
> > > +_stop_nfsd()
> > > +{
> > > + rpc.nfsd 0 2>/dev/null
> > > + pkill rpc.mountd 2>/dev/null
> >
> > If the system under test has nfs filesystems mounted, won't killing
> > those daemons also break the mounts?
> >
> > I think that might break testing of nfs itself, and nfs-booted testing
> > nodes as well?
>
> Possibly. I guess if we want to save we need to launch a container
> or at least a network namespace this is bound too.
Agreed, some isolation from the main system is necessary.
--D
^ permalink raw reply [flat|nested] 13+ messages in thread* Re: [RFC PATCH 1/2] common/nfs: add management helpers
2026-09-09 16:13 ` Darrick J. Wong
@ 2026-09-10 9:45 ` Carlos Maiolino
0 siblings, 0 replies; 13+ messages in thread
From: Carlos Maiolino @ 2026-09-10 9:45 UTC (permalink / raw)
To: Darrick J. Wong
Cc: Christoph Hellwig, zlang, linux-xfs, fstests, jack, Chuck Lever,
Jeff Layton, linux-nfs
On Wed, Sep 09, 2026 at 09:13:42AM -0700, Darrick J. Wong wrote:
> On Tue, Sep 08, 2026 at 11:12:28PM -0700, Christoph Hellwig wrote:
> > On Tue, Sep 08, 2026 at 07:22:26AM -0700, Darrick J. Wong wrote:
> > > > +# Start rpcbind if it is not already running.
> > > > +_start_rpcbind()
> > > > +{
> > > > + rpcinfo -p localhost > /dev/null 2>&1 && return 0
> > > > + rpcbind 2>> $seqres.full || _notrun "Cannot start rpcbind"
> > > > + /usr/sbin/rpc.statd 2>> $seqres.full || _notrun "Cannot start rpc.statd"
> > > > + /usr/sbin/rpc.idmapd 2>> $seqres.full || _notrun "Cannot start rpc.idmapd"
> > > > + /usr/sbin/nfsdcld 2>> $seqres.full || _notrun "Cannot start nfsdcld"
> > >
> > > Aren't these daemons usually configured as system services?
> > >
> > > # service rpcbind start
> > >
> > > etc?
> >
> > They usually are, but doing that as part of a test feels wrong.
> > Adding the relevant maintainers and list.
>
> <nod> I guess for this test we actually want to launch our own nfs
> daemons in a separate pid / network namespace so that they don't
> interfere with nfs operations outside of the test (e.g. testing nfs
> itself, nfsboot, etc)
>
> > >
> > > > +}
> > > > +
> > > > +# Stop rpcbind.
> > > > +_stop_rpcbind()
> > > > +{
> > > > + pkill rpcbind 2>/dev/null
> > > > +}
> > > > +
> > > > +# Start the NFS server if not already running.
> > > > +_start_nfsd()
> > > > +{
> > > > + rpcinfo -p localhost 2>/dev/null | grep -q nfs && return 0
> > > > + rpc.nfsd 2>> $seqres.full || _notrun "Cannot start rpc.nfsd"
> > > > + rpc.mountd 2>> $seqres.full || _notrun "Cannot start rpc.mountd"
> > > > +}
> > > > +
> > > > +# Stop the NFS server.
> > > > +_stop_nfsd()
> > > > +{
> > > > + rpc.nfsd 0 2>/dev/null
> > > > + pkill rpc.mountd 2>/dev/null
> > >
> > > If the system under test has nfs filesystems mounted, won't killing
> > > those daemons also break the mounts?
> > >
> > > I think that might break testing of nfs itself, and nfs-booted testing
> > > nodes as well?
> >
> > Possibly. I guess if we want to save we need to launch a container
> > or at least a network namespace this is bound too.
>
> Agreed, some isolation from the main system is necessary.
Perhaps couldn't we just:
- start nfs server if not started
- only stop nfs server if we started it
And just take advantage of the server running if one is already there?
>
> --D
>
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [RFC PATCH 1/2] common/nfs: add management helpers
2026-09-09 6:12 ` Christoph Hellwig
2026-09-09 16:13 ` Darrick J. Wong
@ 2026-09-10 11:30 ` Jeff Layton
2026-09-10 11:40 ` Carlos Maiolino
1 sibling, 1 reply; 13+ messages in thread
From: Jeff Layton @ 2026-09-10 11:30 UTC (permalink / raw)
To: Christoph Hellwig, Darrick J. Wong
Cc: cem, zlang, linux-xfs, fstests, jack, Chuck Lever, linux-nfs
On Tue, 2026-09-08 at 23:12 -0700, Christoph Hellwig wrote:
> On Tue, Sep 08, 2026 at 07:22:26AM -0700, Darrick J. Wong wrote:
> > > +# Start rpcbind if it is not already running.
> > > +_start_rpcbind()
> > > +{
> > > + rpcinfo -p localhost > /dev/null 2>&1 && return 0
> > > + rpcbind 2>> $seqres.full || _notrun "Cannot start rpcbind"
> > > + /usr/sbin/rpc.statd 2>> $seqres.full || _notrun "Cannot start rpc.statd"
> > > + /usr/sbin/rpc.idmapd 2>> $seqres.full || _notrun "Cannot start rpc.idmapd"
> > > + /usr/sbin/nfsdcld 2>> $seqres.full || _notrun "Cannot start nfsdcld"
> >
> > Aren't these daemons usually configured as system services?
> >
> > # service rpcbind start
> >
> > etc?
>
> They usually are, but doing that as part of a test feels wrong.
> Adding the relevant maintainers and list.
>
>
I don't see a problem with using the normal systemd services as long as
you're just doing a "start" instead of an "enable". That would be a lot
less likely to bitrot than these scripts.
> > > +}
> > > +
> > > +# Stop rpcbind.
> > > +_stop_rpcbind()
> > > +{
> > > + pkill rpcbind 2>/dev/null
> > > +}
> > > +
> > > +# Start the NFS server if not already running.
> > > +_start_nfsd()
> > > +{
> > > + rpcinfo -p localhost 2>/dev/null | grep -q nfs && return 0
> > > + rpc.nfsd 2>> $seqres.full || _notrun "Cannot start rpc.nfsd"
> > > + rpc.mountd 2>> $seqres.full || _notrun "Cannot start rpc.mountd"
> > > +}
> > > +
> > > +# Stop the NFS server.
> > > +_stop_nfsd()
> > > +{
> > > + rpc.nfsd 0 2>/dev/null
> > > + pkill rpc.mountd 2>/dev/null
> >
> > If the system under test has nfs filesystems mounted, won't killing
> > those daemons also break the mounts?
> >
> > I think that might break testing of nfs itself, and nfs-booted testing
> > nodes as well?
>
> Possibly. I guess if we want to save we need to launch a container
> or at least a network namespace this is bound too.
Doing this in a container would be better and less likely to interfere
with other stuff running on the box. Our container isolation is still
not 100% perfect with nfsd (there is still a global mutex, etc.), but
we're getting closer.
--
Jeff Layton <jlayton@kernel.org>
^ permalink raw reply [flat|nested] 13+ messages in thread* Re: [RFC PATCH 1/2] common/nfs: add management helpers
2026-09-10 11:30 ` Jeff Layton
@ 2026-09-10 11:40 ` Carlos Maiolino
2026-09-10 11:48 ` Jeff Layton
0 siblings, 1 reply; 13+ messages in thread
From: Carlos Maiolino @ 2026-09-10 11:40 UTC (permalink / raw)
To: Jeff Layton
Cc: Christoph Hellwig, Darrick J. Wong, zlang, linux-xfs, fstests,
jack, Chuck Lever, linux-nfs
On Thu, Sep 10, 2026 at 07:30:46AM -0400, Jeff Layton wrote:
> On Tue, 2026-09-08 at 23:12 -0700, Christoph Hellwig wrote:
> > On Tue, Sep 08, 2026 at 07:22:26AM -0700, Darrick J. Wong wrote:
> > > > +# Start rpcbind if it is not already running.
> > > > +_start_rpcbind()
> > > > +{
> > > > + rpcinfo -p localhost > /dev/null 2>&1 && return 0
> > > > + rpcbind 2>> $seqres.full || _notrun "Cannot start rpcbind"
> > > > + /usr/sbin/rpc.statd 2>> $seqres.full || _notrun "Cannot start rpc.statd"
> > > > + /usr/sbin/rpc.idmapd 2>> $seqres.full || _notrun "Cannot start rpc.idmapd"
> > > > + /usr/sbin/nfsdcld 2>> $seqres.full || _notrun "Cannot start nfsdcld"
> > >
> > > Aren't these daemons usually configured as system services?
> > >
> > > # service rpcbind start
> > >
> > > etc?
> >
> > They usually are, but doing that as part of a test feels wrong.
> > Adding the relevant maintainers and list.
> >
> >
>
> I don't see a problem with using the normal systemd services as long as
> you're just doing a "start" instead of an "enable". That would be a lot
> less likely to bitrot than these scripts.
My only concern regarding using systemd services is portability. I tried
to keep the test agnostic to the init system being used, but it indeed
would be way easier to put this into xfstests if we just accept this
will be a __not_run on systemd-less distros. Giving the majority of
people I know frequently running xfstests (including me) uses
systemd-based distros, this wouldn't be a problem for me personally...
>
> > > > +}
> > > > +
> > > > +# Stop rpcbind.
> > > > +_stop_rpcbind()
> > > > +{
> > > > + pkill rpcbind 2>/dev/null
> > > > +}
> > > > +
> > > > +# Start the NFS server if not already running.
> > > > +_start_nfsd()
> > > > +{
> > > > + rpcinfo -p localhost 2>/dev/null | grep -q nfs && return 0
> > > > + rpc.nfsd 2>> $seqres.full || _notrun "Cannot start rpc.nfsd"
> > > > + rpc.mountd 2>> $seqres.full || _notrun "Cannot start rpc.mountd"
> > > > +}
> > > > +
> > > > +# Stop the NFS server.
> > > > +_stop_nfsd()
> > > > +{
> > > > + rpc.nfsd 0 2>/dev/null
> > > > + pkill rpc.mountd 2>/dev/null
> > >
> > > If the system under test has nfs filesystems mounted, won't killing
> > > those daemons also break the mounts?
> > >
> > > I think that might break testing of nfs itself, and nfs-booted testing
> > > nodes as well?
> >
> > Possibly. I guess if we want to save we need to launch a container
> > or at least a network namespace this is bound too.
>
> Doing this in a container would be better and less likely to interfere
> with other stuff running on the box. Our container isolation is still
> not 100% perfect with nfsd (there is still a global mutex, etc.), but
> we're getting closer.
>
> --
> Jeff Layton <jlayton@kernel.org>
>
^ permalink raw reply [flat|nested] 13+ messages in thread* Re: [RFC PATCH 1/2] common/nfs: add management helpers
2026-09-10 11:40 ` Carlos Maiolino
@ 2026-09-10 11:48 ` Jeff Layton
0 siblings, 0 replies; 13+ messages in thread
From: Jeff Layton @ 2026-09-10 11:48 UTC (permalink / raw)
To: Carlos Maiolino
Cc: Christoph Hellwig, Darrick J. Wong, zlang, linux-xfs, fstests,
jack, Chuck Lever, linux-nfs
On Thu, 2026-09-10 at 13:40 +0200, Carlos Maiolino wrote:
> On Thu, Sep 10, 2026 at 07:30:46AM -0400, Jeff Layton wrote:
> > On Tue, 2026-09-08 at 23:12 -0700, Christoph Hellwig wrote:
> > > On Tue, Sep 08, 2026 at 07:22:26AM -0700, Darrick J. Wong wrote:
> > > > > +# Start rpcbind if it is not already running.
> > > > > +_start_rpcbind()
> > > > > +{
> > > > > + rpcinfo -p localhost > /dev/null 2>&1 && return 0
> > > > > + rpcbind 2>> $seqres.full || _notrun "Cannot start rpcbind"
> > > > > + /usr/sbin/rpc.statd 2>> $seqres.full || _notrun "Cannot start rpc.statd"
> > > > > + /usr/sbin/rpc.idmapd 2>> $seqres.full || _notrun "Cannot start rpc.idmapd"
> > > > > + /usr/sbin/nfsdcld 2>> $seqres.full || _notrun "Cannot start nfsdcld"
> > > >
> > > > Aren't these daemons usually configured as system services?
> > > >
> > > > # service rpcbind start
> > > >
> > > > etc?
> > >
> > > They usually are, but doing that as part of a test feels wrong.
> > > Adding the relevant maintainers and list.
> > >
> > >
> >
> > I don't see a problem with using the normal systemd services as long as
> > you're just doing a "start" instead of an "enable". That would be a lot
> > less likely to bitrot than these scripts.
>
> My only concern regarding using systemd services is portability. I tried
> to keep the test agnostic to the init system being used, but it indeed
> would be way easier to put this into xfstests if we just accept this
> will be a __not_run on systemd-less distros. Giving the majority of
> people I know frequently running xfstests (including me) uses
> systemd-based distros, this wouldn't be a problem for me personally...
>
That's what I'd probably do. If someone wants to step up and do
something for non-systemd distros then they can have at it.
Alternately, you could use systemd and just fall back to what you're
doing now in the case where it's not present. My only fear there is
that the non-systemd cases would probably bitrot because no one would
use them.
That said, if you're doing all of this in a container then it shouldn't
matter much how it gets started.
> >
> > > > > +}
> > > > > +
> > > > > +# Stop rpcbind.
> > > > > +_stop_rpcbind()
> > > > > +{
> > > > > + pkill rpcbind 2>/dev/null
> > > > > +}
> > > > > +
> > > > > +# Start the NFS server if not already running.
> > > > > +_start_nfsd()
> > > > > +{
> > > > > + rpcinfo -p localhost 2>/dev/null | grep -q nfs && return 0
> > > > > + rpc.nfsd 2>> $seqres.full || _notrun "Cannot start rpc.nfsd"
If you do decide to go this route, note that rpc.nfsd is being
deprecated. We have a new tool for managing the server now called
"nfsdctl" that you probably want to use when possible.
> > > > > + rpc.mountd 2>> $seqres.full || _notrun "Cannot start rpc.mountd"
> > > > > +}
> > > > > +
> > > > > +# Stop the NFS server.
> > > > > +_stop_nfsd()
> > > > > +{
> > > > > + rpc.nfsd 0 2>/dev/null
> > > > > + pkill rpc.mountd 2>/dev/null
> > > >
> > > > If the system under test has nfs filesystems mounted, won't killing
> > > > those daemons also break the mounts?
> > > >
> > > > I think that might break testing of nfs itself, and nfs-booted testing
> > > > nodes as well?
> > >
> > > Possibly. I guess if we want to save we need to launch a container
> > > or at least a network namespace this is bound too.
> >
> > Doing this in a container would be better and less likely to interfere
> > with other stuff running on the box. Our container isolation is still
> > not 100% perfect with nfsd (there is still a global mutex, etc.), but
> > we're getting closer.
> >
> > --
> > Jeff Layton <jlayton@kernel.org>
> >
--
Jeff Layton <jlayton@kernel.org>
^ permalink raw reply [flat|nested] 13+ messages in thread
* [RFC PATCH 2/2] generic: add test for quota enforcement via a nfs share
2026-09-07 16:40 [RFC PATCH 0/2] quota evasion test and nfs helpers cem
2026-09-07 16:40 ` [RFC PATCH 1/2] common/nfs: add management helpers cem
@ 2026-09-07 16:40 ` cem
2026-09-08 10:25 ` Jan Kara
2026-09-08 10:29 ` [RFC PATCH 0/2] quota evasion test and nfs helpers Jan Kara
2026-09-10 11:34 ` Jeff Layton
3 siblings, 1 reply; 13+ messages in thread
From: cem @ 2026-09-07 16:40 UTC (permalink / raw)
To: zlang; +Cc: djwong, hch, linux-xfs, fstests, jack
From: Carlos Maiolino <cem@kernel.org>
This tests the quota enforcement when changing the group of a file via a
NFS share, caused by mishandling of capabilities check.
This initially has been found with a XFS filesystem backing the NFS
share, but this still possible to occur on a different filesystem if it
happens to also mishandle capabilities check.
Signed-off-by: Carlos Maiolino <cmaiolino@redhat.com>
---
tests/generic/803 | 106 ++++++++++++++++++++++++++++++++++++++++++
tests/generic/803.out | 2 +
2 files changed, 108 insertions(+)
create mode 100755 tests/generic/803
create mode 100644 tests/generic/803.out
diff --git a/tests/generic/803 b/tests/generic/803
new file mode 100755
index 000000000000..ab889466d80f
--- /dev/null
+++ b/tests/generic/803
@@ -0,0 +1,106 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2026 Red Hat. All Rights Reserved.
+#
+# FS QA Test No. 803
+#
+# Regression test for group quota evasion via NFS.
+#
+# A user belonging to two groups with quotas enforced on both could bypass
+# group quota by changing a file's group via an NFS client. The NFS server
+# runs as root (real credentials) but impersonates the client user via
+# override_creds() (effective credentials). The old code used
+# has_capability_noaudit(), which checks real credentials, causing
+# XFS_QMOPT_FORCE_RES to be set and bypassing quota checks.
+#
+. ./common/preamble
+_begin_fstest auto quick quota
+
+_cleanup()
+{
+ cd /
+ [ -n "$mpoint" ] && $UMOUNT_PROG $mpoint 2>/dev/null
+ sleep 2
+ [ -n "$exportdir" ] && exportfs -u 127.0.0.1:$exportdir 2>/dev/null
+ _stop_rpcbind
+ $added_to_fsgqa2 && gpasswd -d fsgqa fsgqa2 >> $seqres.full 2>&1
+ rm -rf $tmp.* $mpoint
+}
+
+# Import common functions.
+. ./common/filter
+. ./common/quota
+. ./common/nfs
+
+_require_scratch
+_require_quota
+_require_user
+_require_group fsgqa2
+_require_nfs_server
+_require_nfs_client
+
+_fixed_by_kernel_commit e2f62a9744ebad3bcb6347a648e615026e9efeff \
+ "xfs: fix capability check in xfs"
+
+added_to_fsgqa2=false
+
+_qmount_option "usrquota,grpquota"
+_scratch_mkfs >> $seqres.full 2>&1
+_qmount
+
+# Ensure fsgqa belongs to both fsgqa and fsgqa2 groups.
+if ! id fsgqa | grep -qw fsgqa2; then
+ gpasswd -a fsgqa fsgqa2 >> $seqres.full 2>&1 || \
+ _notrun "Cannot add fsgqa to fsgqa2 group"
+ added_to_fsgqa2=true
+fi
+
+exportdir=$SCRATCH_MNT/exportdir
+mpoint=$TEST_DIR/mpoint-$seq
+nfs_userdir=$mpoint/userdir
+
+mkdir -p $exportdir/userdir $mpoint
+chown fsgqa:fsgqa $exportdir/userdir
+
+setquota -g fsgqa 0 2048 0 0 $SCRATCH_MNT
+setquota -g fsgqa2 0 4096 0 0 $SCRATCH_MNT
+
+# Use exportfs directly so we don't need to deal with /etc/exports file
+exportfs -o rw,insecure,no_root_squash,sync 127.0.0.1:$exportdir \
+ >> $seqres.full 2>&1 || _fail "NFS export of $exportdir failed"
+mount -t nfs -o vers=4 127.0.0.1:$exportdir $mpoint \
+ >> $seqres.full 2>&1 || _fail "NFS mount of $exportdir at $mpoint failed"
+
+# Write a 2MiB file via the NFS share as fsgqa, filling the fsgqa group quota.
+_su fsgqa -c "dd if=/dev/zero of=$nfs_userdir/file1 bs=1M count=2 conv=fsync" \
+ >> $seqres.full 2>&1
+
+# Confirm we hit fsgqa group quota limit, a second write must fail.
+_su fsgqa -c "dd if=/dev/zero of=$nfs_userdir/verify bs=1M count=1 conv=fsync" \
+ >> $seqres.full 2>&1 \
+ && _fail "fsgqa group quota not enforced after writing 2MiB"
+rm -f $nfs_userdir/verify
+
+# Change file1 group to fsgqa2 using the NFS share.
+_su fsgqa -c "chgrp fsgqa2 $nfs_userdir/file1" \
+ || _fail "chgrp of file1 to fsgqa2 failed unexpectedly"
+
+# Write a second 2MiB file via NFS as fsgqa.
+_su fsgqa -c "dd if=/dev/zero of=$nfs_userdir/file2 bs=1M count=2 conv=fsync" \
+ >> $seqres.full 2>&1
+
+# Change file2 to group fsgqa2 via using the NFS share.
+_su fsgqa -c "chgrp fsgqa2 $nfs_userdir/file2" \
+ || _fail "chgrp of file2 to fsgqa2 failed unexpectedly"
+
+# Write a third 2MiB file via the NFS share as fsgqa.
+_su fsgqa -c "dd if=/dev/zero of=$nfs_userdir/file3 bs=1M count=2 conv=fsync" \
+ >> $seqres.full 2>&1
+
+# This chgrp must fail: fsgqa2 is at its 4MiB hardlimit.
+_user_do "chgrp fsgqa2 $nfs_userdir/file3" | \
+ sed "s|$nfs_userdir|MPOINT/userdir|g"
+
+# success, all done
+status=0
+exit
diff --git a/tests/generic/803.out b/tests/generic/803.out
new file mode 100644
index 000000000000..3830b8595793
--- /dev/null
+++ b/tests/generic/803.out
@@ -0,0 +1,2 @@
+QA output created by 803
+chgrp: changing group of 'MPOINT/userdir/file3': Disk quota exceeded
--
2.55.0
^ permalink raw reply related [flat|nested] 13+ messages in thread* Re: [RFC PATCH 2/2] generic: add test for quota enforcement via a nfs share
2026-09-07 16:40 ` [RFC PATCH 2/2] generic: add test for quota enforcement via a nfs share cem
@ 2026-09-08 10:25 ` Jan Kara
0 siblings, 0 replies; 13+ messages in thread
From: Jan Kara @ 2026-09-08 10:25 UTC (permalink / raw)
To: cem; +Cc: zlang, djwong, hch, linux-xfs, fstests, jack
On Mon 07-09-26 18:40:48, cem@kernel.org wrote:
> From: Carlos Maiolino <cem@kernel.org>
>
> This tests the quota enforcement when changing the group of a file via a
> NFS share, caused by mishandling of capabilities check.
> This initially has been found with a XFS filesystem backing the NFS
> share, but this still possible to occur on a different filesystem if it
> happens to also mishandle capabilities check.
>
> Signed-off-by: Carlos Maiolino <cmaiolino@redhat.com>
Looks good to me. Feel free to add:
Reviewed-by: Jan Kara <jack@suse.cz>
Honza
> ---
> tests/generic/803 | 106 ++++++++++++++++++++++++++++++++++++++++++
> tests/generic/803.out | 2 +
> 2 files changed, 108 insertions(+)
> create mode 100755 tests/generic/803
> create mode 100644 tests/generic/803.out
>
> diff --git a/tests/generic/803 b/tests/generic/803
> new file mode 100755
> index 000000000000..ab889466d80f
> --- /dev/null
> +++ b/tests/generic/803
> @@ -0,0 +1,106 @@
> +#! /bin/bash
> +# SPDX-License-Identifier: GPL-2.0
> +# Copyright (c) 2026 Red Hat. All Rights Reserved.
> +#
> +# FS QA Test No. 803
> +#
> +# Regression test for group quota evasion via NFS.
> +#
> +# A user belonging to two groups with quotas enforced on both could bypass
> +# group quota by changing a file's group via an NFS client. The NFS server
> +# runs as root (real credentials) but impersonates the client user via
> +# override_creds() (effective credentials). The old code used
> +# has_capability_noaudit(), which checks real credentials, causing
> +# XFS_QMOPT_FORCE_RES to be set and bypassing quota checks.
> +#
> +. ./common/preamble
> +_begin_fstest auto quick quota
> +
> +_cleanup()
> +{
> + cd /
> + [ -n "$mpoint" ] && $UMOUNT_PROG $mpoint 2>/dev/null
> + sleep 2
> + [ -n "$exportdir" ] && exportfs -u 127.0.0.1:$exportdir 2>/dev/null
> + _stop_rpcbind
> + $added_to_fsgqa2 && gpasswd -d fsgqa fsgqa2 >> $seqres.full 2>&1
> + rm -rf $tmp.* $mpoint
> +}
> +
> +# Import common functions.
> +. ./common/filter
> +. ./common/quota
> +. ./common/nfs
> +
> +_require_scratch
> +_require_quota
> +_require_user
> +_require_group fsgqa2
> +_require_nfs_server
> +_require_nfs_client
> +
> +_fixed_by_kernel_commit e2f62a9744ebad3bcb6347a648e615026e9efeff \
> + "xfs: fix capability check in xfs"
> +
> +added_to_fsgqa2=false
> +
> +_qmount_option "usrquota,grpquota"
> +_scratch_mkfs >> $seqres.full 2>&1
> +_qmount
> +
> +# Ensure fsgqa belongs to both fsgqa and fsgqa2 groups.
> +if ! id fsgqa | grep -qw fsgqa2; then
> + gpasswd -a fsgqa fsgqa2 >> $seqres.full 2>&1 || \
> + _notrun "Cannot add fsgqa to fsgqa2 group"
> + added_to_fsgqa2=true
> +fi
> +
> +exportdir=$SCRATCH_MNT/exportdir
> +mpoint=$TEST_DIR/mpoint-$seq
> +nfs_userdir=$mpoint/userdir
> +
> +mkdir -p $exportdir/userdir $mpoint
> +chown fsgqa:fsgqa $exportdir/userdir
> +
> +setquota -g fsgqa 0 2048 0 0 $SCRATCH_MNT
> +setquota -g fsgqa2 0 4096 0 0 $SCRATCH_MNT
> +
> +# Use exportfs directly so we don't need to deal with /etc/exports file
> +exportfs -o rw,insecure,no_root_squash,sync 127.0.0.1:$exportdir \
> + >> $seqres.full 2>&1 || _fail "NFS export of $exportdir failed"
> +mount -t nfs -o vers=4 127.0.0.1:$exportdir $mpoint \
> + >> $seqres.full 2>&1 || _fail "NFS mount of $exportdir at $mpoint failed"
> +
> +# Write a 2MiB file via the NFS share as fsgqa, filling the fsgqa group quota.
> +_su fsgqa -c "dd if=/dev/zero of=$nfs_userdir/file1 bs=1M count=2 conv=fsync" \
> + >> $seqres.full 2>&1
> +
> +# Confirm we hit fsgqa group quota limit, a second write must fail.
> +_su fsgqa -c "dd if=/dev/zero of=$nfs_userdir/verify bs=1M count=1 conv=fsync" \
> + >> $seqres.full 2>&1 \
> + && _fail "fsgqa group quota not enforced after writing 2MiB"
> +rm -f $nfs_userdir/verify
> +
> +# Change file1 group to fsgqa2 using the NFS share.
> +_su fsgqa -c "chgrp fsgqa2 $nfs_userdir/file1" \
> + || _fail "chgrp of file1 to fsgqa2 failed unexpectedly"
> +
> +# Write a second 2MiB file via NFS as fsgqa.
> +_su fsgqa -c "dd if=/dev/zero of=$nfs_userdir/file2 bs=1M count=2 conv=fsync" \
> + >> $seqres.full 2>&1
> +
> +# Change file2 to group fsgqa2 via using the NFS share.
> +_su fsgqa -c "chgrp fsgqa2 $nfs_userdir/file2" \
> + || _fail "chgrp of file2 to fsgqa2 failed unexpectedly"
> +
> +# Write a third 2MiB file via the NFS share as fsgqa.
> +_su fsgqa -c "dd if=/dev/zero of=$nfs_userdir/file3 bs=1M count=2 conv=fsync" \
> + >> $seqres.full 2>&1
> +
> +# This chgrp must fail: fsgqa2 is at its 4MiB hardlimit.
> +_user_do "chgrp fsgqa2 $nfs_userdir/file3" | \
> + sed "s|$nfs_userdir|MPOINT/userdir|g"
> +
> +# success, all done
> +status=0
> +exit
> diff --git a/tests/generic/803.out b/tests/generic/803.out
> new file mode 100644
> index 000000000000..3830b8595793
> --- /dev/null
> +++ b/tests/generic/803.out
> @@ -0,0 +1,2 @@
> +QA output created by 803
> +chgrp: changing group of 'MPOINT/userdir/file3': Disk quota exceeded
> --
> 2.55.0
>
--
Jan Kara <jack@suse.com>
SUSE Labs, CR
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [RFC PATCH 0/2] quota evasion test and nfs helpers
2026-09-07 16:40 [RFC PATCH 0/2] quota evasion test and nfs helpers cem
2026-09-07 16:40 ` [RFC PATCH 1/2] common/nfs: add management helpers cem
2026-09-07 16:40 ` [RFC PATCH 2/2] generic: add test for quota enforcement via a nfs share cem
@ 2026-09-08 10:29 ` Jan Kara
2026-09-10 11:34 ` Jeff Layton
3 siblings, 0 replies; 13+ messages in thread
From: Jan Kara @ 2026-09-08 10:29 UTC (permalink / raw)
To: cem; +Cc: zlang, djwong, hch, linux-xfs, fstests, jack
On Mon 07-09-26 18:40:46, cem@kernel.org wrote:
> While writing it I stumped on a weird issue that I'm not exactly sure
> how to fix (or if it's perhaps a bug on umount):
>
> During cleanup(), I umount the share and unexport the it so the rest
> of the generic cleanup can take place, specially umounting the scratch
> fs There is some timing though required by umount() to properly cleanup
> internal kernel structures before it can be unexported. I honestly
> assumed umount() was synchronous (unless lazy umount) and once it returned
> it was "done". But for some reason I didn't dig into, I need to wait a
> bit between unmounting the share and unexporting it.
> I tried to wait until the mount was excluded from /proc/mounts but even
> after the mount is gone, something still holds the share a bit
> preventing it to be unexported. So I went with a 2 second sleep :)
Yes, umount should be synchronous. But from time to time someone
inadvertedly offloads some cleanup to a workqueue which causes issues like
you describe. We've been through this a few times :). What you describe
seems to be this kind of issue specific for NFS mounts - would be good to
nail down what's exactly causing it.
Honza
--
Jan Kara <jack@suse.com>
SUSE Labs, CR
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [RFC PATCH 0/2] quota evasion test and nfs helpers
2026-09-07 16:40 [RFC PATCH 0/2] quota evasion test and nfs helpers cem
` (2 preceding siblings ...)
2026-09-08 10:29 ` [RFC PATCH 0/2] quota evasion test and nfs helpers Jan Kara
@ 2026-09-10 11:34 ` Jeff Layton
3 siblings, 0 replies; 13+ messages in thread
From: Jeff Layton @ 2026-09-10 11:34 UTC (permalink / raw)
To: cem, zlang; +Cc: djwong, hch, linux-xfs, fstests, jack, linux-nfs, Chuck Lever
On Mon, 2026-09-07 at 18:40 +0200, cem@kernel.org wrote:
> From: Carlos Maiolino <cem@kernel.org>
>
> Hi folks.
>
> I'm flagging these as RFC because I'd like an input in the approach I
> took here regarding how to setup a local nfs-server to reproduce the bug
> recently fixed on xfs quotas.
>
> The issue is regarding how we checked the credentials before proceeding
> with quota enforcement / or not. And due the chgrp() being run through a
> NSF share, xfs used the wrong credentials allowing an user to evade
> quotas.
>
> The TL;DR; for the approach is:
> - setup a xfs fs with an user belonging to two groups with group
> quotas enforced
> - Setup a local nfs server/client and mount it locally through
> loopback
> - use the user to fill in the share until it exceeds quota
> - change group of the file to the second group.
> - repeat a couple times until the second group quota is
> exceeded.
>
> I'm using the already existing user/groups. The tests uses exportfs directly
> instead of seeting up a exports file, and I added a few new helpers to
> start/stop nfsd and rpcbind. The latter I did as an attempt to make the test
> systemd-agnostic. It is working even if nfs-server systemd service is disabled,
> but I didn't try on a systemd-less OS.
>
> While writing it I stumped on a weird issue that I'm not exactly sure
> how to fix (or if it's perhaps a bug on umount):
>
> During cleanup(), I umount the share and unexport the it so the rest
> of the generic cleanup can take place, specially umounting the scratch
> fs There is some timing though required by umount() to properly cleanup
> internal kernel structures before it can be unexported. I honestly
> assumed umount() was synchronous (unless lazy umount) and once it returned
> it was "done". But for some reason I didn't dig into, I need to wait a
> bit between unmounting the share and unexporting it.
> I tried to wait until the mount was excluded from /proc/mounts but even
> after the mount is gone, something still holds the share a bit
> preventing it to be unexported. So I went with a 2 second sleep :)
>
It may be that nfsd still has some state held here that is being
cleaned up. Chuck has a patchset in progress that may help this:
https://lore.kernel.org/linux-nfs/20260419-umount-kills-nfsv4-state-v9-0-0660bd06d2b6@oracle.com/
> Overall the test works, passing on a patched kernel or failing
> otherwise.
>
> Comments? Flames? Stones?
>
> Cheers.
>
> Carlos Maiolino (2):
> common/nfs: add management helpers
> generic: add test for quota enforcement via a nfs share
>
> common/nfs | 55 ++++++++++++++++++++++
> tests/generic/803 | 106 ++++++++++++++++++++++++++++++++++++++++++
> tests/generic/803.out | 2 +
> 3 files changed, 163 insertions(+)
> create mode 100755 tests/generic/803
> create mode 100644 tests/generic/803.out
--
Jeff Layton <jlayton@kernel.org>
^ permalink raw reply [flat|nested] 13+ messages in thread