Alan's additions
authorCarl N. Baldwin <carl@ecbaldwin.net>
Sun, 10 Feb 2008 03:34:16 +0000 (20:34 -0700)
committerCarl N. Baldwin <carl@ecbaldwin.net>
Sun, 10 Feb 2008 03:34:16 +0000 (20:34 -0700)
snap.sh

diff --git a/snap.sh b/snap.sh
index c5d2985ec120e2651573b0d8c82327ffd3760f5b..077e6f7ca30ff1942e55eff548a0abb50139697a 100755 (executable)
--- a/snap.sh
+++ b/snap.sh
@@ -2,17 +2,12 @@
 
 exec >> /var/log/snap.log 2>&1
 
-# This script makes a number of assumptions about how I am handling things.
-#  * filesystems are mounted on the directory with the same name.  It is
-#    possible to mount them elsewhere in Solaris but I do not.
-#   * examples
-#     * "tank" is mounted on /tank
-#     * "tank/home" is mounted on /tank/home
+# This script makes the following assumptions/requirements:
 #  * this script only handles one zfs filesystem, a wrapper should be created
 #    to handle more
 #  * this script handles all snapshots that are named in this format:
 #    YYYY-MM-DD.hh.mm
-#   * It ignores other snapshots
+#  * It ignores other snapshots that don't follow this naming convention
 
 # This converts the YYYY-MM-DD.hh.mm format to an integer.
 datetime_to_minutes() {
@@ -23,13 +18,40 @@ datetime_to_minutes2() {
   perl -n -e '/(\d+)-(\d+)-(\d+)\.(\d+)\.(\d+)/; $monthadj=int(($2-1)/3)-1; $minadj=int($5/15); $houradj=int($4/3); print $1 * 1048576 + ( $2 + $monthadj ) * 65536 + $3 * 2048 + ( $4 + $houradj ) * 64 + $5 + $minadj,"\n"'
 }
 
-# This number is the number of equally spaced snapshots that should exist over
-# any given period in the past.
-
+# filesystem: This is the zfs filesystem to snapshot
+# mountpoint: This is the mountpoint of the zfs filesystem to snapshot
+# numsnapshots: This number is the number of equally spaced snapshots that should exist over any given period in the past
+# maxagedays: This is the maximum number of days to keep any snapshot around for (0=infinite) (default=0).
 filesystem=$1
-numsnapshots=$2
+mountpoint=$2
+numsnapshots=${3-12}
+maxagedays=${4-0}
+lockdir="/tmp/${filesystem}.lock"
+pool=`echo "$filesystem" | awk -F '/' '{ print $1 }'`
+
+if [ -z "$filesystem" ] || [ -z "$mountpoint" ] || [ -z "$numsnapshots" ] || [ -z "$maxagedays" ]; then
+   echo "-E- Usage: $0 <filesystem> <mountpoint> <numsnapshots> <maxagedays>"
+   exit 1
+fi
+
+if [ ! -d "$mountpoint" ]; then
+   echo "-E- Unable to find the mountpoint: $mountpoint"
+   exit 1
+fi
+
+snapshotdir="${mountpoint}/.zfs/snapshot"
+if [ ! -d "$snapshotdir" ]; then
+   echo "-E- Unable to find the snapshotdir: $snapshotdir"
+   exit 1
+fi
 
-snapshotdir="/${filesystem}/.zfs/snapshot"
+# Check to see if this zfs filesystem has a scrub being performed on it now.
+# If it does, we cannot perform any snapshot create or destroy operations.
+zpool status $pool | grep scrub: | grep "in progress" > /dev/null 2>&1
+if [ $? == 0 ]; then
+   echo "-W- The zfs pool '$pool' is currently being scrubbed. Skipping all snapshot operations."
+   exit 0
+fi
 
 # Get the various components of the date
 datetime=${ZFSDATETIME:-$(date +%Y-%m-%d.%H.%M)}
@@ -38,6 +60,8 @@ datetime=${ZFSDATETIME:-$(date +%Y-%m-%d.%H.%M)}
 echo "-I- Creating ${filesystem}@${datetime}"
 zfs snapshot "${filesystem}@${datetime}"
 
+minutes=$(echo $datetime | datetime_to_minutes)
+
 lockdir="/tmp/zfs-admin-lock"
 if ! mkdir "$lockdir" >/dev/null 2>&1; then
   exit 0
@@ -45,8 +69,6 @@ fi
 cleanup() { rm -rf "$lockdir"; }
 trap cleanup EXIT
 
-minutes=$(echo $datetime | datetime_to_minutes)
-
 # Trim them down
 snapshots=$(ls -d ${snapshotdir}/????-??-??.??.?? 2>/dev/null)
 for snapshot in $snapshots; do
@@ -69,4 +91,10 @@ for snapshot in $snapshots; do
     fi
     window=$((window*2))
   done
+  if [ $maxagedays -gt 0 ] && [ $age -gt $((maxagedays * 24 * 60)) ]; then
+    snapname=$(echo "$snapshot" |
+                     sed 's,/\(.*\)/.zfs/snapshot/\(.*\),\1@\2,')
+    echo "-I- Destroying old $snapname"
+    zfs destroy "$snapname"
+  fi
 done