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