summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-06-20 17:28:36 +0300
committerPaul Buetow <paul@buetow.org>2026-06-20 17:28:36 +0300
commitc9f06a21fb1daa74c9db341636a2c4b118bda1d8 (patch)
treec99369f8da6b3ef49850d92d0396caa00d7d8f99
parent6c13b6a253aec415b8ad850df4abfcecc8efbcd7 (diff)
carp: rollback sink to last snapshot on BACKUP transition
After a CARP failover where f1 serves as MASTER, any NFS writes go to the sink dataset (zdata/sink/f0/zdata/enc/nfsdata). When f1 returns to BACKUP, zfs receive from f0 fails with "destination has been modified since most recent snapshot" because the filesystem state is ahead of the last received snapshot. Fix: on BACKUP transition, roll the sink back to the last zrepl snapshot before setting readonly=on. Writes during the MASTER window (health checks, test writes) are intentionally discarded — f0 is authoritative and replication resumes cleanly from the common snapshot. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
-rw-r--r--f3s/freebsd-hosts/carp/carpcontrol.sh17
1 files changed, 14 insertions, 3 deletions
diff --git a/f3s/freebsd-hosts/carp/carpcontrol.sh b/f3s/freebsd-hosts/carp/carpcontrol.sh
index 6caa447..527699b 100644
--- a/f3s/freebsd-hosts/carp/carpcontrol.sh
+++ b/f3s/freebsd-hosts/carp/carpcontrol.sh
@@ -44,10 +44,21 @@ case "$2" in
service nfsd stop >/dev/null 2>&1
service mountd stop >/dev/null 2>&1
service nfsuserd stop >/dev/null 2>&1
- # Restore readonly=on on the sink dataset so that zrepl can resume
- # writing incoming snapshot data from f0.
+ # Restore the sink dataset for zrepl replication from f0.
+ # Any writes made while MASTER must be rolled back to the last
+ # received snapshot; otherwise zfs receive fails with "destination
+ # has been modified since most recent snapshot". Data written
+ # during the MASTER window is transient (health checks, test writes)
+ # and is intentionally discarded here.
if [ "$HOSTNAME" != 'f0.lan.buetow.org' ]; then
- zfs set readonly=on zdata/sink/f0/zdata/enc/nfsdata
+ SINK="zdata/sink/f0/zdata/enc/nfsdata"
+ LAST_SNAP=$(zfs list -t snapshot -Ho name "$SINK" 2>/dev/null | tail -1)
+ if [ -n "$LAST_SNAP" ]; then
+ zfs rollback "$LAST_SNAP" && \
+ logger "CARP BACKUP: rolled back $SINK to $LAST_SNAP" || \
+ logger "CARP BACKUP: WARNING rollback of $SINK to $LAST_SNAP failed"
+ fi
+ zfs set readonly=on "$SINK"
fi
logger "CARP BACKUP: NFS and stunnel services stopped"
;;