diff --git a/README.zfs-auto-snapshot.txt b/README.zfs-auto-snapshot.txt new file mode 100644 index 0000000..4c14aaa --- /dev/null +++ b/README.zfs-auto-snapshot.txt @@ -0,0 +1,62 @@ +ZFS Automatic Snapshot SMF Service, version 0.5 + +Introduction +----------- + +This is a *prototype* of a simple SMF service which you can configure to +take automatic, scheduled snapshots of any given ZFS filesystem. + + +Usage Instructions +------------------ + +To install, as root, run the following commands: + +# cp zfs-auto-snapshot/lib/svc/method/zfs-auto-snapshot /lib/svc/method +# svccfg import zfs-auto-snapshot/zfs-auto-snapshot.xml + +Once you have installed these, you need to create an instance of the service +for each set of ZFS snapshots you want to take. The properties we need are: + + zfs/fs-name The name of the filesystem + zfs/interval [ hours | days | months ] + zfs/keep How many snapshots to retain. "all" keeps all snapshots. + zfs/period How often you want to take snapshots + (eg. every 10 days) + zfs/snapshot-children "true" if you would like to recursively take snapshots + of all child filesystems of the specified fs-name. + + +An example instance manifest is included in this archive, and the default +instance (which should be disabled) is also documented. + +The script "zfs-auto-snapshot-admin.sh" is a simple shell wrapper which uses +zenity, a scriptable GUI framework in GNOME, to write a service manifest +based on user input. + +# ./zfs-auto-snapshot-admin.sh +Usage: zfs-auto-snapshot-admin.sh [zfs filesystem name] + +The following shows me running it for the ZFS filesystem +"tank/root_filesystem". + +timf@haiiro[593] ./zfs-auto-snapshot-admin.sh tank/root_filesystem +[ a set of dialogs appear, asking for input ] +Thanks, now assuming the default SMF manifest has already been imported, +you can now import the manifest for this instance, using the command : + + # svccfg import auto-snapshot-instance.xml + +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. + +The ZFS Automatic Snapshot SMF Service is released under the terms of the CDDL. + +More background detail about this service can be found in blog posts at: + +http://blogs.sun.com/roller/page/timf?entry=zfs_automatic_snapshots_prototype_1 +http://blogs.sun.com/roller/page/timf?entry=zfs_automatic_snapshots_smf_service +http://blogs.sun.com/roller/page/timf?entry=and_also_for_s10u2_zfs + diff --git a/lib/svc/method/zfs-auto-snapshot b/lib/svc/method/zfs-auto-snapshot index 1388939..3120fde 100755 --- a/lib/svc/method/zfs-auto-snapshot +++ b/lib/svc/method/zfs-auto-snapshot @@ -1,5 +1,25 @@ #!/usr/bin/ksh +# +# 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 2006 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. @@ -191,26 +211,27 @@ function take_snapshot { function destroy_older_snapshots { FILESYS=$1 - KEEP=$2 - if [ "${KEEP}" == "all" ] + COUNTER=$2 + + if [ "${COUNTER}" == "all" ] then return 0 fi - KEEP=$(($KEEP - 1)) + COUNTER=$(($COUNTER - 1)) # walk through the snapshots, newest first, destroying older ones for snapshot in $(zfs list -r -t snapshot -H -o name $FILESYS \ | grep $FILESYS@zfs-auto-snap | sort -r) do - if [ $KEEP -le 0 ] + if [ $COUNTER -le 0 ] then echo "$snapshot being destroyed as per retention policy." zfs destroy $snapshot check_failure $? "Unable to destroy $snapshot" else # don't destroy this one - KEEP=$(($KEEP - 1)) + COUNTER=$(($COUNTER - 1)) fi done } diff --git a/sample-auto-snapshot-instance.xml b/sample-auto-snapshot-instance.xml index e214334..e365f3b 100644 --- a/sample-auto-snapshot-instance.xml +++ b/sample-auto-snapshot-instance.xml @@ -1,10 +1,32 @@ + + version='0.4'> diff --git a/zfs-auto-snapshot-admin.sh b/zfs-auto-snapshot-admin.sh index ee1caa3..61c8a56 100755 --- a/zfs-auto-snapshot-admin.sh +++ b/zfs-auto-snapshot-admin.sh @@ -1,5 +1,25 @@ #!/bin/ksh +# +# 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 2006 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. @@ -9,9 +29,41 @@ # This script implements a simple wizard to schedule the taking of regular # snapshots of this file system. Most of the interesting stuff is at the bottom. # +# Since we'd like it to work with two different versions of zenity, we check +# the version string, and call the appropriate "_26" versions of functions +# if we need to. (zenity that ships in s10u2 is based on GNOME 2.6 and doesn't +# have the same functionality as the 2.14-based zenity) MAIN_TITLE="Take regular ZFS snapshots" +function get_interval_26 { + # Get an interval for taking snapshots + # zenity 2.6 doesn't support the --text option to --list + TITLE="${MAIN_TITLE}: Choose a time period for taking snapshots " + INTERVAL=$(zenity --list --title="${TITLE}" \ + --radiolist --column="select" \ + --column="interval" x "minutes" x "hours" x "days" x "months") + if [ $? -eq 1 ] + then + exit 1; + fi + case $INTERVAL in + 'minutes') + MAX_VAL=60 + ;; + 'hours') + MAX_VAL=24 + ;; + 'days') + MAX_VAL=31 + ;; + 'months') + MAX_VAL=12 + ;; + esac + +} + function get_interval { # get an interval to take snapshots at @@ -41,6 +93,20 @@ function get_interval { } +function get_period_26 { + # work out the period we want between snapshots + # zenity 2.6 doesn't support the --scale option, use a text entry instead. + TITLE="${MAIN_TITLE}: Interval" + TEXT="Enter how often you want to take snapshots (eg. every 10 ${INTERVAL})" + PERIOD=$(zenity --entry --title="${TITLE}" --text="${TEXT}" \ + --entry-text=10) + if [ $? -eq 1 ] + then + exit 1; + fi + +} + function get_period { # work out the period we want between snapshots TITLE="${MAIN_TITLE}: Interval" @@ -54,6 +120,24 @@ function get_period { } +function get_maxsnap_26 { + # choose a number of snapshots to save + # zenity 2.6 doesn't support the --scale option, use a text entry instead + TITLE="${MAIN_TITLE}: Number to save" + TEXT="Choose a maximum number of snapshots to keep, Cancel disables the limit\n\ + \n\ + (Note: once you hit this number of snapshots, the oldest will be\n\ + automatically deleted to make room)" + KEEP_SNAP=$(zenity --entry --title="${TITLE}" \ + --text="${TEXT}" --entry-text="all") + + if [ $? -eq 1 ] + then + KEEP_SNAP="all" + fi +} + + function get_maxsnap { # choose a number of snapshots to save TITLE="${MAIN_TITLE}: Number to save" @@ -85,11 +169,6 @@ function get_snap_children { function show_summary { # let's give the user a summary of what we've done: - echo "SMF instance built to take snapshots using variables:" - echo "interval=$INTERVAL" - echo "period=$PERIOD" - echo "keep_num=$KEEP_SNAP" - echo "recurse=$SNAP_CHILDREN" TITLE="${MAIN_TITLE}: Summary" TEXT="The following snapshot schedule will be created :\n\n\ @@ -99,6 +178,7 @@ function show_summary { Keep snapshots = ${KEEP_SNAP}\n\ Snapshot Children = ${SNAP_CHILDREN}\n\n\ Do you want to write this auto-snapshot manifest now ?" + zenity --question --title="${TITLE}" --text="${TEXT}" if [ $? -eq 1 ] then @@ -118,20 +198,39 @@ fi FILESYS=$1 -#zfs list $FILESYS 2>&1 1> /dev/null +zfs list $FILESYS 2>&1 1> /dev/null if [ $? -ne 0 ] then echo "Unable to see filesystem $1. Exiting now." exit 1; fi -get_interval -get_period -get_maxsnap -get_snap_children -show_summary -ESCAPED_NAME=$(echo $1 | sed -e 's#/#-#g') +VERSION=$(zenity --version) +if [ "$VERSION" == "2.6.0" ] +then + get_interval_26 + get_period_26 + get_maxsnap_26 + get_snap_children + show_summary + +else + # using a more up to date zenity + get_interval + get_period + get_maxsnap + get_snap_children + show_summary +fi + +# this is what works out the instance name: we can't have . or / +# characters in instance names, so we escape them appropriately +# eg. the auto snapshots for the ZFS filesystem tank/tims-fs are +# taken by the SMF instance +# svc:/system/filesystem/zfs/auto-snapshot:tank-tims--fs +ESCAPED_NAME=$(echo $1 | sed -e 's#-#--#g' | sed -e 's#/#-#g' \ + | sed -e 's#\.#-#g') # Now we can build an SMF manifest to perform these actions... @@ -142,7 +241,7 @@ cat > auto-snapshot-instance.xml < + version='0.4'> @@ -185,7 +284,8 @@ cat > auto-snapshot-instance.xml < EOF -echo "Thanks, now import the SMF manifest, using the command :" +echo "Thanks, now assuming the default SMF manifest has already been imported," +echo "you can now import the manifest for this instance, using the command :" echo "" echo " # svccfg import auto-snapshot-instance.xml" echo "" diff --git a/zfs-auto-snapshot.xml b/zfs-auto-snapshot.xml index 824c6e0..6eb39d4 100755 --- a/zfs-auto-snapshot.xml +++ b/zfs-auto-snapshot.xml @@ -2,6 +2,26 @@