2 Commits

Author SHA1 Message Date
Darik Horn
e08ebdf884 Merge branch 'topic/hanoi' of git://github.com/rdparker/zfs-auto-snapshot into hanoi 2014-04-16 16:22:31 -04:00
Ron Parker
109d537ba0 Add a hanoi rotation option 2013-10-30 11:18:52 -05:00
10 changed files with 200 additions and 229 deletions

View File

@@ -1,9 +0,0 @@
[ 1.2.5 (Unreleased) ]
* Start a changelog
* Accept PR#94 from aimileus/macos
- Replace --utc longform option with -u for macos compatibility
* Accept PR#107 from ArakniD/master
- Add optional label for snap removals
-- Jonathan Carter 2019-09-25, 15:24 SAST

View File

@@ -1,28 +1,17 @@
PREFIX := /usr/local
all: all:
install: install:
install -d $(DESTDIR)/etc/cron.d install -d $(DESTDIR)$(PREFIX)/etc/cron.d
install -d $(DESTDIR)/etc/cron.daily install -d $(DESTDIR)$(PREFIX)/etc/cron.daily
install -d $(DESTDIR)/etc/cron.hourly install -d $(DESTDIR)$(PREFIX)/etc/cron.hourly
install -d $(DESTDIR)/etc/cron.weekly install -d $(DESTDIR)$(PREFIX)/etc/cron.weekly
install -d $(DESTDIR)/etc/cron.monthly install -d $(DESTDIR)$(PREFIX)/etc/cron.monthly
install -m 0644 etc/zfs-auto-snapshot.cron.frequent $(DESTDIR)/etc/cron.d/zfs-auto-snapshot install etc/zfs-auto-snapshot.cron.frequent $(DESTDIR)$(PREFIX)/etc/cron.d/zfs-auto-snapshot
install etc/zfs-auto-snapshot.cron.hourly $(DESTDIR)/etc/cron.hourly/zfs-auto-snapshot install etc/zfs-auto-snapshot.cron.hourly $(DESTDIR)$(PREFIX)/etc/cron.hourly/zfs-auto-snapshot
install etc/zfs-auto-snapshot.cron.daily $(DESTDIR)/etc/cron.daily/zfs-auto-snapshot install etc/zfs-auto-snapshot.cron.daily $(DESTDIR)$(PREFIX)/etc/cron.daily/zfs-auto-snapshot
install etc/zfs-auto-snapshot.cron.weekly $(DESTDIR)/etc/cron.weekly/zfs-auto-snapshot install etc/zfs-auto-snapshot.cron.weekly $(DESTDIR)$(PREFIX)/etc/cron.weekly/zfs-auto-snapshot
install etc/zfs-auto-snapshot.cron.monthly $(DESTDIR)/etc/cron.monthly/zfs-auto-snapshot install etc/zfs-auto-snapshot.cron.monthly $(DESTDIR)$(PREFIX)/etc/cron.monthly/zfs-auto-snapshot
install -d $(DESTDIR)$(PREFIX)/share/man/man8 install -d $(DESTDIR)$(PREFIX)/share/man/man8
install -m 0644 src/zfs-auto-snapshot.8 $(DESTDIR)$(PREFIX)/share/man/man8/zfs-auto-snapshot.8 install src/zfs-auto-snapshot.8 $(DESTDIR)$(PREFIX)/share/man/man8/zfs-auto-snapshot.8
install -d $(DESTDIR)$(PREFIX)/sbin install -d $(DESTDIR)$(PREFIX)/sbin
install src/zfs-auto-snapshot.sh $(DESTDIR)$(PREFIX)/sbin/zfs-auto-snapshot install src/zfs-auto-snapshot.sh $(DESTDIR)$(PREFIX)/sbin/zfs-auto-snapshot
uninstall:
rm $(DESTDIR)/etc/cron.d/zfs-auto-snapshot
rm $(DESTDIR)/etc/cron.hourly/zfs-auto-snapshot
rm $(DESTDIR)/etc/cron.daily/zfs-auto-snapshot
rm $(DESTDIR)/etc/cron.weekly/zfs-auto-snapshot
rm $(DESTDIR)/etc/cron.monthly/zfs-auto-snapshot
rm $(DESTDIR)$(PREFIX)/share/man/man8/zfs-auto-snapshot.8
rm $(DESTDIR)$(PREFIX)/sbin/zfs-auto-snapshot

9
README
View File

@@ -10,12 +10,3 @@ snapshots if it is installed.
This program is a posixly correct bourne shell script. It depends only on This program is a posixly correct bourne shell script. It depends only on
the zfs utilities and cron, and can run in the dash shell. the zfs utilities and cron, and can run in the dash shell.
Installation:
-------------
wget https://github.com/zfsonlinux/zfs-auto-snapshot/archive/upstream/1.2.4.tar.gz
tar -xzf 1.2.4.tar.gz
cd zfs-auto-snapshot-upstream-1.2.4
make install

View File

@@ -1,6 +1,2 @@
#!/bin/sh #!/bin/sh
# Only call zfs-auto-snapshot if it's available
which zfs-auto-snapshot > /dev/null || exit 0
exec zfs-auto-snapshot --quiet --syslog --label=daily --keep=31 // exec zfs-auto-snapshot --quiet --syslog --label=daily --keep=31 //

View File

@@ -1,3 +1,3 @@
PATH="/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin" PATH="/usr/bin:/bin:/usr/sbin:/sbin"
*/15 * * * * root which zfs-auto-snapshot > /dev/null || exit 0 ; zfs-auto-snapshot --quiet --syslog --label=frequent --keep=4 // */15 * * * * root zfs-auto-snapshot -q -g --label=frequent --keep=4 //

View File

@@ -1,6 +1,2 @@
#!/bin/sh #!/bin/sh
# Only call zfs-auto-snapshot if it's available
which zfs-auto-snapshot > /dev/null || exit 0
exec zfs-auto-snapshot --quiet --syslog --label=hourly --keep=24 // exec zfs-auto-snapshot --quiet --syslog --label=hourly --keep=24 //

View File

@@ -1,6 +1,2 @@
#!/bin/sh #!/bin/sh
# Only call zfs-auto-snapshot if it's available
which zfs-auto-snapshot > /dev/null || exit 0
exec zfs-auto-snapshot --quiet --syslog --label=monthly --keep=12 // exec zfs-auto-snapshot --quiet --syslog --label=monthly --keep=12 //

View File

@@ -1,6 +1,2 @@
#!/bin/sh #!/bin/sh
# Only call zfs-auto-snapshot if it's available
which zfs-auto-snapshot > /dev/null || exit 0
exec zfs-auto-snapshot --quiet --syslog --label=weekly --keep=8 // exec zfs-auto-snapshot --quiet --syslog --label=weekly --keep=8 //

View File

@@ -64,27 +64,6 @@ Snapshot named filesystem and all descendants.
\fB\-v\fR, \fB\-\-verbose\fR \fB\-v\fR, \fB\-\-verbose\fR
Print info messages. Print info messages.
.TP .TP
\fB\-\-pre-snapshot\fR=\fICOMMAND\fR
Command to run before each dataset is snapshotted.
It is passed the dataset and snapshot name. If it
returns non-zero, snapshotting this dataset is
aborted.
.TP
\fB\-\-post-snapshot\fR=\fICOMMAND\fR
Command to run after each dataset is snapshotted.
It is passed the dataset and snapshot name.
.TP
\fB\-\-destroy-only\fR
Do not create new snapshots, but do destroy older
snapshots. Has no effect unless used with \fB\-k\fR.
.IP
A non-obvious use may be construction of cron jobs or
scripts that run pre-snapshot command(s), then run
zfs-auto-snapshot (without \fB\-k\fR) to quickly
snapshot all datasets, then run post-snapshot
command(s) and clean up with zfs-auto-snapshot
\fB\-\-destroy-only\fR.
.TP
name name
Filesystem and volume names, or '//' for all ZFS datasets. Filesystem and volume names, or '//' for all ZFS datasets.
.SH SEE ALSO .SH SEE ALSO

337
src/zfs-auto-snapshot.sh Normal file → Executable file
View File

@@ -39,10 +39,6 @@ opt_setauto=''
opt_syslog='' opt_syslog=''
opt_skip_scrub='' opt_skip_scrub=''
opt_verbose='' opt_verbose=''
opt_pre_snapshot=''
opt_post_snapshot=''
opt_do_snapshots=1
opt_min_size=0
# Global summary statistics. # Global summary statistics.
DESTRUCTION_COUNT='0' DESTRUCTION_COUNT='0'
@@ -63,6 +59,10 @@ print_usage ()
-n, --dry-run Print actions without actually doing anything. -n, --dry-run Print actions without actually doing anything.
-s, --skip-scrub Do not snapshot filesystems in scrubbing pools. -s, --skip-scrub Do not snapshot filesystems in scrubbing pools.
-h, --help Print this usage message. -h, --help Print this usage message.
-H, --hanoi=INT Use the hanoi rotation scheme.
INT how frequently the hanoi rotation is being run.
It is a number followed by one of w, d, h, m, s for
weeks, days, hours, minutes or seconds.
-k, --keep=NUM Keep NUM recent snapshots and destroy older snapshots. -k, --keep=NUM Keep NUM recent snapshots and destroy older snapshots.
-l, --label=LAB LAB is usually 'hourly', 'daily', or 'monthly'. -l, --label=LAB LAB is usually 'hourly', 'daily', or 'monthly'.
-p, --prefix=PRE PRE is 'zfs-auto-snap' by default. -p, --prefix=PRE PRE is 'zfs-auto-snap' by default.
@@ -73,7 +73,6 @@ print_usage ()
-g, --syslog Write messages into the system log. -g, --syslog Write messages into the system log.
-r, --recursive Snapshot named filesystem and all descendants. -r, --recursive Snapshot named filesystem and all descendants.
-v, --verbose Print info messages. -v, --verbose Print info messages.
--destroy-only Only destroy older snapshots, do not create new ones.
name Filesystem and volume names, or '//' for all ZFS datasets. name Filesystem and volume names, or '//' for all ZFS datasets.
" "
} }
@@ -111,7 +110,7 @@ print_log () # level, message, ...
;; ;;
(inf*) (inf*)
# test -n "$opt_syslog" && logger -t "$opt_prefix" -p daemon.info $* # test -n "$opt_syslog" && logger -t "$opt_prefix" -p daemon.info $*
test -z "$opt_quiet" && test -n "$opt_verbose" && echo $* test -n "$opt_verbose" && echo $*
;; ;;
(deb*) (deb*)
# test -n "$opt_syslog" && logger -t "$opt_prefix" -p daemon.debug $* # test -n "$opt_syslog" && logger -t "$opt_prefix" -p daemon.debug $*
@@ -145,6 +144,123 @@ do_run () # [argv]
} }
do_rotate () # flags, oldglob, target
{
local FLAGS="$1"
local GLOB="$2"
local TARGET="$3"
local KEEP=''
# global DESTRUCTION_COUNT
# global WARNING_COUNT
# global SNAPSHOTS_OLD
# Retain at most $opt_keep number of old snapshots of this filesystem,
# including the one that was just recently created.
KEEP="$opt_keep"
# ASSERT: The old snapshot list is sorted by increasing age.
for jj in $SNAPSHOTS_OLD
do
# Check whether this is an old snapshot of the filesystem.
if [ -z "${jj#$TARGET@$GLOB}" ]
then
KEEP=$(( $KEEP - 1 ))
if [ "$KEEP" -le '0' ]
then
if do_run "zfs destroy $FLAGS '$jj'"
then
DESTRUCTION_COUNT=$(( $DESTRUCTION_COUNT + 1 ))
else
WARNING_COUNT=$(( $WARNING_COUNT + 1 ))
fi
fi
fi
done
}
compute_hanoi_level() # date
{
local DATE="$1"
local EPOCH_TIME=''
local HANOI_NUM=''
local HANOI_LEVEL='1'
# The h* is because on Solaris %H%M will have generated 12h34
EPOCH_TIME=$(date +%s --date="$(echo $DATE | sed 's/-\(..\)h*\(..\)$/ \1:\2/')")
HANOI_NUM=$(($EPOCH_TIME / $opt_hanoi));
while test "$HANOI_NUM" -ne "0"
do
case "${HANOI_NUM}" in
(*[13579])
break
;;
esac
HANOI_LEVEL=$(($HANOI_LEVEL + 1))
HANOI_NUM=$(($HANOI_NUM / 2))
done
echo $HANOI_LEVEL
}
do_hanoi () # flags, oldglob, target
{
local FLAGS="$1"
local GLOB="$2"
local TARGET="$3"
local KEEP=''
local HANOI_LEVEL='0'
local SNAP_DATE=''
local SNAP_LEVEL=''
local POSSIBLY_DESTROY=''
# global DESTRUCTION_COUNT
# global WARNING_COUNT
# global SNAPSHOTS_OLD
HANOI_LEVEL=$(compute_hanoi_level "$DATE")
# Retain at most $opt_keep number of old snapshots of this filesystem,
# including the one that was just recently created.
KEEP="$opt_keep"
# ASSERT: The old snapshot list is sorted by increasing age.
for jj in $SNAPSHOTS_OLD
do
# Check whether this is an old snapshot of the filesystem.
if [ -z "${jj#$TARGET@$GLOB}" ]
then
# If younger snapshot was stored for possible
# deletion, delete it.
if [ -n "$POSSIBLY_DESTROY" ]
then
if do_run "zfs destroy $FLAGS '$POSSIBLY_DESTROY'"
then
DESTRUCTION_COUNT=$(( $DESTRUCTION_COUNT + 1 ))
else
WARNING_COUNT=$(( $WARNING_COUNT + 1 ))
fi
POSSIBLY_DESTROY=''
fi
SNAP_DATE=$(echo $jj | sed 's/.*-\(....-..-..-..h*..\)$/\1/')
SNAP_LEVEL=$(compute_hanoi_level "$SNAP_DATE")
if test "$HANOI_LEVEL" -eq "$SNAP_LEVEL"
then
# By default the hanoi rotation scheme acts as
# though there are an infinite number of
# disks. So instead of immediately destroying
# this snapshot, remember it as possibly
# needing to be destroyed and only do so if an
# older snapshot is found for this set.
POSSIBLY_DESTROY="$jj"
fi
fi
done
}
do_snapshots () # properties, flags, snapname, oldglob, [targets...] do_snapshots () # properties, flags, snapname, oldglob, [targets...]
{ {
local PROPS="$1" local PROPS="$1"
@@ -152,71 +268,27 @@ do_snapshots () # properties, flags, snapname, oldglob, [targets...]
local NAME="$3" local NAME="$3"
local GLOB="$4" local GLOB="$4"
local TARGETS="$5" local TARGETS="$5"
local KEEP=''
local RUNSNAP=1
# global DESTRUCTION_COUNT
# global SNAPSHOT_COUNT # global SNAPSHOT_COUNT
# global WARNING_COUNT # global WARNING_COUNT
# global SNAPSHOTS_OLD
for ii in $TARGETS for ii in $TARGETS
do do
# Check if size check is > 0 if do_run "zfs snapshot $PROPS $FLAGS '$ii@$NAME'"
size_check_skip=0
if [ "$opt_min_size" -gt 0 ]
then
bytes_written=`zfs get -Hp -o value written $ii`
kb_written=$(( $bytes_written / 1024 ))
if [ "$kb_written" -lt "$opt_min_size" ]
then
size_check_skip=1
if [ $opt_verbose -gt 0 ]
then
echo "Skipping target $ii, only $kb_written kB written since last snap. opt_min_size is $opt_min_size"
fi
fi
fi
if [ -n "$opt_do_snapshots" -a "$size_check_skip" -eq 0 ]
then then
if [ "$opt_pre_snapshot" != "" ] SNAPSHOT_COUNT=$(( $SNAPSHOT_COUNT + 1 ))
then else
do_run "$opt_pre_snapshot $ii $NAME" || RUNSNAP=0 WARNING_COUNT=$(( $WARNING_COUNT + 1 ))
fi continue
if [ $RUNSNAP -eq 1 ] && do_run "zfs snapshot $PROPS $FLAGS '$ii@$NAME'" fi
then
[ "$opt_post_snapshot" != "" ] && do_run "$opt_post_snapshot $ii $NAME" if test -z "$opt_hanoi"
SNAPSHOT_COUNT=$(( $SNAPSHOT_COUNT + 1 )) then
else test -z "$opt_keep" && continue
WARNING_COUNT=$(( $WARNING_COUNT + 1 )) do_rotate "$FLAGS" "$GLOB" "$ii"
continue else
fi do_hanoi "$FLAGS" "$GLOB" "$ii"
fi fi
# Retain at most $opt_keep number of old snapshots of this filesystem,
# including the one that was just recently created.
test -z "$opt_keep" && continue
KEEP="$opt_keep"
# ASSERT: The old snapshot list is sorted by increasing age.
for jj in $SNAPSHOTS_OLD
do
# Check whether this is an old snapshot of the filesystem.
if [ -z "${jj#$ii@$GLOB}" ]
then
KEEP=$(( $KEEP - 1 ))
if [ "$KEEP" -le '0' ]
then
if do_run "zfs destroy -d $FLAGS '$jj'"
then
DESTRUCTION_COUNT=$(( $DESTRUCTION_COUNT + 1 ))
else
WARNING_COUNT=$(( $WARNING_COUNT + 1 ))
fi
fi
fi
done
done done
} }
@@ -224,19 +296,11 @@ do_snapshots () # properties, flags, snapname, oldglob, [targets...]
# main () # main ()
# { # {
if [ "$(uname)" = "Darwin" ]; then GETOPT=$(getopt \
GETOPT_BIN="$(brew --prefix gnu-getopt 2> /dev/null || echo /usr/local)/bin/getopt"
else
GETOPT_BIN="getopt"
fi
GETOPT=$($GETOPT_BIN \
--longoptions=default-exclude,dry-run,fast,skip-scrub,recursive \ --longoptions=default-exclude,dry-run,fast,skip-scrub,recursive \
--longoptions=event:,keep:,label:,prefix:,sep: \ --longoptions=event:,hanoi:,keep:,label:,prefix:,sep: \
--longoptions=debug,help,quiet,syslog,verbose \ --longoptions=debug,help,quiet,syslog,verbose \
--longoptions=pre-snapshot:,post-snapshot:,destroy-only \ --options=dnshH:e:l:k:p:rs:qgv \
--longoptions=min-size: \
--options=dnshe:l:k:p:rs:qgvm: \
-- "$@" ) \ -- "$@" ) \
|| exit 128 || exit 128
@@ -282,6 +346,29 @@ do
print_usage print_usage
exit 0 exit 0
;; ;;
(-H|--hanoi)
HANOI_OPT="$2"
MULT="";
INT="";
case "$2" in
(*[0-9]s) MULT=1 ;;
(*[0-9]m) MULT=60 ;;
(*[0-9]h) MULT=3600 ;;
(*[0-9]d) MULT=86400 ;;
(*[0-9]w) MULT=604800 ;;
(*)
print_log error "Unrecognized interval $2 for the $1 parameter."
exit 139
;;
esac
INT=$(echo $2 | sed 's/.$//')
if ! test "$INT" -gt '0' 2>/dev/null
then
print_log error "The $2 parameter must be a positive integer."
fi
opt_hanoi=$(($INT * $MULT))
shift 2
;;
(-k|--keep) (-k|--keep)
if ! test "$2" -gt '0' 2>/dev/null if ! test "$2" -gt '0' 2>/dev/null
then then
@@ -295,10 +382,6 @@ do
opt_label="$2" opt_label="$2"
shift 2 shift 2
;; ;;
(-m|--min-size)
opt_min_size="$2"
shift 2
;;
(-p|--prefix) (-p|--prefix)
opt_prefix="$2" opt_prefix="$2"
while test "${#opt_prefix}" -gt '0' while test "${#opt_prefix}" -gt '0'
@@ -325,7 +408,7 @@ do
shift 1 shift 1
;; ;;
(--sep) (--sep)
case "$2" in case "$2" in
([[:alnum:]_.:\ -]) ([[:alnum:]_.:\ -])
: :
;; ;;
@@ -350,18 +433,6 @@ do
opt_verbose='1' opt_verbose='1'
shift 1 shift 1
;; ;;
(--pre-snapshot)
opt_pre_snapshot="$2"
shift 2
;;
(--post-snapshot)
opt_post_snapshot="$2"
shift 2
;;
(--destroy-only)
opt_do_snapshots=''
shift 1
;;
(--) (--)
shift 1 shift 1
break break
@@ -373,7 +444,7 @@ if [ "$#" -eq '0' ]
then then
print_log error "The filesystem argument list is empty." print_log error "The filesystem argument list is empty."
exit 133 exit 133
fi fi
# Count the number of times '//' appears on the command line. # Count the number of times '//' appears on the command line.
SLASHIES='0' SLASHIES='0'
@@ -388,6 +459,11 @@ then
exit 134 exit 134
fi fi
if test -n "$opt_hanoi" -a -z "$opt_label"
then
opt_label=hanoi
fi
# These are the only times that `zpool status` or `zfs list` are invoked, so # These are the only times that `zpool status` or `zfs list` are invoked, so
# this program for Linux has a much better runtime complexity than the similar # this program for Linux has a much better runtime complexity than the similar
# Solaris implementation. # Solaris implementation.
@@ -395,33 +471,16 @@ fi
ZPOOL_STATUS=$(env LC_ALL=C zpool status 2>&1 ) \ ZPOOL_STATUS=$(env LC_ALL=C zpool status 2>&1 ) \
|| { print_log error "zpool status $?: $ZPOOL_STATUS"; exit 135; } || { print_log error "zpool status $?: $ZPOOL_STATUS"; exit 135; }
ZFS_LIST=$(env LC_ALL=C zfs list -H -t filesystem,volume -s name \ ZFS_LIST=$(env LC_ALL=C zfs list -H -t filesystem,volume -s name \
-o name,com.sun:auto-snapshot,com.sun:auto-snapshot:"$opt_label") \ -o name,com.sun:auto-snapshot,com.sun:auto-snapshot:"$opt_label") \
|| { print_log error "zfs list $?: $ZFS_LIST"; exit 136; } || { print_log error "zfs list $?: $ZFS_LIST"; exit 136; }
if [ -n "$opt_fast_zfs_list" ] if [ -n "$opt_fast_zfs_list" ]
then then
# Check if a snapshot label is being used, in which case restrict the old SNAPSHOTS_OLD=$(env LC_ALL=C zfs list -H -t snapshot -o name -s name|grep $opt_prefix |awk '{ print substr( $0, length($0) - 14, length($0) ) " " $0}' |sort -r -k1,1 -k2,2|awk '{ print substr( $0, 17, length($0) )}') \
# snapshot removal to only snapshots with the same label format || { print_log error "zfs list $?: $SNAPSHOTS_OLD"; exit 137; }
if [ -n "$opt_label" ]
then
SNAPSHOTS_OLD=$(env LC_ALL=C zfs list -H -t snapshot -o name -s name | \
grep "$opt_prefix"_"$opt_label" | \
awk '{ print substr( $0, length($0) - 14, length($0) ) " " $0}' | \
sort -r -k1,1 -k2,2 | \
awk '{ print substr( $0, 17, length($0) )}') \
|| { print_log error "zfs list $?: $SNAPSHOTS_OLD"; exit 137; }
else
SNAPSHOTS_OLD=$(env LC_ALL=C zfs list -H -t snapshot -o name -s name | \
grep $opt_prefix | \
awk '{ print substr( $0, length($0) - 14, length($0) ) " " $0}' | \
sort -r -k1,1 -k2,2 | \
awk '{ print substr( $0, 17, length($0) )}') \
|| { print_log error "zfs list $?: $SNAPSHOTS_OLD"; exit 137; }
fi
else else
SNAPSHOTS_OLD=$(env LC_ALL=C zfs list -H -t snapshot -S creation -o name) \ SNAPSHOTS_OLD=$(env LC_ALL=C zfs list -H -t snapshot -S creation -o name) \
|| { print_log error "zfs list $?: $SNAPSHOTS_OLD"; exit 137; } || { print_log error "zfs list $?: $SNAPSHOTS_OLD"; exit 137; }
fi fi
@@ -481,20 +540,11 @@ do
# Just testing "$ii" != ${ii#$jj} would incorrectly match. # Just testing "$ii" != ${ii#$jj} would incorrectly match.
iii="$ii/" iii="$ii/"
# Exclude datasets that are not named on the command line.
# Exclude datasets
# * that are not named on the command line or
# * those whose prefix is not on the command line (if --recursive flag is set)
IN_ARGS='0' IN_ARGS='0'
for jj in "$@" for jj in "$@"
do do
# Ibid regarding iii.
jjj="$jj/"
if [ "$jj" = '//' -o "$jj" = "$ii" ] if [ "$jj" = '//' -o "$jj" = "$ii" ]
then
IN_ARGS=$(( $IN_ARGS + 1 ))
elif [ -n "$opt_recursive" -a "$iii" != "${iii#$jjj}" ]
then then
IN_ARGS=$(( $IN_ARGS + 1 )) IN_ARGS=$(( $IN_ARGS + 1 ))
fi fi
@@ -578,43 +628,30 @@ do
TARGETS_RECURSIVE="${TARGETS_RECURSIVE:+$TARGETS_RECURSIVE }$ii" # nb: \t TARGETS_RECURSIVE="${TARGETS_RECURSIVE:+$TARGETS_RECURSIVE }$ii" # nb: \t
done done
# ISO style date; fifteen characters: YYYY-MM-DD-HHMM
# On Solaris %H%M expands to 12h34.
DATE=$(date --utc +%F-%H%M)
if test -n "$opt_hanoi" -a "$opt_event" = "-"
then
opt_event=hanoi-$HANOI_OPT-level-$(compute_hanoi_level $DATE)
fi
# Linux lacks SMF and the notion of an FMRI event, but always set this property # Linux lacks SMF and the notion of an FMRI event, but always set this property
# because the SUNW program does. The dash character is the default. # because the SUNW program does. The dash character is the default.
SNAPPROP="-o com.sun:auto-snapshot-desc='$opt_event'" SNAPPROP="-o com.sun:auto-snapshot-desc='$opt_event'"
# ISO style date; fifteen characters: YYYY-MM-DD-HHMM
# On Solaris %H%M expands to 12h34.
# We use the shortfirm -u here because --utc is not supported on macos.
DATE=$(date -u +%F-%H%M)
# The snapshot name after the @ symbol. # The snapshot name after the @ symbol.
SNAPNAME="${opt_prefix:+$opt_prefix$opt_sep}${opt_label:+$opt_label}-$DATE" SNAPNAME="$opt_prefix${opt_label:+$opt_sep$opt_label}-$DATE"
# The expression for matching old snapshots. -YYYY-MM-DD-HHMM # The expression for matching old snapshots. -YYYY-MM-DD-HHMM
SNAPGLOB="${opt_prefix:+$opt_prefix$opt_sep}${opt_label:+$opt_label}-???????????????" SNAPGLOB="$opt_prefix${opt_label:+?$opt_label}????????????????"
if [ -n "$opt_do_snapshots" ] test -n "$TARGETS_REGULAR" \
then && print_log info "Doing regular snapshots of $TARGETS_REGULAR"
test -n "$TARGETS_REGULAR" \
&& print_log info "Doing regular snapshots of $TARGETS_REGULAR"
test -n "$TARGETS_RECURSIVE" \ test -n "$TARGETS_RECURSIVE" \
&& print_log info "Doing recursive snapshots of $TARGETS_RECURSIVE" && print_log info "Doing recursive snapshots of $TARGETS_RECURSIVE"
if test -n "$opt_keep" && [ "$opt_keep" -ge "1" ]
then
print_log info "Destroying all but the newest $opt_keep snapshots of each dataset."
fi
elif test -n "$opt_keep" && [ "$opt_keep" -ge "1" ]
then
test -n "$TARGETS_REGULAR" \
&& print_log info "Destroying all but the newest $opt_keep snapshots of $TARGETS_REGULAR"
test -n "$TARGETS_RECURSIVE" \
&& print_log info "Recursively destroying all but the newest $opt_keep snapshots of $TARGETS_RECURSIVE"
else
print_log notice "Only destroying snapshots, but count of snapshots to preserve not given. Nothing to do."
fi
test -n "$opt_dry_run" \ test -n "$opt_dry_run" \
&& print_log info "Doing a dry run. Not running these commands..." && print_log info "Doing a dry run. Not running these commands..."