Configure Ubuntu 26.04 for NVMe-oF with ONTAP storage
NVMe over Fabrics (NVMe-oF), including NVMe over Fibre Channel (NVMe/FC) and other transports, is supported with Ubuntu 26.04 and Asymmetric Namespace Access (ANA). In NVMe-oF environments, ANA is the equivalent of ALUA multipathing in iSCSI and FC environments and is implemented with in-kernel NVMe multipath.
Learn how to configure NVMe over Fabrics (NVMe-oF) hosts for Ubuntu 26.04. For more support and feature information, see Ubuntu ONTAP support and features.
NVMe-oF with Ubuntu 26.04 has the following known limitation:
-
SAN booting using the NVMe-oF protocol is currently not supported for Ubuntu 26.04 with ONTAP.
For additional details on supported configurations, see the Interoperability Matrix Tool.
Step 1: Install Ubuntu and NVMe software and verify your configuration
To configure your host for NVMe-oF you need to install the host and NVMe software packages, enable multipathing, and verify your host NQN configuration.
-
Install Ubuntu 26.04 on the server. After the installation is complete, verify that you are running the specified Ubuntu 26.04 kernel:
uname -rExample Ubuntu kernel version:
7.0.0-27-generic
-
Install the
nvme-clipackage:apt list | grep nvmeThe following example shows an
nvme-clipackage version:nvme-cli/resolute,now 2.16-1 amd64
-
On the Ubuntu 26.04 host, check the hostnqn string at
/etc/nvme/hostnqn:cat /etc/nvme/hostnqnThe following example shows a
hostnqnvalue:nqn.2014-08.org.nvmexpress:uuid:4c4cxxxx-0050-xxxx-8035-c2cxxxxa5933
-
On the ONTAP system, verify that the
hostnqnstring from/etc/nvme/hostnqnmatches thehostnqnstring for the corresponding subsystem on the ONTAP storage system:vserver nvme subsystem host show -vserver vs_106_fc_nvmeShow example
Vserver Subsystem Host NQN ----------- --------------- ---------------------------------------------------------- vs_106_fc_nvme ub_106 nqn.2014-08.org.nvmexpress:uuid:4c4cxxxx-0050-xxxx-8035-c2c04f4a5933
If the hostnqnstrings don't match, use thevserver modifycommand to update thehostnqnstring on your corresponding ONTAP storage system subsystem to match thehostnqnstring from/etc/nvme/hostnqnon the host.
Step 2: Configure NVMe/FC and NVMe/TCP
Configure NVMe/FC for Broadcom/Emulex or Marvell/Qlogic adapters, or configure NVMe/TCP using manual discovery and connect operations.
Configure NVMe/FC for a Broadcom/Emulex adapter.
-
Verify that you're using the supported adapter model:
-
Display the model names:
cat /sys/class/scsi_host/host*/modelnameYou should see the following output:
LPe36002-M64 LPe36002-M64
-
Display the model descriptions:
cat /sys/class/scsi_host/host*/modeldescYou should see output similar to the following example:
Emulex LPe36002-M64 2-Port 64Gb Fibre Channel Adapter Emulex LPe36002-M64 2-Port 64Gb Fibre Channel Adapter
-
-
Verify that you're using the recommended Broadcom
lpfcfirmware and inbox driver:-
Display the firmware version:
cat /sys/class/scsi_host/host*/fwrevThe command returns the firmware versions:
14.4.393.25, sli-4:6:d 14.4.393.25, sli-4:6:d
-
Display the inbox driver version:
cat /sys/module/lpfc/versionThe following example shows a driver version:
0:14.4.0.13
For the current list of supported adapter driver and firmware versions, see the Interoperability Matrix Tool.
-
-
Verify that
lpfc_enable_fc4_typeis set to3:cat /sys/module/lpfc/parameters/lpfc_enable_fc4_type -
Verify that you can view your initiator ports:
cat /sys/class/fc_host/host*/<port_name>You should see output similar to:
0x100000109bf0447b 0x100000109bf0447c
-
Verify that your initiator ports are online:
cat /sys/class/fc_host/host*/port_stateYou should see the following output:
Online Online
-
Verify that the NVMe/FC initiator ports are enabled and that the target ports are visible:
cat /sys/class/scsi_host/host*/nvme_infoShow example output
NVME Initiator Enabled XRI Dist lpfc0 Total 6144 IO 5894 ELS 250 NVME LPORT lpfc0 WWPN x100000109bf0447b WWNN x200000109bf0447b DID x022600 ONLINE NVME RPORT WWPN x200fd039eaa8138b WWNN x200ad039eaa8138b DID x021006 TARGET DISCSRVC ONLINE NVME Statistics LS: Xmt 0000000187 Cmpl 0000000187 Abort 00000000 LS XMIT: Err 00000000 CMPL: xb 00000000 Err 00000000 Total FCP Cmpl 0000000014096514 Issue 000000001407fcd6 OutIO fffffffffffe97c2 abort 00000048 noxri 00000000 nondlp 0000001c qdepth 00000000 wqerr 00000000 err 00000000 FCP CMPL: xb 00000048 Err 00000077 NVME Initiator Enabled XRI Dist lpfc1 Total 6144 IO 5894 ELS 250 NVME LPORT lpfc1 WWPN x100000109bf0447c WWNN x200000109bf0447c DID x022300 ONLINE NVME RPORT WWPN x2010d039eaa8138b WWNN x200ad039eaa8138b DID x021106 TARGET DISCSRVC ONLINE NVME Statistics LS: Xmt 0000000187 Cmpl 0000000187 Abort 00000000 LS XMIT: Err 00000000 CMPL: xb 00000000 Err 00000000 Total FCP Cmpl 00000000140970ed Issue 00000000140813da OutIO fffffffffffea2ed abort 00000047 noxri 00000000 nondlp 0000002b qdepth 00000000 wqerr 00000000 err 00000000 FCP CMPL: xb 00000047 Err 00000075
Configure NVMe/FC for a Marvell/QLogic adapter.
-
Verify that you are using the supported adapter driver and firmware versions:
cat /sys/class/fc_host/host*/symbolic_nameThe following example shows driver and firmware versions:
QLE2872 FW: v9.15.17 DVR: v10.02.09.100-k QLE2872 FW: v9.15.17 DVR: v10.02.09.100-k
-
Verify that
ql2xnvmeenableis set. This enables the Marvell adapter to function as an NVMe/FC initiator:cat /sys/module/qla2xxx/parameters/ql2xnvmeenableThe expected output is 1.
NVMe/TCP doesn't support the auto-connect operation. Instead, you can discover the NVMe/TCP subsystems and namespaces by performing the NVMe/TCP connect or connect-all operations manually.
-
Check that the initiator port can fetch the discovery log page data across the supported NVMe/TCP LIFs:
nvme discover -t tcp -w <host-traddr> -a <traddr>Show example
# nvme discover -t tcp -w 192.168.167.150 -a 192.168.167.155 Discovery Log Number of Records 8, Generation counter 10 =====Discovery Log Entry 0====== trtype: tcp adrfam: ipv4 subtype: current discovery subsystem treq: not specified portid: 4 trsvcid: 8009 subnqn: nqn.1992-08.com.netapp:sn.9b7d42b764ff11efb8fed039eabac370:discovery traddr: 192.168.167.156 eflags: explicit discovery connections, duplicate discovery information sectype: none =====Discovery Log Entry 1====== trtype: tcp adrfam: ipv4 subtype: current discovery subsystem treq: not specified portid: 2 trsvcid: 8009 subnqn: nqn.1992-08.com.netapp:sn.9b7d42b764ff11efb8fed039eabac370:discovery traddr: 192.168.166.156 eflags: explicit discovery connections, duplicate discovery information sectype: none =====Discovery Log Entry 2====== trtype: tcp adrfam: ipv4 subtype: current discovery subsystem treq: not specified portid: 3 trsvcid: 8009 subnqn: nqn.1992-08.com.netapp:sn.9b7d42b764ff11efb8fed039eabac370:discovery traddr: 192.168.167.155 eflags: explicit discovery connections, duplicate discovery information sectype: none =====Discovery Log Entry 3====== trtype: tcp adrfam: ipv4 subtype: current discovery subsystem treq: not specified portid: 1 trsvcid: 8009 subnqn: nqn.1992-08.com.netapp:sn.9b7d42b764ff11efb8fed039eabac370:discovery traddr: 192.168.166.155 eflags: explicit discovery connections, duplicate discovery information sectype: none =====Discovery Log Entry 4====== trtype: tcp adrfam: ipv4 subtype: nvme subsystem treq: not specified portid: 4 trsvcid: 4420 subnqn: nqn.1992-08.com.netapp:sn.9b7d42b764ff11efb8fed039eabac370:subsystem.ubuntu_26.04_tcp_211 traddr: 192.168.167.156 eflags: none sectype: none =====Discovery Log Entry 5====== trtype: tcp adrfam: ipv4 subtype: nvme subsystem treq: not specified portid: 2 trsvcid: 4420 subnqn: nqn.1992-08.com.netapp:sn.9b7d42b764ff11efb8fed039eabac370:subsystem.ubuntu_26.04_tcp_211 traddr: 192.168.166.156 eflags: none sectype: none =====Discovery Log Entry 6====== trtype: tcp adrfam: ipv4 subtype: nvme subsystem treq: not specified portid: 3 trsvcid: 4420 subnqn: nqn.1992-08.com.netapp:sn.9b7d42b764ff11efb8fed039eabac370:subsystem.ubuntu_26.04_tcp_211 traddr: 192.168.167.155 eflags: none sectype: none =====Discovery Log Entry 7====== trtype: tcp adrfam: ipv4 subtype: nvme subsystem treq: not specified portid: 1 trsvcid: 4420 subnqn: nqn.1992-08.com.netapp:sn.9b7d42b764ff11efb8fed039eabac370:subsystem.ubuntu_26.04_tcp_211 traddr: 192.168.166.155 eflags: none sectype: none
-
Verify that the other NVMe/TCP initiator-target LIF combinations can successfully retrieve discovery log page data:
nvme discover -t tcp -w <host-traddr> -a <traddr>Show example output
#nvme discover -t tcp -w 192.168.167.150 -a 192.168.167.155 #nvme discover -t tcp -w 192.168.167.150 -a 192.168.167.156 #nvme discover -t tcp -w 192.168.166.150 -a 192.168.166.155 #nvme discover -t tcp -w 192.168.166.150 -a 192.168.166.156
-
Run the
nvme connect-allcommand across all the supported NVMe/TCP initiator-target LIFs across the nodes:nvme connect-all -t tcp -w <host-traddr> -a <traddr>Show example
#nvme connect-all -t tcp -w 192.168.167.150 -a 192.168.167.155 #nvme connect-all -t tcp -w 192.168.167.150 -a 192.168.167.156 #nvme connect-all -t tcp -w 192.168.166.150 -a 192.168.166.155 #nvme connect-all -t tcp -w 192.168.166.150 -a 192.168.166.156
The ctrl_loss_tmo timeout default setting for NVMe/TCP is turned off. This means there is no limit on the number of retries (indefinite retry) and you don't need to manually configure a specific ctrl_loss_tmo timeout duration when using the nvme connectornvme connect-allcommands (option -l ). With this default behavior, the NVMe/TCP controllers don't experience timeouts in the event of a path failure and remain connected indefinitely.
Step 3: Optionally, modify the iopolicy in the udev rules
Beginning with Ubuntu 26.04, the default iopolicy for NVMe-oF is set to queue-depth. You can change the iopolicy to round-robin by modifying the udev rules.
-
Open the udev rules file in a text editor with root privileges:
/usr/lib/udev/rules.d/71-nvmf-netapp.rulesYou should see the following output:
vi /usr/lib/udev/rules.d/71-nvmf-netapp.rules
-
Find the line that sets iopolicy for the NetApp ONTAP Controller, as shown in the following example rule:
ACTION=="add", SUBSYSTEM=="nvme-subsystem", ATTR{subsystype}=="nvm", ATTR{model}=="NetApp ONTAP Controller", ATTR{iopolicy}="queue-depth" -
Modify the rule so that queue-depth becomes round-robin:
ACTION=="add", SUBSYSTEM=="nvme-subsystem", ATTR{subsystype}=="nvm", ATTR{model}=="NetApp ONTAP Controller", ATTR{iopolicy}="round-robin" -
Reload the udev rules and apply the changes:
udevadm control --reloadudevadm trigger --subsystem-match=nvme-subsystem -
Verify the current iopolicy for your subsystem:
cat /sys/class/nvme-subsystem/<subsystem>/iopolicyYou should see the following output:
round-robin
|
|
The new iopolicy applies automatically to matching NetApp ONTAP Controller devices. You don't need to reboot. |
Step 4: Optionally, enable 1MB I/O for NVMe/FC
ONTAP reports a Max Data Transfer Size (MDTS) of 8 in the Identify Controller data. This means the maximum I/O request size can be up to 1MB. To issue I/O requests of size 1MB for a Broadcom NVMe/FC host, you should increase the lpfc value of the lpfc_sg_seg_cnt parameter to 256 from the default value of 64.
|
|
These steps don't apply to Qlogic NVMe/FC hosts. |
-
Set the
lpfc_sg_seg_cntparameter to 256:cat /etc/modprobe.d/lpfc.confYou should see an output similar to the following example:
options lpfc lpfc_sg_seg_cnt=256
-
Run the
dracut -fcommand, and reboot the host. -
Verify that the value for
lpfc_sg_seg_cntis 256:cat /sys/module/lpfc/parameters/lpfc_sg_seg_cnt
Step 5: Verify NVMe boot services
The nvmefc-boot-connections.service and nvmf-autoconnect.service boot services included in the NVMe/FC nvme-cli package are automatically enabled when the system boots.
After booting completes, verify that the nvmefc-boot-connections.service and nvmf-autoconnect.service boot services are enabled.
-
Verify that
nvmf-autoconnect.serviceis enabled:systemctl status nvmf-autoconnect.serviceShow example output
nvmf-autoconnect.service - Connect NVMe-oF subsystems automatically during boot Loaded: loaded (/usr/lib/systemd/system/nvmf-autoconnect.service; enabled; preset: enabled) Active: inactive (dead) since Tue 2026-07-07 08:20:42 UTC; 1 week 6 days ago Invocation: fdc6a9313f584a27af26dc76f3e467c8 Main PID: 15938 (code=exited, status=0/SUCCESS) Mem peak: 2M CPU: 24ms Jul 07 08:20:42 SR630-13-203 systemd[1]: Starting nvmf-autoconnect.service - Connect NVMe-oF subsystems automatically during boot... Jul 07 08:20:42 SR630-13-203 systemd[1]: nvmf-autoconnect.service: Deactivated successfully. Jul 07 08:20:42 SR630-13-203 systemd[1]: Finished nvmf-autoconnect.service - Connect NVMe-oF subsystems automatically during boot. -
Verify that
nvmefc-boot-connections.serviceis enabled:systemctl status nvmefc-boot-connections.serviceShow example output
nvmefc-boot-connections.service - Auto-connect to subsystems on FC-NVME devices found during boot Loaded: loaded (/usr/lib/systemd/system/nvmefc-boot-connections.service; enabled; preset: enabled) Active: inactive (dead) since Tue 2026-07-07 08:18:38 UTC; 1 week 6 days ago Invocation: 6f0a5c2d278b461bae223d4450ec6c51 Main PID: 5137 (code=exited, status=0/SUCCESS) Mem peak: 2M CPU: 19ms Jul 07 08:18:38 SR630-13-203 systemd[1]: Starting nvmefc-boot-connections.service - Auto-connect to subsystems on FC-NVME devices found du> Jul 07 08:18:38 SR630-13-203 systemd[1]: nvmefc-boot-connections.service: Deactivated successfully. Jul 07 08:18:38 SR630-13-203 systemd[1]: Finished nvmefc-boot-connections.service - Auto-connect to subsystems on FC-NVME devices found du>
Step 6: Verify multipathing configuration
Verify that the in-kernel NVMe multipath status, ANA status, and ONTAP namespaces are correct for the NVMe-oF configuration.
-
Verify that the in-kernel NVMe multipath is enabled:
cat /sys/module/nvme_core/parameters/multipathThe expected output is "Y".
-
Verify that the appropriate NVMe-oF settings (such as, model set to NetApp ONTAP Controller and load balancing iopolicy set to queue-depth) for the respective ONTAP namespaces correctly reflect on the host:
-
Display the subsystems:
cat /sys/class/nvme-subsystem/nvme-subsys*/modelYou should see the following output:
NetApp ONTAP Controller NetApp ONTAP Controller
-
Display the policy:
cat /sys/class/nvme-subsystem/nvme-subsys*/iopolicyYou should see the following output:
queue-depth queue-depth
-
-
Verify that the namespaces are created and correctly discovered on the host:
nvme listShow example output
Node SN Model --------------------------------------------------------- /dev/nvme0n1 81CZ5BQuUNfGAAAAAAAB NetApp ONTAP Controller Namespace Usage Format FW Rev ----------------------------------------------------------- 1 21.47 GB / 21.47 GB 4 KiB + 0 B FFFFFFFF
-
Verify that the controller state of each path is live and has the correct ANA status:
NVMe/FCnvme list-subsys /dev/nvme0n1The following example outputs show a namespace hosted on a two-node ONTAP controller for an AFF, FAS, ASA, or ASA r2 system with NVMe/FC.
Show AFF, FAS, and ASA example output
nvme-subsys5 - NQN=nqn.1992-08.com.netapp:sn.f7565b15a66911ef9668d039ea951c46:subsystem.nvme1 hostnqn=nqn.2014-08.org.nvmexpress:uuid:4c4c4544-0056-5410-8048-c7c04f425633 \ +- nvme126 fc traddr=nn-0x2036d039ea951c45:pn-0x2038d039ea951c45,host_traddr=nn-0x2000f4c7aa0cd7c3:pn-0x2100f4c7aa0cd7c3 live optimized +- nvme176 fc traddr=nn-0x2036d039ea951c45:pn-0x2037d039ea951c45,host_traddr=nn-0x2000f4c7aa0cd7c2:pn-0x2100f4c7aa0cd7c2 live optimized +- nvme5 fc traddr=nn-0x2036d039ea951c45:pn-0x2039d039ea951c45,host_traddr=nn-0x2000f4c7aa0cd7c2:pn-0x2100f4c7aa0cd7c2 live non-optimized +- nvme71 fc traddr=nn-0x2036d039ea951c45:pn-0x203ad039ea951c45,host_traddr=nn-0x2000f4c7aa0cd7c3:pn-0x2100f4c7aa0cd7c3 live non-optimizedShow ASA r2 example output
nvme-subsys96 - NQN=nqn.1992-08.om.netapp:sn.b351b2b6777b11f0b3c2d039ea5cfc91:subsystem.nvme24 hostnqn=nqn.2014-08.org.nvmexpress:uuid:d3b581b4-c975-11e6-8425-0894ef31a074 \ +- nvme203 fc traddr=nn-0x2011d039ea5cfc90:pn-0x2015d039ea5cfc90,host_traddr=nn-0x200000109bdacc76:pn-0x100000109bdacc76 live optimized +- nvme25 fc traddr=nn-0x2011d039ea5cfc90:pn-0x2014d039ea5cfc90,host_traddr=nn-0x200000109bdacc75:pn-0x100000109bdacc75 live optimized +- nvme30 fc traddr=nn-0x2011d039ea5cfc90:pn-0x2012d039ea5cfc90,host_traddr=nn-0x200000109bdacc75:pn-0x100000109bdacc75 live optimized +- nvme32 fc traddr=nn-0x2011d039ea5cfc90:pn-0x2013d039ea5cfc90,host_traddr=nn-0x200000109bdacc76:pn-0x100000109bdacc76 live optimizedNVMe/TCPnvme list-subsys /dev/nvme1n1The following example outputs show a namespace hosted on a two-node ONTAP controller for an AFF, FAS, ASA, or ASA r2 system with NVMe/TCP.
Show AFF, FAS, and ASA example output
nvme-subsys4 - NQN=nqn.1992-08.com.netapp:sn.64e65e6caae711ef9668d039ea951c46:subsystem.nvme4 hostnqn=nqn.2014-08.org.nvmexpress:uuid:4c4c4544-0035-5910-804b-c2c04f444d33 \ +- nvme102 tcp traddr=192.168.21.20,trsvcid=4420,host_traddr=192.168.21.1,src_addr=192.168.21.1 live non-optimized +- nvme151 tcp traddr=192.168.21.21,trsvcid=4420,host_traddr=192.168.21.1,src_addr=192.168.21.1 live optimized +- nvme4 tcp traddr=192.168.20.20,trsvcid=4420,host_traddr=192.168.20.1,src_addr=192.168.20.1 live non-optimized +- nvme53 tcp traddr=192.168.20.21,trsvcid=4420,host_traddr=192.168.20.1,src_addr=192.168.20.1 live optimizedShow ASA r2 example output
nvme-subsys9 - NQN=nqn.1992-08.com.netapp:sn.9927e165694211f0b4f4d039eab31e9d:subsystem.nvme10 hostnqn=nqn.2014-08.org.nvmexpress:uuid:4c4cxxxx-0035-xxxx-804b-b7cxxxx44d33 \ +- nvme105 tcp traddr=192.168.39.10,trsvcid=4420,host_traddr=192.168.39.20,src_addr=192.168.39.20 live optimized +- nvme153 tcp traddr=192.168.39.11,trsvcid=4420,host_traddr=192.168.39.20,src_addr=192.168.39.20 live optimized +- nvme57 tcp traddr=192.168.38.11,trsvcid=4420,host_traddr=192.168.38.20,src_addr=192.168.38.20 live optimized +- nvme9 tcp traddr=192.168.38.10,trsvcid=4420,host_traddr=192.168.38.20,src_addr=192.168.38.20 live optimized -
Verify that the NetApp plug-in displays the correct values for each ONTAP namespace device:
Columnnvme netapp ontapdevices -o columnShow example output
Device Vserver Namespace Path NSID UUID Size ------------- ------------- ----------------------- ---- -------------------------------------- --------- /dev/nvme0n1 vs_211_tcp /vol/tcpvol1/ns1 1 1cc7bc78-8d7b-4d8e-a3c4-750f9461a6e9 21.47GB
JSONnvme netapp ontapdevices -o jsonShow example output
{ "ONTAPdevices" : [ { "Device":"/dev/nvme0n9", "Vserver":"vs_211_tcp", "Namespace_Path":"/vol/tcpvol9/ns9", "NSID":9, "UUID":"99640dd9-8463-4c12-8282-b525b39fc10b", "Size":"21.47GB", "LBA_Data_Size":4096, "Namespace_Size":5242880 } ] }
Step 7: Review the known issues
There are no known issues for the NVMe-oF host configuration for Ubuntu 26.04 with ONTAP release.