Skip to content

Instantly share code, notes, and snippets.

@bdha
Created January 24, 2012 05:13
Show Gist options
  • Save bdha/1668130 to your computer and use it in GitHub Desktop.
Save bdha/1668130 to your computer and use it in GitHub Desktop.
#!/bin/bash
if ! [ $3 ] ; then
echo "$0 <SOURCE POOL/DATASET> <TARGET_HOST> <TARGET POOL/DATASET>"
exit 1
fi
SRC=$1
TARGET_HOST=$2
DST=$3
SSH="ssh -C -p 2222 -o ConnectionAttempts=2 -o ConnectTimeout=10 -o BatchMode=yes"
KILLFILE=/root/.zfs_repl_kill
EMAIL="sysadmins"
if [ -f $KILLFILE ] ; then
echo "$KILLFILE found. zfs_repl will run once."
fi
function die {
echo $1 | /bin/mailx -s "FAIL: zfs_repl on `hostname` has failed" $EMAIL
exit 1
}
function quit {
echo $1 | /bin/mailx -s "FAIL: zfs_repl on `hostname` has stopped" $EMAIL
exit 0
}
while true ; do
STAMP=$( date '+%Y%m%d%H%M%S' )
DATE="[$( date +%Y%m%d-%H:%M:%S )]"
echo "$DATE [`hostname`] Creating $SRC@repl-$TARGET_HOST-$STAMP"
zfs snapshot -r $SRC@repl-$TARGET_HOST-$STAMP || die "Could not create snapshot: $SRC@repl-$TARGET_HOST-$STAMP"
for FS in $( zfs list -t filesystem -rH -o name $SRC ) ; do
NEWSNAP="$FS@repl-$TARGET_HOST-$STAMP"
LASTSNAP=$( zfs list -rH -o name -t snapshot $SRC | grep ^$FS@repl-$TARGET_HOST | grep -v $STAMP | tail -1 )
if [ $LASTSNAP ] ; then
echo "$DATE [`hostname`] Sending $LASTSNAP -> $NEWSNAP"
SEND=$( zfs send -i $LASTSNAP $NEWSNAP | $SSH $TARGET_HOST zfs recv -vdF $DST | grep -v receiving )
echo "$DATE [$TARGET_HOST] $SEND"
else
echo "$DATE [`hostname`] Sending INITIAL snapshot $NEWSNAP"
SEND=$( zfs send $NEWSNAP | $SSH $TARGET_HOST zfs recv -vdF $DST | grep -v receiving )
echo "$DATE [$TARGET_HOST] $SEND"
fi
done
$SSH $TARGET_HOST zfs list -rH -o name $NEWSNAP > /dev/null
if [ $? != 0 ] ; then
ERROR="$DATE [ERROR] snapshot does not exist on $TARGET_HOST:$NEWSNAP; dying"
echo "$ERROR"
die $ERROR
fi
L_SNAPS=$( zfs list -t snapshot -o name | grep repl | grep $SRC | grep $TARGET_HOST | wc -l )
R_SNAPS=$( $SSH $TARGET_HOST zfs list -t snapshot -o name | grep repl | grep $SRC | grep $TARGET_HOST | wc -l )
if [ "$L_SNAPS" != "$R_SNAPS" ] ; then
ERROR="$DATE [ERROR] Missing snapshots. Local:$L_SNAPS Remote:$R_SNAPS"
echo "$ERROR"
die $ERROR
fi
for OLD in $( zfs list -t snapshot -rH -o name $SRC | grep "@repl-$TARGET_HOST-" ) ; do
OLD_DATE=$( echo $OLD | sed -e "s/^.*@repl-$TARGET_HOST-//" )
if [ $OLD_DATE != $STAMP ] ; then
echo "$DATE [`hostname`] Destroying $OLD (current: $STAMP)"
zfs destroy $OLD
echo "$DATE [$TARGET_HOST] Destroying $OLD (current: $STAMP)"
$SSH $TARGET_HOST zfs destroy $OLD
fi
done
if [ -f $KILLFILE ] ; then
ERROR="$DATE $KILLFILE found, exiting."
echo $ERROR
rm $KILLFILE
quit "$ERROR"
fi
x=0
echo -n "$DATE sleeping"
while [ $x -lt 10 ]; do
echo -n "."
x=`expr $x + 1`
sleep 1
done
echo
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment