Created
February 13, 2019 10:51
-
-
Save AaronJackson/5455f4119b1e9dc82ce556007e16c46b to your computer and use it in GitHub Desktop.
ZFS incremental backup over SSH
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
source_pool=$1 | |
first_sync=$2 | |
if [ $first_sync ] ; then | |
echo "You have asked for an initial sync." | |
echo "If you didn't mean this, you have five five seconds to cancel it." | |
sleep 5 | |
fi | |
if [ ! $source_pool ] ; then exit ; fi | |
LOCK=/root/mirror.$source_pool.lock | |
if [ -f $LOCK ] ; then | |
# We don't want to create another local snapshot before we are | |
# sure the remote is going to be able to receive it | |
exit 1 | |
fi | |
touch $LOCK | |
# Setup/variables: | |
snapshot_string=DO_NOT_DELETE_remote_replication_ | |
timestamp=$(/usr/bin/date '+%Y%m%d%H%M%S') | |
destination_pool=tank/${source_pool} | |
new_snap="$source_pool"@"$snapshot_string""$timestamp" | |
destination_host=cvl-store-0 | |
# Ensure that the remote host is UP | |
ping -c1 $destination_host &>/dev/null || exit 1 | |
# Initial send: | |
if [ $first_sync ] ; then | |
zfs snapshot -r "$new_snap" | |
zfs send -R "$new_snap" | ssh "$destination_host" zfs recv -Fdu "$destination_pool" | |
rm $LOCK | |
exit 0 | |
fi | |
# Incremental sends: | |
# Get old snapshot name. | |
old_snap=$(zfs list -H -o name -t snapshot -r "$source_pool" | grep "$source_pool"@"$snapshot_string" | tail --lines=1) | |
# Let's make sure the name on the remote host matches the local name. | |
remote_old_snap=$(ssh "$destination_host" zfs list -H -o name -t snapshot -r "$destination_pool" | \ | |
grep "$snapshot_string" | tail -n1) | |
check_l=$(echo $old_snap | cut -d@ -f2) | |
check_r=$(echo $remote_old_snap | cut -d@ -f2) | |
if [ $check_l != $check_r ] ; then | |
echo "pool $source_pool is out of sync." | |
echo "Lock file perserved to avoid further attempts." | |
exit 1 | |
fi | |
# Create new recursive snapshot of the whole pool. | |
zfs snapshot -r "$new_snap" | |
# Incremental replication via SSH. | |
zfs send -R -I "$old_snap" "$new_snap" | ssh "$destination_host" zfs recv -Fdu "$destination_pool" | |
# Delete older snaps on the local source | |
delete_from=$(zfs list -H -o name -t snapshot -r "$source_pool" | grep "$snapshot_string" | grep -v "$timestamp") | |
for snap in $delete_from; do | |
zfs destroy "$snap" | |
done | |
rm $LOCK |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment