Skip to main content
ONTAP SAN Host Utilities

Configure Ubuntu 26.04 for NVMe-oF with ONTAP storage

Contributors netapp-pcarriga

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.

Steps
  1. Install Ubuntu 26.04 on the server. After the installation is complete, verify that you are running the specified Ubuntu 26.04 kernel:

    uname -r

    Example Ubuntu kernel version:

    7.0.0-27-generic
  2. Install the nvme-cli package:

    apt list | grep nvme

    The following example shows an nvme-cli package version:

    nvme-cli/resolute,now 2.16-1 amd64
  3. On the Ubuntu 26.04 host, check the hostnqn string at /etc/nvme/hostnqn:

    cat /etc/nvme/hostnqn

    The following example shows a hostnqn value:

    nqn.2014-08.org.nvmexpress:uuid:4c4cxxxx-0050-xxxx-8035-c2cxxxxa5933
  4. On the ONTAP system, verify that the hostnqn string from /etc/nvme/hostnqn matches the hostnqn string for the corresponding subsystem on the ONTAP storage system:

    vserver nvme subsystem host show -vserver vs_106_fc_nvme
    Show example
    Vserver     Subsystem       Host NQN
    ----------- --------------- ----------------------------------------------------------
    vs_106_fc_nvme ub_106 nqn.2014-08.org.nvmexpress:uuid:4c4cxxxx-0050-xxxx-8035-c2c04f4a5933
    Note If the hostnqn strings don't match, use the vserver modify command to update the hostnqn string on your corresponding ONTAP storage system subsystem to match the hostnqn string from /etc/nvme/hostnqn on 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.

NVMeFC - Broadcom/Emulex

Configure NVMe/FC for a Broadcom/Emulex adapter.

Steps
  1. Verify that you're using the supported adapter model:

    1. Display the model names:

      cat /sys/class/scsi_host/host*/modelname

      You should see the following output:

      LPe36002-M64
      LPe36002-M64
    2. Display the model descriptions:

      cat /sys/class/scsi_host/host*/modeldesc

      You 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
  2. Verify that you're using the recommended Broadcom lpfc firmware and inbox driver:

    1. Display the firmware version:

      cat /sys/class/scsi_host/host*/fwrev

      The command returns the firmware versions:

      14.4.393.25, sli-4:6:d
      14.4.393.25, sli-4:6:d
    2. Display the inbox driver version:

      cat /sys/module/lpfc/version

      The 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.

  3. Verify that lpfc_enable_fc4_type is set to 3:

    cat /sys/module/lpfc/parameters/lpfc_enable_fc4_type
  4. Verify that you can view your initiator ports:

    cat /sys/class/fc_host/host*/<port_name>

    You should see output similar to:

    0x100000109bf0447b
    0x100000109bf0447c
  5. Verify that your initiator ports are online:

    cat /sys/class/fc_host/host*/port_state

    You should see the following output:

    Online
    Online
  6. Verify that the NVMe/FC initiator ports are enabled and that the target ports are visible:

    cat /sys/class/scsi_host/host*/nvme_info
    Show 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
NVMe/FC - Marvell/QLogic

Configure NVMe/FC for a Marvell/QLogic adapter.

Steps
  1. Verify that you are using the supported adapter driver and firmware versions:

    cat /sys/class/fc_host/host*/symbolic_name

    The 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
  2. Verify that ql2xnvmeenable is set. This enables the Marvell adapter to function as an NVMe/FC initiator:

    cat /sys/module/qla2xxx/parameters/ql2xnvmeenable

    The expected output is 1.

NVMe/TCP

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.

Steps
  1. 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
  2. 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
  3. Run the nvme connect-all command 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
    Note 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 connect or nvme connect-all commands (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.

Steps
  1. Open the udev rules file in a text editor with root privileges:

    /usr/lib/udev/rules.d/71-nvmf-netapp.rules

    You should see the following output:

    vi /usr/lib/udev/rules.d/71-nvmf-netapp.rules
  2. 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"
  3. 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"
  4. Reload the udev rules and apply the changes:

    udevadm control --reload
    udevadm trigger --subsystem-match=nvme-subsystem
  5. Verify the current iopolicy for your subsystem:

    cat /sys/class/nvme-subsystem/<subsystem>/iopolicy

    You should see the following output:

    round-robin
Note 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.

Note These steps don't apply to Qlogic NVMe/FC hosts.
Steps
  1. Set the lpfc_sg_seg_cnt parameter to 256:

    cat /etc/modprobe.d/lpfc.conf

    You should see an output similar to the following example:

    options lpfc lpfc_sg_seg_cnt=256
  2. Run the dracut -f command, and reboot the host.

  3. Verify that the value for lpfc_sg_seg_cnt is 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.

Steps
  1. Verify that nvmf-autoconnect.service is enabled:

    systemctl status nvmf-autoconnect.service
    Show 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.
  2. Verify that nvmefc-boot-connections.service is enabled:

    systemctl status nvmefc-boot-connections.service
    Show 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.

Steps
  1. Verify that the in-kernel NVMe multipath is enabled:

    cat /sys/module/nvme_core/parameters/multipath

    The expected output is "Y".

  2. 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:

    1. Display the subsystems:

      cat /sys/class/nvme-subsystem/nvme-subsys*/model

      You should see the following output:

      NetApp ONTAP Controller
      NetApp ONTAP Controller
    2. Display the policy:

      cat /sys/class/nvme-subsystem/nvme-subsys*/iopolicy

      You should see the following output:

      queue-depth
      queue-depth
  3. Verify that the namespaces are created and correctly discovered on the host:

    nvme list
    Show 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
  4. Verify that the controller state of each path is live and has the correct ANA status:

    NVMe/FC
    nvme list-subsys /dev/nvme0n1

    The 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-optimized
    Show 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 optimized
    NVMe/TCP
    nvme list-subsys /dev/nvme1n1

    The 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 optimized
    Show 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
  5. Verify that the NetApp plug-in displays the correct values for each ONTAP namespace device:

    Column
    nvme netapp ontapdevices -o column
    Show 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
    JSON
    nvme netapp ontapdevices -o json
    Show 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.