From 7141eab594ff8a362f2e4f3a8565eab699ce1f7e Mon Sep 17 00:00:00 2001 From: Christoph Klaffl Date: Wed, 30 Jan 2019 23:49:38 +0100 Subject: [PATCH] fix bookmark edge case where replication was already done to the latest snapshot (+ test) --- syncoid | 5 ++ .../4_bookmark_replication_edge_case/run.sh | 46 +++++++++++++++++++ 2 files changed, 51 insertions(+) create mode 100755 tests/syncoid/4_bookmark_replication_edge_case/run.sh diff --git a/syncoid b/syncoid index 3f6f9ba..812c733 100755 --- a/syncoid +++ b/syncoid @@ -654,6 +654,11 @@ sub syncdataset { # do a normal replication if bookmarks aren't used or if previous # bookmark replication was only done to the next oldest snapshot if (!$bookmark || $nextsnapshot) { + if ($matchingsnap eq $newsyncsnap) { + # edge case: bookmark replication used the latest snapshot + return 0; + } + my $sendcmd = "$sourcesudocmd $zfscmd send $sendoptions $args{'streamarg'} $sourcefsescaped\@$matchingsnapescaped $sourcefsescaped\@$newsyncsnapescaped"; my $recvcmd = "$targetsudocmd $zfscmd receive $recvoptions $receiveextraargs $forcedrecv $targetfsescaped"; my $pvsize = getsendsize($sourcehost,"$sourcefs\@$matchingsnap","$sourcefs\@$newsyncsnap",$sourceisroot); diff --git a/tests/syncoid/4_bookmark_replication_edge_case/run.sh b/tests/syncoid/4_bookmark_replication_edge_case/run.sh new file mode 100755 index 0000000..2a93ce4 --- /dev/null +++ b/tests/syncoid/4_bookmark_replication_edge_case/run.sh @@ -0,0 +1,46 @@ +#!/bin/bash + +# test replication edge cases with bookmarks + +set -x +set -e + +. ../../common/lib.sh + +POOL_IMAGE="/tmp/syncoid-test-4.zpool" +POOL_SIZE="200M" +POOL_NAME="syncoid-test-4" +TARGET_CHECKSUM="ad383b157b01635ddcf13612ac55577ad9c8dcf3fbfc9eb91792e27ec8db739b -" + +truncate -s "${POOL_SIZE}" "${POOL_IMAGE}" + +zpool create -m none -f "${POOL_NAME}" "${POOL_IMAGE}" + +function cleanUp { + zpool export "${POOL_NAME}" +} + +# export pool in any case +trap cleanUp EXIT + +zfs create "${POOL_NAME}"/src +zfs snapshot "${POOL_NAME}"/src@snap1 +zfs bookmark "${POOL_NAME}"/src@snap1 "${POOL_NAME}"/src#snap1 +# initial replication +../../../syncoid --no-sync-snap --debug --compress=none "${POOL_NAME}"/src "${POOL_NAME}"/dst +# destroy last common snapshot on source +zfs destroy "${POOL_NAME}"/src@snap1 +zfs snapshot "${POOL_NAME}"/src@snap2 + +# replicate which should fallback to bookmarks and stop because it's already on the latest snapshot +../../../syncoid --no-sync-snap --debug --compress=none "${POOL_NAME}"/src "${POOL_NAME}"/dst || exit 1 + +# verify +output=$(zfs list -t snapshot -r -H -o name "${POOL_NAME}") +checksum=$(echo "${output}" | grep -v syncoid_ | shasum -a 256) + +if [ "${checksum}" != "${TARGET_CHECKSUM}" ]; then + exit 1 +fi + +exit 0