mirror of
https://github.com/bashclub/bashclub-zfs-push-pull.git
synced 2024-11-07 21:01:58 +01:00
Implement catchup mode to fix interrupted transfer
When zfs send -R is interrupted, some child filesystems will be at a more recent snapshot than their parent. There's then no way to do a zfs send -R from the root/parent, as the children are inconsistent. Catchup mode handles recursion on its own, instead of relying on zfs to do it. Basically picking a single consistent snapshot across the board, then bringing all to that level.
This commit is contained in:
parent
6d906ad640
commit
fcd5fb0e08
28
backup-zfs
28
backup-zfs
@ -57,6 +57,22 @@ ZFS() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# If initial zfs send -R is interrupted, it can't be resumed.
|
||||||
|
# Rolling back all filesystems to the last consistent snapshot ought
|
||||||
|
# to do the trick, but that's annoying to throw that data away.
|
||||||
|
catchup() {
|
||||||
|
srcparent="${srcfs%/*}" # all but last child component of srcfs
|
||||||
|
root="${srcfs#*/}" # last child component of srcfs
|
||||||
|
target="$(ZFS "$srchost" list -d 1 -t snapshot -H -S creation -o name $srcfs | cut -f2 -d@ | grep "^$tag" | head -n1)"
|
||||||
|
for fs in $(ZFS "$desthost" list -Ho name -r "$destfs/$root" | tac) ; do
|
||||||
|
child="${fs#$destfs/}"
|
||||||
|
destsnap=$(ZFS "$desthost" list -Ho name -S creation -d1 -t snapshot $destfs/$child | head -n1 | cut -f2 -d@)
|
||||||
|
if [[ $destsnap != $target ]] ; then
|
||||||
|
ZFS "$srchost" send $send_opts -R -I @$destsnap $srcparent/$child@$target | ZFS "$desthost" receive $recv_opts -Fue "$destfs/${child%/*}"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
###
|
###
|
||||||
### defaults
|
### defaults
|
||||||
###
|
###
|
||||||
@ -65,12 +81,14 @@ dateopts="+%F_%T"
|
|||||||
keep=5
|
keep=5
|
||||||
verbose=false
|
verbose=false
|
||||||
quiet=false
|
quiet=false
|
||||||
|
catchup=false
|
||||||
|
|
||||||
###
|
###
|
||||||
### parse options
|
### parse options
|
||||||
###
|
###
|
||||||
while getopts "hvqk:t:d:" opt ; do
|
while getopts "chvqk:t:d:" opt ; do
|
||||||
case $opt in
|
case $opt in
|
||||||
|
c) catchup=true ;;
|
||||||
h) usage 0 ;;
|
h) usage 0 ;;
|
||||||
v)
|
v)
|
||||||
verbose=true
|
verbose=true
|
||||||
@ -118,6 +136,14 @@ if [[ $(ZFS "$desthost" list -H -o name "$destfs" 2>/dev/null) != $destfs ]] ; t
|
|||||||
die 1 "destination fs '$destfs' doesn't exist"
|
die 1 "destination fs '$destfs' doesn't exist"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
###
|
||||||
|
### fix interrupted transfer
|
||||||
|
###
|
||||||
|
if $catchup ; then
|
||||||
|
catchup || die $? "catchup failed"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
###
|
###
|
||||||
### create new snapshot on src
|
### create new snapshot on src
|
||||||
###
|
###
|
||||||
|
Loading…
Reference in New Issue
Block a user