Version 0.5

This commit is contained in:
Tim Foster 2008-06-29 18:32:47 +01:00
parent 2b68923d8d
commit 5759424d8e
5 changed files with 245 additions and 20 deletions

View File

@ -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

View File

@ -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
}

View File

@ -1,10 +1,32 @@
<?xml version="1.0"?>
<!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1">
<!--
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
-->
<service_bundle type='manifest' name='space-timf'>
<service
name='system/filesystem/zfs/auto-snapshot'
type='service'
version='0.3'>
version='0.4'>
<create_default_instance enabled='false' />
<instance name='space-timf' enabled='false' >

View File

@ -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 <<EOF
<service
name='system/filesystem/zfs/auto-snapshot'
type='service'
version='0.3'>
version='0.4'>
<create_default_instance enabled='false' />
<instance name='$ESCAPED_NAME' enabled='false' >
@ -185,7 +284,8 @@ cat > auto-snapshot-instance.xml <<EOF
</service_bundle>
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 ""

View File

@ -2,6 +2,26 @@
<!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1">
<!--
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.