File: //usr/local/share/urbackup/dattobd_create_snapshot
#!/bin/sh
set -e
mkdir -p /mnt/urbackup_snaps
CDIR=`dirname $0`
SNAP_ID=$1
SNAP_MOUNTPOINT="$2"
SNAP_DEST=/mnt/urbackup_snaps/$SNAP_ID
SNAP_MOUNTPOINT_SAN=$(echo "$SNAP_MOUNTPOINT" | sed 's@/@_@g')
SNAP_NUM_PATH="/mnt/urbackup_snaps/cbt_info/$SNAP_MOUNTPOINT_SAN-snapdev"
SNAP_COWFILE_PATH="/mnt/urbackup_snaps/cbt_info/$SNAP_MOUNTPOINT_SAN-cowfile"
exists()
{
[ -e "$1" ]
}
has_num ()
{
exists /mnt/urbackup_snaps/cbt_info/*-snapdev && grep "$1" /mnt/urbackup_snaps/cbt_info/*-snapdev > /dev/null
}
get_path()
{
echo $1/$2 | sed 's@//@/@g'
}
CDIR=`dirname $0`
. $CDIR/filesystem_snapshot_common
exit_exclude_snapshot_mountpoints "$SNAP_MOUNTPOINT"
DEVICE=$(df -T -P | egrep " ${SNAP_MOUNTPOINT}\$" | head -n 1 | tr -s " " | cut -d" " -f1)
set_filesystem_type "${SNAP_MOUNTPOINT}"
if [ "x$TYPE" = "x" ]
then
if btrfs subvolume list -o "$SNAP_MOUNTPOINT" > /dev/null 2>&1
then
TYPE="btrfs"
fi
fi
if [ "x$TYPE" = "xbtrfs" ]
then
$CDIR/btrfs_create_filesystem_snapshot "$@"
exit $?
fi
if [ "x$DEVICE" = "x" ]
then
echo "Cannot get device for filesystem $SNAP_MOUNTPOINT"
exit 1
fi
echo "Snapshotting device $DEVICE via dattobd..."
NUM=0
while [ -e "/dev/datto$NUM" ] || has_num $NUM
do
NUM=`expr $NUM + 1`
done
if ! modprobe dattobd
then
echo "Dattobd kernel module not available"
exit 1
fi
sync
TRY_TRANS=0
if [ -e "$SNAP_COWFILE_PATH" ] && [ -e "$SNAP_NUM_PATH" ]
then
TRY_TRANS=1
TRANS_NUM=$(cat "$SNAP_NUM_PATH")
echo "Trying to transition /dev/datto$TRANS_NUM to snapshot..."
echo "dbdctl transition-to-snapshot $(get_path $SNAP_MOUNTPOINT "datto_3d41c58e-6724-4d47-8981-11c766a08a24_$SNAP_ID") $TRANS_NUM"
fi
if [ $TRY_TRANS = 1 ] && dbdctl transition-to-snapshot $(get_path $SNAP_MOUNTPOINT ".datto_3d41c58e-6724-4d47-8981-11c766a08a24_$SNAP_ID") $TRANS_NUM
then
echo "Transitioned /dev/datto$TRANS_NUM to snapshot."
CBT_FILE=$(cat $SNAP_COWFILE_PATH)
echo "CBT_FILE=$CBT_FILE"
echo "CBT=type=datto"
NUM=$TRANS_NUM
else
if [ $TRY_TRANS = 1 ]
then
rm "$SNAP_NUM_PATH"
rm "$SNAP_COWFILE_PATH"
fi
echo "Using /dev/datto$NUM..."
echo "CBT=type=datto&reset=1"
dbdctl setup-snapshot "$DEVICE" $(get_path $SNAP_MOUNTPOINT ".datto_3d41c58e-6724-4d47-8981-11c766a08a24_$SNAP_ID") $NUM
fi
echo $NUM > ${SNAP_DEST}-num
DEV_SIZE=`blockdev --getsize /dev/datto$NUM`
truncate -s100M $(get_path $SNAP_MOUNTPOINT ".overlay_2fefd007-3e48-4162-b2c6-45ccdda22f37_$SNAP_ID")
LODEV=`losetup -f`
if [ "x$LODEV" = x ]
then
rm "${SNAP_DEST}-num"
rm $(get_path $SNAP_MOUNTPOINT ".overlay_2fefd007-3e48-4162-b2c6-45ccdda22f37_$SNAP_ID")
dbdctl destroy $NUM
exit 1
fi
losetup $LODEV $(get_path $SNAP_MOUNTPOINT ".overlay_2fefd007-3e48-4162-b2c6-45ccdda22f37_$SNAP_ID")
echo "0 $DEV_SIZE snapshot /dev/datto$NUM $LODEV N 8" | dmsetup create "wsnap-$SNAP_ID"
echo "Mounting /dev/mapper/wsnap-$SNAP_ID..."
mkdir -p $SNAP_DEST
mkdir -p /mnt/urbackup_snaps/cbt_info
MOUNTOPTS="ro"
if [ $TYPE = "xfs" ]
then
MOUNTOPTS="ro,nouuid"
fi
if ! mount -o $MOUNTOPTS /dev/mapper/wsnap-$SNAP_ID $SNAP_DEST
then
echo "Mounting filesystem failed"
rmdir "$SNAP_DEST"
rm "${SNAP_DEST}-num"
dmsetup remove "wsnap-$SNAP_ID"
losetup -d $LODEV
rm $(get_path $SNAP_MOUNTPOINT ".overlay_2fefd007-3e48-4162-b2c6-45ccdda22f37_$SNAP_ID")
dbdctl destroy $NUM
exit 1
fi
echo "/dev/datto$NUM" > ${SNAP_DEST}-dev
echo "$NUM" > $SNAP_NUM_PATH
echo $(get_path $SNAP_MOUNTPOINT ".datto_3d41c58e-6724-4d47-8981-11c766a08a24_$SNAP_ID") > $SNAP_COWFILE_PATH
echo "SNAPSHOT=$SNAP_DEST"
exit 0