Skip to content

Commit 586287e

Browse files
committed
Implement --send-fallback for the snapshot replication.
This allows a --send-incr to fallback to --send-full if it can't find an earlier snapshot.
1 parent 49b2b5f commit 586287e

File tree

2 files changed

+35
-6
lines changed

2 files changed

+35
-6
lines changed

src/zfs-auto-snapshot.8

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,11 @@ Send zfs full backup to remote hostname (or IP address) and put it in remote po
5252
\fB\-\-send\-incr\fR=[\fIremote host\fR]:[\fIremote pool\fR]
5353
Send zfs incremental backup to remote hostname (or IP address) and put it in remote pool.
5454
.TP
55+
\fB\-\-send\-fallback\fR
56+
Allow to fallback from incremental to full snapshot replication.
57+
.sp
58+
This implies \fI-R\fR to \fBzfs send\fR and \fI-F\fR to \fBzfs receive\fR.
59+
.TP
5560
\fB\-\-send\-opts\fR=\fIOPTS\fR
5661
Option(s) passed to 'zfs send'.
5762
.TP

src/zfs-auto-snapshot.sh

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ opt_send_opts=''
4141
opt_recv_opts=''
4242
opt_send_ssh_opts=''
4343
opt_send_mbuf_opts=''
44+
opt_send_fallback=''
4445
opt_sep='_'
4546
opt_setauto=''
4647
opt_syslog=''
@@ -78,6 +79,7 @@ print_usage ()
7879
-q, --quiet Suppress warnings and notices at the console.
7980
--send-full=F Send zfs full backup.
8081
--send-incr=F Send zfs incremental backup.
82+
--send-fallback Fallback from incremental to full if needed.
8183
--send-opts=F Option(s) passed to 'zfs send'.
8284
--recv-opts=F Option(s) passed to 'zfs receive'.
8385
--send-ssh-opts Option(s) passed to 'ssh'.
@@ -230,8 +232,8 @@ do_send () # snapname, oldglob
230232
local jj
231233

232234
[ -n "$opt_send_mbuf_opts" ] && remote="mbuffer $opt_send_mbuf_opts |"
233-
remote="$remote ssh $opt_send_ssh_opts $opt_send_host "
234-
remote="$remote zfs receive $opt_recv_opts $opt_recv_pool"
235+
remote="$remote ssh $opt_send_ssh_opts $opt_send_host"
236+
remote="$remote zfs receive $opt_recv_opts"
235237

236238
# STEP 1: Go throug all snapshots we've created
237239
for ii in $SNAPS_DONE
@@ -262,22 +264,33 @@ do_send () # snapname, oldglob
262264
# 1: We change from incremental to full.
263265
# 2: We accept that the user have said INCR, and stick with
264266
# it.
265-
if [ "$opt_send_type" = "incr" -a -z "$last_snap" ]; then
267+
# Normally we do point 2, but if --send-fallback is specified,
268+
# we allow it and convert to a full send instead.
269+
if [ "$opt_send_type" = "incr" -a -z "$last_snap" -a -z "$opt_send_fallback" ]; then
266270
if [ -n "$opt_verbose" ]; then
267271
echo "WARNING: No previous snapshots exist but we where called"
268272
echo " with --send-incr. Can not continue."
269273
echo " Please rerun with --send-full."
274+
echo " Or use --send-fallback."
270275
fi
271276
return 1
272277
fi
273278

274-
if [ -n "$opt_recursive" -a -n "$last_snap" ]; then
279+
if [ -n "$opt_recursive" ]; then
275280
# STEP 3: Again, go through ALL snapshots that exists, but this
276281
# time only look for the snapshots that 'starts with'
277282
# the dataset/volume in question AND 'ends with'
278283
# the exact snapshot name/date in step 2.
279284
for jj in $SNAPSHOTS_OLD
280285
do
286+
# When trying to find snapshots recurively, we MUST have a 'last_snap'
287+
# value. Othervise, it will match ALL snapshots for dset (if we had
288+
# used '"^$dset.*@$GLOB" only).
289+
if [ -z "$last_snap" ] && echo "$jj" | grep -qE "^$dset.*@$GLOB"; then
290+
# Use this as last snapshot name
291+
last_snap="${jj#*@}"
292+
fi
293+
281294
if echo "$jj" | grep -qE "^$dset.*@$last_snap"; then
282295
SNAPS_SEND="$SNAPS_SEND
283296
$jj"
@@ -296,9 +309,15 @@ $jj"
296309

297310
if [ $RUNSEND -eq 1 ]; then
298311
if [ "$opt_send_type" = "incr" ]; then
299-
do_run "zfs send $opt_send_opts -i $jj $ii | $remote" || RUNSEND=0
312+
if [ "$jj" = "$ii" -a -n "$opt_send_fallback" ]; then
313+
do_run "zfs send $opt_send_opts -R $ii | $remote -F $opt_recv_pool" \
314+
|| RUNSEND=0
315+
else
316+
do_run "zfs send $opt_send_opts -i $jj $ii | $remote $opt_recv_pool" \
317+
|| RUNSEND=0
318+
fi
300319
else
301-
do_run "zfs send $opt_send_opts -R $jj | $remote" || RUNSEND=0
320+
do_run "zfs send $opt_send_opts -R $jj | $remote $opt_recv_pool" || RUNSEND=0
302321
fi
303322

304323
if [ $RUNSEND = 1 -a -n "$opt_post_send" ]; then
@@ -319,6 +338,7 @@ GETOPT=$(getopt \
319338
--longoptions=pre-snapshot:,post-snapshot:,destroy-only \
320339
--longoptions=send-full:,send-incr:,send-opts:,recv-opts: \
321340
--longoptions=send-ssh-opts:,send-mbuf-opts:,pre-send:,post-send: \
341+
--longoptions=send-fallback \
322342
--options=dnshe:l:k:p:rs:qgv \
323343
-- "$@" ) \
324344
|| exit 128
@@ -419,6 +439,10 @@ do
419439
opt_recv_pool=$(echo "$2" | sed 's,.*:,,')
420440
shift 2
421441
;;
442+
(--send-fallback)
443+
opt_send_fallback=1
444+
shift 1
445+
;;
422446
(--send-opts)
423447
opt_send_opts="$2"
424448
shift 2

0 commit comments

Comments
 (0)