--- /dev/null
+#!/bin/bash
+
+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 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
+
+# This converts the YYYY-MM-DD.hh.mm format to an integer.
+datetime_to_minutes() {
+ perl -n -e '/(\d+)-(\d+)-(\d+)\.(\d+)\.(\d+)/; print $1 * 527040 + $2 * 44640 + $3 * 1440 + $4 * 60 + $5,"\n"'
+}
+
+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=$1
+numsnapshots=$2
+
+snapshotdir="/${filesystem}/.zfs/snapshot"
+
+# Get the various components of the date
+datetime=${ZFSDATETIME:-$(date +%Y-%m-%d.%H.%M)}
+
+# Create the snapshot for this minute
+echo "-I- Creating ${filesystem}@${datetime}"
+zfs snapshot "${filesystem}@${datetime}"
+
+lockdir="/tmp/zfs-admin-lock"
+if ! mkdir "$lockdir" >/dev/null 2>&1; then
+ exit 0
+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
+ snapminutes=$(echo "$snapshot" | sed 's,.*/,,' | datetime_to_minutes)
+ snapminutes2=$(echo "$snapshot" | sed 's,.*/,,' | datetime_to_minutes2)
+ age=$((minutes - snapminutes))
+ window=1
+ while true; do
+ if [ $age -lt $((window * numsnapshots)) ]; then
+ case $((snapminutes2 % window)) in
+ 0) ;;
+ *)
+ snapname=$(echo "$snapshot" |
+ sed 's,/\(.*\)/.zfs/snapshot/\(.*\),\1@\2,')
+ echo "-I- Destroying $snapname"
+ zfs destroy "$snapname"
+ ;;
+ esac
+ break
+ fi
+ window=$((window*2))
+ done
+done