remote-backup/remote-backup
2009-11-23 15:32:03 +01:00

137 lines
3.4 KiB
Bash
Executable File

#!/bin/bash
# ----------------------------------------------------------------------
# mikes handy rotating-filesystem-snapshot utility
# ----------------------------------------------------------------------
# this needs to be a lot more general, but the basic idea is it makes
# rotating backup-snapshots of /home whenever called
# ----------------------------------------------------------------------
#unset PATH # suggestion from H. Milz: avoid accidental use of $PATH
# ------------- system commands used by this script --------------------
###BEGIN: generic tool checker
# FIXME: To reuse this function, be sure to edit this line (space separated
# list).
needed_tools="id echo mount rm mv cp touch rsync"
#
# One shall not need edit anything below this line
###
checktools() {
# This functions attempts to be generic enough to be reused in any program
# that needs to check that specific tools are present on the system
# and can be found in the PATH
var=$(echo $1 | tr '[:lower:]' '[:upper:]')
echo -n "# Looking for $1... "
local_var="$(which $1)"
eval $var="$local_var"
if [ -z "$local_var" ]
then
echo 'NOT FOUND!'
NOTFOUND="$NOTFOUND$1 "
DIE=1
else
echo "$local_var"
FOUND="$FOUND$1 "
fi
unset local_var
}
for tool in $needed_tools
do
checktools "$tool"
done
echo
echo "# Found $FOUND"
echo
if [ -n "$DIE" ]
then
echo "Some tools were not found, please check your installation" >&2
echo "Needed tools: $needed_tools" >&2
echo -n "Not found:" >&2
for tool in $NOTFOUND
do
echo -n " $tool" >&2
done
echo '!' >&2
exit 127
fi
###END: generic tool checker
source /etc/remote-backup.conf
# ------------- the script itself --------------------------------------
# make sure we're running as root
if [ ! $UID -eq 0 ]
then
$ECHO "Sorry, must be root. Exiting..."
exit
fi
if [[ "$REMOUNT" == "true" ]]
then
# attempt to remount the RW mount point as RW; else abort
$MOUNT -o remount,rw $MOUNT_DEVICE $SNAPSHOT_RW ;
if (( $? ))
then
$ECHO "snapshot: could not remount $SNAPSHOT_RW readwrite"
exit
fi
fi
# rotating snapshots of /home (fixme: this should be more general)
# step 1: delete the oldest snapshot, if it exists:
if [ -d $SNAPSHOT_RW/home/hourly.3 ]
then
$RM -rf $SNAPSHOT_RW/home/hourly.3
fi
# step 2: shift the middle snapshots(s) back by one, if they exist
if [ -d $SNAPSHOT_RW/home/hourly.2 ]
then
$MV $SNAPSHOT_RW/home/hourly.2 $SNAPSHOT_RW/home/hourly.3
fi
if [ -d $SNAPSHOT_RW/home/hourly.1 ]
then
$MV $SNAPSHOT_RW/home/hourly.1 $SNAPSHOT_RW/home/hourly.2
fi
# step 3: make a hard-link-only (except for dirs) copy of the latest snapshot,
# if that exists
if [ -d $SNAPSHOT_RW/home/hourly.0 ]
then
$CP -al $SNAPSHOT_RW/home/hourly.0 $SNAPSHOT_RW/home/hourly.1
fi
# step 4: rsync from the system into the latest snapshot (notice that
# rsync behaves like cp --remove-destination by default, so the destination
# is unlinked first. If it were not so, this would copy over the other
# snapshot(s) too!
$RSYNC \
-va \
--delete \
--delete-excluded \
--exclude-from="$EXCLUDES" \
/home/ \
$SNAPSHOT_RW/home/hourly.0
# step 5: update the mtime of hourly.0 to reflect the snapshot time
$TOUCH $SNAPSHOT_RW/home/hourly.0
# and thats it for home.
# now remount the RW snapshot mountpoint as readonly
if [[ "$REMOUNT" == "true" ]]
then
$MOUNT -o remount,ro $MOUNT_DEVICE $SNAPSHOT_RW
if (( $? ))
then
$ECHO "snapshot: could not remount $SNAPSHOT_RW readonly"
exit
fi
fi