fix(linstor): plunger demotes idle-Primary DRBD resources
DRBD auto-promotes a resource to Primary during the provisioning path (e.g. mkfs.ext4 against a freshly created replica), but auto-demote sometimes fails to fire on close. The resource then stays Primary on a node that has no consumer, and CSI on the legitimate target node fails NodePublishVolume with "failed to set source device readwrite". The only recovery is an explicit drbdadm secondary on the stuck node. Add a per-satellite plunger handler that detects local Primaries where every device has open == false and demotes them. Both the detection and the action are local to the satellite, so no peer coordination is needed. open:no makes drbdadm secondary safe; if a real consumer is about to arrive, auto-promote will redo it. Upstream tracker: piraeusdatastore/piraeus-operator#942 Co-Authored-By: Claude <noreply@anthropic.com> Signed-off-by: Andrei Kvapil <kvapss@gmail.com>
This commit is contained in:
parent
f45facca77
commit
a6ac0485a8
1 changed files with 31 additions and 0 deletions
|
|
@ -20,6 +20,34 @@ drbd_status_json() {
|
|||
drbdsetup status --json 2>/dev/null || true
|
||||
}
|
||||
|
||||
# Detect DRBD resources stuck in Primary on this node with no consumer.
|
||||
# Auto-promote can promote a resource to Primary (e.g. during mkfs.ext4
|
||||
# at provisioning time), but auto-demote sometimes fails to fire on
|
||||
# close. The resource then stays Primary on a node that has no
|
||||
# consumer and blocks NodePublishVolume on the actual target node with
|
||||
# "failed to set source device readwrite". Upstream tracker:
|
||||
# https://github.com/piraeusdatastore/piraeus-operator/issues/942
|
||||
#
|
||||
# `open == false` on every device of the resource guarantees nobody is
|
||||
# using it, so `drbdadm secondary` is safe — at worst it's a no-op
|
||||
# that auto-promote will redo when a real consumer arrives.
|
||||
drbd_fix_idle_primary() {
|
||||
local json
|
||||
json="$(drbd_status_json)"
|
||||
[ -n "$json" ] || return 0
|
||||
|
||||
printf '%s' "$json" | jq -r '
|
||||
.[]?
|
||||
| select(.role == "Primary")
|
||||
| select(all(.devices[]?; .open == false))
|
||||
| .name
|
||||
' | while IFS= read -r res; do
|
||||
[ -n "$res" ] || continue
|
||||
log "Idle Primary detected: res=$res open:no -> drbdadm secondary"
|
||||
drbdadm secondary "$res" || log "WARN: secondary failed for $res"
|
||||
done
|
||||
}
|
||||
|
||||
# Detect DRBD resources where resync is stuck:
|
||||
# - at least one local device is Inconsistent
|
||||
# - there is an active SyncTarget peer
|
||||
|
|
@ -154,6 +182,9 @@ while true; do
|
|||
drbdadm up "${secondary}" || echo "Command failed"
|
||||
); done
|
||||
|
||||
# Detect and demote idle Primary resources stuck after auto-promote
|
||||
drbd_fix_idle_primary || true
|
||||
|
||||
# Detect and fix stalled DRBD resync by switching SyncTarget peer
|
||||
drbd_fix_stalled_sync || true
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue