#!/usr/bin/env sh ### nodes.txt # localhost 22 # # # ... ### datasets.txt (Only required for aggregator setup.) # # / # / # # / # # ... if [ ! -f nodes.txt ]; then echo "No nodes specified."; exit 2; fi read BR_HOST BR_PORT BR_ROOT BR_USER < nodes.txt list_filesets() { zfs list | tail -n +2 | cut -d' ' -f1|grep ${BR_ROOT} } get_latest_snapshot() { zfs list -t snapshot | grep ${BR_ROOT} | tail -n1 | cut -d'@' -f2 | cut -d' ' -f 1 } setup_aggregator() { zfs allow -u ${BR_USER} send,snapshot,hold ${BR_ROOT} for dataset in `cat datasets.txt`; do zfs create $dataset done } setup_mirror() { zfs allow -u ${BR_USER} send,snapshot,hold ${BR_ROOT} zfs allow -du ${BR_USER} \ compression,mountpoint,receive,create,mount ${BR_ROOT} } create_snapshot() { id="`date -I`-`date +%s`" zfs snapshot -r ${BR_ROOT}@${id} } send_single_snapshot() { BR_NEW_SNAPSHOT=`get_latest_snapshot` while read BR_REMOTE_ADDR BR_REMOTE_PORT BR_REMOTE_ROOT BR_REMOTE_USER; do zfs send -R ${BR_ROOT}@${BR_NEW_SNAPSHOT} | ssh -i ~/.ssh/id_rsa -o port=${BR_REMOTE_PORT} \ ${BR_REMOTE_USER}@${BR_REMOTE_ADDR} \ zfs receive -dvu ${BR_REMOTE_ROOT}@${BR_NEW_SNAPSHOT} done echo $BR_NEW_SNAPSHOT > "old-snapshot.txt" } send_incremental_snapshot() { BR_NEW_SNAPSHOT=`get_latest_snapshot` while read BR_REMOTE_ADDR BR_REMOTE_PORT BR_REMOTE_ROOT BR_REMOTE_USER; do zfs send -R -i `cat old-snapshot.txt` ${BR_ROOT}@${BR_NEW_SNAPSHOT} | ssh -i ~/.ssh/id_rsa -o port=${BR_REMOTE_PORT} \ ${BR_REMOTE_USER}@${BR_REMOTE_ADDR} \ zfs receive -dvu ${BR_REMOTE_ROOT}@${BR_NEW_SNAPSHOT} done echo $BR_NEW_SNAPSHOT > "old-snapshot.txt" } create_snapshot if [ -f "old-snapshot.txt" ]; then send_incremental_snapshot else send_single_snapshot fi