Skip to content

libnvme: extract fabrics-specific logic into tree-fabrics.c#3365

Merged
igaw merged 3 commits into
linux-nvme:masterfrom
martin-belanger:extract-tree-fabrics
May 16, 2026
Merged

libnvme: extract fabrics-specific logic into tree-fabrics.c#3365
igaw merged 3 commits into
linux-nvme:masterfrom
martin-belanger:extract-tree-fabrics

Conversation

@martin-belanger
Copy link
Copy Markdown

Summary

tree.c currently mixes PCIe/generic tree management with NVMe-oF-specific logic, including TCP address matching, TLS/DHChap sysfs readers, and controller lookup helpers that are only meaningful in a fabrics context. This series begins extracting that fabrics-specific code into a new tree-fabrics.c, compiled only when want_fabrics=true, following the existing *-fabrics.c convention already established by util-fabrics.c and accessors-fabrics.c.

This is a preparation PR. Phases 1–3 are included here. Phase 4 (moving the full ctrl-find cluster: libnvme_lookup_ctrl, libnvme_candidate_init, libnvme_ctrl_find, libnvme_tree_ctrl_match) will follow in a separate series once the libnvmf_context coupling in libnvme_ctrl_alloc() has been resolved.

What this series does

Phase 1 — Create tree-fabrics.c, eliminate #ifdef CONFIG_FABRICS from tree.c

  • Creates src/nvme/tree-fabrics.c and wires it into src/meson.build.
  • Moves the five _tcp_* static matching functions out of tree.c.
  • Extracts the TCP/RDMA transport-selection block from _candidate_init() into a new libnvmf_candidate_init() hook called from the generic path.
  • Adds a libnvmf_candidate_init() stub to no-fabrics.c (returns NULL).
  • Moves struct candidate_args and the ctrl_match_t typedef to private-fabrics.h.
  • After this phase, tree.c has zero #ifdef CONFIG_FABRICS guards.

Phase 2 — Move TLS/DHChap sysfs readers

  • Moves libnvmf_read_sysfs_dhchap(), libnvmf_read_sysfs_tls(), and libnvmf_read_sysfs_tls_mode() from tree.c to tree-fabrics.c as static helpers, behind a single non-static wrapper libnvmf_read_sysfs_fabrics_attrs().
  • libnvme_reconfigure_ctrl() in tree.c is updated to call the wrapper.
  • A no-op stub is added to no-fabrics.c.
  • These attributes only exist on NVMe-oF controllers; in PCIe-only builds the sysfs reads were compiled in but never returned data — now they are excluded entirely.

Phase 3 — Move libnvmf_ctrl_match_config and libnvmf_ctrl_find; rename cleanup

  • libnvmf_ctrl_match_config() (previously _libnvme_ctrl_match_config) and libnvmf_ctrl_find() (previously the 2-param libnvme_ctrl_find) are moved to tree-fabrics.c. Both are purely fabrics-facing (all callers are in fabrics.c).
  • libnvme_ctrl_match_config() is dropped from the public API entirely. It was exported in libnvme.ld but had no external callers — nvme-cli does not call it, and nvme-stas goes through the Python bindings. It was dead API.
  • All underscore-prefixed functions that became non-static (crossing file boundaries) are renamed to use proper libnvme_ / libnvmf_ prefixes: __nvme_ctrl_findlibnvme_ctrl_find (3-param), _candidate_initlibnvme_candidate_init, _tree_ctrl_matchlibnvme_tree_ctrl_match, _libnvme_create_ctrllibnvme_create_ctrl.
  • _discovery_config_json() in fabrics.c is made static (it was accidentally non-static despite being file-local).
  • No new stubs are needed in no-fabrics.c — the moved functions have no callers outside the fabrics layer.

What remains for the follow-up series (Phase 4)

The following functions still live in tree.c because libnvme_lookup_ctrl() is called by both fabrics.c and libnvme_ctrl_alloc() (which constructs a libnvmf_context as a parameter bag for all transport types, including PCIe). This coupling prevents libnvme_lookup_ctrl() and its dependencies from moving cleanly:

  • libnvme_lookup_ctrl()
  • libnvme_candidate_init()
  • libnvme_ctrl_find() (3-param)
  • libnvme_tree_ctrl_match()

Phase 4 will introduce a PCIe-specific path in libnvme_ctrl_alloc() that does not go through libnvmf_context, after which the full ctrl-find cluster can move to tree-fabrics.c and tree.c will no longer need to include private-fabrics.h.

@martin-belanger
Copy link
Copy Markdown
Author

@igaw - Note: One class of checkpatch warning could not be resolved without introducing a different warning. The test file uses printf("test_foo:\n") to label test sections. Checkpatch flags this with "Prefer using __func__". Switching to printf("%s:\n", __func__) eliminates that warning but immediately triggers "ftrace-like logging detected". There is no form that satisfies both checks simultaneously, so the hardcoded function-name strings were kept.

Comment thread libnvme/src/nvme/private-fabrics.h Outdated
@igaw
Copy link
Copy Markdown
Collaborator

igaw commented May 15, 2026

I like it :)

We should check if the kdoc is actually showing up in the API doc, if not than this is good to go, otherwise I would say it's good time to address it when the code is moved around. I guess it is then '/* */' style doc.

Martin Belanger added 3 commits May 15, 2026 14:56
Move transport-specific ctrl matching code out of tree.c:
- TCP matching functions and _candidate_init_fabrics() move to
  tree-fabrics.c (compiled only when CONFIG_FABRICS is set)
- _match_ctrl() renamed to _tree_ctrl_match() (non-static) so it
  can be referenced from tree-fabrics.c
- no-fabrics.c gets a _candidate_init_fabrics() stub returning NULL
- streq0()/streqcase0() helpers move to private.h where both tree.c
  and tree-fabrics.c can reach them without an extra include
- struct candidate_args / ctrl_match_t / related declarations move
  to private-fabrics.h; the iface_list field stays conditionally
  compiled on HAVE_NETDB||CONFIG_FABRICS while the rest of the
  struct is unconditional (portability fix for musl/HAVE_NETDB=0)

Tests:
- test/tree.c renamed to test/tree-fabrics.c (fabrics-only); move its
  meson registration under if want_fabrics inside the HAVE_NETDB block
- test/tree-fabrics.c extended with 7 new test functions covering
  PCIe/loop matching, well-known NQN, "none" normalization, RDMA/FC
  config matching, and pagination
- new test/tree.c added with 7 non-fabrics tests for host/subsystem
  creation, deduplication, iteration, and attribute getters; always
  compiled regardless of fabrics config

Signed-off-by: Martin Belanger <Martin.Belanger@dell.com>
Assisted-by: Claude:claude-sonnet-4-6 [Claude Code]
libnvme_read_sysfs_dhchap(), libnvme_read_sysfs_tls(), and
libnvme_read_sysfs_tls_mode() are fabrics-only — the sysfs attributes
they read (dhchap_secret, tls_key, tls_mode, …) are never present on
PCIe controllers. Move them to tree-fabrics.c as static helpers under
a single non-static wrapper libnvmf_read_sysfs_fabrics_attrs(), and
rename all four with the libnvmf_ prefix to reflect their scope.

Declare the wrapper in private-fabrics.h; add a no-op stub in
no-fabrics.c. libnvme_reconfigure_ctrl() in tree.c now calls the
wrapper instead of the three individual functions.

Signed-off-by: Martin Belanger <Martin.Belanger@dell.com>
Assisted-by: Claude:claude-sonnet-4-6 [Claude Code]
libnvme_ctrl_find() and _libnvme_ctrl_match_config() are only called
from fabrics.c and are therefore fabrics-only. Rename them to
libnvmf_ctrl_find() and _libnvmf_ctrl_match_config() to make that
scope explicit.

libnvme_ctrl_match_config() was the public wrapper around
_libnvme_ctrl_match_config(). It was exported in libnvme.ld but has no
callers outside of the library itself. Drop it entirely rather than
carry it as dead public API. The internal _libnvmf_ctrl_match_config()
is sufficient.

Move the two remaining internal declarations from private.h to
private-fabrics.h, where they belong alongside the other
fabrics-internal helpers.

Signed-off-by: Martin Belanger <Martin.Belanger@dell.com>
Assisted-by: Claude:claude-sonnet-4-6 [Claude Code]
@martin-belanger
Copy link
Copy Markdown
Author

martin-belanger commented May 15, 2026

We should check if the kdoc is actually showing up in the API doc, if not than this is good to go, otherwise I would say it's good time to address it when the code is moved around. I guess it is then '/* */' style doc.

The kdoc in private-fabrics.h does not show up in the API docs. The doc build (doc/meson.build) feeds only the public headers to kernel-doc, and private-fabrics.h is not among them. So we're good to go.

@igaw
Copy link
Copy Markdown
Collaborator

igaw commented May 16, 2026

Great cleanup. I like it! Thanks!

@igaw igaw merged commit 27cbebd into linux-nvme:master May 16, 2026
28 of 29 checks passed
@martin-belanger martin-belanger deleted the extract-tree-fabrics branch May 16, 2026 11:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants