Skip to content

Commit d063d3b

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 71389d5 commit d063d3b

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=''
@@ -77,6 +78,7 @@ print_usage ()
7778
-q, --quiet Suppress warnings and notices at the console.
7879
--send-full=F Send zfs full backup.
7980
--send-incr=F Send zfs incremental backup.
81+
--send-fallback Fallback from incremental to full if needed.
8082
--send-opts=F Option(s) passed to 'zfs send'.
8183
--recv-opts=F Option(s) passed to 'zfs receive'.
8284
--send-ssh-opts Option(s) passed to 'ssh'.
@@ -231,8 +233,8 @@ do_send () # snapname, oldglob
231233
local jj
232234

233235
[ -n "$opt_send_mbuf_opts" ] && remote="mbuffer $opt_send_mbuf_opts |"
234-
remote="$remote ssh $opt_send_ssh_opts $opt_send_host "
235-
remote="$remote zfs receive $opt_recv_opts $opt_recv_pool"
236+
remote="$remote ssh $opt_send_ssh_opts $opt_send_host"
237+
remote="$remote zfs receive $opt_recv_opts"
236238

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

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

298311
if [ $RUNSEND -eq 1 ]; then
299312
if [ "$opt_send_type" = "incr" ]; then
300-
do_run "zfs send $opt_send_opts -i $jj $ii | $remote" || RUNSEND=0
313+
if [ "$jj" = "$ii" -a -n "$opt_send_fallback" ]; then
314+
do_run "zfs send $opt_send_opts -R $ii | $remote -F $opt_recv_pool" \
315+
|| RUNSEND=0
316+
else
317+
do_run "zfs send $opt_send_opts -i $jj $ii | $remote $opt_recv_pool" \
318+
|| RUNSEND=0
319+
fi
301320
else
302-
do_run "zfs send $opt_send_opts -R $jj | $remote" || RUNSEND=0
321+
do_run "zfs send $opt_send_opts -R $jj | $remote $opt_recv_pool" || RUNSEND=0
303322
fi
304323

305324
if [ $RUNSEND = 1 -a -n "$opt_post_send" ]; then
@@ -320,6 +339,7 @@ GETOPT=$(getopt \
320339
--longoptions=pre-snapshot:,post-snapshot:,destroy-only \
321340
--longoptions=send-full:,send-incr:,send-opts:,recv-opts: \
322341
--longoptions=send-ssh-opts:,send-mbuf-opts:,pre-send:,post-send: \
342+
--longoptions=send-fallback \
323343
--options=dnshe:l:k:p:rs:qgv \
324344
-- "$@" ) \
325345
|| exit 128
@@ -420,6 +440,10 @@ do
420440
opt_recv_pool=$(echo "$2" | sed 's,.*:,,')
421441
shift 2
422442
;;
443+
(--send-fallback)
444+
opt_send_fallback=1
445+
shift 1
446+
;;
423447
(--send-opts)
424448
opt_send_opts="$2"
425449
shift 2

0 commit comments

Comments
 (0)