NVME-DISCOVER(1)

πŸ’… nvme-discover(1) β€” NVMe Manual 🌸

okay bestie, this is the nvme-discover page from the NVMe Manual, and it’s literally about sending Get Log Page requests to a Discovery Controller. ✨


πŸ’– NAME πŸ’–

nvme-discover β€” send a Get Log Page request to a Discovery Controller. πŸ’…

🌈 SYNOPSIS 🌈

nvme [<global-options>] discover
                        [--raw=<filename> | -r <filename>]
                        [--device=<device> | -d <device>]
                        [--config=<filename> | -J <filename>]
                        [--persistent[=<no|auto|force>] | -p]
                        [--quiet]
                        [--no-reuse]
                        [--force]
                        [--nbft]
                        [--no-nbft]
                        [--nbft-path=<STR>]
                        [--owner=<NAME>]
                        [<fabrics-options>]

✨ DESCRIPTION ✨

Okay so nvme discover sends one or more Get Log Page requests to an NVMe-over-Fabrics Discovery Controller. 🫢

If you give it no parameters at all, nvme discover will try to find a /usr/local/etc/nvme/discovery.conf file and use that to supply a list of Discovery commands to run. If that /usr/local/etc/nvme/discovery.conf file doesn’t exist, the command will quit with an error. 😭 No file, no party.

Otherwise, you should point it at a specific Discovery Controller with --transport, --traddr, and β€” if necessary β€” --trsvcid. Then a Discovery request gets sent to that specified Discovery Controller. ✨

πŸ¦‹ BACKGROUND πŸ¦‹

The NVMe-over-Fabrics spec defines the concept of a Discovery Controller that an NVMe Host can query on a fabric network to discover NVMe subsystems contained in NVMe Targets which it can connect to on the network. The Discovery Controller will return Discovery Log Pages that give the NVMe Host specific information β€” such as network address and unique subsystem NQN β€” that the NVMe Host can use to issue an nvme connect command to connect itself to a storage resource contained in that NVMe subsystem on the NVMe Target. πŸ’…

Note that the base NVMe spec defines the NQN (NVMe Qualified Name) format that an NVMe endpoint (device, subsystem, etc) must follow to guarantee a unique name under the NVMe standard. In particular, the Host NQN uniquely identifies the NVMe Host, and may be used by the Discovery Controller to control what NVMe Target resources are allocated to the NVMe Host for a connection. πŸ‘‘

A Discovery Controller has its own NQN defined in the NVMe-over-Fabrics spec: nqn.2014-08.org.nvmexpress.discovery. All Discovery Controllers must use this NQN name. This NQN is used by default by nvme-cli for the discover command. 🌟

πŸŽ€ OPTIONS πŸŽ€

  • -r <filename>, --raw=<filename> β€” this field will take the output of the nvme discover command and dump it to a raw binary file. By default nvme discover will dump the output to stdout. πŸ“
  • -d <device>, --device=<device> β€” this field takes a device as input. It must be a persistent device associated with a Discovery Controller previously created by the command "connect-all" or "discover". <device> follows the format nvme*, eg. nvme0, nvme1. πŸŽ€
  • -J <filename>, --config=<filename> β€” use the specified JSON configuration file instead of the default /usr/local/etc/nvme/config.json file, or none to not read in an existing configuration file. The JSON configuration file format is documented in https://github.com/linux-nvme/nvme-cli/blob/master/libnvme/doc/config-schema.json. πŸ¦‹
  • -p, --persistent[=<no|auto|force>] β€” keep the discovery controller connected after retrieving the discovery log page, instead of disconnecting once it’s done. Because the value is optional, it must be attached directly to the option: --persistent=force for the long form, -pforce for the short form. A value given as a separate argument (--persistent force, -p force) is no value of the option but an extra argument, and the command fails. 🚨
    • no β€” never persist. Use this to opt out of the default.
    • auto (the default, both when the option is omitted entirely and when --persistent is given with no value) β€” persist a Discovery Log Page entry’s connection only where that entry’s own EPCSD (Explicit Persistent Connection Support for Discovery) flag reports support for it; degrade to non-persistent, with a log message, for entries that don’t.
    • force β€” persist regardless of what EPCSD reports, for a target whose self-reported EPCSD cannot be trusted.

auto and force ask each discovery controller for a keep-alive timeout of 30 seconds, or the --keep-alive-tmo value when it is given. no asks for none, even when --keep-alive-tmo is given. πŸ’œ

  • --quiet β€” suppress already connected errors. πŸ™ˆ
  • --no-reuse β€” always create a new connection, never reuse an existing one. ✨
  • --force β€” (deprecated, see --no-reuse). πŸ’€
  • --nbft β€” only look at NBFT tables. πŸ¦‹
  • --no-nbft β€” do not look at NBFT tables. 🚫
  • --nbft-path=<STR> β€” use a user-defined path to the NBFT tables. πŸŽ€
  • --owner=<NAME> β€” record NAME as the owner of connected controllers in the NVMe ownership registry, so other orchestrators (and nvme-disconnect-all) leave them alone. See nvme-disconnect-all(1). When --nbft is also given, --owner takes precedence over its default owner of nbft. πŸ‘‘

🧚 FABRICS OPTIONS 🧚

The following options are common to NVMe over Fabrics commands such as nvme connect: 🌈

  • -a <traddr>, --traddr=<traddr> β€” specify the network address of the controller. For transports using IP addressing (e.g. rdma, tcp), this should be an IP address. 🌐
  • --concat β€” enable secure concatenation (TCP). πŸ”
  • -c <#>, --reconnect-delay=<#> β€” set the delay in seconds before reconnect is attempted after a connection loss. ⏳
  • -C <secret>, --kxchap-ctrl-secret=<secret> β€” controller authentication secret for bi-directional authentication. If not specified, bi-directional authentication is not attempted. πŸ”‘
  • -S <secret>, --kxchap-secret=<secret> β€” host authentication secret (KX-HMAC-CHAP). Must be provided in ASCII format as defined in the NVMe specification. 🧚
  • -C <secret>, --dhchap-ctrl-secret=<secret> β€” controller authentication secret for bi-directional authentication. If not specified, bi-directional authentication is not attempted. (deprecated, see --kxchap-ctrl-secret). πŸ’€
  • -S <secret>, --dhchap-secret=<secret> β€” host authentication secret (DH-HMAC-CHAP). Must be provided in ASCII format as defined in the NVMe specification. (deprecated, see --kxchap-secret). πŸ’€
  • --disable-sqflow β€” disable submission queue flow control. πŸ›‘
  • -G, --data-digest β€” enable data digest generation/verification (TCP). βœ…
  • -D, --duplicate-connect β€” allow duplicate connections to the same subsystem. πŸ‘―
  • -g, --hdr-digest β€” enable header digest generation/verification (TCP). βœ…
  • -f <iface>, --host-iface=<iface> β€” specify the network interface to use for the connection. 🧡
  • -I <hostid>, --hostid=<hostid> β€” specify the host UUID. πŸͺͺ
  • -q <hostnqn>, --hostnqn=<hostnqn> β€” override the default host NQN. 🌸
  • -w <traddr>, --host-traddr=<traddr> β€” specify the source address on the host side of the connection. πŸ“
  • -k <#>, --keep-alive-tmo=<#> β€” set the keep-alive timeout in seconds. πŸ’“
  • --keyring=<keyring> β€” keyring to use for TLS key lookup. πŸ”‘
  • -n <subnqn>, --nqn=<subnqn> β€” specify the NVMe subsystem NQN to connect to. 🎯
  • -i <#>, --nr-io-queues=<#> β€” number of I/O queues to create. 🧺
  • -P <#>, --nr-poll-queues=<#> β€” number of polling queues to create. πŸŒ€
  • -W <#>, --nr-write-queues=<#> β€” number of write queues to create. ✍️
  • -Q <#>, --queue-size=<#> β€” queue depth for I/O queues. πŸ“
  • -l <#>, --ctrl-loss-tmo=<#> β€” maximum time in seconds to retry reconnect attempts after controller loss. ⏱️
  • -s <trsvcid>, --trsvcid=<trsvcid> β€” transport service identifier (e.g. TCP/rdma port). Default is 4420 for RDMA. πŸ”Œ
  • -T <#>, --tos=<#> β€” type of service value for the connection (TCP). 🚦
  • -t <trtype>, --transport=<trtype> β€” specify the transport type. Supported values include:
    • rdma β€” RDMA (RoCE, iWARP, InfiniBand)
    • tcp β€” TCP/IP
    • fc β€” Fibre Channel (experimental)
    • loop β€” Local loopback transport
  • --tls β€” enable TLS encryption (TCP). πŸ”
  • --tls-key=<tls-key> β€” TLS key for the connection. It is recommended to preload keys into the system keyring instead of passing them via the command line. πŸ—οΈ
  • --tls-key-identity=<identity> β€” identity associated with the TLS key. πŸͺͺ

✨ GLOBAL OPTIONS ✨

Okay bestie, these ones live at the top level of the nvme command β€” like, they're the popular girls of the CLI β€” but they're all available to this subcommand too. πŸ’…

  • --dry-run β€” Shows you the command it would run and then... doesn't run it. It's giving look-but-don't-touch. Very safe, very demure. πŸŽ€
  • --no-ioctl-probing β€” Turns off probing for 64-bit IOCTL support. No probing, no poking, we simply do not ask. 🫢
  • --no-retries β€” Kills the retry logic on transient errors. One shot, no second chances, main character energy only. πŸ’€
  • -o <fmt>, --output-format=<fmt> β€” Sets the reporting format to normal, tabular, json, or binary. Only one output format at a time, please β€” we don't do mixed aesthetics. πŸ”₯
  • --output-format-version=<version> β€” Picks which version of the output format you want. Version 1 keeps the original field naming, while version 2 (that's the default, iykyk) gives you more consistent and script-friendly field names. Any other version? Rejected. Not even a little bit sorry. πŸ™ˆ
  • --quiet β€” Suppresses informational messages. Errors still get reported (we're not hiding the tea), and --quiet cancels any --verbose for the library log level. They literally cannot coexist. 😭
  • --set-options=<key=value>[,<key=value>...] β€” Sets libnvme library options just for this invocation. The supported keys are force-4k, mi-probe-enabled, test-base-dir and test-sysfs-dir. Slay, custom configuration. 🌸
  • --timeout=<ms> β€” Sets the timeout for the command in milliseconds. infinite or -1 waits with no time limit at all (0xffffffff) β€” literally forever, bestie, no cap. ⭐
  • -v, --verbose β€” Cranks up the detail in the output. You can specify it multiple times to get even more verbosity, which is honestly iconic of it. πŸ‘‘
Fun fact bestie: all of these can also be set as machine-wide defaults in nvme-cli.conf(5). And a command-line flag always overrides the file β€” the flag wins, periodt. πŸ’–

🌈 EXAMPLES 🌈

Like, actual examples, because reading about it is one thing and doing it is another:

  • Query the Discover Controller with IP4 address 192.168.1.3 for all resources allocated for NVMe Host name host1-rogue-nqn on the RDMA network. Port 4420 is used by default:
# nvme discover --transport=rdma --traddr=192.168.1.3 \
--hostnqn=host1-rogue-nqn
  • Issue a nvme discover command using the default system defined NBFT tables:
# nvme discover --nbft
  • Issue a nvme discover command with a user-defined path for the NBFT table:
# nvme discover --nbft-path=/sys/firmware/acpi/tables/NBFT1
  • Issue a nvme discover command using a /usr/local/etc/nvme/discovery.conf file:
# Machine default 'nvme discover' commands. Query the
# Discovery Controller's two ports (some resources may only
# be accessible on a single port). Note an official
# nqn (Host) name defined in the NVMe specification is being used
# in this example.
-t rdma -a 192.168.69.33 -s 4420 -q nqn.2014-08.com.example:nvme:nvm-subsystem-sn-d78432
-t rdma -a 192.168.1.4   -s 4420 -q nqn.2014-08.com.example:nvme:nvm-subsystem-sn-d78432

At the prompt type "nvme discover". That's it. That's the whole vibe check. ✨


πŸ¦‹ SEE ALSO πŸ¦‹

Go give these icons some love too:


πŸ’œ AUTHORS πŸ’œ

This was written by Jay Freyensee[1]. Respect the author, bestie. 🫢


πŸŽ€ NVME πŸŽ€

Part of the nvme-user suite. One big happy family. 🌸


πŸ“ NOTES πŸ“

  1. Jay Freyensee mailto:james.p.freyensee@intel.com

And that's the whole page, bestie β€” go forth and discover. 🧚 This little masterpiece is part of the NVMe suite, dated 10/30/2026, and it's genuinely so iconic of it. Mwah. πŸ’‹πŸ‘‘

πŸ“¦ where this page comes from