NFS Configuration: Difference between revisions
m Restore the qs_nfsv4_sessions.sh diagnostic with its correct installed path under /opt/osnexus/quantastor/bin (QSTOR-12352) |
m State the supported topology explicitly -- a node serves NFS from scale-up or scale-out pools, not both, with the reasons -- and stop presenting the legacy qs-util nfsstandard/nfsganesha verbs as a way to switch modes; the NFS Services Configuration dialog is the supported path (QSTOR-12352) |
||
| Line 8: | Line 8: | ||
! Section !! Purpose | ! Section !! Purpose | ||
|- | |- | ||
| [[#The two NFS server implementations|The two NFS server implementations]] || Scale-up versus scale-out, | | [[#The two NFS server implementations|The two NFS server implementations]] || Scale-up versus scale-out, which storage architecture selects which, and why a node serves one or the other | ||
|- | |- | ||
| [[#Configuring the NFS service|Configuring the NFS service]] || The NFS Services Configuration dialog, field by field | | [[#Configuring the NFS service|Configuring the NFS service]] || The NFS Services Configuration dialog, field by field | ||
| Line 57: | Line 57: | ||
</pre> | </pre> | ||
Selecting '''Scale-out''' moves NFS-Ganesha to 2049 with NFSv3 and NFSv4 enabled, and stops, disables and masks the kernel NFS server | Selecting '''Scale-out''' moves NFS-Ganesha to 2049 with NFSv3 and NFSv4 enabled, and stops, disables and masks the kernel NFS server. On a system with no Ceph storage the Ganesha service is left masked and not running. | ||
QuantaStor | === A node serves NFS from scale-up pools or scale-out pools, not both === | ||
'''This is a supported-configuration constraint, not a limitation to design around.''' A given storage system serves NFS from ZFS Storage Pools or from CephFS pools -- whichever its NFS Server Type selects -- and not from both at once. The reasons are specific to each server: | |||
* '''CephFS does not work properly behind the kernel NFS server.''' Re-exporting a CephFS mount through <code>nfsd</code> is not a supported combination, which is why the scale-out path exists at all. | |||
* '''NFS-Ganesha has too many gaps to put in front of a scale-up pool.''' The comparison below shows them: no NFSv3 on the alternate port, no NLM locking, no Kerberos, and a set of per-client export options it does not implement. A ZFS pool served through Ganesha would lose capability that scale-up administrators depend on. | |||
So the mode switch masking the other server is the '''intended''' behaviour, and the right way to read it. Plan a node as a scale-up NAS or a scale-out NAS and set the NFS Server Type to match. If you need both architectures, use separate storage systems -- they can be members of the same grid. | |||
The practical consequence to plan for is that '''switching the mode on a node that has shares on the other kind of pool takes those shares offline for NFS clients''', immediately and without a confirmation prompt. They remain reachable over SMB. Check what the node is serving before you change the setting. | |||
QuantaStor sets Scale-out for you in the one case where it is unambiguous: when a Ceph file system or Ceph object pool is created on a system that has '''no''' ZFS Storage Pools. If ZFS pools are present it leaves the setting alone and raises a warning alert reading ''"SCALE-UP pool(s) present on local system. Not configuring SCALE-OUT NFS settings."'' -- which is the same constraint, enforced from the other direction. | |||
For the Ceph side of the picture, see [[Scale-out File Setup (ceph)]]. | For the Ceph side of the picture, see [[Scale-out File Setup (ceph)]]. | ||
| Line 381: | Line 392: | ||
There is no <code>qs</code> command for this operation. It is available from the WUI and the REST API only. | There is no <code>qs</code> command for this operation. It is available from the WUI and the REST API only. | ||
One appliance-side command covers a case the dialog does not. <code>qs-util nfsrdma</code> enables NFS over RDMA: it loads the <code>rpcrdma</code> module, sets <code>rdma=y</code> and <code>rdma-port=20049</code> in {{Code|1=/etc/nfs.conf}} after backing the file up, restarts the server and verifies the RDMA port came up. RDMA has no equivalent in the WUI, and it needs lossless or PFC configured on both the appliance and the client to be worth having. | |||
'''<code>qs-util nfsstandard</code> and <code>qs-util nfsganesha</code> are legacy and should not be used.''' They predate NFS server mode being managed properly, and the '''NFS Server Type''' setting in the [[#Configuring the NFS service|NFS Services Configuration]] dialog is the supported way to switch between the two servers. Use the dialog. | |||
== NFS over an HA storage pool == | == NFS over an HA storage pool == | ||
| Line 519: | Line 532: | ||
</pre> | </pre> | ||
With the server type set to '''Scale-out''', Ganesha owns 2049 and no port override is needed. NFSv3 is not an option against the alternate port. | With the server type set to '''Scale-out''', Ganesha owns 2049 and no port override is needed, and this is the configuration to be in if a node is serving CephFS shares over NFS -- see [[#A node serves NFS from scale-up pools or scale-out pools, not both|A node serves NFS from scale-up pools or scale-out pools, not both]]. NFSv3 is not an option against the alternate port. | ||
=== Windows clients === | === Windows clients === | ||
Revision as of 05:45, 3 September 2026
QuantaStor provides NFS access to Network Shares via two server implementations, and which one serves a share is decided by the storage architecture underneath it. This page covers those two servers and how one is selected, the NFS protocol versions on offer, the export configuration QuantaStor generates and where it lives on the appliance, the export options a client access rule can produce, how export changes are applied, NFS across an HA storage pool, how UIDs and GIDs resolve, and how to mount a share from Linux.
Creating and modifying shares, the Add NFS Client Access dialog and its checkboxes, quotas, aliases and snapshot management all belong to Network Shares. This page starts where that one stops: at the server and the client.
| Section | Purpose |
|---|---|
| The two NFS server implementations | Scale-up versus scale-out, which storage architecture selects which, and why a node serves one or the other |
| Configuring the NFS service | The NFS Services Configuration dialog, field by field |
| NFS protocol versions | NFSv3, NFSv4 and the NFSv4 minor versions, and what changes for a client |
| The export configuration QuantaStor generates | The files on the appliance, and the exact export lines written into them |
| Client access rules and export options | Every export option QuantaStor can emit, and what sets it |
| Applying export changes | Reload versus restart, and when a client is interrupted |
| Restarting the NFS service | The Restart Storage Services operation and when it is needed |
| NFS over an HA storage pool | What a client sees when a pool fails over |
| How UIDs and GIDs resolve | ID mapping, Manage GIDs, and AD-backed ownership |
| Snapshot access over NFS | The _snaps and .zfs sub-exports as an NFS client sees them
|
| Mounting from a Linux client | A worked mount, the options that matter, and making it persistent
|
| Ports and firewall | What has to be reachable, and what QuantaStor does not pin |
| Troubleshooting | The failures that come up most, and what to check |
The two NFS server implementations
| Scale-up | Scale-out | |
|---|---|---|
| Server | The Linux kernel NFS server | NFS-Ganesha, a user-space NFS server |
| Serves shares on | ZFS Storage Pools | CephFS pools and Ceph object gateway buckets |
| Service | nfs-server.service (nfsd) |
nfs-ganesha.service (ganesha.nfsd)
|
| Export configuration | /etc/exports |
/etc/ganesha/ganesha.conf
|
| Owns TCP/UDP 2049 | Yes | Only when Scale-out is selected |
The setting that chooses between them decides, in practice, which of the two servers owns port 2049. Selecting Scale-up leaves the kernel NFS server on 2049 serving both NFSv3 and NFSv4, and configures NFS-Ganesha for the alternate port 2249 in NFSv4-only mode so that the two do not contend for 2049 or for the RPC mount service. QuantaStor records that in the header of the generated exports file:
## NOTE: Scale-out CephFS NAS exports are presented via NFS-Ganesha on alternate default port 2249 rather than 2049.
Selecting Scale-out moves NFS-Ganesha to 2049 with NFSv3 and NFSv4 enabled, and stops, disables and masks the kernel NFS server. On a system with no Ceph storage the Ganesha service is left masked and not running.
A node serves NFS from scale-up pools or scale-out pools, not both
This is a supported-configuration constraint, not a limitation to design around. A given storage system serves NFS from ZFS Storage Pools or from CephFS pools -- whichever its NFS Server Type selects -- and not from both at once. The reasons are specific to each server:
- CephFS does not work properly behind the kernel NFS server. Re-exporting a CephFS mount through
nfsdis not a supported combination, which is why the scale-out path exists at all. - NFS-Ganesha has too many gaps to put in front of a scale-up pool. The comparison below shows them: no NFSv3 on the alternate port, no NLM locking, no Kerberos, and a set of per-client export options it does not implement. A ZFS pool served through Ganesha would lose capability that scale-up administrators depend on.
So the mode switch masking the other server is the intended behaviour, and the right way to read it. Plan a node as a scale-up NAS or a scale-out NAS and set the NFS Server Type to match. If you need both architectures, use separate storage systems -- they can be members of the same grid.
The practical consequence to plan for is that switching the mode on a node that has shares on the other kind of pool takes those shares offline for NFS clients, immediately and without a confirmation prompt. They remain reachable over SMB. Check what the node is serving before you change the setting.
QuantaStor sets Scale-out for you in the one case where it is unambiguous: when a Ceph file system or Ceph object pool is created on a system that has no ZFS Storage Pools. If ZFS pools are present it leaves the setting alone and raises a warning alert reading "SCALE-UP pool(s) present on local system. Not configuring SCALE-OUT NFS settings." -- which is the same constraint, enforced from the other direction.
For the Ceph side of the picture, see Scale-out File Setup (ceph).
What differs between them
The two servers are not interchangeable, and several things configured per share reach only one of them.
| Scale-up (kernel) | Scale-out (Ganesha) | |
|---|---|---|
| Export path a client mounts | /export/<share> |
/<share>, or /s3/<bucket> for an object gateway bucket
|
| NFSv3 | Available | Not available while the server is on port 2249, because the RPC mount service is left to the kernel server |
| NFSv3 byte-range locking (NLM) | Available | Disabled -- the shipped configuration sets enable_nlm = false
|
| Quota reporting over NFS (RQUOTA) | Not offered -- no rquotad is registered with rpcbind |
Not offered -- the shipped configuration sets enable_rquota = false, noted in the file as not supported on CephFS
|
| Kerberos security | Available | Not available; every generated export is sectype = sys
|
| Read-only, root squash, client filter | Honoured | Honoured |
| Full port range, async writes, subtree checks, custom export options, Filter Priority | Honoured | Not applied. These are accepted and stored, and the WUI still shows them, but they are not written into the Ganesha configuration |
| NFSv4 referrals for a Global Namespace | Generated | Not generated |
Neither server offers RQUOTA, so quota on a client does not report a share's quota. Read the share quota from the WUI or from qs share-get, and per-user and per-group quotas from qs share-quota-list --share=<share>. Network Shares covers how they are set.
Hand edits to /etc/ganesha/ganesha.conf survive only outside the EXPORT sections, which QuantaStor regenerates. Put additions in /etc/ganesha/ganesha.conf.custom, which is appended verbatim on every save. Keep the OSNEXUS header comment in place: a ganesha.conf that does not contain that string is treated as foreign and replaced with the QuantaStor default.
Configuring the NFS service

The NFS Services Configuration dialog holds every NFS setting that applies to a whole storage system. It is a per-system dialog even though it is reached from the Network Shares view -- the Storage System combo at the top selects which member of the grid you are configuring, and the fields below repopulate from that system's current configuration when you change it.
| Setting | Default | Notes |
|---|---|---|
| NFS Server Type | Scale-up | Scale-up or Scale-out, as described above. |
| NFS Protocol Mode | NFS v3/v4 | NFS v3/v4, NFS v3, or NFS v4. See NFS protocol versions. |
| Disable NFSv4 /export Browsing | off | Per the dialog's own tooltip this blocks creation of the NFSv4 export root (fsid=0), which is what lets a client mount the top of the tree and browse every share. In the default NFS v3/v4 mode QuantaStor generates no root export, so there is nothing for the setting to suppress and it has no effect there.
|
| Manage GIDs | on | See How UIDs and GIDs resolve. |
| Enable Kerberos Security | off | Enables the two Kerberos Security Settings below and switches Default Security Policy to kerberos. Clearing it switches the policy back to system and greys both fields out again.
|
| Kerberos Mode | Kerberos Integrity (krb5i) | Kerberos Integrity (krb5i), Kerberos Privacy (krb5p), or Kerberos Client/Server Auth (krb5). These map to the NFS sec=krb5i, sec=krb5p and sec=krb5 export options.
|
| Default Security Policy | system |
kerberos or system. The system-wide default that a share uses unless it carries its own override. Its tooltip makes the point that matters: with Kerberos configured you can still have Network Shares that do not require Kerberos security, because each share can override this.
|

Two details about the dialog are worth knowing before you read a value off it. The Default Security Policy actually stored is a third value, inherit, which the dialog never shows -- it renders the resolved policy instead, so a system with Kerberos off displays system while the stored setting is inherit. And NFS Server Type is read back from the Ganesha configuration on disk rather than from the database, so it always reflects which server currently holds port 2049.
There is no qs command for any of these settings -- they are set from the WUI and the REST API only. You can read the whole configuration back with qs system-get:
Nfs Mode: NFSv3+v4
Nfs4 Kerberos Enabled: false
Nfs Kerberos Mode: 0
Nfs4 Browsing Disabled: false
Default Nfs Security Policy: inherit
Nfs Server Type: scaleup
Nfs Manage Gids: true
Nfsd Service Status: Running
Kerberos

Enable Kerberos Security turns on the GSS daemons and puts a sec= prefix on the export lines QuantaStor generates. It does not build the Kerberos environment for you: no keytab is created, and /etc/krb5.conf is not written. QuantaStor says so at the time, raising an alert that reads "Secure NFSv4 access on '<system>' will not be enabled until the Kerberos configuration steps are completed including manually editing /etc/krb5.conf to setup the domain/realm(s) for your environment."
The practical order is therefore to establish Kerberos first and enable the checkbox second. Joining the system to an Active Directory domain is the supported route -- the domain join generates /etc/krb5.conf from a template, creates the machine keytab at /etc/krb5.keytab, and points Samba at the system keytab. See Network Shares for the Join AD Domain operation and Security Configuration for the wider authentication picture.
How the policy resolves for a given share, in order:
- Start from the system's Default Security Policy.
- If that is
inherit, resolve it tokerberoswhen Enable Kerberos Security is on and tosystemwhen it is off. - If the share carries its own override, that wins.
The per-share override is the one part of this the CLI does reach: qs share-modify --share=<share> --nfs-security-policy=<inherit|kerberos|system>, with inherit the default. Two consequences follow from how the resolved policy is used:
- An effective policy of
systememits nosec=option at all. QuantaStor never writessec=sys; AUTH_SYS is what the server falls back to. - A per-share policy of
kerberoson a system where Enable Kerberos Security is off is silently ignored, because thesec=prefix is only emitted when Kerberos is enabled system-wide.
Only one flavour is offered at a time. QuantaStor writes a single sec=krb5, sec=krb5i or sec=krb5p, never a list, so a client must match the configured mode.
NFS protocol versions
NFS Protocol Mode is a system-wide radio with three positions, and it writes the vers3 and vers4 keys in the [nfsd] section of /etc/nfs.conf:
| Mode | [nfsd] vers3 |
[nfsd] vers4 |
Use it when |
|---|---|---|---|
| NFS v3/v4 (default) | y |
y |
Mixed client estates. Each client's own mount options decide which version it gets. |
| NFS v3 | y |
n |
Clients that cannot speak NFSv4 and you want to be certain nothing negotiates up. |
| NFS v4 | n |
y |
Kerberos, or a policy of NFSv4 only. Removes the need for rpcbind and the NFSv3 helper daemons. |
QuantaStor does not configure the NFSv4 minor versions. The vers4.0, vers4.1 and vers4.2 keys in /etc/nfs.conf are left at their distribution defaults, which have 4.1 and 4.2 enabled. In the default mode a Linux client asking for -o vers=4 negotiates 4.2, and -o vers=4.1 is honoured if you pin it. If you need to pin or exclude a minor version, edit those keys by hand -- but note that applying the dialog rewrites vers3 and vers4 in the same file, and the NFS configuration is reapplied from the database each time the QuantaStor service starts.
What changes for a client between v3 and v4
| NFSv3 | NFSv4 | |
|---|---|---|
| Mount path (default protocol mode) | <ip>:/export/<share> |
<ip>:/export/<share> -- the same
|
| Ports needed | 2049 plus rpcbind on 111, plus mountd, statd and lockd on ephemeral ports |
2049 only |
| Identity on the wire | Numeric UID and GID | user@domain strings, mapped at both ends
|
| Locking | Separate NLM protocol, via lockd |
Part of the protocol, with server-side state |
| Server state | Stateless; a server restart is transparent to a hard mount | Stateful; a server restart makes the client re-establish its session and reclaim locks |
| Browsing the whole tree | Not possible; each export is mounted by path | Mount <ip>:/ and walk down into export/
|
The mount path being identical for both versions is worth stating plainly, because NFSv4 servers commonly present shares under a pseudo-root that hides the real path. On QuantaStor in the default protocol mode the NFSv4 pseudo-filesystem is rooted at / and the shares appear beneath /export, exactly where NFSv3 finds them.
The export configuration QuantaStor generates
| File | What it is |
|---|---|
/etc/exports |
Generated by QuantaStor for the kernel NFS server. One line per exported share, rebuilt from the database whenever anything relevant changes and whenever the QuantaStor service starts. |
/etc/exports.custom |
Where your own export entries go. Its contents are appended verbatim to the generated file after a ## CUSTOM EXPORTS marker line.
|
/etc/nfs.conf |
The NFS daemon configuration. QuantaStor writes [nfsd] vers3, [nfsd] vers4 and [mountd] manage-gids and preserves the rest.
|
/etc/default/nfs-kernel-server |
QuantaStor writes RPCMOUNTDOPTS and the GSS daemon switches here.
|
/etc/ganesha/ganesha.conf |
The scale-out server's configuration, with a QuantaStor-managed EXPORT section per Ceph share.
|
/etc/ganesha/ganesha.conf.custom |
Where your own Ganesha entries go. |
The generated exports file opens with its own warning:
## WARNING: FILE GENERATED BY QUANTASTOR CORE SERVICES, MANUAL CHANGES MAY BE LOST ## ## NOTE: Scale-out CephFS NAS exports are presented via NFS-Ganesha on alternate default port 2249 rather than 2049. ##
Take that literally. On each regeneration QuantaStor keeps only single-# comments and export lines whose path is not under /export, /mnt/storage-pools/, /mnt/namespaces/ or /mnt/cloud-containers/; everything else it wrote before, and everything after the ## CUSTOM EXPORTS marker, is discarded and rebuilt. A hand-added export under /export will disappear. Use /etc/exports.custom instead.
A share is exported at /export/<share>, which is a recursive bind mount of the share's real path under /mnt/storage-pools/qs-<pool-id>/<share>. Both paths are shown by qs share-get as Export Path and Share Path.
A share created with default settings gets one [public] client rule, and produces one line:
/export/share1 *(rw,insecure,sync,no_subtree_check,crossmnt,fsid=8d13e546-ffa8-3abd-8c3f-d425443501ac)
Every client access rule on the share becomes one <filter>(<options>) group on that same line, and QuantaStor assembles the options in a fixed order:
[sec=krb5|krb5i|krb5p,] ro|rw , secure|insecure , async|sync , subtree_check|no_subtree_check
[,<custom export options>] [,crossmnt] [,nohide] [,fsid=<share UUID>] [,refer=...]
The fsid= value is the share's own object ID. Pinning it to something stable, rather than letting the server derive it from the underlying device, is what keeps a client's file handles valid across a service restart or a move of the pool to another node. It changes if a share is deleted and recreated under the same name, which is the usual cause of a stale file handle on a client that stayed mounted.
Rule order within a line
The kernel NFS server uses the first matching entry on a line, not the most specific one, so the order QuantaStor writes them in is what decides which rule a client gets. QuantaStor sorts most specific first:
| Order | Filter kind | Example |
|---|---|---|
| 1 | Single IP address | 192.168.10.44
|
| 2 | Host or domain wildcard, and netgroups | *.example.com, @netgrp
|
| 3 | Network | 192.168.10.0/24
|
| 4 | Public | *
|
Filter Priority on a rule breaks ties within a class -- it does not lift a network rule above a host rule. Leaving it on Auto sorts the rule last within its class. Five rules on one share come out like this:
/export/share1 192.168.10.44(rw,secure,sync,no_subtree_check,no_root_squash,anonuid=150,anongid=100,crossmnt,fsid=...)
*.example.com(rw,secure,sync,no_subtree_check,crossmnt,fsid=...)
@netgrp(rw,secure,sync,no_subtree_check,crossmnt,fsid=...)
192.168.10.0/24(ro,secure,async,subtree_check,crossmnt,fsid=...)
*(rw,insecure,sync,no_subtree_check,crossmnt,fsid=...)
(Shown wrapped for readability; the appliance writes one share per physical line.)
Sub-exports for snapshot browsing
A share can produce two extra export lines, both covered under Snapshot access over NFS. Neither carries an fsid=.
| Line | Appears when | Extra options |
|---|---|---|
/export/<share>/.zfs |
The share has at least one snapshot and NFS browsing of the hidden snapshot directory is enabled | crossmnt,nohide
|
/export/<share>_snaps |
The share has at least one activated GMT snapshot and NFS _snaps browsing is enabled |
crossmnt
|
Because both are conditional on snapshots existing, the set of exports on a system grows and shrinks as snapshots are taken and expired. A client that mounted /export/<share>_snaps will find it gone once the last activated snapshot is removed.
Client access rules and export options
Access to a share over NFS is granted per client by a rule carrying its own export options. The dialog for adding and modifying those rules, the five filter kinds, and every checkbox on it are documented on Network Shares under NFS client access. What follows is the export option each control produces, and the CLI equivalents.
| Export option | Set by | What it does |
|---|---|---|
rw / ro |
Read Only on the rule, or Read Only on the share -- the share-level setting wins | Whether the client may write. |
insecure / secure |
Allow Full Port Range Access -- ticked gives insecure |
secure requires the client's requests to come from a reserved source port below 1024. Many clients do not use one by default, including macOS without resvport and a good number of containerised and appliance clients, so secure is a common cause of an unexplained permission denied.
|
sync / async |
Async Writes | async lets the server acknowledge a write before it is on stable storage. Faster, and it breaks the NFS protocol's durability guarantee; the dialog's tooltip says not recommended.
|
no_subtree_check / subtree_check |
Subtree checks | Subtree checking asks the server to verify that a file handle falls within the exported subtree. It exists for nested exports, costs performance, and can break renames. QuantaStor does not nest NFS exports, so leave it off. |
no_root_squash |
Allow Root Access, which appends the literal string to the rule's custom options | Without it, root on the client is mapped to the anonymous user. This is one of the few options QuantaStor does not write itself -- it reaches the export line through the custom options field.
|
crossmnt |
On unless Disable NFS cross-mount access to share is set on the share | Lets a client traverse from the export into file systems mounted beneath it. It is what makes snapshot directories reachable through a single mount. |
fsid=<uuid> |
QuantaStor, automatically | A stable file system identity for the export. Do not set it by hand. |
sec=krb5 / krb5i / krb5p |
The system Kerberos Mode, when Kerberos is enabled and the effective policy is kerberos |
The security flavour a client must match. |
| Anything else | Custom NFS Export Options on the rule | A comma-delimited list, appended verbatim. This is how you reach options QuantaStor has no control for -- all_squash, anonuid=, anongid=, no_wdelay.
|
Options QuantaStor never writes on its own, and which therefore behave as the kernel's defaults unless you add them to the custom options field, include root_squash (the default, hence the Allow Root Access toggle), wdelay, all_squash, anonuid= and anongid=.
From the CLI
qs share-client-add --share=share1 --filter=192.168.10.0/24 --rdonly=true qs share-client-add --share=share1 --filter=192.168.10.44 --options="no_root_squash,anonuid=150,anongid=100" qs share-client-list --share=share1 qs share-client-modify --share=share1 --filter=192.168.10.0/24 --async=true qs share-client-remove --share=share1 --filter=192.168.10.0/24
The commands are qs share-client-add, qs share-client-list, qs share-client-modify and qs share-client-remove. A rule is identified by its --filter, so modify and remove take the same filter string the rule was created with. --filter takes several filters in one call, comma-separated, and creates one rule per filter -- --filter="192.168.10.1,192.168.10.2" adds two rules, not one.
Three traps in the CLI surface:
--securedefaults totrueon the CLI and to off in the WUI. A rule added withqs share-client-addand no--securecomes outsecure; the same rule added in the dialog, and the[public]rule QuantaStor creates with a new share, come outinsecure. If a client works when you add its rule in the WUI and fails when you script it, this is why. Pass--secure=falseexplicitly.--optionsis not normalised on modify. Onshare-client-add, a recognised export option typed into--optionsis folded into the matching flag. Onshare-client-modifyit is kept as free text, so--options=roproduces a self-contradictory(rw,...,ro)on the export line. Use the dedicated flags.- IPv6 filters are not accepted. A client filter may contain letters, digits and
@ / * . -only, so a colon in an address or prefix is rejected outright: "Unable to update network share with invalid client access rule '2001:db8::5', valid characters include alpha-numeric and symbols '@/*.-'." Restrict NFS access by IPv4 network, host name or netgroup instead.
To copy a whole set of NFS rules and SMB settings from one share to another, use qs share-copy-settings --share=<target> --share-copy-settings-source=<source>.
A share with no NFS client rule and no SMB access is taken offline, with the state detail "No access via SMB or NFS has been configured, share is offline." and no line in the exports file. Adding at least one client rule is what puts it back. The one exception is a Kerberos system, where a share with no client rules is still exported to * with the Kerberos prefix.
Applying export changes
Export changes and service configuration changes are applied by two different mechanisms, and only one of them touches clients.
| Change | How it is applied | Client impact |
|---|---|---|
| Add, modify or remove a client access rule | The exports file is regenerated and exportfs -r is run |
None. The server swaps its export table in place. |
| Create, modify, delete, enable, disable, snapshot, clone or rename a share; cross-mount and snapshot browsing options; a share's NFS security policy | Same | None |
| Default Security Policy and NFS Server Type in the NFS Services Configuration dialog | Same | None from the reload itself. Changing the server type does swap which daemon is serving. |
| NFS Protocol Mode, Enable Kerberos Security, Kerberos Mode, Disable NFSv4 /export Browsing, Manage GIDs | Configuration files are written and nfs-server is restarted |
Momentary interruption for every NFS client on that system |
| HA VIF changes and an HA pool failover | Exports regenerated plus, on the releasing node, a service restart | See NFS over an HA storage pool |
The five settings in the fourth row are the only ones in the dialog that bounce the service, and the dialog restarts it only when one of them actually changes -- reapplying the dialog with nothing altered does not interrupt anything.
A reload really is transparent: an active NFSv3 mount and an active NFSv4.2 mount both kept serving reads across repeated export regenerations while client rules were added and removed and snapshot sub-exports appeared, with no error and no remount.
Removing a client access rule additionally unexports that one filter and path immediately, rather than waiting for the regeneration, so that client loses access at once while every other client on the share is untouched.
Restarting the NFS service

The toolbar and menu item are labelled Restart NFS/SMB Services, and the dialog that opens is titled Restart Storage Services. It restarts the NFS service, the CIFS/SMB service, or both, on the storage system chosen in the combo. Both checkboxes are ticked when the dialog opens, so restarting only NFS means clearing the CIFS/SMB one first.
The dialog carries its own warning, and it is accurate: "WARNING: This will momentarily interrupt access to the volumes/shares associated with these services and may effect workloads using them." NFS is restarted first, then SMB.
What it does not do is regenerate the exports file. It is purely a service bounce, so the exports the server comes back with are whatever the last regeneration left on disk. If a share is missing from the exports file, restarting the service will not add it -- fix the share's client rules or its pool state instead, which regenerates the file on its own.
Reach for it when:
- the NFS service is reported as not running, or has been left in a failed state;
- an NFSv4 client is wedged in a way that only clearing server-side state will fix;
- you hand-edited
/etc/nfs.confand need the daemon to re-read it.
There is no qs command for this operation. It is available from the WUI and the REST API only.
One appliance-side command covers a case the dialog does not. qs-util nfsrdma enables NFS over RDMA: it loads the rpcrdma module, sets rdma=y and rdma-port=20049 in /etc/nfs.conf after backing the file up, restarts the server and verifies the RDMA port came up. RDMA has no equivalent in the WUI, and it needs lossless or PFC configured on both the appliance and the client to be worth having.
qs-util nfsstandard and qs-util nfsganesha are legacy and should not be used. They predate NFS server mode being managed properly, and the NFS Server Type setting in the NFS Services Configuration dialog is the supported way to switch between the two servers. Use the dialog.
NFS over an HA storage pool
An HA Storage Pool moves between nodes together with one or more virtual network interfaces. Clients must mount the HA VIF, never a node's own management or data address -- that is the whole point of the VIF, and a mount to a physical address does not follow the pool. See HA Cluster Setup (JBODs) for setting the group up.
What QuantaStor does during a failover, in order:
- On the releasing node, the HA VIFs are firewalled off first, so clients stop reaching the node before anything about the exports changes.
- The pool's shares are removed from the exports file and unexported, then the pool is exported at the storage layer.
- The NFS and SMB services on that node are restarted to force session cleanup. This happens asynchronously and can land up to a few minutes after the failover otherwise looks finished, and it interrupts clients of other pools on the same node as well.
- On the acquiring node, the pool is imported, the exports file is regenerated and reloaded, and the NFS and SMB services are started if they were not already running.
- The VIF firewall block is lifted last, so a client's first packet after the move arrives at a server that is already exporting the share.
What a client sees:
- NFSv3 with a hard mount -- I/O stalls while the VIF is down and resumes when it comes back on the new node. Because NFSv3 is stateless and the export keeps the same
fsid=, the mount recovers without intervention. A soft mount returns errors to the application instead, which is usually worse. - NFSv4 -- the client's session is gone. It sees a stale client ID or a bad session, re-establishes, and reclaims what it can.
- Locks are not migrated. QuantaStor does not send
sm-notifyto NFSv3 clients and does not coordinate an NFSv4 grace period across the failover, so byte-range locks held before the move are lost. An application that depends on advisory locking for correctness has to be able to re-acquire them, and there is a window in which another client can take a lock the previous holder still believes it owns.
Two HA-specific settings affect NFS:
- Enforce NFS HA VIF Access on the HA group replaces a public (
*) client filter on that pool's shares with one entry per HA interface subnet, written as<network>/<netmask>. It is a way to keep a share that is nominally public reachable only from the networks the HA VIFs live on. - QuantaStor installs a systemd drop-in for
nfs-serverthat makes its start-timeexportfs -rfailure-tolerant. Without it, the service refuses to start on a node whose export paths are absent -- which is the normal state for a pool that has failed over away.
How UIDs and GIDs resolve
QuantaStor stores POSIX ownership on the file system, so what a client sees depends on how the two ends agree about identity.
NFSv3 sends numeric UIDs and GIDs on the wire. There is no translation: a file owned by UID 1001 shows as whatever user is 1001 on the client. Matching numeric IDs at both ends is the only thing that makes ownership meaningful.
NFSv4 sends user@domain strings, which each end maps through rpc.idmapd. The domain is configured in /etc/idmapd.conf, and QuantaStor leaves it unset, so it defaults to the appliance's DNS domain -- its fully-qualified name minus the host part. If the client's idmap domain does not match, every file shows as nobody:nogroup even though access works. This is the single most common NFSv4 surprise. Set Domain in [General] on the client to match the appliance, then restart nfs-idmapd or run nfsidmap -c to flush the cache.
Name-to-ID resolution on the appliance goes through NSS. Out of the box that is local files, then SSSD, then winbind. Joining Active Directory is what populates the last two: the domain join rewrites /etc/nsswitch.conf and configures SSSD and winbind, at which point AD users and groups resolve on the appliance and their POSIX identities can be used for NFS ownership. Whether IDs come from the directory's RFC 2307 attributes or from an algorithmic mapping is decided by the AD join, not by anything on this page -- see Network Shares for the join and Security Configuration for directory integration.
Manage GIDs
Manage GIDs is on by default. Its tooltip describes it exactly: the appliance ignores the group list a client sends and makes its own independent check of the user's group memberships, via local /etc/group or the directory service.
The reason it exists is a hard limit in AUTH_SYS: the credential a client sends carries at most 16 supplementary group IDs. A user who belongs to more than 16 groups has some of them silently dropped, and loses access to files whose group fell off the end -- non-deterministically, because which 16 survive is up to the client. With Manage GIDs on, the server discards the client's list entirely and resolves the user's full group membership itself.
Two consequences to plan for:
- The appliance must be able to resolve the user's groups. If a UID resolves on the client but not on the appliance, that user loses all supplementary groups rather than gaining the full set. On an AD-backed system that means the join has to be healthy.
- It takes effect in
rpc.mountd, so changing it restarts the NFS service and interrupts clients.
QuantaStor writes it in two places -- [mountd] manage-gids in /etc/nfs.conf and RPCMOUNTDOPTS="--manage-gids" in /etc/default/nfs-kernel-server -- and reads the setting back from those files rather than from the database, so an edit made by hand is what the WUI will report.
Snapshot access over NFS
Which snapshot browsing routes are open is a per-share decision made on the share's Advanced Settings, and the defaults are deliberately restrictive: over NFS, both routes are closed. Network Shares documents the switches. This section is what the NFS side looks like once they are open.
| Route | Export | What a client sees |
|---|---|---|
The _snaps folder |
/export/<share>_snaps, a separate export beside the share |
One directory per activated snapshot, named @GMT-2026.09.03-05.10.53. Mount it in its own right.
|
| The hidden snapshot directory | /export/<share>/.zfs, a sub-export of the share |
.zfs/snapshot/ reached from inside the share's own mount, holding one read-only directory per snapshot -- named GMT-2026.09.03-05.10.53, without the leading @. On a scale-out share the equivalent directory is .snap.
|
Reading a file out of a snapshot therefore looks like this:
sudo mount -t nfs -o vers=4,ro 192.168.10.5:/export/share1 /mnt/share1 ls /mnt/share1/.zfs/snapshot/ # GMT-2026.09.03-05.10.53 cp /mnt/share1/.zfs/snapshot/GMT-2026.09.03-05.10.53/report.xlsx ~/ sudo mount -t nfs -o vers=3,ro 192.168.10.5:/export/share1_snaps /mnt/share1_snaps ls /mnt/share1_snaps/ # @GMT-2026.09.03-05.10.53
Traversing into .zfs/snapshot/<name> from inside the share's mount depends on crossmnt, because each snapshot is a file system of its own. That is why Disable NFS cross-mount access to share and snapshot browsing interact: turning cross-mount off leaves the directory visible and its contents unreachable.
Neither export appears until the share has snapshots, and the _snaps export additionally needs at least one snapshot that is activated. A snapshot that exists but is not active is not presented to clients.
Mounting from a Linux client
Install the NFS client package first: nfs-common on Debian and Ubuntu, nfs-utils on RHEL, Rocky and SUSE.
The View Mount Command dialog -- right-click a share, described on Network Shares -- gives you the share path and a ready-made mount command for whichever network port you pick, which is the quickest way to get the right address for a share you are looking at.
A worked mount
sudo mkdir -p /mnt/share1 sudo mount -t nfs -o vers=4,hard,proto=tcp 192.168.10.5:/export/share1 /mnt/share1
That is the whole of it for a normal share. The options worth thinking about:
| Option | Notes |
|---|---|
vers=3 / vers=4 / vers=4.1 |
Pin the version rather than letting the client negotiate, so a client's behaviour does not change when the appliance's protocol mode does. vers=4 negotiates 4.2 against a QuantaStor appliance.
|
hard (default) |
Retry indefinitely. This is what you want for anything holding data: an HA failover, a service restart or a network blip becomes a stall the application survives rather than an I/O error it has to handle. Use soft only where a hung process is worse than a failed write, and pair it with timeo and retrans.
|
proto=tcp (default) |
Explicit is better than implicit, and UDP is not appropriate for NFS at any useful scale. |
rsize / wsize |
Leave them alone. A Linux client already negotiates 1 MiB (1048576) in each direction against a QuantaStor appliance, over both NFSv3 and NFSv4, so the common advice to raise them to 1 MB has nothing left to raise. Confirm what you actually got with nfsstat -m rather than setting them on faith.
|
ro |
Worth using for a snapshot mount or an audit, and it is enforced by the client as well as the export. |
noresvport |
Use a non-reserved source port. Needed only if a rule was created with secure; if the rule has Allow Full Port Range Access set -- which is the WUI default -- this is unnecessary.
|
sec=krb5i |
Required when the share's effective security policy is Kerberos, and must match the appliance's Kerberos Mode. Get a ticket first with kinit, and confirm it with klist.
|
Making it persistent
Add a line to /etc/fstab:
192.168.10.5:/export/share1 /mnt/share1 nfs vers=4,hard,proto=tcp,_netdev 0 0
_netdev is the part that matters: it tells the client not to attempt the mount until networking is up, which is what stops a boot from hanging or the mount from silently failing. Leave the dump and fsck fields at 0. On a systemd client, x-systemd.automount in place of a plain mount is worth considering for a share that is not needed at boot, since it defers the mount until something touches the directory.
An NFSv4 client can mount the top of the tree and walk down to find every share it has access to:
sudo mount -t nfs -o vers=4,ro 192.168.10.5:/ /mnt/qs ls /mnt/qs/export # share1 share2 share3
A share on a CephFS pool or a Ceph object gateway bucket is served by NFS-Ganesha, and two things differ. The path is the Ganesha pseudo path -- /<share>, or /s3/<bucket> for a bucket -- not /export/<share>. And while the storage system's NFS Server Type is Scale-up, Ganesha is on port 2249 rather than 2049, so the client has to be told:
sudo mount -t nfs -o vers=4,port=2249,mountport=2249 192.168.10.5:/share1 /mnt/share1
With the server type set to Scale-out, Ganesha owns 2049 and no port override is needed, and this is the configuration to be in if a node is serving CephFS shares over NFS -- see A node serves NFS from scale-up pools or scale-out pools, not both. NFSv3 is not an option against the alternate port.
Windows clients
Every Network Share is exported over NFS and SMB at the same time, and SMB is the right protocol for a Windows client -- it carries Windows ACLs, Active Directory identity and the Previous Versions snapshot tab, none of which an NFS mount gives you. See Network Shares for the SMB share options and the AD domain join.
Confirming what is exported and who is mounted
showmount -e 192.168.10.5 # every export the appliance is offering showmount -a 192.168.10.5 # NFSv3 mounts currently held, as <client>:<path> nfsstat -m # on the client: what each mount actually negotiated
showmount reports NFSv3 state, so an NFSv4 mount does not appear in -a. Both need rpcbind and the mount service reachable, which means they do not work against a scale-out share on port 2249.
Ports and firewall
| Service | Ports | Needed for |
|---|---|---|
| NFS | 2049 TCP and UDP, 111 TCP and UDP | NFSv4 needs 2049 only. NFSv3 also needs rpcbind on 111. |
| NFS Ganesha | 2249 TCP | Scale-out shares while the server type is Scale-up. |
| NFS over RDMA | 20049 | Only after qs-util nfsrdma.
|
Those are the definitions QuantaStor's own firewall management works from, in /opt/osnexus/quantastor/conf/qs_services_firewall.conf, and the ports it monitors for reachability.
NFSv3 needs more than that list. mountd, statd and lockd take ephemeral ports, and QuantaStor does not pin them, so NFSv3 through a stateful firewall needs those ports fixed by hand in /etc/nfs.conf and opened to match. Check what they currently are with rpcinfo -p <appliance>. NFSv4 has none of this problem, which on its own is a reason to prefer it where a firewall sits between the client and the appliance.
Troubleshooting
- Confirm the share has at least one NFS client access rule --
qs share-client-list --share=<share>. A share with none, and no SMB access, is taken offline. - List what the appliance is actually exporting:
showmount -e <appliance>. If the share is not there, the exports file has not been regenerated with it; check the share's state and its pool's state rather than restarting the service. - Confirm the pool is imported on the node you are talking to. A share on an HA pool that has failed over is exported on the other node.
Permission denied on mount
- Check that the client's address matches a rule, and that a broader rule is not being matched first. The first matching entry on the export line wins, and QuantaStor orders host rules ahead of network rules ahead of the public rule.
- Check whether the rule is a
securerule, which every rule created byqs share-client-addwithout an explicit--secure=falseis. Asecurerule requires the client to connect from a reserved source port below 1024, and a client mounting withnoresvport, or one that never uses a privileged port, is refused. The fix is to set Allow Full Port Range Access on the rule, or recreate it with--secure=false. Confirm what the rule actually is withqs share-client-list --share=<share>, or by reading the export line. - On a Kerberos system, confirm the client has a valid ticket and is using the
sec=flavour the appliance is configured for.
NFSv4 clients hang while NFSv3 clients keep working
This pattern points at the NFSv4 client tracking daemon, nfsdcld, which records client state in a small database on the appliance's root file system. A full root file system can corrupt that database, at which point the daemon fails, the kernel blocks NFS server threads waiting on it, and NFSv4 mounts stall while stateless NFSv3 traffic is unaffected.
QuantaStor detects this and repairs it automatically -- it moves the damaged database aside so the daemon rebuilds it, and restarts the NFS server -- and raises an alert saying so. Repair is rate limited and gives up after a few attempts, so if the alert persists, the thing to fix is free space on the root file system. Recovery is deliberately skipped on a system where NFS-Ganesha is serving, and on a node whose pool has failed over away, because a stale failure there is not an outage.
Files show as nobody:nogroup over NFSv4
An ID mapping domain mismatch. See How UIDs and GIDs resolve. Access still works; only the displayed ownership is wrong.
Stale NFS file handle
The export's fsid= is the share's object ID, so it changes if a share is deleted and recreated under the same name. A client that stayed mounted across that is holding handles for a file system that no longer exists. Remount:
sudo umount -l /mnt/share1 sudo mount -t nfs -o vers=4 192.168.10.5:/export/share1 /mnt/share1
NFSv3 mounts fail with an RPC port mapper error
NFSv3 needs rpcbind, on port 111, in addition to the NFS server. Check that 111 is reachable and that the appliance's protocol mode has not been set to NFS v4, which disables NFSv3 outright.
Finding out who is connected
QuantaStor tracks SMB sessions only. The SMB Sessions tab and qs share-session-list do not report NFS clients, so do not read an empty list as nobody being mounted. For NFS, use the NFS Stats tab of the Share Dashboard for throughput and operation rates, and showmount -a for NFSv3 mounts.
For NFSv4 the appliance ships a script that correlates each client's open files back to the share and dataset holding them, which is the only way to answer "who has this file open" over NFSv4. Run it as root on the appliance:
/opt/osnexus/quantastor/bin/qs_nfsv4_sessions.sh /opt/osnexus/quantastor/bin/qs_nfsv4_sessions.sh -v /opt/osnexus/quantastor/bin/qs_nfsv4_sessions.sh --path=/mnt/storage-pools/
It prints one row per open file as client IP | open file | mountpoint or dataset. -v adds debugging detail and --path= narrows it to one subtree; the default is all of /mnt/storage-pools/. It reads NFSv4 client state out of the kernel, so it needs root and reports nothing for NFSv3 mounts.
Slow NFS writes
Work through the storage before the protocol. Synchronous NFS writes land in the pool's ZFS intent log, so a pool without a write log device commits them to the data disks -- see Storage Pools for adding one. After that, confirm the client negotiated 1 MiB read and write sizes with nfsstat -m, confirm raw network throughput between the two ends independently of NFS, and only then consider Async Writes on the client rule, which trades the protocol's durability guarantee for speed.
Related pages
- Network Shares -- creating and modifying shares, the NFS client access dialog, SMB options, quotas and snapshots
- Storage Pools -- the pools shares are provisioned from, and write log devices
- Security Configuration -- directory integration and authentication
- HA Cluster Setup (JBODs) -- HA Storage Pools and the virtual interfaces NFS clients mount
- Scale-out File Setup (ceph) -- CephFS pools, which are what the scale-out NFS server exists for
- QuantaStor CLI Command Reference -- full argument lists for the
qscommands used here
Verified against QuantaStor 6.9.0.