7 Commits

Author SHA1 Message Date
39bce83e0f Merge pull request #18 from hawkowl/master
Set zfs-auto-snapshot to use UTC time for snapshots
2013-06-24 14:19:33 -07:00
6ea2d7f5b1 Set the snapshots to use UTC time, which makes the date/time display correctly in Windows 7 Previous Versions. 2013-06-24 21:48:47 +08:00
dd27aa1c56 Update Makefile for the manual page 2013-06-17 08:23:57 -05:00
f5fc21ace0 Add a manpage 2013-06-16 15:31:33 -07:00
bf4e97b07d Add a switch for the fast zfs list invocation.
Implement a `--fast` switch that uses the optimized `zfs list`
invocation instead of the slower regular form.

If the optimized form is generally better, then use it as the
default and reverse the switch to `--slow` sometime later.

Issue: zfsonlinux/zfs-auto-snapshot#16
2013-05-08 19:36:44 -05:00
53ad1dc042 Merge pull request #15 from tisoft/patch-1
Use only name property for zfs list
2013-05-08 15:33:31 -07:00
b6fba51643 Use only name property for zfs list
zfs list is very slow if it needs to retrieve other properties than name. See zfsonlinux/zfs#450 for reference.

This change uses only the name of the snapshot and uses awk to extract the snapshot date from the name and sort to sort it:

1. get all snapshot names, sorted by name
2. use grep to filter out any snapshot, that isn't correctly prefixed (maybe a check for the correct date format could also be added here)
3. use awk to extract the date and put the date before the snapshot
4. use sort to reverse sort this, first by date, then by snapshot name
5. use awk to remove the date, so that just the snapshot name is left

This significally speeds it up on my system (/root/zfs-auto-snapshot is the changed one, running with -n to get only the times for snapshot retrieval):

root@tatooine:/root# time /root/zfs-auto-snapshot -d -v // --label=frequent --keep=4 -n
Debug: Including rpool for regular snapshot.
Debug: Including rpool/DATA for regular snapshot.
Debug: Including rpool/DATA/ldap for recursive snapshot.
Debug: Including rpool/DATA/postgresql for recursive snapshot.
Debug: Including rpool/DATA/vm for regular snapshot.
Debug: Including rpool/DATA/vm/alderaan.example.net for recursive snapshot.
Debug: Including rpool/DATA/vm/bespin.example.net for recursive snapshot.
Debug: Including rpool/DATA/vm/coruscant.example.net for recursive snapshot.
Debug: Including rpool/DATA/vm/dagobah.example.net for recursive snapshot.
Debug: Including rpool/DATA/vm/dantooine.example.net for recursive snapshot.
Debug: Including rpool/DATA/vm/dev.example.net for recursive snapshot.
Debug: Including rpool/DATA/vm/monitor.example.net for recursive snapshot.
Debug: Including rpool/DATA/vm/office.example.net for recursive snapshot.
Debug: Including rpool/DATA/vm/test.example.net for recursive snapshot.
Debug: Including rpool/ROOT for recursive snapshot.
Debug: Excluding rpool/ROOT/ubuntu-1 because rpool/ROOT includes it recursively.
Doing regular snapshots of rpool rpool/DATA rpool/DATA/vm
Doing recursive snapshots of rpool/DATA/ldap rpool/DATA/postgresql rpool/DATA/vm/alderaan.example.net rpool/DATA/vm/bespin.example.net rpool/DATA/vm/coruscant.example.net rpool/DATA/vm/dagobah.example.net rpool/DATA/vm/dantooine.example.net rpool/DATA/vm/dev.example.net rpool/DATA/vm/monitor.example.net rpool/DATA/vm/office.example.net rpool/DATA/vm/test.example.net rpool/ROOT
Doing a dry run. Not running these commands...
zfs snapshot -o com.sun:auto-snapshot-desc='-'  'rpool@zfs-auto-snap_frequent-2013-04-16-2344'
zfs destroy  'rpool@zfs-auto-snap_frequent-2013-04-16-2315'
zfs snapshot -o com.sun:auto-snapshot-desc='-'  'rpool/DATA@zfs-auto-snap_frequent-2013-04-16-2344'
zfs destroy  'rpool/DATA@zfs-auto-snap_frequent-2013-04-16-2315'
zfs snapshot -o com.sun:auto-snapshot-desc='-'  'rpool/DATA/vm@zfs-auto-snap_frequent-2013-04-16-2344'
zfs destroy  'rpool/DATA/vm@zfs-auto-snap_frequent-2013-04-16-2315'
zfs snapshot -o com.sun:auto-snapshot-desc='-' -r 'rpool/DATA/ldap@zfs-auto-snap_frequent-2013-04-16-2344'
zfs destroy -r 'rpool/DATA/ldap@zfs-auto-snap_frequent-2013-04-16-2315'
zfs snapshot -o com.sun:auto-snapshot-desc='-' -r 'rpool/DATA/postgresql@zfs-auto-snap_frequent-2013-04-16-2344'
zfs destroy -r 'rpool/DATA/postgresql@zfs-auto-snap_frequent-2013-04-16-2315'
zfs snapshot -o com.sun:auto-snapshot-desc='-' -r 'rpool/DATA/vm/alderaan.example.net@zfs-auto-snap_frequent-2013-04-16-2344'
zfs destroy -r 'rpool/DATA/vm/alderaan.example.net@zfs-auto-snap_frequent-2013-04-16-2315'
zfs snapshot -o com.sun:auto-snapshot-desc='-' -r 'rpool/DATA/vm/bespin.example.net@zfs-auto-snap_frequent-2013-04-16-2344'
zfs destroy -r 'rpool/DATA/vm/bespin.example.net@zfs-auto-snap_frequent-2013-04-16-2315'
zfs snapshot -o com.sun:auto-snapshot-desc='-' -r 'rpool/DATA/vm/coruscant.example.net@zfs-auto-snap_frequent-2013-04-16-2344'
zfs destroy -r 'rpool/DATA/vm/coruscant.example.net@zfs-auto-snap_frequent-2013-04-16-2315'
zfs snapshot -o com.sun:auto-snapshot-desc='-' -r 'rpool/DATA/vm/dagobah.example.net@zfs-auto-snap_frequent-2013-04-16-2344'
zfs destroy -r 'rpool/DATA/vm/dagobah.example.net@zfs-auto-snap_frequent-2013-04-16-2315'
zfs snapshot -o com.sun:auto-snapshot-desc='-' -r 'rpool/DATA/vm/dantooine.example.net@zfs-auto-snap_frequent-2013-04-16-2344'
zfs destroy -r 'rpool/DATA/vm/dantooine.example.net@zfs-auto-snap_frequent-2013-04-16-2315'
zfs snapshot -o com.sun:auto-snapshot-desc='-' -r 'rpool/DATA/vm/dev.example.net@zfs-auto-snap_frequent-2013-04-16-2344'
zfs destroy -r 'rpool/DATA/vm/dev.example.net@zfs-auto-snap_frequent-2013-04-16-2315'
zfs snapshot -o com.sun:auto-snapshot-desc='-' -r 'rpool/DATA/vm/monitor.example.net@zfs-auto-snap_frequent-2013-04-16-2344'
zfs destroy -r 'rpool/DATA/vm/monitor.example.net@zfs-auto-snap_frequent-2013-04-16-2315'
zfs snapshot -o com.sun:auto-snapshot-desc='-' -r 'rpool/DATA/vm/office.example.net@zfs-auto-snap_frequent-2013-04-16-2344'
zfs destroy -r 'rpool/DATA/vm/office.example.net@zfs-auto-snap_frequent-2013-04-16-2315'
zfs snapshot -o com.sun:auto-snapshot-desc='-' -r 'rpool/DATA/vm/test.example.net@zfs-auto-snap_frequent-2013-04-16-2344'
zfs destroy -r 'rpool/DATA/vm/test.example.net@zfs-auto-snap_frequent-2013-04-16-2315'
zfs snapshot -o com.sun:auto-snapshot-desc='-' -r 'rpool/ROOT@zfs-auto-snap_frequent-2013-04-16-2344'
zfs destroy -r 'rpool/ROOT@zfs-auto-snap_frequent-2013-04-16-2315'
@zfs-auto-snap_frequent-2013-04-16-2344, 15 created, 15 destroyed, 0 warnings.

real	0m6.936s
user	0m0.076s
sys	0m0.184s
root@tatooine:/root# time /sbin/zfs-auto-snapshot -d -v // --label=frequent --keep=4 -n
Debug: Including rpool for regular snapshot.
Debug: Including rpool/DATA for regular snapshot.
Debug: Including rpool/DATA/ldap for recursive snapshot.
Debug: Including rpool/DATA/postgresql for recursive snapshot.
Debug: Including rpool/DATA/vm for regular snapshot.
Debug: Including rpool/DATA/vm/alderaan.example.net for recursive snapshot.
Debug: Including rpool/DATA/vm/bespin.example.net for recursive snapshot.
Debug: Including rpool/DATA/vm/coruscant.example.net for recursive snapshot.
Debug: Including rpool/DATA/vm/dagobah.example.net for recursive snapshot.
Debug: Including rpool/DATA/vm/dantooine.example.net for recursive snapshot.
Debug: Including rpool/DATA/vm/dev.example.net for recursive snapshot.
Debug: Including rpool/DATA/vm/monitor.example.net for recursive snapshot.
Debug: Including rpool/DATA/vm/office.example.net for recursive snapshot.
Debug: Including rpool/DATA/vm/test.example.net for recursive snapshot.
Debug: Including rpool/ROOT for recursive snapshot.
Debug: Excluding rpool/ROOT/ubuntu-1 because rpool/ROOT includes it recursively.
Doing regular snapshots of rpool rpool/DATA rpool/DATA/vm
Doing recursive snapshots of rpool/DATA/ldap rpool/DATA/postgresql rpool/DATA/vm/alderaan.example.net rpool/DATA/vm/bespin.example.net rpool/DATA/vm/coruscant.example.net rpool/DATA/vm/dagobah.example.net rpool/DATA/vm/dantooine.example.net rpool/DATA/vm/dev.example.net rpool/DATA/vm/monitor.example.net rpool/DATA/vm/office.example.net rpool/DATA/vm/test.example.net rpool/ROOT
Doing a dry run. Not running these commands...
zfs snapshot -o com.sun:auto-snapshot-desc='-'  'rpool@zfs-auto-snap_frequent-2013-04-16-2348'
zfs destroy  'rpool@zfs-auto-snap_frequent-2013-04-16-2315'
zfs snapshot -o com.sun:auto-snapshot-desc='-'  'rpool/DATA@zfs-auto-snap_frequent-2013-04-16-2348'
zfs destroy  'rpool/DATA@zfs-auto-snap_frequent-2013-04-16-2315'
zfs snapshot -o com.sun:auto-snapshot-desc='-'  'rpool/DATA/vm@zfs-auto-snap_frequent-2013-04-16-2348'
zfs destroy  'rpool/DATA/vm@zfs-auto-snap_frequent-2013-04-16-2315'
zfs snapshot -o com.sun:auto-snapshot-desc='-' -r 'rpool/DATA/ldap@zfs-auto-snap_frequent-2013-04-16-2348'
zfs destroy -r 'rpool/DATA/ldap@zfs-auto-snap_frequent-2013-04-16-2315'
zfs snapshot -o com.sun:auto-snapshot-desc='-' -r 'rpool/DATA/postgresql@zfs-auto-snap_frequent-2013-04-16-2348'
zfs destroy -r 'rpool/DATA/postgresql@zfs-auto-snap_frequent-2013-04-16-2315'
zfs snapshot -o com.sun:auto-snapshot-desc='-' -r 'rpool/DATA/vm/alderaan.example.net@zfs-auto-snap_frequent-2013-04-16-2348'
zfs destroy -r 'rpool/DATA/vm/alderaan.example.net@zfs-auto-snap_frequent-2013-04-16-2315'
zfs snapshot -o com.sun:auto-snapshot-desc='-' -r 'rpool/DATA/vm/bespin.example.net@zfs-auto-snap_frequent-2013-04-16-2348'
zfs destroy -r 'rpool/DATA/vm/bespin.example.net@zfs-auto-snap_frequent-2013-04-16-2315'
zfs snapshot -o com.sun:auto-snapshot-desc='-' -r 'rpool/DATA/vm/coruscant.example.net@zfs-auto-snap_frequent-2013-04-16-2348'
zfs destroy -r 'rpool/DATA/vm/coruscant.example.net@zfs-auto-snap_frequent-2013-04-16-2315'
zfs snapshot -o com.sun:auto-snapshot-desc='-' -r 'rpool/DATA/vm/dagobah.example.net@zfs-auto-snap_frequent-2013-04-16-2348'
zfs destroy -r 'rpool/DATA/vm/dagobah.example.net@zfs-auto-snap_frequent-2013-04-16-2315'
zfs snapshot -o com.sun:auto-snapshot-desc='-' -r 'rpool/DATA/vm/dantooine.example.net@zfs-auto-snap_frequent-2013-04-16-2348'
zfs destroy -r 'rpool/DATA/vm/dantooine.example.net@zfs-auto-snap_frequent-2013-04-16-2315'
zfs snapshot -o com.sun:auto-snapshot-desc='-' -r 'rpool/DATA/vm/dev.example.net@zfs-auto-snap_frequent-2013-04-16-2348'
zfs destroy -r 'rpool/DATA/vm/dev.example.net@zfs-auto-snap_frequent-2013-04-16-2315'
zfs snapshot -o com.sun:auto-snapshot-desc='-' -r 'rpool/DATA/vm/monitor.example.net@zfs-auto-snap_frequent-2013-04-16-2348'
zfs destroy -r 'rpool/DATA/vm/monitor.example.net@zfs-auto-snap_frequent-2013-04-16-2315'
zfs snapshot -o com.sun:auto-snapshot-desc='-' -r 'rpool/DATA/vm/office.example.net@zfs-auto-snap_frequent-2013-04-16-2348'
zfs destroy -r 'rpool/DATA/vm/office.example.net@zfs-auto-snap_frequent-2013-04-16-2315'
zfs snapshot -o com.sun:auto-snapshot-desc='-' -r 'rpool/DATA/vm/test.example.net@zfs-auto-snap_frequent-2013-04-16-2348'
zfs destroy -r 'rpool/DATA/vm/test.example.net@zfs-auto-snap_frequent-2013-04-16-2315'
zfs snapshot -o com.sun:auto-snapshot-desc='-' -r 'rpool/ROOT@zfs-auto-snap_frequent-2013-04-16-2348'
zfs destroy -r 'rpool/ROOT@zfs-auto-snap_frequent-2013-04-16-2315'
@zfs-auto-snap_frequent-2013-04-16-2348, 15 created, 15 destroyed, 0 warnings.

real	3m30.995s
user	0m0.152s
sys	0m0.792s
root@tatooine:/root# 

I'm not an awk god, so I tried a bit until I got a working version. There might be better ways. I also don't know if this catches every adge case, but it is a start for improvement. :)
2013-04-17 01:07:00 +03:00
3 changed files with 88 additions and 5 deletions

View File

@ -11,5 +11,7 @@ install:
install etc/zfs-auto-snapshot.cron.daily $(DESTDIR)$(PREFIX)/etc/cron.daily/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)$(PREFIX)/etc/cron.monthly/zfs-auto-snapshot
install -d $(DESTDIR)$(PREFIX)/share/man/man8
install src/zfs-auto-snapshot.8 $(DESTDIR)$(PREFIX)/share/man/man8/zfs-auto-snapshot.8
install -d $(DESTDIR)$(PREFIX)/sbin
install src/zfs-auto-snapshot.sh $(DESTDIR)$(PREFIX)/sbin/zfs-auto-snapshot

70
src/zfs-auto-snapshot.8 Normal file
View File

@ -0,0 +1,70 @@
.TH ZFS-AUTO-SNAPSHOT "8" "June 16, 2013" "zfs-auto-snapshot.sh" "System Administration Commands"
.SH NAME
zfs-auto-snapshot \- take regular ZFS snapshots
.SH SYNOPSIS
.B zfs-auto-snapshot
[\fIoptions\fR] [\fI-l label\fR] \fI<'//' | name \fR[\fIname\fR...]\fI>\fR
.SH DESCRIPTION
.B zfs-auto-snapshot
automatically creates, rotates, and destroys snapshots for all your
ZFS datasets, and is compatible with both zfsonlinux and zfs-fuse.
.SH OPTIONS
.TP
\fB\-\-default\-exclude\fR
By default \fBzfs-auto-snapshot\fR will snapshot all datasets except
for those in which the user-property \fBcom.sun:auto-snapshot\fR is
set to \fBfalse\fR. This option reverses the behavior and requires
\fBcom.sun:auto-snapshot\fR to be set to \fBtrue\fR.
.TP
\fB\-d\fR, \fB\-\-debug\fR
Print debugging messages.
.TP
\fB\-e\fR, \fB\-\-event\fR=\fIEVENT\fR
Set the com.sun:auto\-snapshot\-desc property to EVENT.
.TP
\fB\-\-fast\fR
Use a faster zfs list invocation.
.TP
\fB\-n\fR, \fB\-\-dry\-run\fR
Print actions without actually doing anything.
.TP
\fB\-s\fR, \fB\-\-skip\-scrub\fR
Do not snapshot filesystems in scrubbing pools.
.TP
\fB\-h\fR, \fB\-\-help\fR
Print the usage message.
.TP
\fB\-k\fR, \fB\-\-keep\fR=\fINUM\fR
Keep NUM recent snapshots and destroy older snapshots.
.TP
\fB\-l\fR, \fB\-\-label\fR=\fILAB\fR
LAB is usually 'hourly', 'daily', or 'monthly'.
.TP
\fB\-p\fR, \fB\-\-prefix\fR=\fIPRE\fR
PRE is 'zfs\-auto\-snap' by default.
.TP
\fB\-q\fR, \fB\-\-quiet\fR
Suppress warnings and notices at the console.
.TP
\fB\-\-send\-full\fR=\fIF\fR
Send zfs full backup. Unimplemented.
.TP
\fB\-\-send\-incr\fR=\fIF\fR
Send zfs incremental backup. Unimplemented.
.TP
\fB\-\-sep\fR=\fICHAR\fR
Use CHAR to separate date stamps in snapshot names.
.TP
\fB\-g\fR, \fB\-\-syslog\fR
Write messages into the system log.
.TP
\fB\-r\fR, \fB\-\-recursive\fR
Snapshot named filesystem and all descendants.
.TP
\fB\-v\fR, \fB\-\-verbose\fR
Print info messages.
.TP
name
Filesystem and volume names, or '//' for all ZFS datasets.
.SH SEE ALSO
.BR zfs (8)

View File

@ -29,6 +29,7 @@ opt_backup_incremental=''
opt_default_exclude=''
opt_dry_run=''
opt_event='-'
opt_fast_zfs_list=''
opt_keep=''
opt_label=''
opt_prefix='zfs-auto-snap'
@ -54,6 +55,7 @@ print_usage ()
--default-exclude Exclude datasets if com.sun:auto-snapshot is unset.
-d, --debug Print debugging messages.
-e, --event=EVENT Set the com.sun:auto-snapshot-desc property to EVENT.
--fast Use a faster zfs list invocation.
-n, --dry-run Print actions without actually doing anything.
-s, --skip-scrub Do not snapshot filesystems in scrubbing pools.
-h, --help Print this usage message.
@ -193,7 +195,7 @@ do_snapshots () # properties, flags, snapname, oldglob, [targets...]
# {
GETOPT=$(getopt \
--longoptions=default-exclude,dry-run,skip-scrub,recursive \
--longoptions=default-exclude,dry-run,fast,skip-scrub,recursive \
--longoptions=event:,keep:,label:,prefix:,sep: \
--longoptions=debug,help,quiet,syslog,verbose \
--options=dnshe:l:k:p:rs:qgv \
@ -226,6 +228,10 @@ do
fi
shift 2
;;
(--fast)
opt_fast_zfs_list='1'
shift 1
;;
(-n|--dry-run)
opt_dry_run='1'
shift 1
@ -339,9 +345,14 @@ 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") \
|| { print_log error "zfs list $?: $ZFS_LIST"; exit 136; }
SNAPSHOTS_OLD=$(env LC_ALL=C zfs list -H -t snapshot -S creation -o name) \
|| { print_log error "zfs list $?: $SNAPSHOTS_OLD"; exit 137; }
if [ -n "$opt_fast_zfs_list" ]
then
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; }
else
SNAPSHOTS_OLD=$(env LC_ALL=C zfs list -H -t snapshot -S creation -o name) \
|| { print_log error "zfs list $?: $SNAPSHOTS_OLD"; exit 137; }
fi
# Verify that each argument is a filesystem or volume.
for ii in "$@"
@ -493,7 +504,7 @@ 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.
DATE=$(date +%F-%H%M)
DATE=$(date --utc +%F-%H%M)
# The snapshot name after the @ symbol.
SNAPNAME="$opt_prefix${opt_label:+$opt_sep$opt_label-$DATE}"