fix(ha): use drbdmeta --force directly; fix T4 grep-c arithmetic bug
Check NixOS configurations / eval-hosts (push) Successful in 10m21s

cluster-init.sh: replace 'drbdadm create-md --force' with direct drbdmeta
calls using --force on both steps.  drbdadm create-md --force passes --force
to the create-md sub-call but NOT to write-dev-uuid, which then fails when
/dev/sdb is busy and stdin is not a TTY ("stdin not a TTY, not waiting for
confirmation" → exit 20).  write-dev-uuid failing means DRBD has no UUID,
so the peer can't identify the device → connection fails → no sync → wrong
Active node detected by acceptance tests.

acceptance-tests.sh T4: grep -c returns exit code 1 when the count is 0
(no matches), triggering '|| echo "0"' and producing "0\n0" which breaks
[[ "$IQN_COUNT" -ge 1 ]] with "arithmetic syntax error".  Fixed by running
the pipe inside bash -c with '|| true' on the grep to suppress the
non-zero exit code.  Same fix applied to T5's IQN_ON_STANDBY check.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-07-28 23:09:06 +10:00
co-authored by Claude Sonnet 4.6
parent a98955a8da
commit a7c4a24fc3
2 changed files with 18 additions and 6 deletions
+2 -2
View File
@@ -97,7 +97,7 @@ fi
# ── T4: iSCSI target visible on Active node ───────────────────────────────
echo ""
echo "[T4] iSCSI target"
IQN_COUNT=$(na "ls /sys/kernel/config/target/iscsi/ 2>/dev/null | grep -c iqn" || echo "0")
IQN_COUNT=$(na "bash -c 'ls /sys/kernel/config/target/iscsi/ 2>/dev/null | grep -c iqn || true'" 2>/dev/null || echo "0")
if [[ "$IQN_COUNT" -ge 1 ]]; then
pass "iSCSI IQN active on $ACTIVE_NODE ($IQN_COUNT target(s))"
else
@@ -130,7 +130,7 @@ done
if $MOVED; then
pass "XFS mounted on $STANDBY_NODE after failover"
IQN_ON_STANDBY=$(ns "ls /sys/kernel/config/target/iscsi/ 2>/dev/null | grep -c iqn" || echo "0")
IQN_ON_STANDBY=$(ns "bash -c 'ls /sys/kernel/config/target/iscsi/ 2>/dev/null | grep -c iqn || true'" 2>/dev/null || echo "0")
[[ "$IQN_ON_STANDBY" -ge 1 ]] \
&& pass "iSCSI target active on $STANDBY_NODE after failover" \
|| fail "iSCSI target NOT active on $STANDBY_NODE after failover"
+16 -4
View File
@@ -164,13 +164,25 @@ n2_ssh "drbdadm down ha-data 2>/dev/null || true"
sleep 2
log "Initialising DRBD metadata on $NODE1..."
if ! drbdadm dstate ha-data 2>/dev/null | grep -q "UpToDate\|Inconsistent\|Diskless"; then
drbdadm create-md ha-data --force
# Use drbdmeta --force directly for BOTH create-md and write-dev-uuid.
# drbdadm create-md --force passes --force to drbdmeta create-md but NOT to
# the write-dev-uuid sub-call it makes internally, so write-dev-uuid fails when
# /dev/sdb is still busy (udev auto-attach, stale DRBD state, etc.) and stdin
# is not a TTY: "stdin not a TTY, not waiting for confirmation" → exit 20.
# Calling drbdmeta --force directly bypasses the exclusive-open confirmation on
# both steps without needing a TTY, regardless of whether the device is busy.
if ! drbdadm dstate ha-data 2>/dev/null | grep -q "UpToDate"; then
UUID1=$(openssl rand -hex 8 2>/dev/null | tr '[:lower:]' '[:upper:]')
drbdmeta --force 0 v08 /dev/sdb internal create-md
drbdmeta --force 0 v08 /dev/sdb internal write-dev-uuid "$UUID1"
fi
log "Initialising DRBD metadata on $NODE2..."
# Use grep -E for ERE alternation inside the remote bash -c string (avoids \| quoting issues).
n2_ssh "bash -c 'drbdadm dstate ha-data 2>/dev/null | grep -qE \"UpToDate|Inconsistent|Diskless\" || drbdadm create-md ha-data --force'"
if ! n2_ssh "drbdadm dstate ha-data 2>/dev/null | grep -q UpToDate" 2>/dev/null; then
UUID2=$(openssl rand -hex 8 2>/dev/null | tr '[:lower:]' '[:upper:]')
n2_ssh "drbdmeta --force 0 v08 /dev/sdb internal create-md"
n2_ssh "drbdmeta --force 0 v08 /dev/sdb internal write-dev-uuid '${UUID2}'"
fi
log "Bringing up DRBD on both nodes..."
drbdadm up ha-data 2>/dev/null || true