NVME-DISCOVERD(8)

πŸ“¦ version 3.2, in arch rolling

πŸ’… nvme-discoverd πŸ’…

okay so bestie, welcome to nvme-discoverd(8) from the NVMe Manual β€” the NVMe-oF discovery and connectivity daemon that literally keeps your fabrics connections alive so you don't have to 🫢


✨ NAME ✨

nvme-discoverd β€” NVMe-oF discovery and connectivity daemon. that's it, that's the vibe 🌸


πŸŽ€ SYNOPSIS πŸŽ€

nvme-discoverd [--config=<FILE>] [--nvme-path=<PATH>] [--debug] [--help]

πŸ¦‹ DESCRIPTION πŸ¦‹

okay so nvme-discoverd is a persistent daemon whose whole job is connecting the host's desired NVMe-oF controllers and keeping them connected. main character energy fr fr πŸ‘‘

It reads three sources to build its set of desired connections:

  1. the NBFT ACPI table (boot-time controllers, iconic)
  2. the shared NVMe-oF fabrics configuration (see nvme-fabrics.conf(5))
  3. the Discovery Log Pages of any Discovery Controllers it connects to β€” and yes that includes FC targets found via FC kickstart ✨

big important thing: it never disconnects a live controller in response to a discovery change. the only disconnects it causes are a side effect of stopping its own systemd units β€” at shutdown or on request. periodt πŸ’…


At shutdown, a unit is stopped only after the file systems mounted with the _netdev option are unmounted. a file system on an NVMe-oF namespace must use _netdev in fstab(5).

⚠️ without _netdev, the controller can be disconnected while the file system is still mounted. not cute. not slay. please use it 😭

Every connection attempt is delegated to nvme connect, which runs inside a systemd transient unit instead of writing directly to /dev/nvme-fabrics. the result? a stuck connect attempt never blocks the daemon's event loop πŸ™ˆ Each unit is named after a hash of the controller's transport identity. iykyk.


Failed connections retry with exponential backoff. Discovery Controllers from NBFT or the fabrics config represent explicit intent, so they always retry forever πŸ”₯

A Discovery Controller found only through a referral or FC kickstart is different energy: it gives up after dc-giveup-timeout (default 72hours) of unbroken failure and gets dropped from tracking πŸ’€


A TLS connection needs tlshd(8) from ktls-utils. enable it with:

systemctl enable --now tlshd

when both are enabled, nvme-discoverd starts after tlshd. the way that just works 🧚


Before connecting or reconnecting anything, nvme-discoverd checks the system-wide exclusion list. it also registers ownership of every controller it connects β€” --owner discoverd, or --owner nbft for an NBFT-sourced controller β€” in the NVMe-oF ownership registry. see nvme-registry-list(1) and nvme-exclusion-add(1) πŸŽ€


A Discovery Controller that has no owner β€” for example one connected with nvme discover --persistent β€” is not tracked. when its discovery log changes, or when it reconnects, nvme-discoverd runs nvme connect-all for it in a transient unit, just like the legacy udev rules do. the connections it makes have no owner, and nvme disconnect-all removes them. events from a Discovery Controller with another owner are ignored πŸ™…


🌈 real talk: nvme-discoverd is still experimental. it's meant to replace the older udev-rule/systemd-unit autoconnect mechanism.

by default, the legacy mechanism is built only when nvme-discoverd is not. building with -Dnvmf-autoconnect=enabled installs both.

  • the legacy udev rules are active as soon as they are installed
  • nvme-discoverd runs only when the administrator enables it with systemctl enable --now nvme-discoverd
  • while nvme-discoverd is active, nvmf-autoconnect.service and the FC kickstart skip their connect step

πŸ‘‘ OPTIONS πŸ‘‘

  • -c <FILE>, --config=<FILE> β€” path to the daemon's own configuration file. default: /usr/local/etc/nvme/nvme-discoverd.conf; see CONFIGURATION below. good news: a missing file is not an error β€” every knob just keeps its default πŸ’–
  • --nvme-path=<PATH> β€” absolute or relative path to the nvme binary that transient connection units exec. default: /usr/local/sbin/nvme. mainly useful for running nvme-discoverd against a locally built nvme instead of the installed one πŸ”₯
  • -d, --debug β€” enable debug-level logging for both nvme-discoverd and the libnvme calls it makes, overriding the configured debug-level πŸ›
  • -h, --help β€” print usage and exit. short, sweet, iconic ✨

πŸ“ CONFIGURATION πŸ“

nvme-discoverd.conf holds the daemon's own knobs, in a [Global] section and a [Discovery] section:

[Global]
nbft = true
debug-level = info

[Discovery]
epcsd-poll-interval-minutes = 15
fc-kickstart-interval-minutes = 0
dc-giveup-timeout = 72hours
zeroconf = false

πŸ’œ the knobs, explained

nbft (boolean, default true) β€” adopts and connects controllers listed in the NBFT ACPI table.

debug-level (err, warn, info, or debug; default info) β€” sets the log threshold. --debug on the command line overrides it.

epcsd-poll-interval-minutes (default 15, minimum 1) β€” how often, in minutes, to reconnect and re-check a DC whose effective EPCSD (Explicit Persistent Connection Support for Discovery) is 0. such a DC is disconnected between checks 😭

fc-kickstart-interval-minutes (default 0) β€” re-issues FC kickstart every N minutes. 0 = only at startup and on every FC controller drop.

dc-giveup-timeout (default 72hours) β€” the give-up horizon described above. it takes a systemd time span ("72hours", "3 days 5 hours") or a unit-less value in seconds:

  • "infinity" = never give up 🌈
  • 0 = give up on the first failure πŸ’€

A DC connects with a keep-alive timeout of 30 seconds, or with its configured keep-alive-tmo (see nvme-fabrics.conf(5)). a DC configured with persistent = no connects with none 🫢


zeroconf (boolean, default false) β€” connects to and manages Discovery Controllers found through mDNS (TP8009). it requires:

  • systemd-resolved v258 or later with mDNS enabled (MulticastDNS=yes)
  • an nvme-discoverd built with mDNS support

it is re-read on SIGHUP ✨


πŸ’‘ heads up bestie: the connections nvme-discoverd manages come entirely from the shared fabrics configuration, not from this file. which Discovery Controllers and subsystems to connect, host identity, per-connection parameters β€” all of that lives in nvme-fabrics.conf(5).

🌸 SIGNALS 🌸

  • SIGHUP β€” reload both nvme-discoverd.conf and the shared fabrics configuration. newly desired connections are started; nothing already connected is ever disconnected by a reload. if the fabrics configuration fails to reload (e.g. a syntax error), the previous one is kept and the failure is logged πŸ“
  • SIGTERM, SIGINT β€” shut down gracefully. bye bestie πŸ‘‹

πŸŽ€ FILES πŸŽ€

  • /usr/local/etc/nvme/nvme-discoverd.conf β€” the daemon's own configuration; see CONFIGURATION.
  • /usr/local/etc/nvme/nvme-discoverd.conf.sample β€” a commented example of nvme-discoverd.conf with every knob at its default. it is not read; copy it to nvme-discoverd.conf to change a setting 🧚
  • /usr/local/etc/nvme/nvme-fabrics.conf, /usr/local/etc/nvme/nvme-fabrics.conf.d/*.conf β€” the connections nvme-discoverd manages; see nvme-fabrics.conf(5).
  • /run/nvme/discoverd/ β€” runtime state linking each connected controller to the systemd transient unit that owns it. does not survive a reboot πŸ’€

🌈 SEE ALSO 🌈

nvme-fabrics.conf(5) tlshd(8) nvme-connect(1) nvme-registry-list(1) nvme-exclusion-add(1)


⭐ NVME ⭐

Part of the nvme-user suite πŸ’–


okay that's the whole page bestie, you ate that 🫢✨ this gorgeous little manpage is brought to you by the NVMe crew, dated 10/30/2026 β€” go forth and keep those controllers connected, no cap πŸ’…πŸŽ€

πŸ“¦ where this page comes from