Skip to content

Commit 84304c7

Browse files
schmidt-scaledclaude
authored andcommitted
lvol: block all LVS ports (all roles) on network-outage self-detection
spdk_lvs_change_leader_state gated the whole block sequence (freeze, block_port, add_reject_hublvol_port, leadership drop) on lvs->leader, so on a JC-detected network outage only the current leaders blocked their ports. But leadership can move during an outage — e.g. the primary goes offline while a node is partitioned, so on recovery the secondary is the new leader — leaving a follower's port unblocked while it comes back with stale redirect/leadership state (2026-07-07 soak: LVS_1 tertiary served IO paths it could not forward, then failed over into the live secondary leader). Scope the change to the network-outage path only: that caller uniquely enters with groupid == 0 (api_bdev_distrib_set_non_leader() no-arg, from the JC network-outage detector), whereas the writer-conflict and targeted JC-signal callers pass a non-zero jm_vuid. So when groupid == 0, run the full block for every LVS regardless of lvs->leader (the leadership-drop lines are no-ops on a follower; freeze + block_port + hublvol-port reject run the same as for a leader, subject to the existing node_role != NODE_TERTIARY guard). Non-zero groupid (conflict) is unchanged. No new unblock needed: the hublvol-port reject self-clears via the existing 10s spdk_lvs_remove_rules_poller; the subsystem block_port is unblocked by the control plane on recovery (which now reopens all of the node's LVS ports). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent 06896dc commit 84304c7

1 file changed

Lines changed: 13 additions & 1 deletion

File tree

lib/lvol/lvol.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3528,8 +3528,20 @@ spdk_lvs_change_leader_state(uint64_t groupid)
35283528
int rc = 0;
35293529
SPDK_NOTICELOG("Attempting to change leadership state internally groupid %" PRIu64 ".\n", groupid);
35303530
pthread_mutex_lock(&g_lvol_stores_mutex);
3531+
/*
3532+
* groupid == 0 is the network-outage path: the JC lost quorum and called
3533+
* api_bdev_distrib_set_non_leader() with no jm_vuid (alg_journal.cpp
3534+
* network-outage detection). In that case block ALL of this node's LVS
3535+
* ports regardless of role/leadership -- leadership can move during the
3536+
* outage (e.g. the primary goes offline while partitioned, so the
3537+
* secondary becomes the new leader on recovery), so a follower's port
3538+
* must be blocked too. For non-leaders the leadership-drop below is a
3539+
* no-op; the freeze + block_port + hublvol-port reject still run, which
3540+
* is the intended "same as leader" behaviour on outage. Non-zero groupid
3541+
* (writer-conflict / targeted JC signal) stays leader-only, unchanged.
3542+
*/
35313543
TAILQ_FOREACH(lvs, &g_lvol_stores, link) {
3532-
if ((lvs->groupid == groupid || groupid == 0) && lvs->leader) {
3544+
if ((lvs->groupid == groupid || groupid == 0) && (lvs->leader || groupid == 0)) {
35333545
lvs->queue_failed_rsp = true;
35343546
if (spdk_blob_freeze_on_conflict_send_msg(lvs->blobstore,
35353547
spdk_lvs_conflict_signal, lvs)) {

0 commit comments

Comments
 (0)