diff --git a/Changelog b/Changelog
new file mode 100644
index 0000000..b28c348
--- /dev/null
+++ b/Changelog
@@ -0,0 +1,81 @@
+0.11
+
+* Add RBAC support
+ - the service now runs under a zfssnap role
+ - service start/stop logs stay under /var/svc/log
+ - other logs saved to /export/home/zfssnap (and syslog)
+* Add a 'zfs/interval' property value 'none' which doesn't use cron
+* Add a 'zfs/fs-name' property value '##'
+* Add a cache of svcprops to the method script
+* Add a com.sun:auto-snapshot user property, com.sun:auto-snapshot:$LABEL
+ takes precedence
+* Remove the seconds field of the snapshot name - we don't really need it
+* Make recursive snapshots the default for bundled '//' manifests
+* Changed the way // works with recursive snapshots
+ (look for local props only when using -r)
+* Set avoidscrub to false by default (bug was fixed in in nv_94)
+* Bugfix from Dan - Volumes are datasets too
+* Automatically snapshot everything by setting com.sun:auto-snapshot=true
+ on startup. (this gets done on all root pools - existing properties set
+ to false will override this)
+* Check for missed snapshots on startup
+* Clean up shell style
+* Clean up preremove script
+* Write this Changelog
+
+0.10
+
+* Bugfix from Reid Spencer - Tim can't spell "RECURSIVE" (hah, I can now!:-)
+* Bugfix from Breandan Dezendorf - Labelled snapshots not being destroyed correctly
+* Ability to avoid taking snapshots when pool scrubs are in progress
+
+0.9
+
+* SVR4 packaging (with ugly postinstall/preremove scripts)
+* Add some canned instances for frequent,daily,hourly,weekly,monthly snapshots
+* Add 'zfs/fs-name' '//' property value
+* Change the timeout for the start/stop methods to infinity
+* Allow power users to avoid having ':' in snapshot names via $SEP
+* Add GUI utilities and some basic GNOME integration
+
+0.8
+
+* Bugfix from Dick Davies - fencepost error in crontab entries
+* Add locking around crontab updates
+* Add zfs/verbose feature for more logging if you really need it
+
+0.7
+
+* Bugfix from Bill Sommerfeld - make less logging noise
+* Add logging to syslog
+
+0.6
+
+* Option to take backups using zfs send after snapshots are taken
+* Allow us to have multiple schedules per filesystem (add labels)
+* Better fault handling - drop SMF instance to 'maintenance' if stuff goes wrong
+
+0.5
+
+* Bugfix from Joe Little - recursive snapshots weren't respecting retention limits
+
+0.4
+
+* Make zenity gui work on s10u2
+* Clean up the logic that the gui uses to name different instances
+
+0.3
+
+* Add snapshot retention limits
+
+0.2
+
+* Fix the gui to show a different string when changing the interval
+* Fix a bug where seperate instances were removing each other's cron jobs
+
+0.1
+
+* Take periodic snapshots using cron and SMF
+* Snapshot children
+* Add zenity gui to create SMF manifests
+
diff --git a/README.zfs-auto-snapshot.txt b/README.zfs-auto-snapshot.txt
index 3845e97..28179b3 100644
--- a/README.zfs-auto-snapshot.txt
+++ b/README.zfs-auto-snapshot.txt
@@ -27,7 +27,7 @@ GUI is documented as part of the installation instructions below.
INSTALLATION
To install, as root, pkgadd TIMFauto-snapshot. This package now contains
-several canned SMF instances which are enabled by default. These are:
+several canned SMF instances. These are:
online 1:17:43 svc:/system/filesystem/zfs/auto-snapshot:hourly
online 1:17:46 svc:/system/filesystem/zfs/auto-snapshot:monthly
@@ -149,10 +149,13 @@ you can now import the manifest for this instance, using the command :
then issue the command :
# svcadm enable svc:/system/filesystem/zfs/auto-snapshot:tank-root_filesystem
-You can see what work will be done by checking your crontab. As of version
-0.7, all logging from the service is done from the method script using
-the print_log function, which uses logger(1) to send message to syslogd(1M)
-at priority level "daemon.notice".
+
+The service is run by a restricted role "zfssnap", which is created when installing
+the service. It has the "ZFS File System Administration" RBAC Profile, as well
+as the solaris.smf.manage.zfs-auto-snapshot Authorization. In order to see what
+the service is doing, you can view the SMF log files in /var/svc/log for each
+service instance and syslog, with more detailed logging output being sent to
+the log files in the zfssnap role's home directory. (/export/home/zfssnap, by default)
SEE ALSO
diff --git a/src/i.manifest b/src/i.manifest
new file mode 100755
index 0000000..72ebfdd
--- /dev/null
+++ b/src/i.manifest
@@ -0,0 +1,76 @@
+#!/bin/sh
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# i.manifest - smf(5) service manifest install class action script
+#
+
+repfile=$PKG_INSTALL_ROOT/etc/svc/repository.db
+export repfile
+
+#
+# If the repository does not yet exist, create it from the appropriate seed. If
+# for some reason the seeds do not exist, svccfg(1M) will create the repository
+# automatically.
+#
+if [ ! -f $repfile ]; then
+ if [ -n "$SUNW_PKG_INSTALL_ZONENAME" -a \
+ "$SUNW_PKG_INSTALL_ZONENAME" != "global" ]; then
+ [ -f $PKG_INSTALL_ROOT/lib/svc/seed/nonglobal.db ] && \
+ /usr/bin/cp $PKG_INSTALL_ROOT/lib/svc/seed/nonglobal.db \
+ $repfile
+ else
+ [ -f $PKG_INSTALL_ROOT/lib/svc/seed/global.db ] && \
+ /usr/bin/cp $PKG_INSTALL_ROOT/lib/svc/seed/global.db \
+ $repfile
+ fi
+ /usr/bin/chmod 0600 $repfile
+ /usr/bin/chown root:sys $repfile
+fi
+
+if [ ! -r $PKG_INSTALL_ROOT/etc/svc/volatile/repository_door ]; then
+ #
+ # smf(5) is not presently running for the destination environment.
+ # Since we presently cannot refresh without a running svc.startd(1M), we
+ # cannot consistently handle dependent placement. Defer to next boot.
+ #
+ while read src dst; do
+ /usr/bin/cp -p $src $dst
+ done
+else
+ #
+ # Local package install.
+ #
+ while read src dst; do
+ /usr/bin/cp -p $src $dst
+
+ [ "$PKG_INSTALL_ROOT" = "" -o "$PKG_INSTALL_ROOT" = "/" ] && \
+ SVCCFG_CHECKHASH=1 /usr/sbin/svccfg import $dst
+ done
+fi
+
+exit 0
diff --git a/src/lib/svc/method/zfs-auto-snapshot b/src/lib/svc/method/zfs-auto-snapshot
index 5fa0404..d864ff5 100755
--- a/src/lib/svc/method/zfs-auto-snapshot
+++ b/src/lib/svc/method/zfs-auto-snapshot
@@ -52,6 +52,7 @@
result=$SMF_EXIT_OK
+export PATH=/usr/sbin:/usr/bin:${PATH}
# A prefix we use on all snapshot created by this script.
# See the definition of $SNAPNAME in the take_snapshot()
@@ -76,6 +77,9 @@ LOG=""
# a null string in this variable says we don't.
HAS_RECURSIVE=$(zfs snapshot 2>&1 | fgrep -e '-r')
+# OpenSolaris has no pfksh, so for now, we need to pfexec
+# all calls to zfs that require privileges
+PFZFS="pfexec zfs"
function get_pair {
NAME=$1
@@ -95,7 +99,7 @@ SMF_PROPS="$(svcprop -t -p zfs -p restarter/logfile $1 |\
-e 's#zfs/backup-lock#zfs/backup_lock#g' \
-e 's#zfs/snapshot-children#zfs/snapshot_children#g' \
-e 's#zfs/backup-save-cmd#zfs/backup_save_cmd#g' \
- -e 's#zfs/##g' -e 's/$/,/g')"
+ -e 's#zfs/##g' -e 's#restarter/##g' -e 's/$/,/g')"
IFS=,
for line in $SMF_PROPS ; do
IFS='
@@ -377,7 +381,13 @@ function take_snapshot {
FMRI=$1
zfs_smf_props $FMRI
- export LOG=$logfile
+ # When taking snapshots, because we're running as a role
+ # and can't redirect our output through SMF, we don't have
+ # permissions to log to /var/svc/log, so we instead log
+ # to the role's home directory.
+ LOG_BASE=$(basename $logfile)
+ export LOG="$HOME/$LOG_BASE"
+
typeset DATE=$(date +%F-%H${SEP}%M)
typeset FILESYS="$fs_name"
typeset KEEP=$keep
@@ -466,20 +476,20 @@ function take_snapshot {
for child in $(zfs list -r -H -o name -t filesystem,volume $fs) ; do
destroy_older_snapshots $child $KEEP $LABEL
print_note "Taking snapshot $child@$SNAPNAME"
- zfs snapshot $child@$SNAPNAME
+ $PFZFS snapshot $child@$SNAPNAME
check_failure $? "Unable to take snapshot $child@$SNAPNAME."
done
else
destroy_older_snapshots $fs $KEEP $LABEL $HAS_RECURSIVE
print_note "Taking recursive snapshot $fs@$SNAPNAME"
- zfs snapshot -r $fs@$SNAPNAME
+ $PFZFS snapshot -r $fs@$SNAPNAME
check_failure $? "Unable to take recursive snapshots of $fs@$SNAPNAME."
fi
else
destroy_older_snapshots $fs $KEEP $LABEL
print_note "Taking snapshot $fs@$SNAPNAME"
- zfs snapshot $fs@$SNAPNAME
+ $PFZFS snapshot $fs@$SNAPNAME
check_failure $? "Unable to take snapshot $fs@$SNAPNAME."
fi
@@ -532,7 +542,7 @@ function destroy_older_snapshots {
# using print_note, as this checks our $VERBOSE flag
print_note "$snapshot being destroyed ${RECURSIVE} as per \
retention policy."
- zfs destroy ${RECURSIVE} $snapshot
+ $PFZFS destroy ${RECURSIVE} $snapshot
check_failure $? "Unable to destroy $snapshot" "NON_FATAL"
else
# don't destroy this one
@@ -697,12 +707,12 @@ function take_backup { # filesystem backup-type label fmri
case $BACKUP in
"incremental")
print_note "Starting incr. ZFS send of differences between $PREV_SNAP and $LAST_SNAP."
- zfs send -i $PREV_SNAP $LAST_SNAP | $BACKUP_SAVE_CMD
+ $PFZFS send -i $PREV_SNAP $LAST_SNAP | $BACKUP_SAVE_CMD
check_failure $? "Error performing incremental backup of $dataset."
;;
"full")
print_note "Starting ZFS send of $LAST_SNAP."
- zfs send $LAST_SNAP | $BACKUP_SAVE_CMD
+ $PFZFS send $LAST_SNAP | $BACKUP_SAVE_CMD
check_failure $? "Error performing full backup of $dataset."
;;
esac
@@ -826,7 +836,7 @@ function auto_include {
*false | false*)
;;
*)
- zfs set com.sun:auto-snapshot=true $pool
+ $PFZFS set com.sun:auto-snapshot=true $pool
;;
esac
fi
diff --git a/src/postinstall b/src/postinstall
index a59c173..a1a4d07 100755
--- a/src/postinstall
+++ b/src/postinstall
@@ -25,6 +25,58 @@
# Use is subject to license terms.
#
-# a postinstall script - it should import the manifests
-# and enable the service
-echo "Post install script doing nathing!"
+# a postinstall script - adds zfssnap role.
+# Return 0 if a user exists, 1 otherwise.
+#
+
+# Check if the first argument is 0, settting our return
+# variable to an error otherwise
+#
+function check_error {
+ RETURN_CODE=$1
+ ERROR="$2"
+ if [ "$RETURN_CODE" -ne 0 ] ; then
+ echo "ERROR: $ERROR"
+ fi
+}
+
+function user_exists {
+ typeset USER=$1
+ if /usr/bin/grep ^$USER: $BASEDIR/etc/passwd > /dev/null ; then
+ return 0
+ else
+ return 1
+ fi
+}
+
+function auth_exists {
+ typeset AUTH=$1
+ if /usr/bin/grep ^$AUTH: $BASEDIR/etc/security/auth_attr > /dev/null ; then
+ return 0
+ else
+ return 1
+ fi
+}
+
+# add our authorization
+if ! auth_exists solaris.smf.manage.zfs-auto-snapshot; then
+ echo "solaris.smf.manage.zfs-auto-snapshot:::Manage the ZFS Automatic Snapshot Service::" \
+ >> /etc/security/auth_attr
+fi
+
+# add the zfssnap role - probably only works on a local system :-(
+if ! user_exists zfssnap; then
+ /usr/sbin/roleadd -d /export/home/zfssnap -c "ZFS Automatic Snapshots role" \
+ -P "ZFS File System Management" \
+ -A solaris.smf.manage.zfs-auto-snapshot -m zfssnap
+ check_error $? "Unable to create zfssnap role!"
+ /usr/bin/passwd -r files -N zfssnap
+ check_error $? "Unable to make zfssnap a no-password account"
+
+ # make sure their path has /usr/sbin in it
+ echo "PATH=/usr/sbin:\${PATH}" >> /export/home/zfssnap/.profile
+ echo "export PATH" >> /export/home/zfssnap/.profile
+else
+ echo "zfssnap role already exists."
+fi
+
diff --git a/src/r.manifest b/src/r.manifest
new file mode 100755
index 0000000..489f786
--- /dev/null
+++ b/src/r.manifest
@@ -0,0 +1,83 @@
+#!/bin/sh
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# r.manifest - smf(5) manifest remove class action script
+#
+
+if [ "$PKG_INSTALL_ROOT" != "" -a "$PKG_INSTALL_ROOT" != "/" ]; then
+ #
+ # We can't safely disable the service in this case.
+ #
+ smf_alive=no
+else
+ #
+ # We can verify if the service is disabled prior to
+ # removal.
+ #
+ if [ -r /etc/svc/volatile/repository_door ]; then
+ smf_alive=yes
+ fi
+fi
+
+MFSTSCAN=/lib/svc/bin/mfstscan
+SVCCFG=/usr/sbin/svccfg
+SVCPROP=/usr/bin/svcprop
+
+while read mfst; do
+ if [ "$smf_alive" = "yes" ]; then
+ ENTITIES=`$SVCCFG inventory $mfst`
+
+ for fmri in $ENTITIES; do
+ #
+ # Determine whether any of our instances are
+ # enabled.
+ #
+ en_p=`$SVCPROP -C -p general/enabled $fmri 2>/dev/null`
+ en_o=`$SVCPROP -C -p general_ovr/enabled $fmri 2>/dev/null`
+
+ if [ "$en_p" = "true" -o "$en_o" = "true" ]; then
+ echo "$fmri remains enabled; aborting"
+ exit 1
+ fi
+
+ $SVCCFG delete $fmri
+ done
+
+ #
+ # Delete the manifest hash value.
+ #
+ pg_name=`$MFSTSCAN -t $mfst`
+ if $SVCPROP -q -p $pg_name smf/manifest; then
+ $SVCCFG -s smf/manifest delpg $pg_name
+ fi
+ fi
+
+ /usr/bin/rm $mfst
+done
+
+exit 0
diff --git a/src/var/svc/manifest/system/filesystem/auto-snapshot-daily.xml b/src/var/svc/manifest/system/filesystem/auto-snapshot-daily.xml
index 0c20d8e..81ed4dd 100644
--- a/src/var/svc/manifest/system/filesystem/auto-snapshot-daily.xml
+++ b/src/var/svc/manifest/system/filesystem/auto-snapshot-daily.xml
@@ -21,13 +21,21 @@ snapshots into the past.
type='method'
name='start'
exec='/lib/svc/method/zfs-auto-snapshot start'
- timeout_seconds='0' />
+ timeout_seconds='0'>
+
+
+
+
+ timeout_seconds='0' >
+
+
+
+
diff --git a/src/var/svc/manifest/system/filesystem/auto-snapshot-frequent.xml b/src/var/svc/manifest/system/filesystem/auto-snapshot-frequent.xml
index 6701fd7..ee3179b 100644
--- a/src/var/svc/manifest/system/filesystem/auto-snapshot-frequent.xml
+++ b/src/var/svc/manifest/system/filesystem/auto-snapshot-frequent.xml
@@ -17,19 +17,27 @@ com.sun:auto-snapshot:frequent=true every
+
+
+
+
+
+
+ type='method'
+ name='stop'
+ exec='/lib/svc/method/zfs-auto-snapshot stop'
+ timeout_seconds='0' >
+
+
+
+
-
-
-
+
diff --git a/src/var/svc/manifest/system/filesystem/auto-snapshot-hourly.xml b/src/var/svc/manifest/system/filesystem/auto-snapshot-hourly.xml
index eec69bf..76f0e9f 100644
--- a/src/var/svc/manifest/system/filesystem/auto-snapshot-hourly.xml
+++ b/src/var/svc/manifest/system/filesystem/auto-snapshot-hourly.xml
@@ -18,16 +18,24 @@ and keeps 24 of these snapshots into the past.
+ type='method'
+ name='start'
+ exec='/lib/svc/method/zfs-auto-snapshot start'
+ timeout_seconds='0'>
+
+
+
+
-
+
+
+
+
+
diff --git a/src/var/svc/manifest/system/filesystem/auto-snapshot-monthly.xml b/src/var/svc/manifest/system/filesystem/auto-snapshot-monthly.xml
index d4a9178..1b7bcfe 100644
--- a/src/var/svc/manifest/system/filesystem/auto-snapshot-monthly.xml
+++ b/src/var/svc/manifest/system/filesystem/auto-snapshot-monthly.xml
@@ -18,16 +18,24 @@ and keeps 12 of these snapshots into the past.
+ type='method'
+ name='start'
+ exec='/lib/svc/method/zfs-auto-snapshot start'
+ timeout_seconds='0'>
+
+
+
+
-
+
+
+
+
+
diff --git a/src/var/svc/manifest/system/filesystem/auto-snapshot-weekly.xml b/src/var/svc/manifest/system/filesystem/auto-snapshot-weekly.xml
index fa41274..bea8d0e 100644
--- a/src/var/svc/manifest/system/filesystem/auto-snapshot-weekly.xml
+++ b/src/var/svc/manifest/system/filesystem/auto-snapshot-weekly.xml
@@ -18,16 +18,24 @@ and keeps 4 of these snapshots into the past.
+ type='method'
+ name='start'
+ exec='/lib/svc/method/zfs-auto-snapshot start'
+ timeout_seconds='0'>
+
+
+
+
-
+
+
+
+
+
diff --git a/src/var/svc/manifest/system/filesystem/zfs-auto-snapshot.xml b/src/var/svc/manifest/system/filesystem/zfs-auto-snapshot.xml
index a8a77cf..b7e1f71 100755
--- a/src/var/svc/manifest/system/filesystem/zfs-auto-snapshot.xml
+++ b/src/var/svc/manifest/system/filesystem/zfs-auto-snapshot.xml
@@ -56,6 +56,14 @@
+
+
+
+
+
+