From 15bbf270bea1d5438043b72182b0cd275b61602d Mon Sep 17 00:00:00 2001 From: Tim Foster Date: Mon, 14 Jul 2008 00:47:24 +0100 Subject: [PATCH] 0.11 work, part 1 - perf improvements for //, shell style, minor bugfixes --- README.zfs-auto-snapshot.txt | 20 +- src/auto-snapshot-instance.xml | 3 +- src/lib/svc/method/zfs-auto-snapshot | 397 +++++++++--------- src/pkginfo | 2 +- src/postinstall | 2 + src/preremove | 13 +- src/prototype | 2 +- src/samples/auto-snapshot-space-archive.xml | 2 +- .../auto-snapshot-space-timf,backup.xml | 2 +- .../auto-snapshot-space-timf,daily.xml | 2 +- .../auto-snapshot-space-timf,frequent.xml | 2 +- .../auto-snapshot-space-timf,monthly.xml | 2 +- src/samples/auto-snapshot-tank-rootfs.xml | 2 +- .../system/filesystem/auto-snapshot-daily.xml | 11 +- .../filesystem/auto-snapshot-frequent.xml | 13 +- .../filesystem/auto-snapshot-hourly.xml | 13 +- .../filesystem/auto-snapshot-monthly.xml | 13 +- .../filesystem/auto-snapshot-weekly.xml | 13 +- .../system/filesystem/zfs-auto-snapshot.xml | 108 ++--- 19 files changed, 304 insertions(+), 318 deletions(-) diff --git a/README.zfs-auto-snapshot.txt b/README.zfs-auto-snapshot.txt index 5b43422..4415fd0 100644 --- a/README.zfs-auto-snapshot.txt +++ b/README.zfs-auto-snapshot.txt @@ -1,15 +1,14 @@ NAME -ZFS Automatic Snapshot SMF Service, version 0.10 - +ZFS Automatic Snapshot SMF Service, version 0.11 DESCRIPTION -This is a simple SMF service which you can configure to take automatic, -scheduled snapshots of any given ZFS filesystem as well as perform simple -incremental or full backups of that filesystem. +This is a simple SMF service which can will take automatic, +scheduled snapshots of given ZFS filesystems and can perform simple +incremental or full backups of those filesystems. Documentation for the service is contained in the manifest file, zfs-auto-snapshot.xml. @@ -21,11 +20,10 @@ This GUI is installed in the GNOME menu under: Administration -> Automatic Snapshots We also bundle a simple GUI application, which will query the user for the -properties required, and will proceed to build an instance manifest. This +properties required, and will then build an instance manifest. This GUI is documented as part of the installation instructions below. - INSTALLATION To install, as root, pkgadd TIMFauto-snapshot. This package now contains @@ -64,6 +62,10 @@ The properties each instance needs are: command: # zfs set com.sun:auto-snapshot:frequent=true tank/timf + When the "snap-children" property is set to true, + only locally-set filesystem properties are used to + determine which filesystems to snapshot - + property inheritance is not respected. zfs/interval [ hours | days | months ] @@ -110,7 +112,7 @@ Usage: zfs-auto-snapshot-admin.sh [zfs filesystem name] EXAMPLES -The following shows me running it for the ZFS filesystem +The following shows us running it for the ZFS filesystem "tank/root_filesystem". timf@haiiro[593] ./zfs-auto-snapshot-admin.sh tank/root_filesystem @@ -144,5 +146,7 @@ http://blogs.sun.com/timf/entry/zfs_automatic_snapshot_service_logging http://blogs.sun.com/timf/entry/zfs_automatic_snapshots_0_8 http://blogs.sun.com/timf/entry/zfs_automatic_for_the_people http://blogs.sun.com/timf/entry/zfs_automatic_snapshots_0_10 +http://blogs.sun.com/timf/entry/zfs_automatic_snapshots_0_11 The ZFS Automatic Snapshot SMF Service is released under the terms of the CDDL. + diff --git a/src/auto-snapshot-instance.xml b/src/auto-snapshot-instance.xml index aaf4e2c..22eb537 100644 --- a/src/auto-snapshot-instance.xml +++ b/src/auto-snapshot-instance.xml @@ -4,7 +4,7 @@ + version='0.11'> @@ -12,7 +12,6 @@ &1 | fgrep -e '-r') + # this function validates the properties in the FMRI passed to it, then # calls a function to create cron job that schedules a snapshot schedule based # on the properties set in the service instance. @@ -84,22 +95,21 @@ function schedule_snapshots { case $BACKUP in 'full' | 'incremental' ) - if [ -z "${BACKUP_SAVE_CMD}" ] - then - check_failure 1 "Backup requested, but no backup command specified." - fi + if [ -z "${BACKUP_SAVE_CMD}" ] ; then + check_failure 1 \ + "Backup requested, but no backup command specified." + fi ;; esac # for now, we're forcing the offset to be 0 seconds. typeset OFFSET=0 - if [ "$FILESYS" != "//" ] - then - # validate the filesystem - zfs list $FILESYS 2>&1 1> /dev/null - check_failure $? "ZFS filesystem does not exist!" - fi + if [ "$FILESYS" != "//" ] ; then + # validate the filesystem + zfs list $FILESYS 2>&1 1> /dev/null + check_failure $? "ZFS filesystem does not exist!" + fi # remove anything that's there at the moment unschedule_snapshots $FMRI @@ -108,11 +118,10 @@ function schedule_snapshots { # finally, check our status before we return STATE=$(svcprop -p restarter/state $FMRI) - if [ "${STATE}" == "maintenance" ] - then - STATE=1 + if [ "${STATE}" == "maintenance" ] ; then + STATE=1 else - STATE=0 + STATE=0 fi return $STATE } @@ -139,51 +148,53 @@ function add_cron_job { # $INTERVAL $PERIOD $OFFSET $FMRI case $INTERVAL in 'minutes') - TIMES=$(get_divisor 0 59 $PERIOD) - ENTRY="$TIMES * * * *" + TIMES=$(get_divisor 0 59 $PERIOD) + ENTRY="$TIMES * * * *" ;; 'hours') - TIMES=$(get_divisor 0 23 $PERIOD) - ENTRY="0 $TIMES * * *" + TIMES=$(get_divisor 0 23 $PERIOD) + ENTRY="0 $TIMES * * *" ;; 'days') - TIMES=$(get_divisor 1 31 $PERIOD) - ENTRY="0 0 $TIMES * *" + TIMES=$(get_divisor 1 31 $PERIOD) + ENTRY="0 0 $TIMES * *" ;; 'months') - TIMES=$(get_divisor 1 12 $PERIOD) - ENTRY="0 0 1 $TIMES *" + TIMES=$(get_divisor 1 12 $PERIOD) + ENTRY="0 0 1 $TIMES *" ;; esac # Since we may have multiple instances all trying to start at # the same time, we need some form of locking around crontab. - # Normally we'd be able to get SMF to manage this, by defining dependencies - + # Normally we'd be able to get SMF to manage this, by defining dependencies - # but I'm not sure there's a way to prevent it from starting two instances # at the same time (without requiring users to explicitly state dependencies # and change them each time new instances are added) - # This isn't perfect (eg. if someone else if running crontab at the + # This isn't perfect (eg. if someone else is running crontab at the # same time as us, we'll fail) but it'll do for now. LOCK_OWNED="false" - while [ "$LOCK_OWNED" == "false" ] - do - mkdir /tmp/zfs-auto-snapshot-lock - if [ $? -eq 0 ] - then - LOCK_OWNED=true - else - sleep 1 - fi + while [ "$LOCK_OWNED" == "false" ] ; do + mkdir /tmp/zfs-auto-snapshot-lock > /dev/null 2>&1 + if [ $? -eq 0 ] ; then + LOCK_OWNED=true + else + sleep 1 + fi done # adding a cron job is essentially just looking for an existing entry, # removing it, and appending a new one. Neato. - crontab -l | grep -v "/lib/svc/method/zfs-auto-snapshot $FMRI$" > /tmp/saved-crontab.$$ - echo "${ENTRY} /lib/svc/method/zfs-auto-snapshot $FMRI" >> /tmp/saved-crontab.$$ + crontab -l | grep -v "/lib/svc/method/zfs-auto-snapshot $FMRI$" \ + > /tmp/saved-crontab.$$ + + echo "${ENTRY} /lib/svc/method/zfs-auto-snapshot $FMRI" \ + >> /tmp/saved-crontab.$$ + crontab /tmp/saved-crontab.$$ check_failure $? "Unable to add cron job!" @@ -203,18 +214,18 @@ function unschedule_snapshots { # See notes on $LOCK_OWNED variable in function add_cron_job LOCK_OWNED="false" - while [ "$LOCK_OWNED" == "false" ] - do - mkdir /tmp/zfs-auto-snapshot-lock - if [ $? -eq 0 ] - then - LOCK_OWNED=true - else - sleep 1 - fi - done + while [ "$LOCK_OWNED" == "false" ]; do + mkdir /tmp/zfs-auto-snapshot-lock > /dev/null 2>&1 + if [ $? -eq 0 ] ; then + LOCK_OWNED=true + else + sleep 1 + fi + done + + crontab -l | grep -v "/lib/svc/method/zfs-auto-snapshot $FMRI$" \ + > /tmp/saved-crontab.$$ - crontab -l | grep -v "/lib/svc/method/zfs-auto-snapshot $FMRI$" > /tmp/saved-crontab.$$ crontab /tmp/saved-crontab.$$ check_failure $? "Unable to unschedule snapshots for $FMRI" @@ -223,21 +234,19 @@ function unschedule_snapshots { # finally, check our status before we return STATE=$(svcprop -p restarter/state $FMRI) - if [ "${STATE}" == "maintenance" ] - then - STATE=1 + if [ "${STATE}" == "maintenance" ] ; then + STATE=1 else - STATE=0 + STATE=0 fi } -# This function actually takes the snapshot of the filesystem. This is what -# really does the work. We name snapshots based on a standard time format +# This function actually takes the snapshot of the filesystem. # $1 is assumed to be a valid FMRI function take_snapshot { - - typeset FMRI=$1 + # want this to be global, used by check_failure + FMRI=$1 typeset DATE=$(date +%F-%H${SEP}%M${SEP}%S) typeset FILESYS=$(svcprop -p zfs/fs-name $FMRI) @@ -245,8 +254,8 @@ function take_snapshot { typeset SNAP_CHILDREN=$(svcprop -p zfs/snapshot-children $FMRI) typeset BACKUP=$(svcprop -p zfs/backup $FMRI) - typeset STATE=0 + typeset STATE=0 # an identifier allows us to setup multiple snapshot schedules # per filesystem - so we append a