What a clever trick. I really hadn't given much thought to doing this.
But yes it works. And yes, it is utilizing functionality in an intended and supported
way.
And yes, the "invisible" directory is intentional. That aspect was desired by
those interested in multi-tenancy where you don't want the other tenants to have any
idea of the location or even existence of other tenants.
One tiny caveat - Ganesha has no subtree checking for handles so handle guessing can be
used to access files not intended to be visible.
As to fs vs fs_ng, I'm insufficiently knowledgeable about the changes for ng so I
can't offer much advice there.
If fs_ng works given testing, then that is probably the best way to go.
Frank
-----Original Message-----
From: purkaitabhinandan(a)gmail.com [mailto:purkaitabhinandan@gmail.com]
Sent: Tuesday, August 18, 2026 9:42 PM
To: devel(a)lists.nfs-ganesha.org
Subject: [NFS-Ganesha-Devel] Guidance: keeping `RecoveryRoot` inside an exported tree via
a nested export with `Access_Type = None`
Hi — a design question rather than a bug report, and I'd like to check whether
we're leaning on behaviour that is intended before we build on it.
### Setup
- NFS-Ganesha **V6.5**, built with `USE_FSAL_VFS=ON`, and notably
`USE_RADOS_RECOV=OFF` / `USE_RADOS_GRACE=OFF`, so the rados recovery backends
are not available to us.
- One Ganesha instance per volume, running in a container, single server
(no active/active, no clustering).
- The container exports a single block-backed filesystem, and the export is the
**root** of that filesystem:
```
EXPORT {
Export_Id = 1;
Path = /data/export;
Pseudo = /;
Access_Type = RW;
Squash = No_Root_Squash;
SecType = sys;
Protocols = 4;
FSAL { Name = VFS; }
}
```
### Problem
`RecoveryBackend = fs` defaults its `RecoveryRoot` to `/var/lib/nfs/ganesha`, which in our
container is ephemeral — it is discarded on every restart, so `clid_count` is always 0 on
start-up and no client can reclaim (`nfs4_op_open.c` returns `NFS4ERR_NO_GRACE` for
`CLAIM_PREVIOUS`).
The only durable storage the server has is the exported filesystem itself, which follows
the server when it moves. So we would like `RecoveryRoot` to live on that filesystem — but
since we export its root, the recovery directory would sit inside the exported tree,
visible and writable by clients.
### What we're considering
Add a second export covering just the recovery directory, with no access:
```
EXPORT {
Export_Id = 2;
Path = /data/export/.ganesha;
Pseudo = /.ganesha;
Access_Type = None;
Protocols = 4;
FSAL { Name = VFS; }
}
```
### What we observed (V6.5, FSAL_VFS)
Both exports load:
```
Export ... 1 pseudo (/) path (/data/export) perms (... no_root_squash,
RWrw, ...)
Export ... 2 pseudo (/.ganesha) path (/data/export/.ganesha) perms (... ----, ...)
NFSv4 pseudo file system successfully initialized ```
From a client — including **root** under `No_Root_Squash`:
- `ls -a` on the share does **not** list `.ganesha` at all
- `stat`/`cat` on that path return `ENOENT`, not `EACCES`
- `rm -rf <share>/* <share>/.[!.]*` removes everything else and leaves the
recovery data untouched
- the parent export continues to serve reads and writes normally
Controlled by removing only the second export and restarting: the same directory (same
inode, mode 0700) then appears in `ls -a` and its contents are readable over NFS. So the
nested export is unambiguously what makes it unreachable.
### Questions
1. **Is this a supported use of nested exports**, or are we relying on an
accident? Is there an intended mechanism for excluding a subdirectory from an
export that we've missed?
2. **Is the READDIR filtering intentional and stable?** We expected `EACCES` on
traversal and instead the junction is omitted from the listing entirely, which
is nicer for us — but we don't want to depend on it if it's incidental.
3. **Any correctness concern with `RecoveryRoot` living inside an exported
tree?** The server writes its own client database into a path that is
nominally part of an export, albeit one no client can enter. Is there
re-entrancy, FSAL, or grace-period interaction we should worry about?
4. For a single-server, one-instance-per-volume deployment where the recovery
directory travels with the exported filesystem, **is `fs` or `fs_ng`
preferable?** We read `recovery_fs_ng.c` as adding atomic generation swaps via
`rename()` + `symlink()`; our backing filesystem is ext4, so both are viable.
_______________________________________________
Devel mailing list -- devel(a)lists.nfs-ganesha.org To unsubscribe send an email to
devel-leave(a)lists.nfs-ganesha.org