Fix backup snapshot drift
Occasionally, the latest snapshot in the snapshots dir would get out of sync with the backup drive. Change the script to detect drift and fix it before performing a backup.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
export SOURCE_DIR=${SOURCE_DIR:=root}
|
||||
export SOURCE_DIR=${SOURCE_DIR:=/}
|
||||
# Fix basename / showing up as "/" -> change to "root"
|
||||
if [ $(basename $SOURCE_DIR) = / ]; then
|
||||
export SNAPSHOT_PREFIX=${SNAPSHOT_PREFIX:=root}
|
||||
@@ -25,27 +25,58 @@ echo "LATEST: $LATEST"
|
||||
echo "BACKUP_DRIVE_MNT: $BACKUP_DRIVE_MNT"
|
||||
echo "BACKUP_DIR: $BACKUP_DIR"
|
||||
|
||||
# Sync latest backups
|
||||
# The "latest" symlinks can get out of sync for a variety of reasons,
|
||||
# including backups run while the disk is unplugged.
|
||||
# They must be kept in sync so that snapshots are sent with a parent
|
||||
# that actually exists on the backup drive
|
||||
#
|
||||
# In order to keep them in sync we'll do the following:
|
||||
# 1. Check the <backup>-latest on the backup drive matches
|
||||
# <backup>-latest in the snapshot directory
|
||||
# 2. If they don't match, assume the backup drive has the correct
|
||||
# snapshot. Replace the <backup>-latest symlink in the snapshots
|
||||
# directory with the one from the backup drive
|
||||
#
|
||||
# First check if the symlinks exist
|
||||
if [ -L $SNAPSHOT_DIR/$LATEST ] && [ -L $BACKUP_DIR/$LATEST ]
|
||||
then
|
||||
# Get the actual name of the latest backup
|
||||
LATEST_SNAPSHOT=$(basename $(readlink $SNAPSHOT_DIR/$LATEST))
|
||||
LATEST_BACKUP=$(basename $(readlink $BACKUP_DIR/$LATEST))
|
||||
# If the latest backups don't match
|
||||
if [ $LATEST_SNAPSHOT != $LATEST_BACKUP ]
|
||||
then
|
||||
echo "Detected drift. Synchronizing latest snapshot with backup. Set to $LATEST_BACKUP."
|
||||
# Remove and replace the snapshot directory's latest
|
||||
rm $SNAPSHOT_DIR/$LATEST
|
||||
ln -s $SNAPSHOT_DIR/$LATEST_BACKUP $SNAPSHOT_DIR/$LATEST
|
||||
fi
|
||||
fi
|
||||
|
||||
# Create readonly snapshot
|
||||
btrfs subvolume snapshot -r $SOURCE_DIR $SNAPSHOT_DIR/$SNAPSHOT_NAME
|
||||
|
||||
# Check if backup disk is mounted
|
||||
# Attempt to mount backup disk
|
||||
mount $BACKUP_DRIVE_MNT
|
||||
mountpoint $BACKUP_DRIVE_MNT
|
||||
|
||||
if [ $? = 0 ]; then
|
||||
if [ -d $BACKUP_DIR/$LATEST ]; then
|
||||
# Check if backup disk is mounted
|
||||
mountpoint $BACKUP_DRIVE_MNT
|
||||
if [ $? = 0 ]; then # backup drive mounted
|
||||
# If we have a latest, use it as the parent
|
||||
if [ -L $BACKUP_DIR/$LATEST ]; then
|
||||
btrfs send -p $SNAPSHOT_DIR/$LATEST $SNAPSHOT_DIR/$SNAPSHOT_NAME | btrfs receive $BACKUP_DIR
|
||||
else
|
||||
btrfs send $SNAPSHOT_DIR/$SNAPSHOT_NAME | btrfs receive $BACKUP_DIR
|
||||
fi
|
||||
|
||||
# Update latest in snapshot dir
|
||||
rm -f $SNAPSHOT_DIR/$LATEST
|
||||
ln -s $SNAPSHOT_DIR/$SNAPSHOT_NAME $SNAPSHOT_DIR/$LATEST
|
||||
|
||||
# Update latest in backup dir
|
||||
rm -f $BACKUP_DIR/$LATEST
|
||||
ln -s $BACKUP_DIR/$SNAPSHOT_NAME $BACKUP_DIR/$LATEST
|
||||
else
|
||||
echo "Backup location $BACKUP_DRIVE_MNT not mounted. Snapshot $SNAPSHOT_NAME not synced"
|
||||
fi
|
||||
|
||||
# Update latest in snapshot dir
|
||||
rm -f $SNAPSHOT_DIR/$LATEST
|
||||
ln -s $SNAPSHOT_DIR/$SNAPSHOT_NAME $SNAPSHOT_DIR/$LATEST
|
||||
|
||||
Reference in New Issue
Block a user