zfs_backup
#!/bin/ksh93 -p
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (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
#
# Script to back up file systems based on the names of their snapshots.
#
#
# Usage: zfs_backup [ -p namespec ] source [[user@]host]destination
#
# If sending to a remote system this is done via ssh so the users needs
# to have the "ZFS File System Management" profile.
#
snapname=day
function remote_dest
{
if [[ ${dest_host:-${this_host}} == ${this_host} ]]
then
if [[ $1 == "-n" ]]
then
shift
fi
$@
else
echo ssh -CxA -o CompressionLevel=9 $dest_host $@ >&2
ssh -CxA -o CompressionLevel=9 $dest_host $@
fi
return $?
}
function do_pans
{
typeset depth=0
typeset -a arr
while read snapshot
do
if ! test_snap $snapshot
then
while (( depth >= 0))
do
send_snap $snapshot $arr[$depth]
let depth=depth-1
done
return
else
arr[depth]=$snapshot
let depth=depth+1
fi
done
send_snap $snapshot
while (( depth >= 0))
do
send_snap $snapshot $arr[$depth]
let depth=depth-1
done
}
typeset -ft do_snap
function do_snap
{
typeset snapshot
typeset fs=$1
typeset last_sn
while read snapshot
do
typeset xfs=${snapshot%@*}
typeset sn=${snapshot#*@}
if [[ ${fs} != ${xfs} ]]
then
continue
fi
if [[ ${sn#${snapname}} == ${sn} ]]
then
continue
fi
if [[ "$last_sn" != "" ]]
then
if ! remote_dest -n pfexec /usr/sbin/zfs list ${dest_fs}${fs#${src}}@${snapshot#*@} > /dev/null 2>&1
then
echo pfexec /usr/sbin/zfs send -i $last_sn ${snapshot} remote_dest pfexec /usr/sbin/zfs receive ${zFORCE:+-F} ${dest_fs}${fs#${src}} || exit
pfexec /usr/sbin/zfs send -i $last_sn ${snapshot} |\
remote_dest "${BUFFER} pfexec /usr/sbin/zfs receive ${zFORCE:+-F} ${dest_fs}${fs#${src}}" || exit
fi
else
if ! remote_dest -n pfexec /usr/sbin/zfs list ${dest_fs}${fs#${src}} > /dev/null 2>&1
then
echo pfexec /usr/sbin/zfs send ${snapshot}
pfexec /usr/sbin/zfs send ${snapshot} | \
remote_dest "${BUFFER} pfexec /usr/sbin/zfs receive ${dest_fs}${fs#${src}}"
fi
fi
last_sn=${snapshot}
done
}
function do_fs
{
typeset x
while read x
do
echo $x
(pfexec /usr/sbin/zfs list -o name -H -t snapshot -r $x | do_snap $x) < /dev/null
done
}
function usage
{
print "USAGE: $0 [ -p prefix ] from to" >&2
exit
}
while getopts p:F c
do
case $c in
p) snapname=$OPTARG ;;
F) zFORCE=F ;;
\?) usage; exit ;;
esac
done
shift $(($OPTIND – 1))
(( $# < 1 )) && usage
src=$1
dest_fs=${2#*:}
dest_host=${2%:*}
if [[ $dest_host == $2 ]]
then
dest_host=""
fi
this_host=$(uname -n)
if [[ ${dest_host:-${this_host}} == ${this_host} ]]
then
BUFFER=""
else
BUFFER="/usr/local/bin/buffer -v |"
fi
pfexec /usr/sbin/zfs list -r -o name -H -t filesystem $src| do_fs
Trackbacks & Pingbacks