scripts/zfsync.sh

79 lines
2.6 KiB
Bash
Executable File

#!/bin/sh
# zfsync: sync zfs pool(s) between two servers
# in case of failure, unexpected reboot while syncing, etc.:
#
# launch "zfsync.sh init"
#
# or manually:
#
# - destroy all snapshots on both local & $bro
# - for i in ftp web mail; do zfs snapshot servers/$i/home@newsync ;done
# - for i in ftp web mail; do zfs send servers/$i/home@newsync | ssh "$bro" zfs receive -vFd servers ;done
# - for i in ftp web mail; do zfs rename servers/$i/home@newsync servers/$i/home@prevsync ;done
# - ssh "$bro" 'for i in ftp web mail; do zfs rename servers/$i/home@newsync servers/$i/home@prevsync ;done'
bro="{{ bro }}"
pools="ftp mail web"
SENDZABBIX="zabbix_sender --config /usr/local/etc/zabbix6/zabbix_agentd.conf --key check.zfsync"
HOSTNAME=$(/bin/hostname -f | /usr/bin/cut -d '.' -f 1,1)
LOCKFILE=/tmp/zfsync.lock
ZROOT=zdata/servers
echo "$(date): ZFSync starting."
if [ -e "$LOCKFILE" ]
then
echo "ERROR: $0 is already running with pid $(cat $LOCKFILE), check $LOCKFILE"
exit 1
fi
echo ${$}>$LOCKFILE
alert()
{
${SENDZABBIX} --value 1 >/dev/null
exit $?
}
if [ "$1" ]
then
if [ "$1" = "init" ]
then
echo "wiping previous syncs"
for snapshot in $(zfs list -t snapshot -o name | grep -e prevsync -e newsync); do zfs destroy "$snapshot" ; done
ssh -q "$bro" 'for snapshot in $(zfs list -t snapshot -o name | grep -e prevsync -e newsync); do zfs destroy $snapshot ; done'
echo "making full snapshots"
for jail in $pools; do zfs snapshot "$ZROOT/$jail/home@newsync";done
echo "sending full snapshots"
for jail in $pools; do zfs send "$ZROOT/$jail/home@newsync" | ssh -q "$bro" 'zfs receive -vFdu zdata' ;done
echo "renaming them to use them as a base for diff snapshots"
for jail in $pools; do zfs rename "$ZROOT/$jail/home@newsync" "$ZROOT/$jail/home@prevsync" ;done
ssh -q "$bro" 'for jail in ftp mail web; do zfs rename zdata/servers/$jail/home@newsync zdata/servers/$jail/home@prevsync ;done'
exit $?
fi
fi
for pool in $pools
do
dataset="$ZROOT/${pool}/home"
echo "making new snapshot for ${pool}"
zfs snapshot "${dataset}@newsync" || alert
echo "sending snapshot"
ssh -q "$bro" "zfs set readonly=on ${dataset}" || alert
sleep 2
zfs send -i @prevsync "${dataset}@newsync" | ssh -q "$bro" "zfs receive -vFdu zdata" || alert
ssh -q "$bro" "zfs set readonly=off ${dataset}" || alert
echo "cleaning"
zfs destroy "${dataset}@prevsync" || alert
zfs rename "${dataset}@newsync" "${dataset}@prevsync" || alert
ssh -q "$bro" "zfs destroy ${dataset}@prevsync && zfs rename ${dataset}@newsync ${dataset}@prevsync" || alert
done
echo
${SENDZABBIX} --value 0 >/dev/null
rm -f $LOCKFILE
echo "$(date): ZFSync ending."