forked from extern/zfs-auto-snapshot
Version 0.5
This commit is contained in:
parent
2b68923d8d
commit
5759424d8e
62
README.zfs-auto-snapshot.txt
Normal file
62
README.zfs-auto-snapshot.txt
Normal 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
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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' >
|
||||
|
@ -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 ""
|
||||
|
@ -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.
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user