Introduction
The VAST NFS package provides a modified version of the Linux NFS client and server kernel code stacks designed to be built for a large range of kernel versions, with support for additional stack features.
It contains backported upstream NFS stack code from Linux v6.12.x LTS kernel branch. This allows older kernels to receive the full functionality of newer NFS stack code. See kernels support. The package applies also to older kernels too but with less functionality (legacy VAST NFS).
As a source package, it can be built and used for all the modern architectures that Linux supports: Intel (x86-64), AArch64 (ARM64), RISC-V, POWER (ppc64el), s390x, and more.
Features
- NFS stack improvements and fixes
- Multipath support for NFSv3
- Multipath support for NFSv4.1 (not for legacy kernels)
- Nvidia GDS integration
License
VAST NFS is distributed under the GPLv2 license.
Document generated on 2026.09.14 19:54 for v4.5.9, branch 4.5
Package download
It is possible to download the latest version of the package with the following command:
curl -sSf https://vast-nfs.s3.amazonaws.com/download.sh | bash -s --
Or a specific version with:
curl -sSf https://vast-nfs.s3.amazonaws.com/download.sh | bash -s -- --version <version>
For building from source, see Source build.
Document generated on 2026.09.14 19:54 for v4.5.9, branch 4.5
Source build
There are various ways possible to build this package from source.
- Packaged build output (RPM or Deb package)
- Build without packaging, for the purpose loading directly from a development tree
This section provides information about how to accomplish it.
Document generated on 2026.09.14 19:54 for v4.5.9, branch 4.5
Supported kernel versions
This package is supported on the following Linux distribution kernels:
- Red Hat Enterprise Linux 9.3 to 9.8 and derivatives (CentOS, Rocky, Alma)
- Red Hat Enterprise Linux 10.0 to 10.2 and derivatives (CentOS, Rocky, Alma)
- SUSE Enterprise Linux 15 SP7 and above
- Ubuntu 24 LTS with 6.8 HWE kernel to 6.17 HWE kernel (including)
- Ubuntu 22 LTS with 6.8 HWE kernel to 6.17 HWE kernel (including)
- Ubuntu 20 LTS with 6.8 HWE kernel to 6.17 HWE kernel (including)
Generic upstream kernel support ranges are the following:
- Linux v6.5 to v7.1 (including)
NOTE: For older kernels and distributions, see legacy support in this page below.
When building under a NVIDIA/Mellanox OFED environment, the IB layer of OFED is targeted for NFS RDMA support.
Legacy VAST NFS version 4.0.x fallback
The source package for VAST NFS 4.5.x includes the older VAST NFS 4.0.x branch code targeting older kernels that belong to:
- Red Hat Enterprise Linux 8.1 to 8.9, 9.3 and derivatives (CentOS, Rocky, Alma)
- SUSE Enterprise Linux 15
- Ubuntu 22 LTS
- Ubuntu 20 LTS
- Ubuntu 18 LTS
Generic upstream kernel support ranges are the following:
- Linux v4.15 to v6.6.
NOTE: Some older distribution kernels (such as RH 8.1) may require a recent Mellanox OFED being installed, as it provides a more recent IB layer along with newer kernel APIs.
Legacy VAST NFS 3.x fallback
The source package for VAST NFS 4.5.x includes the older VAST NFS 3.x branch code targeting older kernels that belong to:
- Red Hat Enterprise Linux 7.x and derivatives (CentOS 7.x)
- SUSE Enterprise Linux 12
Building the 4.x source package will result in a package marked as 3.x due to
the less supported functionality. It currently has less functionality than 4.x
(e.g. for NFSv4.1 mounts, no remoteports-based multipath).
Document generated on 2026.09.14 19:54 for v4.5.9, branch 4.5
Mellanox OFED support
All versions of Mellanox OFED that successfully install on a Linux system should be supported by this package. Newer OFED versions are preferred.
If the Mellanox OFED is installed on a system, this package can also be built in such a way that NFS RDMA is functional and working using the Mellanox RDMA stack instead of the inbox kernel RDMA stack, which the installation of the Mellanox OFED supersedes.
The state where the Mellanox OFED is installed is detected automatically by the build scripts, and the resultant package will only work with that particular Mellanox OFED version.
Document generated on 2026.09.14 19:54 for v4.5.9, branch 4.5
Building an installable package
The following command will build the source package. It detects the currently running kernel, distribution, and optional Mellanox OFED installation.
./build.sh bin
Following a successful build, the resultant package should reside in a dist/
sub-directory, for example:
$ ls -1 dist/vastnfs* | grep -v debug
vastnfs-4.5.1-kernel_6.12.0_55.37.1.el10_0.x86_64.rpm
For older kernel, the build relies on the legacy VAST NFS 3.x sources that are included in the source package.
See Installation for installation instructions.
Arguments
The build.sh bin command can receive the following optional arguments:
--without-rpcrdma: Don't build RDMA support--dkms: Generate a DKMS-based package even if no DKMS-based Mellanox OFED is installed.--no-ofed: Don't detect Mellanox OFED installation, and instead build a driver targeting the inbox kernel instead.--with-exporter: Include the optionalvastnfs-exporter(Prometheus HTTP server). Requirespython3andpython3-prometheus-client(>= 0.16) on the build host. Adds both as package runtime dependencies.
Regarding DKMS
DKMS is a source-based package for which the binary driver is built on-demand. This is useful for minor kernel updates.
If Mellanox OFED installation is detected, and if that installation is DKMS-based, then the resultant package will also be DKMS-based by default. This is currently supported only on Debian-based system. Otherwise, the built package will install binaries that depend on the current kernel version.
Document generated on 2026.09.14 19:54 for v4.5.9, branch 4.5
Development build
The following command should build the driver for the current kernel, assuming that a compiler and the kernel headers are installed for the local machine. Further development package of the relevant Linux distro may be needed.
make
When this command is issued, no package is being generated and instead the kernel modules reside within the built source tree.
To load the newly built development version, the following command can be
issued (sudo is being used by the script):
./scripts/control.sh dev-reload
Document generated on 2026.09.14 19:54 for v4.5.9, branch 4.5
Signing kernel modules for secure boot
Some systems have Secure Boot enabled, meaning that unauthorized kernel code cannot be loaded.
$ dmesg | grep secure
[ 0.000000] secureboot: Secure boot enabled
Only trusted private keys can sign kernel modules that can be loaded.
At package build time
If you are building the package yourself, likely that you already have a key that that is used to sign its kernel modules.
For building a binary package where the module are signed, provide two
environment variables, MODULE_SIGN_PRIV_KEY and MODULE_SIGN_PUB_KEY
pointing to the key pair:
export MODULE_SIGN_PRIV_KEY=<path to private key>
export MODULE_SIGN_PUB_KEY=<path to public key>
./build.sh bin
The produced package will contain signed kernel modules.
Expect to see "Found Sign tool at" in the output to confirm that signing took place.
If you don't have a key
If you are new to secure boot, it is possible to create your own key, and enroll it in the BIOS. This is a general procedure is not specific to the VAST NFS driver.
- Create a key
openssl req -new -x509 -newkey rsa:2048 -keyout MOK.priv -outform DER -out MOK.der -nodes -days 3650 -subj "/CN=My Custom Key/"
- Enroll the key
sudo mokutil --import MOK.der
You will be prompted to set a password. Make sure to remember this password, as you'll need it during the next boot.
- Reboot your system
After enrolling the key, reboot your system. During the boot process, you'll see a blue screen with the title "MOK management." This is where you'll use the password you set earlier.
- Enroll the key in MOK
Follow these steps in the MOK management screen:
- Choose "Enroll MOK."
- Select "Continue."
- Choose "Yes" to confirm that you want to enroll the key.
- Enter the password you set earlier.
- Select "OK" to complete the enrollment process.
- Your system should now boot normally, and your custom key is enrolled in MOK.
Document generated on 2026.09.14 19:54 for v4.5.9, branch 4.5
Installation
This section deals with installation of the binary package. The goal is for the installed NFS stack to supersede the inbox kernel NFS stack.
Document generated on 2026.09.14 19:54 for v4.5.9, branch 4.5
RHEL 9.x/10.x
(see supported versions here)
Install for binary packages:
sudo yum install ./dist/vastnfs-[1-9]*.x86_64.rpm
sudo dracut -f
Alternatively,
- For DKMS packages:
sudo yum install ./dist/vastnfs-dkms-*.noarch.rpm
This should result in the generation of kernel module binaries by the DKMS subsystem.
Following install, rebooting is required for the newly installed drivers to load.
Verify that the package is indeed installed (versions should match):
rpm -qa | grep vastnfs
To further validate installation, verify that rpcrdma in the right path
exists and get loaded from it. All the added kernel modules go under
updates/bundle:
rpm -qif /lib/modules/`uname -r`/extra/vastnfs/bundle/net/sunrpc/xprtrdma/rpcrdma.ko
$ modinfo rpcrdma | grep filename:
filename: /lib/modules/..../extra/vastnfs/bundle/net/sunrpc/xprtrdma/rpcrdma.ko
Document generated on 2026.09.14 19:54 for v4.5.9, branch 4.5
Installing under Ubuntu/Debian
(see supported versions here)
For Ubuntu/Debian, either a DKMS-based package or kernel module binary package was generated by the build command (see build section)
- For binary packages:
sudo dpkg -i ./dist/vastnfs-modules_*-generic_amd64.deb
sudo update-initramfs -u -k `uname -r`
Alternatively,
- For DKMS packages:
sudo dpkg -i ./dist/vastnfs-dkms_*.deb
This should result in the generation of kernel module binaries by the DKMS subsystem.
Verify that the package is indeed installed (versions should match):
dpkg -l | grep vastnfs-modules
To further validate installation, verify that rpcrdma in the right path
exists and get loaded from it. All the added kernel modules go under
updates/bundle:
dpkg -S /lib/modules/`uname -r`/updates/bundle/net/sunrpc/xprtrdma/rpcrdma.ko
Verification
Reboot, to ensure that this version is loaded correctly.
Once rebooted, and to verify fully once it is loaded, for each kernel module, loaded version should match installed version. For example:
$ cat /sys/module/sunrpc/srcversion
4CC8389C7889F82F5A59269
$ modinfo sunrpc | grep srcversion
srcversion: 4CC8389C7889F82F5A59269
(This is only an example - srcversion is different for each build and kernel module).
Document generated on 2026.09.14 19:54 for v4.5.9, branch 4.5
Configuration
This section deals with configurations for the provided NFS stack in this package.
Document generated on 2026.09.14 19:54 for v4.5.9, branch 4.5
Multipath
To make an efficient load balanced used of single NFS mount, multipath should be enabled.
Under the multipath scheme used in this package, all participating local and remote ports have distinct network IP addresses. This section deals with the configuration that enable this mode.
Document generated on 2026.09.14 19:54 for v4.5.9, branch 4.5
RHEL 9.x/8.x
This package is supported on RHEL, and the RHEL-based distributions such as CentOS Linux, Rocky Linux, and Alma Linux.
NOTE: On RHEL 7.x-based kernels the package installs in backward-compatibility mode: it only provides multipath on NFSv3 mounts.
Here we demonstrate multipath with two local interfaces on the same subnet.
First we need to install NetworkManager-config-routing-rules.
yum install NetworkManager-config-routing-rules
Configuring for multipath with nmcli
Suppose we have a host with two network cards, ib0 and ib1. The network cards are directly connected to the server's switch and belong to the same IP subnet. We need to define source-based routing to the server (with IP 192.168.40.11) to take advantage of multipath mode.
$ nmcli -f 'GENERAL.DEVICE,IP4.ADDRESS' device show
GENERAL.DEVICE: enp1s0
IP4.ADDRESS[1]: 192.168.122.235/24
GENERAL.DEVICE: ib0
IP4.ADDRESS[1]: 192.168.40.1/24
GENERAL.DEVICE: ib1
IP4.ADDRESS[1]: 192.168.40.2/24
GENERAL.DEVICE: lo
IP4.ADDRESS[1]: 127.0.0.1/8
- Verify that routing tables 101 and 102 are empty:
ip route show table 101
ip route show table 102
- Add symbolic names for custom routing tables:
echo '101 101' >> /etc/iproute2/rt_tables
echo '102 102' >> /etc/iproute2/rt_tables
- Add custom routing tables for ib0 and ib1:
nmcli device modify ib0 ipv4.routes "192.168.40.0/24 src=192.168.40.1 table=101"
nmcli device modify ib1 ipv4.routes "192.168.40.0/24 src=192.168.40.2 table=102"
- Add custom routing rules with priority 100:
nmcli device modify ib0 +ipv4.routing-rules "priority 100 from 192.168.40.1 table 101"
nmcli device modify ib1 +ipv4.routing-rules "priority 100 from 192.168.40.2 table 102"
- Reload configuration and verify it:
$ nmcli connection reload
$ ip route get 192.168.40.11 from 192.168.40.1
192.168.40.11 from 192.168.40.1 dev ib0 table 101
cache
$ ip route get 192.168.40.11 from 192.168.40.2
192.168.40.11 from 192.168.40.2 dev ib1 table 102
cache
- If needed, troubleshoot with commands:
ip route show table 101
ip route show table 102
ip rule show
Configuring for multipath using old style network-scripts interface
We configure new source routing tables:
echo '101 101' >> /etc/iproute2/rt_tables
echo '102 102' >> /etc/iproute2/rt_tables
For this example we assume two interfaces are configured via ifcfg- scripts:
$ grep IPADDR /etc/sysconfig/network-scripts/ifcfg-ib0
IPADDR=192.168.40.1
$ grep IPADDR /etc/sysconfig/network-scripts/ifcfg-ib1
IPADDR=192.168.40.2
For each interface we need to add a route- and rule- files:
$ cat /etc/sysconfig/network-scripts/route-ib0
192.168.40.0/24 via 192.168.40.1 table 101
$ cat /etc/sysconfig/network-scripts/rule-ib0
from 192.168.40.1/32 table 101
NOTE: This is only an example. The IP addresses you pick depend on your network configuration.
After reloading with nmcli connection reload, the ip command with regard to routing
should look like this (notice the two added lookup lines):
$ ip rule
0: from all lookup local
32764: from 192.168.40.1 lookup 101
32765: from 192.168.40.2 lookup 102
32766: from all lookup main
32767: from all lookup default
$ ip route show table 101
192.168.40.0/24 via 192.168.40.1 dev ib0
$ ip route show table 102
192.168.40.0/24 via 192.168.40.2 dev ib1
Verify that the IPs and routing tables appear correctly. Below are examples which will vary based on environment:
IP addresses:
$ ip a s | grep 192.168.40
inet 192.168.40.1/24 brd 192.168.40.255 scope global ib0
inet 192.168.40.2/24 brd 192.168.40.255 scope global ib1
Document generated on 2026.09.14 19:54 for v4.5.9, branch 4.5
Ubuntu
Ubuntu installations can use netplan to specify the network configuration.
For each port, we need to have one IP address in the subnet. For each IP
address, source routing needs to be enabled.
For example, in the updated 01-netcfg.yml for local port configuration (ib0,
ib1, ib2, ib3), append routes and routing-policy rules:
ib0:
dhcp4: no
addresses: [172.25.1.101/24]
routes:
- to: 172.25.1.0/24
via: 172.25.1.101
table: 101
routing-policy:
- from: 172.25.1.101
table: 101
ib1:
dhcp4: no
addresses: [172.25.1.102/24]
routes:
- to: 172.25.1.0/24
via: 172.25.1.102
table: 102
routing-policy:
- from: 172.25.1.102
table: 102
ib2:
dhcp4: no
addresses: [172.25.1.103/24]
routes:
- to: 172.25.1.0/24
via: 172.25.1.103
table: 103
routing-policy:
- from: 172.25.1.103
table: 103
ib3:
dhcp4: no
addresses: [172.25.1.104/24]
routes:
- to: 172.25.1.0/24
via: 172.25.1.104
table: 104
routing-policy:
- from: 172.25.1.104
table: 104
NOTE: This is only an example. The IP addresses you pick depend on your network configuration.
The apply the new configuration, run:
sudo netplan apply
Verify that the IPs and routing tables appear correctly. Below are examples which will vary based on environment:
IP addresses:
$ ip a s | grep 172.25.1
inet 172.25.1.101/20 brd 172.25.1.255 scope global ib0
inet 172.25.1.102/20 brd 172.25.1.255 scope global ib1
inet 172.25.1.103/20 brd 172.25.1.255 scope global ib2
inet 172.25.1.104/20 brd 172.25.1.255 scope global ib3
Routing tables:
$ for i in 101 103 102 104; do ip route show table $i; done;
172.25.1.0/20 via 172.25.1.101 dev ib0 proto static
172.25.1.0/20 via 172.25.1.102 dev ib1 proto static
172.25.1.0/20 via 172.25.1.103 dev ib2 proto static
172.25.1.0/20 via 172.25.1.104 dev ib3 proto static
Document generated on 2026.09.14 19:54 for v4.5.9, branch 4.5
ARP configuration
For usage of localports= multipath (see mount
parameters, there are several sysctl configuration
that need to apply to make sure traffic goes in an out of the correct
interface.
rp_filter
When using localports=, make sure that the rp_filter sysctl option is
disabled on the corresponding network interfaces, for each interface:
echo 'net.ipv4.conf.<iface>.rp_filter = 0' >> /etc/sysctl.d/nfs-multipath.conf
It may be easier to disable for all of them depending of circumstances:
echo 'net.ipv4.conf.all.rp_filter = 0' >> /etc/sysctl.d/nfs-multipath.conf
To load the new configuration, run /usr/bin/sysctl --system.
arp_announce and arp_ignore
Similar to the above, set, for each interface set:
echo 'net.ipv4.conf.<iface>.arp_announce = 1' >> /etc/sysctl.d/nfs-multipath.conf
echo 'net.ipv4.conf.<iface>.arp_ignore = 2' >> /etc/sysctl.d/nfs-multipath.conf
To load the new configuration, run /usr/bin/sysctl --system.
Persisting sysctl changes with NetworkManager
For setups with NetworkManager, create a script to automatically apply sysctl when interfaces are up:
echo -e '#!/bin/bash\n\n/usr/bin/sysctl --system\n' > /etc/NetworkManager/dispatcher.d/00-sysctl
chmod +x /etc/NetworkManager/dispatcher.d/00-sysctl
Document generated on 2026.09.14 19:54 for v4.5.9, branch 4.5
Uninstalling the package
This section deals with removal of the driver package.
Document generated on 2026.09.14 19:54 for v4.5.9, branch 4.5
RHEL 8.x/9.0
Uninstalling the driver involves removal of RPM package and making sure the boot image is regenerated:
sudo yum remove -y vastnfs
sudo dracut -f
To unload the driver, a reboot is recommended.
Document generated on 2026.09.14 19:54 for v4.5.9, branch 4.5
Ubuntu
Uninstalling the driver involves removal of the Deb package and making sure the boot image is regenerated:
sudo apt remove -y vastnfs-modules
sudo update-initramfs -u -k `uname -r`
To unload the driver, a reboot is recommended.
Document generated on 2026.09.14 19:54 for v4.5.9, branch 4.5
Usage
There are extra features that this stack enables and these are described in this section.
If no extra features are used, the usage and behavior of the provided NFS stack matches the upstream or distribution NFS stack versions.
Document generated on 2026.09.14 19:54 for v4.5.9, branch 4.5
Mount parameters
This package adds to the standard mount parameters that the original Linux NFS stack originally supports.
VAST NFS parameters
The VAST NFS client supports the following additional mount parameters that can be used individually or together.
-
remoteports=<IP-SPEC | dns>enables multipath allowing a single client to spread traffic across multiple endpoint IPs. The parameter takes a list of addresses.The IP specification allows addresses to be specified using an inclusive range operator with
-:<FIRST-IP>-<LAST-IP>.Multiple ranges and individual IPs can be combined using the
~operator:<FIRST-IP>-<LAST-IP>~<IP>.Example usage:
mount -o vers=3,remoteports=172.25.1.1-172.25.1.32 172.25.1.1:/With a special mode
remoteports=dns, the client will issue one or more DNS queries with the mount target DNS name and will get back an array of addresses and use those as the list of remote addresses as if it was passed explicitly. Example:mount -t nfs -o vers=3,nconnect=16,remoteports=dns vippool3.company.lab:/ /mntNotes:
- Do not use this option in driver versions prior to 4.0.29.
- This feature expects that no DNS caching done on the DNS server or locally.
If caching exist on the DNS server, and the number of DNS addresses returned
in the DNS response is lower than the value of nconnect, it may result in
unintended reduction of the remoteports array due to repeating (cached) DNS
responses. In order to test if DNS caching is enabled in your environment
run:
If the responses contain the same ip addresess, then caching is enabled.$ for i in $(seq 3); do dig <dns-name>.example.com +short; done 10.10.12.7 10.10.12.6 10.10.12.2 - If DNS caching is enabled, It is required to increase the number of addresses
in the DNS server response in order for the client to correctly distribute
connections across different remote ports.
See example (4 addresses in the DNS response):
$ dig <dns-name>.example.com +short 10.10.12.1 10.10.12.14 10.10.12.9 10.10.12.3
-
localports=<INT-SPEC>controls which client interfaces are used to send traffic. By default the vastnfs driver will send traffic over one network interface. If the client has multiple network interfaces you can add additional interfaces with this parameter.The interface specification uses the same form as
remoteportsabove with the-and~operators and the IPs assigned to the client interfaces.Interface names can be used instead of the IP. The driver will resolve the IP currently on the interface and use that IP as described above. Specifying interface names that have no IP or are not enabled is not supported and will fail the mount operation.
Example usage:
mount -o vers=3,localports=172.25.1.1-172.25.1.2 172.25.1.1:/ mount -o vers=3,localports=eth0~eth1 172.25.1.1:/The
localportsparameter is not necessary for multipath to work. However if the local machine has more than one IP address configured for the local subnet, it may be useful to prevent a single local port from trying to surpass its maximum line rate while the other local ports are underused.When
localportsoption is used with TCP, the host should guarantee proper binding of connections to their network interfaces via policy-based routing (a.k.a source-based routing).Also, for GDS-based setups, it is necessary for making the transport layer to perform GPU-based routing for GPU overload to be utilized.
NOTE: Usage of
localportsneeds to include ARP configuration of interfaces. -
nconnect=<NUM>enables multiple connections for a single mount. This parameter is available on recent Linux kernels and the vastnfs client allows it to be used on Linux kernels for which it was not backported.The recommended values for this parameter depend on both the protocol in use and the line rate of the physical transport:
Line rate /
Protocol40Gbps 100Gbps 200Gbps TCP 4 8 16 RDMA 4 8 Example usage:
mount -o vers=3,nconnect=8 172.25.1.1:/ -
pconnect=<NUM>. Under NFSv4.1 with client-based multipath (remoteports=), multiple NFS client contexts are used, each one to a single IP address fromremoteports=, withnconnectas a limiting factor.This mount option
pconnet, however, controls the amount of connections made by each client. Thenconnectparameter still controls the total amount of connections. For example, passingnconnect=12andpconnect=3will create 4 clients with 3 connections each, all to the same destination address, and regardless of how big isremoteports.Under NFSv3, this mount option can be passed as well, to achieve the same distribution to target IP addresses.
Example usage:
mount -o vers=4.1,nconnect=8,pconnect=2,remoteports=172.25.1.1-172.25.1.8 172.25.1.1:/Note that
pconnecthigher than1reduces the amount of target IP addresses, so when scaling depends on a large amount of target IP addresses, we should also increasenconnectby thepconnectfactor when supplying this parameter.
Multipath mount examples
Often the above parameters are combined and used together.
Consider this multipath mount:
mount -o vers=3,nconnect=8,remoteports=172.25.1.1-172.25.1.32 172.25.1.1:/
This mount command will result in 8 TCP connections, going to a psuedo-random sub-range of 8 addresses under the provided 32 address range.
While multipath can be used with TCP (proto=tcp), using it with RDMA (proto=rdma)
will have less CPU utilization.
Here is a more advanced example of an RDMA mount with 4 connections, 8 remote ports and 4 local ports:
mount -o proto=rdma,port=20049,vers=3,nconnect=4,localports=172.25.1.101-172.25.1.104,remoteports=172.25.1.1-172.25.1.8 172.25.1.1:/
Advanced parameters
NFS optimizations
-
forcerdirplus- Instructs the NFS client to always send an NFSv3READDIRPLUSrequests for servers that support it. On some remote systems this can improve directory listing performance significantly. -
relmtime- Don't block stat() calls while there are pending writes. This improves the scenario in which 'ls -l' blocks while the same client is writing to a file under the listed directory. -
optlockflush- This is an optimization for applications that use a lock to protect a read-mostly file. The assumption that GETATTR costs less than zapping the read-cache, and that we can use GETATTR to detect whether the file was modified at the server.
NFS operational parameters
noextend- Turns off the default extend-to-page optimization in writes, useful for some specific applications having multiple clients on NFSv3.
Additional transport parameters
These parameters can be used for experimentation and fine-tuning.
-
noidlexprt- Do not disconnect idle connections. -
remoteports_offset=<NUM>- Controls the offset into picking out ofremoteportsfor transports if the number of actual transports vianconnectis smaller than the amount of IPs given here. If not given a pseudo-random number is picked based on source IP address. -
localports_failover- Special mode for multipath where failing transports can temporarily move from local addresses that cannot serve connections, for example on a local cable disconnect. For this option to work,noidlexprtneeds to be passed too, along with annconnectvalue that is at least a multiple of the port count inremoteportsoverlocalports. This option is supported for RDMA only and is on by default.Example:
mount -o rdma,vers=3,noidlexprt,localports_failover,localports=172.25.1.101-172.25.1.104,remoteports=172.25.1.1-172.25.1.8 172.25.1.1:/This is only supported for NFSv3.
-
spread_readsorspread_writes- Whether a single file's IO should use a single connection or multiple connections. Single connection enjoys a few optimizations on the server side for latency but multiple increases the potential bandwidth.These are only supported for NFSv3.
-
mdconnect- Specifies the number of additional transport connections dedicated exclusively to metadata operations. Limited at 8. When enabled, the transports defined bynconnecthandle only READ/WRITE requests, while the extra connections defined bymdconnectserve metadata requests exclusively. This option is particularly useful in scenarios where heavy data I/O causes metadata operations to be queued and starved on shared transport channels.This is only supported for NFSv3.
-
nosharetransport- This option causes the client to establish its own isolated transport connections. The client will not share the transport connections with any other mount done before or after.This is only supported for NFSv3.
-
sharetransport=N- N is positive number that identifies mounts sharing the same transport connections. If two or more mounts to a particular NFS server have a different value of sharetransport, these mounts will use different connections. If you don't specify the option value for mounts to a particular NFS server, all the mounts will shate one transport connections.This is only supported for NFSv4.x
Document generated on 2026.09.14 19:54 for v4.5.9, branch 4.5
Module parameters
The VAST NFS client also supports module parameters that can be configured at module load time to control global behavior:
-
expanding_readahead_enable=<BOOL>- Enable expanding readahead triggered byfadvise(POSIX_FADV_SEQUENTIAL)system calls. When enabled, applications that signal sequential access patterns will benefit from adaptive readahead that starts atexpanding_readahead_initialsize and doubles on each sequential access up to the maximum readahead limit. For random access patterns, the readahead size is reduced by half to minimize unnecessary prefetching. Default:true -
expanding_readahead_mmap_enable=<BOOL>- Enable expanding readahead triggered by memory-mapped file access. When enabled, files accessed viammap()will use adaptive readahead similar to thefadvisemode above. This is useful for applications that memory-map large files and access them sequentially. Default:true -
expanding_readahead_initial=<SIZE>- Set the initial expanding readahead size in bytes. This is the starting size for adaptive readahead and also the minimum size when readahead is reduced due to random access patterns. Default:131072(128 KiB)
These parameters can be set when after loading the module:
sudo modprobe nfs # ensure kernel module load
echo yes | sudo tee /sys/module/nfs/parameters/expanding_readahead_enable
echo yes | sudo tee /sys/module/nfs/parameters/expanding_readahead_mmap_enable
Or configured persistently in /etc/modprobe.d/, e.g:
options nfs expanding_readahead_enable=1 expanding_readahead_mmap_enable=1
Document generated on 2026.09.14 19:54 for v4.5.9, branch 4.5
vastnfs-ctl
This helper script is installed with the package, and can assist in various situations.
The usage of this script is optional in most cases.
Status
Observe the status of the loaded NFS services and kernel modules
vastnfs-ctl status
Example output:
version: v4.0-pre4-11-ge520dd8eb9cb
kernel modules: sunrpc rpcrdma compat_nfs_ssc lockd nfs_acl auth_rpcgss nfsd rpcsec_gss_krb5 nfs nfsv3 nfsv4
services: rpcbind.socket rpcbind
rpc_pipefs: /var/lib/nfs/rpc_pipefs
Reload
The following command will try to reload the NFS stack. It will first try to unmount all NFS file systems, and then reload all the necessary kernel modules.
vastnfs-ctl reload
Example output:
vastnfs-ctl: stopping service rpcbind.socket
vastnfs-ctl: umounting fs /var/lib/nfs/rpc_pipefs
vastnfs-ctl: unloading kmod nfsv4
vastnfs-ctl: unloading kmod nfsv3
vastnfs-ctl: unloading kmod nfs
vastnfs-ctl: unloading kmod rpcsec_gss_krb5
vastnfs-ctl: unloading kmod nfsd
vastnfs-ctl: unloading kmod auth_rpcgss
vastnfs-ctl: unloading kmod nfs_acl
vastnfs-ctl: unloading kmod lockd
vastnfs-ctl: unloading kmod compat_nfs_ssc
vastnfs-ctl: unloading kmod rpcrdma
vastnfs-ctl: unloading kmod sunrpc
vastnfs-ctl: loading kmod sunrpc
vastnfs-ctl: loading kmod rpcsec_gss_krb5
vastnfs-ctl: loading kmod rpcrdma
vastnfs-ctl: loading kmod nfsv4
vastnfs-ctl: loading kmod nfsv3
vastnfs-ctl: loading kmod nfsd
vastnfs-ctl: loading kmod nfs_acl
vastnfs-ctl: loading kmod nfs
vastnfs-ctl: loading kmod lockd
vastnfs-ctl: loading kmod compat_nfs_ssc
vastnfs-ctl: loading kmod auth_rpcgss
vastnfs-ctl: mounting fs /var/lib/nfs/rpc_pipefs
vastnfs-ctl: starting service rpcbind.socket
Tracing
The vastnfs-ctl utility comes with a helper command for tracing the NFS
stack. Please see a short tutorial on using vastnfs-ctl trace.
Show NFS Clients
Use vastnfs-ctl nfs-clients path to show the status of NFS client used by specific path.
Use vastnfs-ctl nfs-clients to show status of all active NFS clients.
Example output:
NFS client 3000
state: 0
hostname: server.nfs-testing.com
rpc_clnt: 3
hostname: The used NFS server
rpc_clnt: The RPC client's ID used by the NFS client
Show RPC Clients Used by the NFS Protocol
Use vastnfs-ctl rpc-clients <path> to display the status of RPC clients for a specific path.
Use vastnfs-ctl rpc-clients to display the status of all active RPC clients.
Note: This command shows RPC clients used by the NFS protocol only. Clients used by other protocols aren't included.
Example output:
rpc_client: 3 switch-2002
sunrpc-id: 3
RPC iostats version: 1.1 p/v: 100003/3 (nfs)
xprt: tcp 1012 1 2 0 0 6474 6473 0 77192 3579 128 26235 66718
192.168.23.11, state: CONNECTED BOUND
remote_port_idx: 0
role: REG
pci device:
hardware gpus:
remoteports_offset: 0 0
spread reads: 0 writes: 0
mdconnect: 0
per-op statistics
NULL: 1 1 0 44 24 0 0 0 0
GETATTR: 0 0 0 0 0 0 0 0 0
SETATTR: 0 0 0 0 0 0 0 0 0
LOOKUP: 0 0 0 0 0 0 0 0 0
ACCESS: 0 0 0 0 0 0 0 0 0
READLINK: 0 0 0 0 0 0 0 0 0
READ: 0 0 0 0 0 0 0 0 0
WRITE: 0 0 0 0 0 0 0 0 0
CREATE: 0 0 0 0 0 0 0 0 0
MKDIR: 0 0 0 0 0 0 0 0 0
SYMLINK: 0 0 0 0 0 0 0 0 0
MKNOD: 0 0 0 0 0 0 0 0 0
REMOVE: 0 0 0 0 0 0 0 0 0
RMDIR: 0 0 0 0 0 0 0 0 0
RENAME: 0 0 0 0 0 0 0 0 0
LINK: 0 0 0 0 0 0 0 0 0
READDIR: 0 0 0 0 0 0 0 0 0
READDIRPLUS: 0 0 0 0 0 0 0 0 0
FSSTAT: 0 0 0 0 0 0 0 0 0
FSINFO: 0 0 0 0 0 0 0 0 0
PATHCONF: 0 0 0 0 0 0 0 0 0
COMMIT: 0 0 0 0 0 0 0 0 0
rpc_client: The unique ID of the RPC client and the associated transport switch.
xprt: The brief status of transport/transports.
Show RPC Transport Switches
Use vastnfs-ctl rpc-switches <path> to show the status of RPC transport switches for a specific path.
Use vastnfs-ctl rpc-switches to show the status of all active RPC transport switches.
Example output:
RPC switch-2002
num_xprts=1
num_active=1
num_unique_destaddr=1
queue_len=0
xprt-2-tcp: CONNECTED BOUND
queue_len: The number of currently allocated RPC tasks for this transport switch.
xprt-2-tcp: The transport (or list of transports) in use, along with their current status (e.g., CONNECTED, BOUND).
Show RPC Transports
Use vastnfs-ctl rpc-transports <path> to show RPC transports associated with a specific path.
Use vastnfs-ctl rpc-transports to show all active RPC transports used by the NFS protocol.
This command reads sysfs /sys/kernel/sunrpc/xprt-switches/*/xprt*/xprt_info and
related fields for transports belonging to VastNFS mounts.
Example output:
xprt-2-tcp CONNECTED BOUND
dstaddr=192.168.23.11
binding_q_len=0
sending_q_len=0
pending_q_len=0
backlog_q_len=0
tasks_queuelen=0
remote_port_idx=0
reconnection_attempts=0
transport=tcp
The first line shows the transport name (xprt-2-tcp) and current state flags
(CONNECTED, BOUND, etc.). Queue depth lines come from sysfs xprt_info:
| Field | Meaning |
|---|---|
binding_q_len | Tasks waiting for bind/rpcbind |
sending_q_len | Tasks waiting to send |
pending_q_len | Tasks in flight (awaiting reply) |
backlog_q_len | Tasks waiting for a free request slot |
tasks_queuelen | Total tasks associated with this transport |
When a transport is disconnected, xprt_info may report <closed> and queue
fields are not shown.
For continuous monitoring, the Prometheus exporter
exposes these queue depths as
queue length gauges
with xprt_id, netid, and addr labels. Switch-level queue_len from
rpc-switches is not exported by the exporter.
Show RPC Transport Statistics
Use vastnfs-ctl rpc-transports-stats <path> to show per-operation RPC
statistics for transports associated with a specific mount path.
Use vastnfs-ctl rpc-transports-stats to show statistics for all active RPC
transports used by VastNFS mounts.
This command reads the per-op stats section from debugfs
/sys/kernel/debug/sunrpc/rpc_xprt/*/extra for transports belonging to VastNFS
mounts. Rows where all counters are zero are omitted.
Example output:
xprt-2-tcp addr=192.168.23.11:2049 CONNECTED BOUND
per-op stats
op ops trans t/o sent recv q_ms rtt_ms exe_ms errs
NULL 1 1 0 44 24 0 0 0 0
GETATTR 12 12 0 1234 5678 1 2 1 0
READ 100 100 0 1048576 2097152 10 50 40 0
The header line shows the transport name, remote addr, and current state flags.
The table columns map directly to the Prometheus exporter RPC
counters.
The q_ms column is cumulative queue time (milliseconds), not an
instantaneous queue depth — see
queue length gauges
for live depths from rpc-transports.
For continuous monitoring, use the Prometheus exporter.
It exposes these per-op counters with xprt_id, netid, addr, and op
labels, plus per-transport queue depths and state flags from the same sysfs and
debugfs sources as rpc-transports and rpc-transports-stats.
Show Cached NFS Inode State
Use vastnfs-ctl dump-meta-data <path> to show the inode state using the file's absolute path.
Use vastnfs-ctl dump-meta-data :inode@mount_point to show the inode state by inode number and mount point.
Use vastnfs-ctl dump-meta-data :inode@fsid to show the inode state by inode number and fsid, where fsid is the value from the third column of /proc/self/mountinfo.
Example output:
junk.fsxlog fh 0x010001010100000066f43ebcefa3000000000000
idx 0 mode 0100644 owner 0:0 flags 0x82:0xc nlink 1
size 285 state 0x100 version 1879990373217750775 count 0
atime 1750877260079976788ns mtime 1750877474684478199ns ctime 1750877474684478199ns
nfsi flags 0x4 cache validity 0x0 gencount 4942822 attrtimeo 12000
timestamp 4297125548 unlock_mtime 0ns jiffies 217558
access_cache 1 entryes, cached 0 pages flags 0x0
First line displays the file name and its NFS file handle.
Document generated on 2026.09.14 19:54 for v4.5.9, branch 4.5
Using NFS over TLS
This procedure shows how to mount an NFS share over a Transport Layer Security (TLS) channel on systems that run either RHEL 9 / Rocky Linux 9 or Ubuntu 24.04 LTS.
1. Prerequisites
- A server that exports an NFS share and supports RFC 9289 - Towards Remote Procedure Call Encryption by Default.
- The kernel needs to be new enough to have been built with
CONFIG_NET_HANDSHAKE=y. Examples: RHEL 9.x or upstream kernel 6.7 and above. - Access to certificates that the client will trust (either a private CA certificate or the server certificate itself)
2. Install the required packages
RHEL 9 / Rocky Linux 9
sudo dnf install nfs-utils ktls-utils
The ktls-utils package delivers tlshd, the user‑space handshake daemon that enables kTLS.
Ubuntu 24.04 LTS
sudo apt update
sudo apt install nfs-common ktls-utils (>= 0.11)
If your mirror does not yet carry version 0.11 or later, download the package manually:
wget -4 https://archive.ubuntu.com/ubuntu/pool/universe/k/ktls-utils/ktls-utils_0.11-1_amd64.deb
sudo dpkg -i ktls-utils_0.11-1_amd64.deb
3. Enable the tlshd handshake daemon
sudo systemctl enable --now tlshd.service
Verify that the service is active:
systemctl --no-pager status tlshd
4. Provide certificates
The client must present a certificate chain that it trusts. Use one of the following options:
Option A — use an existing Enterprise CA
- Copy the CA certificate that signed the NFS server’s certificate to the client.
- Continue with Section 5.
Option B — generate a private CA and a server certificate (lab use)
WARNING: Self‑signed certificates are suitable only for testing. Use a trusted CA in production environments.
# Create a private CA (valid for 10 years)
openssl req \
-x509 -nodes -new -sha256 -days 3650 \
-newkey rsa:2048 \
-keyout RootCA.key \
-out RootCA.crt \
-subj "/CN=Demo‑Root‑CA"
# Create a server key and CSR (replace with real FQDN / IP)
openssl req \
-new -nodes -newkey rsa:2048 \
-keyout server.key \
-out server.csr \
-subj "/CN=nfs.example.com"
cat > domains.ext <<'EOF'
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage=digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment
subjectAltName=DNS:nfs.example.com,IP:192.0.2.10
EOF
# Sign the CSR with the private CA (valid for ~3 years)
openssl x509 -req -in server.csr \
-CA RootCA.crt -CAkey RootCA.key -CAcreateserial \
-out server.crt -days 1024 -sha256 -extfile domains.ext
NOTE:
subjectAltNamefield must contain DNS names / IP addressees of server, used by client during connection establishing.
Copy RootCA.crt (or server.crt if you pinned only the server certificate) to the client.
5. Configure tlshd
Edit /etc/tlshd.conf and set the path to the certificate or trust store that you copied in the previous step. For example:
[authenticate.client]
x509.truststore=/etc/pki/ca-trust/source/anchors/RootCA.crt
NOTE: On Ubuntu, place the file in
/usr/local/share/ca-certificates/and runsudo update-ca-certificates.
Reload the daemon:
sudo systemctl restart tlshd.service
6. Mount the NFS share over TLS
-
Create a mount point:
sudo mkdir -p /mnt/nfs_tls -
Mount the share. Replace
nfs.example.com:/exportwith your export path:sudo mount -o xprtsec=tls nfs.example.com:/export /mnt/nfs_tlsThe
-o xprtsec=tlsoption tells the NFS client to negotiate a kTLS session with the server via tlshd.
To make the mount persistent, add an entry to /etc/fstab:
nfs.example.com:/export /mnt/nfs_tls nfs4 xprtsec=tls 0 0
7. Verify the TLS session
Run ss or nfsstat and check that the connection uses tls:
ss -tna | grep nfs
A line similar to the following confirms that the mount is encrypted:
ESTAB 0 0 192.0.2.100:915 192.0.2.10:2049 tls
8. Troubleshooting
| Symptom | Possible cause | Resolution |
|---|---|---|
mount returns permission denied | The client does not trust the server certificate | Verify that the correct CA / certificate is listed in tlshd.conf and restart tlshd |
mount hangs | tlshd is not running | Start the service with systemctl enable --now tlshd |
9. Additional resources
man nfsman tlshd
Document generated on 2026.09.14 19:54 for v4.5.9, branch 4.5
Monitoring and diagnosis
This section contains resources that may help in diagnosing NFS mount issues.
There are specific VAST NFS extensions such as multipath that we should consider when debugging. Also, there can be issue outside the scope of differences between this implementation and the upstream or distribution-based implementation.
See also the Prometheus exporter for scraping RPC transport statistics from client hosts.
Document generated on 2026.09.14 19:54 for v4.5.9, branch 4.5
Detecting running version
To verify that the driver is loaded, check if the /sys/module/sunrpc/parameters/nfs_bundle_version exists. The content of the file can be obtained via:
cat /sys/module/sunrpc/parameters/nfs_bundle_version
The content of the file indicates the loaded version. If it does not exist,
then either it was not loaded yet, or that the NFS layer that is provided with
the installed kernel is loaded instead - in that case the upper directory /sys/module/sunrpc exists.
Document generated on 2026.09.14 19:54 for v4.5.9, branch 4.5
Mount and transport state
Normally, the mountstats command shows NFS mount status. We have extended the
interface it uses, /proc/self/mountstats, with our own extra state reporting
via /sys. The extended information contains the IP addresses related to the
transport, and a string that indicates its state flags.
The extended form of it is obtainable via /sys/kernel/debug. For the
association to an NFS mount, we need to obtain the related sunrpc-id of the
mount point.
But first, we need to enable sunrpc-id reporting. This can be done using
the following command after boot:
echo 1 | sudo tee /sys/module/sunrpc/parameters/expose_id_in_mountstats
Then, identify the sunrpc-id relevant to the mount point by looking into
/proc/self/mountstats:
$ cat /proc/self/mountstats | grep -E 'fstype nfs|sunrpc-id'
device 192.168.40.7:/opt/export mounted on /mnt/export with fstype nfs statvers=1.1
sunrpc-id: 4
Now we are ready to fetch the full mountstats via the following command:
sudo cat /sys/kernel/debug/sunrpc/rpc_clnt/4/stats
The added information contains multipath IP address information per xprt
(transport) and xprt state in string format. The numbers in the first xprt:
line are counters and other numbers related that transports.
For example:
xprt: rdma 0 0 1 0 24 3 3 0 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 11 0 0 0
172.25.1.101 -> 172.25.1.1, state: CONNECTED BOUND
xprt: rdma 0 0 1 0 24 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 11 0 0 0
172.25.1.102 -> 172.25.1.2, state: CONNECTED BOUND
xprt: rdma 0 0 1 0 23 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 11 0 0 0
172.25.1.103 -> 172.25.1.3, state: CONNECTED BOUND
xprt: rdma 0 0 1 0 22 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 11 0 0 0
172.25.1.104 -> 172.25.1.4, state: CONNECTED BOUND
xprt: rdma 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
172.25.1.101 -> 172.25.1.5, state: BOUND
xprt: rdma 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
172.25.1.102 -> 172.25.1.6, state: BOUND
xprt: rdma 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
172.25.1.103 -> 172.25.1.7, state: BOUND
xprt: rdma 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
172.25.1.104 -> 172.25.1.8, state: BOUND
Document generated on 2026.09.14 19:54 for v4.5.9, branch 4.5
Prometheus exporter
The vastnfs-exporter is an optional HTTP server that exposes VastNFS RPC
transport statistics for Prometheus. It runs on NFS client hosts (the host
that mounts VastNFS exports) and reads kernel debugfs/sysfs — the NFS server is
out of scope.
The exporter mirrors the discovery logic of vastnfs-ctl: it walks VastNFS mount
RPC transports and publishes per-operation counters (same source as
rpc-transports-stats),
live per-transport queue depths (same sysfs fields as
rpc-transports), transport
state flags, and per-mount config (vastnfs_mount_info).
Default listen address: 0.0.0.0:9001. Endpoints:
| Path | Description |
|---|---|
/metrics | Prometheus text exposition |
/ | Minimal health/index body |
Build (optional)
Default package builds omit the exporter. Include it when building packages:
./build.sh bin --with-exporter
With --with-exporter, packages add python3 and python3-prometheus-client
(>= 0.16) as runtime dependencies and install the exporter files listed below.
See Building packages for other build.sh bin flags.
The exporter source must be committed before ./build.sh src — the packaging
scripts use git archive HEAD, which ships only committed files.
Install paths
After installing a package built with --with-exporter:
| File | RPM path | DEB path |
|---|---|---|
Python modules (exporter.py, metrics.py, discovery.py, version) | /usr/share/vastnfs-exporter/ | /usr/share/vastnfs-exporter/ |
| Wrapper script | /usr/bin/vastnfs-exporter | /usr/bin/vastnfs-exporter |
| systemd unit | /usr/lib/systemd/system/vastnfs-exporter.service | /lib/systemd/system/vastnfs-exporter.service |
The wrapper executes python3 /usr/share/vastnfs-exporter/exporter.py "$@".
The service unit is installed but not auto-enabled. After package install:
sudo systemctl enable --now vastnfs-exporter
Verify:
curl -s localhost:9001/metrics | head
Prerequisites
The exporter reads kernel debugfs and sysfs, not /proc mountstats.
debugfs must be mounted at /sys/kernel/debug. Most distributions mount it at
boot; verify with:
mount | grep debugfs
ls /sys/kernel/debug/vastnfs
If debugfs is not mounted, RPC metrics stay empty and
vastnfs_exporter_vastnfs_present is 0. Mount manually if needed:
sudo mount -t debugfs none /sys/kernel/debug
Paths the exporter uses:
| Path | Filesystem | Role |
|---|---|---|
/sys/kernel/debug/vastnfs/nfs_sb/* | debugfs | Identify VastNFS mounts (not present in upstream Linux NFS) |
/sys/kernel/debug/vastnfs/nfs_clnt/* | debugfs | Map NFS clients to rpc_clnt IDs |
/sys/kernel/debug/sunrpc/rpc_xprt/*/extra | debugfs | Per-operation RPC counters (per-op stats) |
/sys/kernel/debug/sunrpc/rpc_xprt/*/info | debugfs | Transport id, netid, addr, port labels |
/sys/kernel/sunrpc/rpc-clients/, xprt-switches/ | sysfs | Traverse RPC client → xprt-switch → transport IDs |
/sys/kernel/sunrpc/xprt-switches/*/xprt*/xprt_state | sysfs | Transport state flags (CONNECTED, BOUND, etc.) |
/sys/kernel/sunrpc/xprt-switches/*/xprt*/xprt_info | sysfs | Live queue depths (binding_q_len, sending_q_len, etc.) |
Discovery walks VastNFS NFS clients, resolves each to an RPC client and its transports via sysfs, then reads per-op counters from debugfs and queue depths and state flags from sysfs for those transports only.
Debugfs files are root-owned and often mode 0400; /sys/kernel/debug itself
is often mode 700. The packaged service runs as unprivileged vastnfs-exporter
with the capabilities needed to traverse and read these paths (same requirement
as sudo vastnfs-ctl).
systemd
The vastnfs-exporter service runs as a dedicated unprivileged user
(vastnfs-exporter) with systemd hardening enabled. The unit declares
RequiresMountsFor=/sys/kernel/debug so the service does not start until
debugfs is mounted.
Manual run
Packaged binary
sudo systemctl stop vastnfs-exporter # if running as a service
sudo vastnfs-exporter # listens on 0.0.0.0:9001
curl -s localhost:9001/metrics
Flags
| Flag | Default | Description |
|---|---|---|
--host | 0.0.0.0 | Listen address |
--port | 9001 | Listen port |
--shutdown-timeout | 5 | Grace period after SIGTERM/SIGINT before exit (seconds) |
Manual runs need root (or CAP_SYS_ADMIN + CAP_DAC_READ_SEARCH) to read
debugfs, same as vastnfs-ctl.
Metrics
The exporter uses a private Prometheus registry (no default python_* or
process_* series).
Labels
Per-transport labels used across RPC metrics:
| Label | Description | Example |
|---|---|---|
xprt_id | Kernel RPC transport ID | 2 |
netid | RPC network ID | tcp, rdma |
addr | Remote endpoint | 192.168.23.11:2049 |
RPC counter metrics add op (RPC operation name, e.g. READ, WRITE,
GETATTR). Queue length gauges and vastnfs_rpc_xprt_state use only
xprt_id, netid, and addr (state gauges also add state; see below).
Exporter-level state and self-observability metrics have no transport labels.
RPC counters (per transport, per operation)
Each counter is a cumulative total with labels xprt_id, netid, addr, and
op. All-zero per-op rows are omitted (same filter as
vastnfs-ctl rpc-transports-stats).
| Metric | Description |
|---|---|
vastnfs_rpc_xprt_ops_total | Total RPC operations |
vastnfs_rpc_xprt_trans_total | Total RPC transmissions |
vastnfs_rpc_xprt_timeouts_total | Total RPC timeouts |
vastnfs_rpc_xprt_bytes_sent_total | Total bytes sent |
vastnfs_rpc_xprt_bytes_received_total | Total bytes received |
vastnfs_rpc_xprt_queue_milliseconds_total | Cumulative queue wait time (ms); per-op q_ms column in rpc-transports-stats — not an instantaneous queue depth |
vastnfs_rpc_xprt_rtt_milliseconds_total | Total round-trip time (ms) |
vastnfs_rpc_xprt_execute_milliseconds_total | Total execute time (ms) |
vastnfs_rpc_xprt_errors_total | Total RPC errors |
Queue length gauges (per transport)
Instantaneous queue depths for each VastNFS mount transport. These are
Prometheus gauges (current depth), not cumulative counters. Source: sysfs
xprt_info (key=value lines), matching the binding_q_len, sending_q_len,
and related fields printed by vastnfs-ctl rpc-transports.
Do not confuse these with vastnfs_rpc_xprt_queue_milliseconds_total above —
that counter is cumulative wait time from debugfs per-op stats (q_ms).
| Metric | Sysfs field | Description |
|---|---|---|
vastnfs_rpc_xprt_binding_queue_length | binding_q_len | Tasks waiting for bind/rpcbind |
vastnfs_rpc_xprt_sending_queue_length | sending_q_len | Tasks waiting to send |
vastnfs_rpc_xprt_pending_queue_length | pending_q_len | Tasks in flight (awaiting reply) |
vastnfs_rpc_xprt_backlog_queue_length | backlog_q_len | Tasks waiting for a free request slot |
vastnfs_rpc_xprt_tasks_queue_length | tasks_queuelen | Total tasks associated with this transport |
Labels: xprt_id, netid, addr.
One series set per mount transport each scrape. Queue gauges are omitted when
xprt_info is unreadable or the kernel reports <closed> (disconnected
transports). Switch-level queue_len from rpc-switches is not exported.
During reconnection a transport may show state flags (e.g. CONNECTING) in
vastnfs_rpc_xprt_state while queue gauges are absent — the kernel does not
expose xprt_info queue fields until the transport is connected.
Transport state
vastnfs_rpc_xprt_state is a gauge set to 1 for each active state flag on a
transport. A transport in CONNECTED BOUND emits two series (one per flag).
Common state values: CONNECTED, BOUND, CONNECTING, CLOSE, DISCONN.
Labels: xprt_id, netid, addr, state.
Mount configuration
vastnfs_mount_info — gauge 1 per mount. Labels: nfs_id, mountpoint,
proto (effective transport), options (NFS mount options from
/proc/self/mountinfo, joined to nfs_sb via sb_id). Independent of xprt metrics.
State gauges (always emitted)
| Metric | Values | Description |
|---|---|---|
vastnfs_exporter_vastnfs_present | 0 or 1 | 1 when /sys/kernel/debug/vastnfs exists |
vastnfs_exporter_mount_count | non-negative integer | Number of VastNFS mounts exported this scrape |
vastnfs_exporter_xprt_count | non-negative integer | Number of VastNFS mount transports exported this scrape |
These gauges are emitted on every scrape, including when RPC collection fails
(xprt_count → 0; mount_count follows mount discovery).
Self-observability
| Metric | Type | Description |
|---|---|---|
vastnfs_exporter_build_info | info | Build version (version label) |
vastnfs_exporter_scrape_duration_seconds | gauge | Wall-clock time of the last collection |
vastnfs_exporter_collection_errors_total | counter | Failed collection attempts |
Behavior when VastNFS or debugfs is absent
The exporter process stays up. /metrics always returns HTTP 200 — never
5xx for collection failures.
When VastNFS is not loaded, debugfs is not mounted, or VastNFS is loaded but
there are no mounts yet, the scrape contains no vastnfs_rpc_xprt_* series.
State gauges are still emitted so operators can tell why the scrape is empty:
| Condition | vastnfs_exporter_vastnfs_present | vastnfs_exporter_xprt_count | RPC metrics |
|---|---|---|---|
| debugfs not mounted / vastnfs not loaded | 0 | 0 | absent |
| vastnfs loaded, no mounts | 1 | 0 | absent |
| vastnfs loaded, mounts active | 1 | > 0 | present |
See also
vastnfs-ctl rpc-transports-stats— per-op counter sourcevastnfs-ctl rpc-transports— queue depth fields on the CLI- Mount and transport state — debugfs background
- Building packages —
--with-exporterflag
Document generated on 2026.09.14 19:54 for v4.5.9, branch 4.5
External resources
Official upstream guide for admins: Linux v6.12 NFS admin guide.
On the linux-nfs.org site: General troubleshooting recommendations - Linux NFS
Linux distribution pages
- Archlinux NFS troubleshooting
- Chapter 3. Mounting NFS shares Red Hat Enterprise Linux 8 | Red Hat Customer Portal
Document generated on 2026.09.14 19:54 for v4.5.9, branch 4.5
Tracing
The supplied vastnfs-ctl helper script allows tracing the driver. The
underlying mechanism uses trace-cmd in order to accomplish that.
Prerequisites
trace-cmd
Make sure that the trace-cmd command is available.
Red Hat-based: dnf install -y trace-cmd
Debian-based: apt install trace-cmd
It is invoked by the script using sudo.
Loaded kernel modules
The vastnfs-ctl status command should indicate that the modules are already
loaded prior to starting trace.
# vastnfs-ctl status | grep modules
kernel modules: sunrpc rpcrdma lockd nfs_acl auth_rpcgss rpcsec_gss_krb5 nfs nfsv3 nfsv4
Performing trace
For trace collections there are 3 run modes:
- Live - traces are emitted as they happen.
- Collect to RAM.
- Collect to RAM and files.
Live traces
This is useful when there are not a lot of events, such as in the mount stage.
There are present commands for this, for example:
vastnfs-ctl trace cmd meta
Collect to RAM
Manages cyclic buffers in RAM - execution goes to background. Later, the traces can be saved to a file.
In the following example, we use 1GB of buffers for data-based IO and 100MB for transports, connection management and error handling.
vastnfs-ctl trace cmd collect \
buffer meta 100 class meta \
buffer io 1000 class all
Output should be as followed:
Events:
class meta 149 events bufsize 100 MB
class all 493 events bufsize 1000 MB
Instructing trace-cmd to start background collection to RAM...
Saving the buffers to a file
$ vastnfs-ctl trace cmd save
Saving tracing data to nfs-traces-20221020-122203.tar.gz... (via /tmp/vastnfs-tmp-BzoxUUyTPp)
(note: the tracing RAM buffer is pruged and 'collect' will be
needed to be used again to collect new data)
-rw-r--r-- 1 root root 2202606 Oct 20 12:22 /home/user/workdir/nfs-traces-20221020-122203.tar.gz
Done. To start a new session use 'collect' again.
Observing a saved trace report
The developers can use the extracted nfs-traces-<timestamp>.tar.gz tarball
and trace-cmd report to see meaningful output of the saved traces.
Collect to RAM and files
Manages cyclic buffers both in RAM and files, where the RAM is immediately flushed to files. Execution stays in foreground. Useful for large volume of traces.
Append an outdir <path> to the collect command. The directory needs to exist
before execution.
For example:
$ vastnfs-ctl trace cmd collect buffer meta 100 class meta buffer io 1000 class all outdir saved-traces-20221001
Checking tracepoints...
Output directory: saved-traces-20221001
Output FS type: ext4
FS storage for traces: 696192 MB
Events:
class meta 149 events bufsize 100 MB
class all 493 events bufsize 1000 MB
Saving logfile: /home/dan/vd/kernel/vastnfs/saved-traces-20221001/collect.log
Running trace-cmd. Wait for it to prompt readiness.
Hit Ctrl^C to stop recording
...
...
Collection done, saved-traces-20221001 can be packed and sent.
Document generated on 2026.09.14 19:54 for v4.5.9, branch 4.5
Troubleshooting
This section includes some troubleshooting tips when building or installing the driver.
Document generated on 2026.09.14 19:54 for v4.5.9, branch 4.5
Installation problems
dnf errors about conflicting prerequisites
If you have a custom-built kernel you might encounter an error like this:
sudo dnf install dist/vastnfs-4.0.23-kernel_5.15.147.el9.x86_64.rpm
...
Error:
Problem: conflicting requests
- nothing provides kernel(PDE_DATA) = 0x0e0f5bd2 needed by vastnfs-4.0.23-kernel_5.15.147.el9.x86_64 from @commandline
- nothing provides kernel(__alloc_pages) = 0xc7233469 needed by vastnfs-4.0.23-kernel_5.15.147.el9.x86_64 from @commandline
- nothing provides kernel(__bitmap_weight) = 0x63c4d61f needed by vastnfs-4.0.23-kernel_5.15.147.el9.x86_64 from @commandline
- nothing provides kernel(__cpu_online_mask) = 0x564405cb needed by vastnfs-4.0.23-kernel_5.15.147.el9.x86_64 from @commandline
...
The problem is that the kernel-core package for your kernel is not reporting
features that the vastnfs package requires. This could either be due to:
- The target kernel is installed from a custom kernel RPM, but that RPM was not properly built to include kabichk 'provides' specifications (standard RHEL-based kernels always have kabichk).
- The target kernel wasn't installed with
rpm/dnf/yumbut rather installed using some custom setup.
Confirm that your kernel is installed as a package by checking with rpm:
$ rpm -qa | grep kernel-core
You can see what kernel() features that kernel-core package says it
provides with:
$ rpm -q --provides kernel-core-$(uname -r) | grep kernel
If the kernel was installed with a package but the package doesn't say it
provides the symbols vastnfs is looking and you suspect it's a packaging
issue with your custom kernel RPM you can force the install with --nodeps
to bypass the dependency check.
$ sudo rpm -i --nodeps ./dist/vastnfs-vast*.x86_64.rpm
A reboot is required for the new drivers to load.
If the vastnfs driver works in this configuration consider updating your custom RPM kernel builds to specify the kernel features it provides to avoid this in the future.
sunrpc: Unknown symbol mlx_backport_dependency_symbol (err -2)
This means VAST NFS tried to load but the MOFED kernel layer is not loaded and cannot load.
The reason is that by default a VAST NFS build depends directly on the MOFED kernel modules in case the MOFED installation exists.
The usual scenario for this is following a kernel upgrade. After a kernel upgrade, if the MOFED kernel modules are not prepared for the new kernel, they are not loading, and system administrators sometimes don't notice it because the inbox Infiniband layers are loaded instead and cover for that. However, VAST NFS directly depends on the Infiniband layer it was compiled against.
The most trivial way is to reinstall MOFED (or at minimum, its kernel module subpackage), followed by VAST NFS rebuild and install.
Another option, suppose that MOFED installation is no longer desired,
is to run ./build.sh bin --no-ofed to create a VAST NFS build that does
not depend on it, and reinstall it instead.
Compilation errors when used with DOCA OFED following kernel upgrade within the same RHEL minor
Kernel updates within the same RHEL minor (e.g., '4.18.0-553' to e.g., '4.18.0-553.69.1'), sometimes break the ability to build or load VAST NFS.
The workaround is to rebuild and reinstall the OFED kernel modules, and then rebuild VAST NFS kernel modules ontop.
dnf install -y doca-extra kernel-devel-$(uname -r)
rm -rf /tmp/DOCA.*
/opt/mellanox/doca/tools/doca-kernel-support
cd /tmp/DOCA.*
rpm -Uvh doca-kernel-repo*.rpm
dnf makecache
dnf install -y doca-ofed-userspace
dnf install -y --disablerepo=doca doca-kernel-\*
# Reinstall mlnx-ofa_kernel-devel to support VAST NFS rebuild
dnf download mlnx-ofa_kernel-devel
rpm2cpio mlnx-ofa_kernel-devel-*.rpm | (cd / && cpio -imdv)
ln -sf /usr/src/ofa_kernel/x86_64/$(uname -r) /etc/alternatives/ofa_kernel_headers
(Last three commands are workaround to bring the new mlnx-ofa_kernel-devel, because a trivial dnf install -y mlnx-ofa_kernel-devel does not do the right thing. NVIDIA may fix this issue in the future)
Older procedure for Mellanox OFED
An alternative to the procedure above for MLNX OFED, without going through DOCA OFED RPMs or procedure:
# Making some dependencies are installed
dnf install -y kernel-devel-$(uname -r) patch
# Copying of OFA kernel source
cd /usr/src
(if [[ -e ofa_kernel/x86_64/$(uname -r) ]] ; then echo ERROR: ofa_kernel/x86_64/$(uname -r) already exists; sleep 5; exit 1 ; fi)
cp -a ofa_kernel-*/source/ ofa_kernel/x86_64/$(uname -r)
# Configuring and rebuilding mlnx-ofa_kernel based on the original build's configure.mk.kernel
cd ofa_kernel/x86_64/$(uname -r)
./configure --with-linux-obj=/usr/src/kernels/$(uname -r) --with-njobs=32 $(for i in $(cat /usr/src/ofa_kernel/x86_64/$(readlink -f -- $(modinfo mlx_compat | grep filename: | awk '{print $2}')| awk -F/ '{print $5}')/configure.mk.kernel | grep ^CONFIG_ | uniq); do ./configure --help | grep -E " $i " ; done | awk -F" " '{print $1}') -j32
make -j32
make install -j32
# Pointing to it
ln -sf /usr/src/ofa_kernel/x86_64/$(uname -r) /etc/alternatives/ofa_kernel_headers
# Making sure initramfs contains the regenerated mlnx-ofa_kenrel
dracut -f
Document generated on 2026.09.14 19:54 for v4.5.9, branch 4.5
License Notice
VAST NFS is distributed under the terms of the GNU General Public License version 2 (GPLv2) as published by the Free Software Foundation.
See the gnu-gpl-v2-0 file for the full license text.
Document generated on 2026.09.14 19:54 for v4.5.9, branch 4.5
GNU General Public License
Version 2, June 1991
Copyright © 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too.
When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.
We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations.
Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and modification follow.
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The “Program”, below, refers to any such program or work, and a “work based on the Program” means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term “modification”.) Each licensee is addressed as “you”.
Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program.
You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions:
- a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change.
- b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License.
- c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program.
In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License.
3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following:
- a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or,
- b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or,
- c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable.
If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance.
5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License.
7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice.
This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and “any later version”, you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation.
10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the “copyright” line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands show w and show c should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than show w and show c; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your school, if any, to sign a “copyright disclaimer” for the program, if necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License.
Document generated on 2026.09.14 19:54 for v4.5.9, branch 4.5
4.5.9
Source: vastnfs-4.5.9.tar.xz
(released Sep 14, 2026)
- Add optional Prometheus exporter (
vastnfs-exporter) for per-mount RPC transport metrics (build with--with-exporter). - Add the
extended_groupsmount option to send up to 1024 AUTH_UNIX supplementary groups to the server. - Add plain TCP fallback for the MOUNT RPC when mount-over-TLS is unavailable, while keeping xprtsec on the NFS data connection (
tls_mount_fallback_enabled, enabled by default). - Keep the client source IP stable across reconnects so mounts recover cleanly after network interruptions.
- Fix mdconnect metadata RPC load balancing.
- Fix a possible crash when opening existing symlinks over NFSv3.
- Expand kernel/build compatibility, now supporting Linux 7.1.
- Add DKMS support on Fedora-based distributions and fix DKMS packaging issues.
- Add TencentOS to CentOS-like distro detection.
- Multiple bug fixes.
4.5.8
Source: vastnfs-4.5.8.tar.xz
(released Jul 8, 2026)
- Add Job-ID support for NFS operations.
- Expand kernel/build compatibility and backports (Linux 6.18, 6.19, 7.0, SLED RPM builds, SLES 15/16 fallback behavior) and sync upstream to v6.12.57.
- Add TLS support for the NFSv3 MOUNT connection and enable xprtsec policy for MOUNT by default on VAST servers.
- Improve TLS and key handling by supporting kernel keyrings, validating TLS certificate fields in client matching, and redacting certificate serial values in mount options.
- Add per-transport stats in driver and
vastnfs-ctl. - Fix multiple NFSv4 delegation issues when using multipathing.
- Fix ENOKEY race conditions in concurrent
remoteports=dnsmounts and ignoreINADDR_ANYaddresses from DNS replies. - Fix alternate server handling, including mountstats RPC accounting and an
nfs_server_add_altBUG_ON with alt_server sizing. - Restore the
relmtimemount option after upstream sync fallout and fix additional NFS client edge cases (localports, setattr delegation, and in_dev reference handling). - Enable large folios by default from Linux 6.12 and RHEL 9.7
- Better diagnostic messages if NFS server is unresponsive.
- Set fallback source version to
v4.0.41. - Multiple bug fixes.
4.5.7
Source: vastnfs-4.5.7.tar.xz
(released May 12, 2026)
- build.sh: fixup for azurelinux
- Further backports to improve the deadlock fix of
nfs_lock_and_join_requests. - Sync fallback to v4.0.40.
4.5.6
Source: vastnfs-4.5.6.tar.xz
(released Apr 27, 2026)
- Added expandable read-ahead, and enabled by default. Read-ahead starts at 128 KB default and grows to
read_ahead_kbsetting only after sequential IO. Can be turned off via kernel module parameter. - Backport upstream fix to a deadlock on rare cases (commit 8e5419d6542 "nfs: Add missing release on error in nfs_lock_and_join_requests()")
4.5.5
Source: vastnfs-4.5.5.tar.xz
(released Mar 11, 2026)
- Fix a cleanup issue in umount under Linux kernels 6.16 and above that prevented driver reload.
4.5.4
Source: vastnfs-4.5.4.tar.xz
(released Feb 12, 2026)
- For unsupported kernels, sync fallback logic to v4.0.39
4.5.3
Source: vastnfs-4.5.3.tar.xz
(released Feb 11, 2026)
- Fix a build issue for systems with DOCA 3.2.1 and above, that prevented rpcrdma (NFS RDMA) from being loaded.
4.5.2
Source: vastnfs-4.5.2.tar.xz
(released Jan 26, 2026)
- Trivial build fixes for newer kernels
- NFS directory cache fixes
- Fix performance regression from upstream related to directory listing
- Fix for
optlockflushandrelmtimeactivation with NFSv4.x - Fix a crash on pnfs MDS=DS session trunking
- Add the
pconnectmount option (see documentation) - Enable
localports_failoverby default whichlocalportsis used - Implement
localportsfailover during mount stage vastnfs-ctlfixes for IO stats- For unsupported kernels, sync fallback logic to v4.0.38
- Various tracing and debugability improvments
- Documentation updates
4.5.1
Source: vastnfs-4.5.1.tar.xz
(released Oct 23, 2025)
- Build script fix.
4.5.0
Source: vastnfs-4.5.0.tar.xz
(released Oct 23, 2025)
- First release of 4.5.0, a rebase of the stack on Linux v6.6 LTS, bringing newer stack features from that kernel. See NFS over TLS.
- If installing for the first time, see supported kernel versions.
- Contains 4.0.36 source as build-time fallback that is triggered based on kernel version detection.
- Older 4.0 tree will be maintained separately (see older changelog)
Document generated on 2026.09.14 19:54 for v4.5.9, branch 4.5