mirror of
https://github.com/uroni/urbackup_backend.git
synced 2025-10-26 11:36:50 +00:00
159 lines
4.5 KiB
Bash
Executable File
159 lines
4.5 KiB
Bash
Executable File
#!/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
|
|
|
|
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$TYPE" != "xxfs" ] && [ "x$TYPE" != "xext4" ]
|
|
then
|
|
echo "File system $TYPE not supported"
|
|
exit 1
|
|
fi
|
|
|
|
if [ "x$DEVICE" = "x" ]
|
|
then
|
|
echo "Cannot get device for filesystem $SNAP_MOUNTPOINT"
|
|
exit 1
|
|
fi
|
|
|
|
echo "Snapshotting device $DEVICE via dm..."
|
|
|
|
if ! dmsetup table "$DEVICE" > /dev/null 2>&1
|
|
then
|
|
echo "$DEVICE is not a device mapper device. Cannot snapshot via dm."
|
|
exit 1
|
|
fi
|
|
|
|
modprobe dm_snapshot
|
|
|
|
DEV_SIZE=$(blockdev --getsz "$DEVICE")
|
|
|
|
if [ "x$DEV_SIZE" = "x" ]
|
|
then
|
|
echo "Cannot get device size of device $DEVICE"
|
|
exit 1
|
|
fi
|
|
|
|
DEVNAME=$(basename $DEVICE)
|
|
|
|
RUUID="a31725acca86421d"
|
|
|
|
ORIG_DEVICE="/dev/mapper/$DEVNAME-$RUUID-clone"
|
|
ERA_META_FN=".era-meta_3d41c58e-6724-4d47-8981-11c766a08a24"
|
|
|
|
ERA_RESET=0
|
|
if ! command -v era_dump >/dev/null 2>&1
|
|
then
|
|
echo "thin-provisioning-tools not installed. CBT not enabled."
|
|
elif modprobe dm_era && ! dmsetup table "$DEVICE" | grep " era " > /dev/null 2>&1 && ! dmsetup table "$DEVICE" | grep " snapshot-origin " > /dev/null 2>&1
|
|
then
|
|
echo "Layering in dm-era device..."
|
|
META_SIZE=$(( (((DEV_SIZE*4)/1024)/512)*512 + 3*1024*1024 ))
|
|
if [ $META_SIZE -lt $((4*1024*1024)) ]
|
|
then
|
|
META_SIZE=$((4*1024*1024))
|
|
fi
|
|
|
|
if [ -e "$SNAP_MOUNTPOINT/$ERA_META_FN" ]
|
|
then
|
|
chattr -i "$SNAP_MOUNTPOINT/$ERA_META_FN" || true
|
|
rm "$SNAP_MOUNTPOINT/$ERA_META_FN"
|
|
fi
|
|
|
|
fallocate -l $META_SIZE "$SNAP_MOUNTPOINT/$ERA_META_FN"
|
|
chattr +i "$SNAP_MOUNTPOINT/$ERA_META_FN"
|
|
echo "FLOCK_PERM=$SNAP_MOUNTPOINT/$ERA_META_FN"
|
|
|
|
ORIG_DEVICE="/dev/mapper/$DEVNAME-$RUUID-clone-era"
|
|
dmsetup table "$DEVICE" | dmsetup create "$DEVNAME-$RUUID-clone-era"
|
|
urbackupclientbackend --internal --print-dm-file-extents "$SNAP_MOUNTPOINT/$ERA_META_FN" --file-dm-block-dev "$ORIG_DEVICE" | dmsetup create "$DEVNAME-$RUUID-era-metadata"
|
|
dmsetup table "$DEVNAME-$RUUID-era-metadata" | dmsetup create "$DEVNAME-$RUUID-era-metadata-access"
|
|
dd if=/dev/zero of=/dev/mapper/$DEVNAME-$RUUID-era-metadata bs=512 count=$(blockdev --getsz /dev/mapper/$DEVNAME-$RUUID-era-metadata) > /dev/null 2>&1
|
|
echo "0 $DEV_SIZE era /dev/mapper/$DEVNAME-$RUUID-era-metadata $ORIG_DEVICE 1024" | dmsetup create "$DEVNAME-$RUUID-clone"
|
|
echo "CBT=type=era&reset=1"
|
|
ERA_RESET=1
|
|
fi
|
|
|
|
OVERLAY_FN="$SNAP_MOUNTPOINT/.overlay_2fefd007-3e48-4162-b2c6-45ccdda22f37_$SNAP_ID"
|
|
if [ -e "$OVERLAY_FN" ]
|
|
then
|
|
chattr -i "$OVERLAY_FN" || true
|
|
rm "$OVERLAY_FN"
|
|
fi
|
|
|
|
fallocate -l 5G "$OVERLAY_FN"
|
|
chattr +i "$OVERLAY_FN"
|
|
echo "FLOCK=$OVERLAY_FN"
|
|
|
|
if ! [ -e "/dev/mapper/$DEVNAME-$RUUID-clone" ]
|
|
then
|
|
dmsetup table "$DEVICE" | dmsetup create "$DEVNAME-$RUUID-clone"
|
|
fi
|
|
|
|
urbackupclientbackend --internal --print-dm-file-extents "$OVERLAY_FN" --file-dm-block-dev "$ORIG_DEVICE" | dmsetup create "$DEVNAME-$SNAP_ID-cow-storage"
|
|
# Needs to run with mlockall for root device -> cannot do that in bash
|
|
urbackupclient_dmsnaptool --dev "$DEVICE" --clone-dev "/dev/mapper/$DEVNAME-$RUUID-clone" --snap-dev "/dev/mapper/$DEVNAME-$SNAP_ID" --cow-dev "/dev/mapper/$DEVNAME-$SNAP_ID-cow-storage" --origin-dev "/dev/mapper/$DEVNAME-$RUUID-origin" --era-access-dev "/dev/mapper/$DEVNAME-$RUUID-era-metadata-access" --dev-size "$DEV_SIZE"
|
|
|
|
truncate -s100M $SNAP_MOUNTPOINT/.overlay_2fefd007-3e48-4162-b2c6-45ccdda22f37_$SNAP_ID-wsnap
|
|
|
|
LODEV=`losetup -f`
|
|
|
|
if [ "x$LODEV" = x ]
|
|
then
|
|
echo "TODO: Cleanup"
|
|
exit 1
|
|
fi
|
|
|
|
losetup $LODEV $SNAP_MOUNTPOINT/.overlay_2fefd007-3e48-4162-b2c6-45ccdda22f37_$SNAP_ID-wsnap
|
|
|
|
echo "0 $DEV_SIZE snapshot /dev/mapper/$DEVNAME-$SNAP_ID $LODEV N 8" | dmsetup create "$DEVNAME-$SNAP_ID-wsnap"
|
|
|
|
echo "Mounting /dev/mapper/$DEVNAME-$SNAP_ID-wsnap..."
|
|
|
|
MOUNTOPTS="ro"
|
|
|
|
if [ $TYPE = "xfs" ]
|
|
then
|
|
MOUNTOPTS="ro,nouuid"
|
|
fi
|
|
|
|
mkdir -p "$SNAP_DEST"
|
|
|
|
if ! mount -o $MOUNTOPTS "/dev/mapper/$DEVNAME-$SNAP_ID-wsnap" "$SNAP_DEST"
|
|
then
|
|
echo "Mounting filesystem failed"
|
|
#TODO: CLEANUP
|
|
exit 1
|
|
fi
|
|
|
|
echo "$DEVNAME" > ${SNAP_DEST}-name
|
|
echo "/dev/mapper/$DEVNAME-$SNAP_ID" > ${SNAP_DEST}-dev
|
|
echo "SNAPSHOT=$SNAP_DEST"
|