@@ -41,6 +41,7 @@ opt_send_opts=''
41
41
opt_recv_opts=' '
42
42
opt_send_ssh_opts=' '
43
43
opt_send_mbuf_opts=' '
44
+ opt_send_fallback=' '
44
45
opt_sep=' _'
45
46
opt_setauto=' '
46
47
opt_syslog=' '
@@ -77,6 +78,7 @@ print_usage ()
77
78
-q, --quiet Suppress warnings and notices at the console.
78
79
--send-full=F Send zfs full backup.
79
80
--send-incr=F Send zfs incremental backup.
81
+ --send-fallback Fallback from incremental to full if needed.
80
82
--send-opts=F Option(s) passed to 'zfs send'.
81
83
--recv-opts=F Option(s) passed to 'zfs receive'.
82
84
--send-ssh-opts Option(s) passed to 'ssh'.
@@ -231,8 +233,8 @@ do_send () # snapname, oldglob
231
233
local jj
232
234
233
235
[ -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 "
236
238
237
239
# STEP 1: Go throug all snapshots we've created
238
240
for ii in $SNAPS_DONE
@@ -263,22 +265,33 @@ do_send () # snapname, oldglob
263
265
# 1: We change from incremental to full.
264
266
# 2: We accept that the user have said INCR, and stick with
265
267
# 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
267
271
if [ -n " $opt_verbose " ]; then
268
272
echo " WARNING: No previous snapshots exist but we where called"
269
273
echo " with --send-incr. Can not continue."
270
274
echo " Please rerun with --send-full."
275
+ echo " Or use --send-fallback."
271
276
fi
272
277
return 1
273
278
fi
274
279
275
- if [ -n " $opt_recursive " -a -n " $last_snap " ]; then
280
+ if [ -n " $opt_recursive " ]; then
276
281
# STEP 3: Again, go through ALL snapshots that exists, but this
277
282
# time only look for the snapshots that 'starts with'
278
283
# the dataset/volume in question AND 'ends with'
279
284
# the exact snapshot name/date in step 2.
280
285
for jj in $SNAPSHOTS_OLD
281
286
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
+
282
295
if echo " $jj " | grep -qE " ^$dset .*@$last_snap " ; then
283
296
SNAPS_SEND=" $SNAPS_SEND
284
297
$jj "
@@ -297,9 +310,15 @@ $jj"
297
310
298
311
if [ $RUNSEND -eq 1 ]; then
299
312
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
301
320
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
303
322
fi
304
323
305
324
if [ $RUNSEND = 1 -a -n " $opt_post_send " ]; then
@@ -320,6 +339,7 @@ GETOPT=$(getopt \
320
339
--longoptions=pre-snapshot:,post-snapshot:,destroy-only \
321
340
--longoptions=send-full:,send-incr:,send-opts:,recv-opts: \
322
341
--longoptions=send-ssh-opts:,send-mbuf-opts:,pre-send:,post-send: \
342
+ --longoptions=send-fallback \
323
343
--options=dnshe:l:k:p:rs:qgv \
324
344
-- " $@ " ) \
325
345
|| exit 128
420
440
opt_recv_pool=$( echo " $2 " | sed ' s,.*:,,' )
421
441
shift 2
422
442
;;
443
+ (--send-fallback)
444
+ opt_send_fallback=1
445
+ shift 1
446
+ ;;
423
447
(--send-opts)
424
448
opt_send_opts=" $2 "
425
449
shift 2
0 commit comments