Skip to content

Instantly share code, notes, and snippets.

@jsoref
Created August 30, 2022 23:25
Show Gist options
  • Save jsoref/45cf063d9bec3d474a341843d68f6986 to your computer and use it in GitHub Desktop.
Save jsoref/45cf063d9bec3d474a341843d68f6986 to your computer and use it in GitHub Desktop.
Sync a bunch of zfs volumes to a remote (designed to be called from a cron-like system)
#!/bin/bash
##
# https://gist.githubusercontent.com/ertug/1087896/raw/0ff791dce616993f8557bf74e1f47cebb4b69aae/zfs-snapshot.sh
# original code: http://andyleonard.com/2010/04/07/automatic-zfs-snapshot-rotation-on-freebsd/
# 07/17/2011 - ertug: made it compatible with zfs-fuse which doesn't have .zfs directories
##
# Path to ZFS executable:
ZFS=/sbin/zfs
SETTINGS=/root/zfs.sync
SVOLUMES=$SETTINGS/volumes
DESTHOST=$(cat $SETTINGS/dest-host)
HOSTPOOL=$(cat $SETTINGS/host-pool)
DESTPOOL=$(cat $SETTINGS/dest-pool)
VOLUMES=$(cd $SVOLUMES; ls)
if [ -z "$HOSTPOOL" ] || [ -z "$VOLUMES" ] || [ -z "$DESTHOST" ] || [ -z "$DESTPOOL" ]; then
(
echo "$0: incomplete configuration"
echo "dest: $DESTHOST"
echo " pool: $DESTPOOL"
echo "pool: $HOSTPOOL"
echo " volumes: $VOLUMES"
) >&2
exit 1
fi
for a in $VOLUMES; do
NEXTSNAP=$(date +%Y%m%d%H%M)
VOLUME=$(cat $SVOLUMES/$a/vol)
zfs snapshot -r $HOSTPOOL/$VOLUME@$NEXTSNAP
PREVSNAP=$(cat $SVOLUMES/$a/prev-snap 2>/dev/null)
LASTSNAP=$(cat $SVOLUMES/$a/last-snap)
if [ -z "$LASTSNAP" ] || [ "$PREVSNAP" = "$LASTSNAP" ]; then
(
echo "$0: invalid volume settings"
echo "pool: $HOSTPOOL"
echo " volume: $VOLUME"
echo "prevsnap: $PREVSNAP"
echo "lastsnap: $LASTSNAP"
echo "... ignoring prevsnap"
) >&2
PREVSNAP=
fi
mv -f $SVOLUMES/$a/last-send.log $SVOLUMES/$a/prev-send.log
mv -f $SVOLUMES/$a/last-send.err $SVOLUMES/$a/prev-send.err
if zfs send -Rci @$LASTSNAP $HOSTPOOL/$VOLUME@$NEXTSNAP |
ssh $DESTHOST zfs recv -Fduv $DESTPOOL > $SVOLUMES/$a/last-send.log 2> $SVOLUMES/$a/last-send.err; then
mv $SVOLUMES/$a/last-snap $SVOLUMES/$a/prev-snap
echo "$NEXTSNAP" > $SVOLUMES/$a/last-snap
if [ ! -z "$PREVSNAP" ]; then
zfs destroy -r $HOSTPOOL/$VOLUME@$PREVSNAP
ssh $DESTHOST zfs destroy -r $DESTPOOL/$VOLUME@$PREVSNAP
fi
true
else
LASTERR=$?
(
echo "$0: send $VOLUME failed..."
echo "zfs send -Rci @$LASTSNAP $HOSTPOOL/$VOLUME@$NEXTSNAP | ssh $DESTHOST zfs recv -Fduv $DESTPOOL"
echo "output:"
cat $SVOLUMES/$a/last-send.log
echo "error:"
cat $SVOLUMES/$a/last-send.err
echo "exit: $LASTERR"
) >&2
fi
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment