X-Git-Url: http://git.pippins.net/embedvideo/.git/?a=blobdiff_plain;f=zfs-replicate;h=8b53d1fb0d4e7a53f4475778cb21c02fc4047251;hb=b12a5ad3bc477a5369871300b89f5a658df11554;hp=413d078e05cf28311896be3d7d94bcca454aa6d0;hpb=a7cc781d51dcfb24d9a062bdb60ba76ea79be676;p=zfs-nexenta%2F.git diff --git a/zfs-replicate b/zfs-replicate index 413d078..8b53d1f 100755 --- a/zfs-replicate +++ b/zfs-replicate @@ -1,26 +1,24 @@ -#/bin/bash +#!/bin/bash +# Author: Carl Baldwin & Alan Pippin +# Description: This script replicates a remote zfs filesystem to a local zfs pool. +# This script will keep all snapshots in sync, removing the ones +# that have been deleted since the last replicate was performed. +# This script will only send the new, or missing, snapshots since +# the last replicate was performed. # Usage: replicate + +# source our configuration +config="${0%/*}/zfs-scripts.conf" +[ -e "${config}.dist" ] && . ${config}.dist +[ -e "${config}" ] && . ${config} + +# command line arg parsing remote=$1 remote_fs=$2 remote_pool=${2%%/*} -remote_lockdir="/tmp/zfs-admin-lock" hostname=`hostname` -# Set the name of the local pool used to store the backup of the remote -local_pool=backups - -# Set the email address to send notification to -mailto=root@pippins.net -mailx=/usr/bin/mailx - -# When this variable is set, local filesystems will be destroyed -# before receiving a full streams into them from the remote source. -destroy_local_filesystem_on_full_replicate=0 - -# The ssh connection doesn't find zfs without this. -zfs=/usr/sbin/zfs - # Setup our cleanup and exit trap cleanup() { if [[ -e "$local_list" ]]; then @@ -30,17 +28,32 @@ cleanup() { rm -f $remote_list fi if [[ -n "$remote" ]]; then - ssh $remote ls -d "$remote_lockdir" > /dev/null 2>&1 + ssh $remote ls -d "$lockdir" > /dev/null 2>&1 if [[ $? == 0 ]]; then - ssh $remote rm -rf "$remote_lockdir" + ssh $remote rm -rf "$lockdir" fi fi } fatal_and_exit() { echo -e 2>&1 "$1" + # Destroy the backup markers on the local filesystem if they exist + if [[ -n "$current_backup_marker" ]]; then + zfs list -t snapshot ${local_pool}/${current_backup_marker} > /dev/null 2>&1 + if [ $? == 0 ]; then + $zfs destroy ${local_pool}/${current_backup_marker} + fi + fi + if [[ -n "$previous_backup_marker" ]]; then + zfs list -t snapshot ${local_pool}/${previous_backup_marker} > /dev/null 2>&1 + if [ $? == 0 ]; then + $zfs destroy ${local_pool}/${previous_backup_marker} + fi + fi + # send email notification if [[ -n "$2" ]]; then echo -e "$1" | $mailx -s "zfs replicate on $hostname failed" "$2" fi + # exit exit 1 } trap fatal_and_exit INT @@ -79,10 +92,10 @@ set -x # Create the remote lockdir before continuing with the replicate # Spinlock on creating the lock maxsleeptime=60 -maxattempts=100 +maxattempts=500 attempts=0 while true; do - ssh $remote mkdir "$remote_lockdir" >/dev/null 2>&1 + ssh $remote mkdir "$lockdir" >/dev/null 2>&1 if [ $? != 0 ]; then # Another zfs admin tool is running. # Wait a random amount of time and try again @@ -96,7 +109,7 @@ while true; do if [[ $attempts -gt $maxattempts ]]; then # We've exceeded our maximum while loop count echo "-E- The zfs filesystem has been locked down. Skipping replicate operation." - fail_msg=`ssh $remote ls -ld $remote_lockdir 2>&1` + fail_msg=`ssh $remote ls -ld $lockdir 2>&1` fatal_and_exit "zfs-replicate-all unable to obtain zfs admin lock:\n$fail_msg" $mailto fi done @@ -164,8 +177,13 @@ if [ $no_markers == 0 ]; then fatal_and_exit "-E- remote incremental $zfs rollback command failed" $mailto fi # Now it should be safe to send the snaps - ssh $remote $zfs send -R -I${previous_backup_marker} ${current_backup_marker} | - $zfs receive -vF -d ${local_pool}/${remote_pool} + if [[ $throttle_enable == 1 && -e $throttle ]]; then + ssh $remote $zfs send -R -I${previous_backup_marker} ${current_backup_marker} | + $throttle $throttle_opt | $zfs receive -vF -d ${local_pool}/${remote_pool} + else + ssh $remote $zfs send -R -I${previous_backup_marker} ${current_backup_marker} | + $zfs receive -vF -d ${local_pool}/${remote_pool} + fi if [ $? != 0 ]; then fatal_and_exit "-E- remote incremental $zfs send command failed" $mailto fi @@ -184,8 +202,13 @@ else if [[ -n "$common" ]]; then # We found a common snapshot, incrementally send the new snaps - ssh $remote $zfs send -R -I${common/*@/@} ${current_backup_marker} | - $zfs receive -vF -d ${local_pool}/${remote_pool} + if [[ $throttle_enable == 1 && -e $throttle ]]; then + ssh $remote $zfs send -R -I${common/*@/@} ${current_backup_marker} | + $throttle $throttle_opt | $zfs receive -vF -d ${local_pool}/${remote_pool} + else + ssh $remote $zfs send -R -I${common/*@/@} ${current_backup_marker} | + $zfs receive -vF -d ${local_pool}/${remote_pool} + fi if [ $? != 0 ]; then fatal_and_exit "-E- remote incremental $zfs send command failed" $mailto fi @@ -207,8 +230,13 @@ else fi fi # Send the full filesystem - ssh $remote $zfs send -R ${current_backup_marker} | - $zfs receive -vF -d ${local_pool}/${remote_pool} + if [[ $throttle_enable == 1 && -e $throttle ]]; then + ssh $remote $zfs send -R ${current_backup_marker} | + $throttle $throttle_opt | $zfs receive -vF -d ${local_pool}/${remote_pool} + else + ssh $remote $zfs send -R ${current_backup_marker} | + $zfs receive -vF -d ${local_pool}/${remote_pool} + fi if [ $? != 0 ]; then fatal_and_exit "-E- remote full $zfs send command failed" $mailto fi