drbd-dev.lists.linux.dev archive mirror
 help / color / mirror / Atom feed
From: Su Yue <glass.su@suse.com>
To: drbd-dev@lists.linbit.com, drbd-dev@lists.linux.dev
Cc: philipp.reisner@linbit.com, lars.ellenberg@linbit.com,
	christoph.boehmwalder@linbit.com, joel.colledge@linbit.com,
	Su Yue <glass.su@suse.com>, Heming Zhao <heming.zhao@suse.com>,
	Claude Fable 5 <noreply@anthropic.com>,
	Gemini <gemini-code-assist@google.com>
Subject: [PATCH RESEND] drbd: consider resync after peer forced Primary from Outdated/Outdated
Date: Wed, 12 Aug 2026 08:46:31 +0800	[thread overview]
Message-ID: <20260812004631.83718-1-glass.su@suse.com> (raw)

When a node is force-promoted to Primary with --force while both nodes
are Outdated, it generates a new current data generation UUID.

If they are connected, the state change transition updates the peer disk
state to UpToDate. However, because if both nodes were Outdated,
the state machine does not automatically trigger a sync handshake
(the CONSIDER_RESYNC flag is only set if both disks were D_INCONSISTENT).

CONSIDER_RESYNC was only armed when both sides' previous disk state was
D_INCONSISTENT. When both disks are D_OUTDATED instead (e.g. after both
nodes were explicitly outdated and reconnected) and one side is then
force-promoted to Primary/D_UP_TO_DATE, only the promoted node redoes
the UUID handshake and moves to L_WF_BITMAP_S. The peer never arms
CONSIDER_RESYNC, stays in L_ESTABLISHED, and drops the
incoming bitmap in receive_bitmap() with "unexpected repl_state
(Established) in receive_bitmap". The two nodes then diverge
permanently: the Primary stuck at WFBitMapS/Consistent, the Secondary
falsely reporting UpToDate/UpToDate.

To reproduce:
====================================
ssh node2 drbdadm down drbd0
sleep 1
drbdadm down drbd0
sleep 1
drbdadm outdate drbd0 && drbdadm up drbd0
sleep 1
ssh node2 "drbdadm outdate drbd0 && drbdadm up drbd0 "
sleep 1
drbdadm status
echo "node2 drbdadm status:"
ssh node2 drbdadm status
drbdadm primary --force drbd0
drbdadm status
ssh node2 drbdadm status
====================================

Fix this by expanding the CONSIDER_RESYNC check in finish_state_change()
to also cover D_OUTDATED disk states when the peer is force-promoted to
Primary and UpToDate. This successfully triggers the subsequent handshake,
completing the resync and elevating both nodes disks to UpToDate cleanly.

Signed-off-by: Su Yue <glass.su@suse.com>
Reviewed-by: Heming Zhao <heming.zhao@suse.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Gemini <gemini-code-assist@google.com>
---
 drbd/drbd_state.c | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/drbd/drbd_state.c b/drbd/drbd_state.c
index e7f9cab01c58..73cd2807d1fc 100644
--- a/drbd/drbd_state.c
+++ b/drbd/drbd_state.c
@@ -3147,9 +3147,16 @@ static void finish_state_change(struct drbd_resource *resource, const char *tag)
 					}
 				}
 
-				/* Peer was forced D_UP_TO_DATE & R_PRIMARY, consider to resync */
-				if (disk_state[OLD] == D_INCONSISTENT &&
-				    peer_disk_state[OLD] == D_INCONSISTENT && peer_disk_state[NEW] == D_UP_TO_DATE &&
+				/* Peer was forced D_UP_TO_DATE & R_PRIMARY, consider to resync.
+				 * Also cover D_OUTDATED, not just D_INCONSISTENT: e.g. after both
+				 * nodes were D_OUTDATED (both --outdate'd, then reconnected) and
+				 * one side is force-promoted to Primary/D_UP_TO_DATE, we still
+				 * need to redo the handshake here, or we get stuck: the newly
+				 * forced Primary moves on to L_WF_BITMAP_S and sends its bitmap,
+				 * while we never armed CONSIDER_RESYNC and stay in L_ESTABLISHED. */
+				if ((disk_state[OLD] == D_INCONSISTENT || disk_state[OLD] == D_OUTDATED) &&
+				    (peer_disk_state[OLD] == D_INCONSISTENT || peer_disk_state[OLD] == D_OUTDATED) &&
+				    peer_disk_state[NEW] == D_UP_TO_DATE &&
 				    peer_role[OLD] == R_SECONDARY && peer_role[NEW] == R_PRIMARY)
 					set_bit(CONSIDER_RESYNC, &peer_device->flags);
 
-- 
2.54.0


                 reply	other threads:[~2026-08-12  0:46 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260812004631.83718-1-glass.su@suse.com \
    --to=glass.su@suse.com \
    --cc=christoph.boehmwalder@linbit.com \
    --cc=drbd-dev@lists.linbit.com \
    --cc=drbd-dev@lists.linux.dev \
    --cc=gemini-code-assist@google.com \
    --cc=heming.zhao@suse.com \
    --cc=joel.colledge@linbit.com \
    --cc=lars.ellenberg@linbit.com \
    --cc=noreply@anthropic.com \
    --cc=philipp.reisner@linbit.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).