libnvme: fix persistent discovery ctrl disconnect decisions - #3811
Merged
igaw merged 1 commit intoAug 11, 2026
Conversation
discover_lookup_ctrl_by_device() and discover_lookup_ctrl() forced fctx->persistent to FORCE whenever they found an already-connected discovery controller, regardless of what --persistent requested. This also poisoned persistence for every referral discovered in the same walk, not just the reused connection. Signed-off-by: Martin Belanger <martin.belanger@dell.com>
Mr-Bossman
reviewed
Aug 11, 2026
Contributor
|
LGTM this fixes the issue i brought up. |
Collaborator
|
Thanks! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-on fix to #3776.
nvme discover/nvme connect-allsit at the same level as orchestrators like nvme-discoverd and nvme-stas: they're convenience helpers that combine several decisions (lookup, connect, walk referrals, disconnect) rather than a single primitive operation likeconnect/disconnect. As orchestrators, they must not interfere with connections owned by another orchestrator -- if they find an existing connection while walking, they may reuse it to fetch its Discovery Log Page, but they must never disconnect it afterward, even under--persistent=no.--persistentdescribes what this invocation should do with the connections it creates; it says nothing about a connection it merely found already in place, which another orchestrator may be relying on to persist.Two related bugs violated that boundary. First,
discover_lookup_ctrl_by_device()anddiscover_lookup_ctrl()silently forcedfctx->persistenttoFORCEwhenever they found an already-connected discovery controller, regardless of what--persistentactually requested. Sincelibnvmf_discover()copiesfctxwholesale into every referral it walks (nfctx = *fctx), that override also poisoned persistence for every referral discovered in the same walk, not just the reused connection -- so a plain-p=noagainst a target with an already-connected discovery controller silently forced everything downstream to persist too.Second, the primary discovery connection (ie. primary = the first DC) itself never got a disconnect decision at all. Referrals get one from their parent, computed from the referral's own entry in the parent's log before ever connecting. The primary has no parent to do this for it, and every discovery controller's own EPCSD is only ever reported in its own Discovery Log Page, as a
SUBTYPE=03h("current discovery subsystem") entry describing itself --_nvmf_discover()discarded that entry as an ordinary already-connected match, without ever reading it. Fixed by extracting it and deciding, at the point the connection processes its own log, using the same FORCE/AUTO/NO logic already used for referrals. An absent self entry is treated asEPCSD=0, matching the spec's own definition of the bit: "not reported". This new decision only ever applies to a primary connection we created in this call -- if it was already connected when we found it, per the orchestrator-coexistence rule above, we never touch it.Verified via build (
-Dwerror=true),meson test, andmake checkpatch-diff, all clean.Not yet verified live -- @Mr-Bossman, would you mind testing this. Thanks.