fix replication with '0' named bookmarks

This commit is contained in:
Christoph Klaffl 2026-02-18 14:57:38 +01:00
parent 1ae8f26e82
commit 3a1a19b39b
No known key found for this signature in database
GPG Key ID: 8FC1D76EED4970D2
2 changed files with 52 additions and 4 deletions

View File

@ -575,7 +575,7 @@ sub syncdataset {
my $targetsize = getzfsvalue($targethost,$targetfs,$targetisroot,'-p used'); my $targetsize = getzfsvalue($targethost,$targetfs,$targetisroot,'-p used');
my $bookmark = 0; my $bookmark = '';
my $bookmarkcreation = 0; my $bookmarkcreation = 0;
$matchingsnap = getmatchingsnapshot($sourcefs, $targetfs, \%snaps); $matchingsnap = getmatchingsnapshot($sourcefs, $targetfs, \%snaps);
@ -596,7 +596,7 @@ sub syncdataset {
} }
} }
if (! $bookmark) { if ($bookmark eq '') {
# force delete is not possible for the root dataset # force delete is not possible for the root dataset
if ($args{'force-delete'} && index($targetfs, '/') != -1) { if ($args{'force-delete'} && index($targetfs, '/') != -1) {
writelog('INFO', "Removing $targetfs because no matching snapshots were found"); writelog('INFO', "Removing $targetfs because no matching snapshots were found");
@ -669,7 +669,7 @@ sub syncdataset {
my $nextsnapshot = 0; my $nextsnapshot = 0;
if ($bookmark) { if ($bookmark ne '') {
my $bookmarkescaped = escapeshellparam($bookmark); my $bookmarkescaped = escapeshellparam($bookmark);
if (!defined $args{'no-stream'}) { if (!defined $args{'no-stream'}) {
@ -727,7 +727,7 @@ sub syncdataset {
# do a normal replication if bookmarks aren't used or if previous # do a normal replication if bookmarks aren't used or if previous
# bookmark replication was only done to the next oldest snapshot # bookmark replication was only done to the next oldest snapshot
# edge case: skip repilcation if bookmark replication used the latest snapshot # edge case: skip repilcation if bookmark replication used the latest snapshot
if ((!$bookmark || $nextsnapshot) && !($matchingsnap eq $newsyncsnap)) { if (($bookmark eq '' || $nextsnapshot) && !($matchingsnap eq $newsyncsnap)) {
($exit, $stdout) = syncincremental($sourcehost, $sourcefs, $targethost, $targetfs, $matchingsnap, $newsyncsnap, defined($args{'no-stream'})); ($exit, $stdout) = syncincremental($sourcehost, $sourcefs, $targethost, $targetfs, $matchingsnap, $newsyncsnap, defined($args{'no-stream'}));

View File

@ -0,0 +1,48 @@
#!/bin/bash
# test replication with fallback to bookmarks and special named snapshot/bookmark '0'
set -x
set -e
. ../../common/lib.sh
POOL_IMAGE="/tmp/syncoid-test-013.zpool"
POOL_SIZE="200M"
POOL_NAME="syncoid-test-013"
TARGET_CHECKSUM="b927125d2113c8da1a7f0181516e8f57fee5d268bdd5386d6ff7ddf31d6d6a35 -"
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@0
# initial replication
../../../syncoid --no-sync-snap --create-bookmark --debug --compress=none "${POOL_NAME}"/src "${POOL_NAME}"/dst
# destroy last common snapshot on source
zfs destroy "${POOL_NAME}"/src@0
zfs snapshot "${POOL_NAME}"/src@1
# replicate which should fallback to bookmarks
../../../syncoid --no-sync-snap --create-bookmark --debug --compress=none "${POOL_NAME}"/src "${POOL_NAME}"/dst
# verify
output=$(zfs list -t snapshot -r -H -o name "${POOL_NAME}"; zfs list -t bookmark -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