32 Commits

Author SHA1 Message Date
92db087bb0 Merge pull request #109 from mergwyn/master
Correct incorrect sh syntax
2019-09-30 09:30:55 +02:00
f938d9cc1c Correct incorrect sh syntax
'==' is not valid in sh
2019-09-25 23:13:21 +01:00
4538217932 Clear trailing whitespaces 2019-09-25 13:30:46 +00:00
99e1a6103d Initiate changelog 2019-09-25 13:25:05 +00:00
86a95095ee Add note about macos compatibility 2019-09-25 15:13:00 +02:00
363a847ee3 Merge pull request #94 from aimileus/macos
Support macOS with Homebrew gnu-getopt
2019-09-25 15:10:13 +02:00
12945110d3 Merge pull request #107 from ArakniD/master
Updated zfs-auto-snapshot.sh
2019-09-25 15:08:23 +02:00
d5646c901e Install from release instead of master
Install from release instead of master
2019-09-25 15:06:33 +02:00
4a59d0d615 Updated zfs-auto-snapshot.sh
Updated old snapshot removal to include the optional snapshot label
2019-09-07 14:56:30 +10:00
ef7ae674f5 Merge pull request #98 from diablodale/missing-log-info
fix for verbose logging not working
2019-04-12 22:54:42 +02:00
b0a5909335 Merge pull request #42 from FransUrbo/snapname_fix
Fix SNAPNAME and SNAPGLOB.
2019-04-12 22:53:29 +02:00
3689b2c43d Merge pull request #91 from schors/master
Fix recursive snapshots
2019-04-12 22:47:53 +02:00
d27bbfa650 Merge pull request #96 from diablodale/uninstall
add uninstall - fix zfsonlinux/zfs-auto-snapshot#95
2019-04-12 22:47:29 +02:00
897ca026e1 Merge pull request #59 from rkarlsba/patch-3
Added --min-size
2019-04-12 22:46:38 +02:00
3e48c8956e Merge pull request #100 from jsoref/spelling
spelling: construction
2019-04-12 22:35:17 +02:00
3efc478828 spelling: construction 2018-11-25 20:32:28 -05:00
c99de67c63 fix verbose logging
- corrects regression introduced
2018-10-15 18:20:13 +02:00
4425d681f3 add uninstall - fix zfsonlinux/zfs-auto-snapshot#95
- intentionally does not remove directories
- intentionally does not force deletes
2018-10-13 19:50:50 +02:00
6f6d1202cf Support macOS with Homebrew gnu-getopt 2018-09-29 11:09:27 +02:00
6ee4553cf6 Fix jjj vs jj bug in recursive snapshot selection 2018-07-12 13:03:07 +03:00
6c7da10e24 Fix recursive snapshot 2018-07-11 17:32:57 +03:00
3d9992b086 Undo PR#82 (fixes #86 and fixes #87) 2018-06-15 13:10:29 +02:00
f145cf6e07 Revert PR85 2018-04-21 09:27:26 +02:00
838b03b41f Merge pull request #82 from attie/improve_list
Improve performance of listings
2018-04-17 13:34:47 +02:00
e1268767b8 Merge pull request #85 from riyad/fix-recursive-snapshots-with-noauto-descendants
Fix recursive snapshots for datasets with noauto descendants
2018-04-17 13:33:38 +02:00
e93096c2d9 Fix recursive snapshots for datasets with noauto descendants
Fixes #80
2018-04-11 14:38:22 +02:00
1ae1adc5f0 Merge pull request #79 from jbnance/man-page-perms
Set permissions on man page to 0644 when installing
2018-03-13 14:14:13 +02:00
41eddc97cc only list entities that we are interested in 2018-01-18 17:22:30 +00:00
2b7b694a95 Set permissions on man page to 0644 when installing 2017-12-27 15:34:39 -06:00
277287f824 Further cron logic cleanups 2017-09-18 09:25:02 +02:00
27413ac798 Added --min-size
Added an option to inhibit generation of empty (or very small) snapshots.
2017-01-16 00:59:13 +01:00
6e32b25d8f Fix SNAPNAME and SNAPGLOB.
* Currently the following command line:

    zfs-auto-snapshot.sh.orig --keep 7 --label daily --prefix '' --sep '-' \
      --event "daily-$(date --utc +"%Y%m%d.%H%M")" --recursive --verbose //

  will give the following result:

    zfs snapshot -o com.sun:auto-snapshot-desc='daily-20150403.0013' \
      -r 'share/.Bacula@-daily-2015-04-03-0013'

* If instead 'prefix=daily', this would be the result:

    zfs snapshot -o com.sun:auto-snapshot-desc='daily-20150403.0015' \
      -r 'share/.Bacula@daily-daily-2015-04-03-0016'

* If 'prefix=daily' and 'label=NULL':

    zfs snapshot -o com.sun:auto-snapshot-desc='daily-20150403.0017' \
      -r 'share@daily'

This because SNAPNAME is constructed wrongly. Instead, only separate
the 'prefix' from the 'label' with 'sep' if 'prefix' is actually set.
2015-04-03 02:12:16 +02:00
10 changed files with 106 additions and 33 deletions

9
CHANGELOG Normal file
View File

@ -0,0 +1,9 @@
[ 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

@ -14,6 +14,15 @@ install:
install etc/zfs-auto-snapshot.cron.weekly $(DESTDIR)/etc/cron.weekly/zfs-auto-snapshot install etc/zfs-auto-snapshot.cron.weekly $(DESTDIR)/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)/etc/cron.monthly/zfs-auto-snapshot
install -d $(DESTDIR)$(PREFIX)/share/man/man8 install -d $(DESTDIR)$(PREFIX)/share/man/man8
install src/zfs-auto-snapshot.8 $(DESTDIR)$(PREFIX)/share/man/man8/zfs-auto-snapshot.8 install -m 0644 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

6
README
View File

@ -15,7 +15,7 @@ the zfs utilities and cron, and can run in the dash shell.
Installation: Installation:
------------- -------------
wget https://github.com/zfsonlinux/zfs-auto-snapshot/archive/master.zip wget https://github.com/zfsonlinux/zfs-auto-snapshot/archive/upstream/1.2.4.tar.gz
unzip master.zip tar -xzf 1.2.4.tar.gz
cd zfs-auto-snapshot-master cd zfs-auto-snapshot-upstream-1.2.4
make install make install

View File

@ -1,5 +1,6 @@
#!/bin/sh #!/bin/sh
# Only call zfs-auto-snapshot if it's available # Only call zfs-auto-snapshot if it's available
which zfs-auto-snapshot > /dev/null && \ 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/local/sbin:/usr/sbin:/sbin"
*/15 * * * * root which zfs-auto-snapshot > /dev/null && zfs-auto-snapshot --quiet --syslog --label=frequent --keep=4 // */15 * * * * root which zfs-auto-snapshot > /dev/null || exit 0 ; zfs-auto-snapshot --quiet --syslog --label=frequent --keep=4 //

View File

@ -1,5 +1,6 @@
#!/bin/sh #!/bin/sh
# Only call zfs-auto-snapshot if it's available # Only call zfs-auto-snapshot if it's available
which zfs-auto-snapshot > /dev/null && \ 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,5 +1,6 @@
#!/bin/sh #!/bin/sh
# Only call zfs-auto-snapshot if it's available # Only call zfs-auto-snapshot if it's available
which zfs-auto-snapshot > /dev/null && \ 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,5 +1,6 @@
#!/bin/sh #!/bin/sh
# Only call zfs-auto-snapshot if it's available # Only call zfs-auto-snapshot if it's available
which zfs-auto-snapshot > /dev/null && \ 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

@ -78,7 +78,7 @@ It is passed the dataset and snapshot name.
Do not create new snapshots, but do destroy older Do not create new snapshots, but do destroy older
snapshots. Has no effect unless used with \fB\-k\fR. snapshots. Has no effect unless used with \fB\-k\fR.
.IP .IP
A non-obvious use may be constructon of cron jobs or A non-obvious use may be construction of cron jobs or
scripts that run pre-snapshot command(s), then run scripts that run pre-snapshot command(s), then run
zfs-auto-snapshot (without \fB\-k\fR) to quickly zfs-auto-snapshot (without \fB\-k\fR) to quickly
snapshot all datasets, then run post-snapshot snapshot all datasets, then run post-snapshot

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

@ -42,6 +42,7 @@ opt_verbose=''
opt_pre_snapshot='' opt_pre_snapshot=''
opt_post_snapshot='' opt_post_snapshot=''
opt_do_snapshots=1 opt_do_snapshots=1
opt_min_size=0
# Global summary statistics. # Global summary statistics.
DESTRUCTION_COUNT='0' DESTRUCTION_COUNT='0'
@ -110,7 +111,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+x} && test -n "$opt_verbose" && echo $* test -z "$opt_quiet" && 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 $*
@ -161,7 +162,23 @@ do_snapshots () # properties, flags, snapname, oldglob, [targets...]
for ii in $TARGETS for ii in $TARGETS
do do
if [ -n "$opt_do_snapshots" ] # Check if size check is > 0
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" != "" ] if [ "$opt_pre_snapshot" != "" ]
then then
@ -174,7 +191,7 @@ do_snapshots () # properties, flags, snapname, oldglob, [targets...]
else else
WARNING_COUNT=$(( $WARNING_COUNT + 1 )) WARNING_COUNT=$(( $WARNING_COUNT + 1 ))
continue continue
fi fi
fi fi
# Retain at most $opt_keep number of old snapshots of this filesystem, # Retain at most $opt_keep number of old snapshots of this filesystem,
@ -191,7 +208,7 @@ do_snapshots () # properties, flags, snapname, oldglob, [targets...]
KEEP=$(( $KEEP - 1 )) KEEP=$(( $KEEP - 1 ))
if [ "$KEEP" -le '0' ] if [ "$KEEP" -le '0' ]
then then
if do_run "zfs destroy -d $FLAGS '$jj'" if do_run "zfs destroy -d $FLAGS '$jj'"
then then
DESTRUCTION_COUNT=$(( $DESTRUCTION_COUNT + 1 )) DESTRUCTION_COUNT=$(( $DESTRUCTION_COUNT + 1 ))
else else
@ -207,12 +224,19 @@ do_snapshots () # properties, flags, snapname, oldglob, [targets...]
# main () # main ()
# { # {
GETOPT=$(getopt \ if [ "$(uname)" = "Darwin" ]; then
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:,keep:,label:,prefix:,sep: \
--longoptions=debug,help,quiet,syslog,verbose \ --longoptions=debug,help,quiet,syslog,verbose \
--longoptions=pre-snapshot:,post-snapshot:,destroy-only \ --longoptions=pre-snapshot:,post-snapshot:,destroy-only \
--options=dnshe:l:k:p:rs:qgv \ --longoptions=min-size: \
--options=dnshe:l:k:p:rs:qgvm: \
-- "$@" ) \ -- "$@" ) \
|| exit 128 || exit 128
@ -271,6 +295,10 @@ 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'
@ -297,7 +325,7 @@ do
shift 1 shift 1
;; ;;
(--sep) (--sep)
case "$2" in case "$2" in
([[:alnum:]_.:\ -]) ([[:alnum:]_.:\ -])
: :
;; ;;
@ -345,7 +373,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'
@ -367,20 +395,33 @@ 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
SNAPSHOTS_OLD=$(env LC_ALL=C zfs list -H -t snapshot -o name -s name | \ # Check if a snapshot label is being used, in which case restrict the old
grep $opt_prefix | \ # snapshot removal to only snapshots with the same label format
awk '{ print substr( $0, length($0) - 14, length($0) ) " " $0}' | \ if [ -n "$opt_label" ]
sort -r -k1,1 -k2,2 | \ then
awk '{ print substr( $0, 17, length($0) )}') \ SNAPSHOTS_OLD=$(env LC_ALL=C zfs list -H -t snapshot -o name -s name | \
|| { print_log error "zfs list $?: $SNAPSHOTS_OLD"; exit 137; } 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
@ -440,11 +481,20 @@ 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
@ -534,13 +584,14 @@ SNAPPROP="-o com.sun:auto-snapshot-desc='$opt_event'"
# ISO style date; fifteen characters: YYYY-MM-DD-HHMM # ISO style date; fifteen characters: YYYY-MM-DD-HHMM
# On Solaris %H%M expands to 12h34. # On Solaris %H%M expands to 12h34.
DATE=$(date --utc +%F-%H%M) # 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_label:+$opt_sep$opt_label}-$DATE" SNAPNAME="${opt_prefix:+$opt_prefix$opt_sep}${opt_label:+$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_label:+?$opt_label}????????????????" SNAPGLOB="${opt_prefix:+$opt_prefix$opt_sep}${opt_label:+$opt_label}-???????????????"
if [ -n "$opt_do_snapshots" ] if [ -n "$opt_do_snapshots" ]
then then