Skip to content

Commit 41054fc

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 1196bcf commit 41054fc

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'.
@@ -189,22 +191,33 @@ find_last_snap () # dset, GLOB
189191
# 1: We change from incremental to full.
190192
# 2: We accept that the user have said INCR, and stick with
191193
# it.
192-
if [ "$opt_send_type" = "incr" -a -z "$last_snap" ]; then
194+
# Normally we do point 2, but if --send-fallback is specified,
195+
# we allow it and convert to a full send instead.
196+
if [ "$opt_send_type" = "incr" -a -z "$last_snap" -a -z "$opt_send_fallback" ]; then
193197
if [ -n "$opt_verbose" ]; then
194198
echo > /dev/stderr "WARNING: No previous snapshots exist but we where called"
195199
echo > /dev/stderr " with --send-incr. Can not continue."
196200
echo > /dev/stderr " Please rerun with --send-full."
201+
echo > /dev/stderr " Or use --send-fallback."
197202
fi
198203
return 1
199204
fi
200205

201-
if [ -n "$opt_recursive" -a -n "$last_snap" ]; then
206+
if [ -n "$opt_recursive" ]; then
202207
# STEP 2: Again, go through ALL snapshots that exists, but this
203208
# time only look for the snapshots that 'starts with'
204209
# the dataset/volume in question AND 'ends with'
205210
# the exact snapshot name/date in step 2.
206211
for jj in $SNAPSHOTS_OLD
207212
do
213+
# When trying to find snapshots recurively, we MUST have a 'last_snap'
214+
# value. Othervise, it will match ALL snapshots for dset (if we had
215+
# used '"^$dset.*@$GLOB" only).
216+
if [ -z "$last_snap" ] && echo "$jj" | grep -qE "^$dset.*@$GLOB"; then
217+
# Use this as last snapshot name
218+
last_snap="${jj#*@}"
219+
fi
220+
208221
if echo "$jj" | grep -qE "^$dset.*@$last_snap"; then
209222
echo $jj
210223
fi
@@ -288,8 +301,8 @@ do_send () # snapname, oldglob
288301
local jj
289302

290303
[ -n "$opt_send_mbuf_opts" ] && remote="mbuffer $opt_send_mbuf_opts |"
291-
remote="$remote ssh $opt_send_ssh_opts $opt_send_host "
292-
remote="$remote zfs receive $opt_recv_opts $opt_recv_pool"
304+
remote="$remote ssh $opt_send_ssh_opts $opt_send_host"
305+
remote="$remote zfs receive $opt_recv_opts"
293306

294307
# STEP 1: Go throug all snapshots we've created
295308
for ii in $SNAPS_DONE
@@ -309,9 +322,15 @@ do_send () # snapname, oldglob
309322

310323
if [ $RUNSEND -eq 1 ]; then
311324
if [ "$opt_send_type" = "incr" ]; then
312-
do_run "zfs send $opt_send_opts -i $jj $ii | $remote" || RUNSEND=0
325+
if [ "$jj" = "$ii" -a -n "$opt_send_fallback" ]; then
326+
do_run "zfs send $opt_send_opts -R $ii | $remote -F $opt_recv_pool" \
327+
|| RUNSEND=0
328+
else
329+
do_run "zfs send $opt_send_opts -i $jj $ii | $remote $opt_recv_pool" \
330+
|| RUNSEND=0
331+
fi
313332
else
314-
do_run "zfs send $opt_send_opts -R $jj | $remote" || RUNSEND=0
333+
do_run "zfs send $opt_send_opts -R $jj | $remote $opt_recv_pool" || RUNSEND=0
315334
fi
316335

317336
if [ $RUNSEND = 1 -a -n "$opt_post_send" ]; then
@@ -332,6 +351,7 @@ GETOPT=$(getopt \
332351
--longoptions=pre-snapshot:,post-snapshot:,destroy-only \
333352
--longoptions=send-full:,send-incr:,send-opts:,recv-opts: \
334353
--longoptions=send-ssh-opts:,send-mbuf-opts:,pre-send:,post-send: \
354+
--longoptions=send-fallback \
335355
--options=dnshe:l:k:p:rs:qgv \
336356
-- "$@" ) \
337357
|| exit 128
@@ -432,6 +452,10 @@ do
432452
opt_recv_pool=$(echo "$2" | sed 's,.*:,,')
433453
shift 2
434454
;;
455+
(--send-fallback)
456+
opt_send_fallback=1
457+
shift 1
458+
;;
435459
(--send-opts)
436460
opt_send_opts="$2"
437461
shift 2

0 commit comments

Comments
 (0)