#!/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."