2010-08-18

Backups. They’re im­por­tant.

I’ve used and loved rdiff-backup for years un­til the day fi­nally came that I had to re­cover old files from it. Restoring an en­tire rdiff-backup archive might be straight­for­ward, but the process of ex­tract­ing scat­tered older ver­sions of files is not a pretty one. And hope­ful as I am, archfs is just not there yet.

This, along with the co­in­ci­den­tal ac­qui­si­tion of an ad­di­tional ter­abyte hard drive, got me think­ing about the other ways I could be do­ing my reg­u­lar back­ups. With a new ap­pre­ci­a­tion for data trans­parency, this help­ful com­par­i­son of rdiff-backup and rsnap­shot was all it took to con­vince me to make the switch to rsnap­shot.

My cur­rent backup scheme is to copy every­thing to one of two ex­ter­nal USB backup dri­ves and ro­tate it off site about once a month:

Backup scheme

The data trans­fers rep­re­sented by black ar­rows are now fa­cil­i­tated by rsnap­shot and pre­serve the last six ver­sions.

Since the backup drive is­n’t al­ways con­nected rsnap­shot can’t be sched­uled to run at a spe­cific time, but each com­puter will dis­play a prompt to be­gin back­ups when it de­tects that the backup drive has been con­nected. Regular no­ti­fi­ca­tions to con­nect the backup drive and ex­e­cute off-site ro­ta­tions are pro­vided by a per­sonal time man­age­ment de­vice.

First, a udev rule to de­tect the drive as it con­nects:

# External backup hard drives
ATTR{partition}=="1", ATTRS{vendor}=="WDC WD10", ATTRS{model}=="EADS-*", RUN+="/opt/akbackup/device-inserted.sh"

Then a script to re­spond (device-inserted.sh):

#!/bin/bash
# Note: This script must finish quickly because udev is effectively paused while it is running

# Run all this in the background
{
# Wait for partition to be automatically mounted
counter=0
while [ $counter -lt 20 ]; do
grep -q '/media/akbackup' /proc/mounts && break
sleep 1
let counter++
done

if [ $counter -ge 20 ]; then
exit 0
fi

# Prompt to back up
/opt/akbackup/gui-prompt.sh
} &

exit 0

And the prompt it­self (gui-prompt.sh):

#!/bin/bash

function die() {
zenity --error --title "Backups" --text "An error occurred while running backups. Please see the system log for details."
exit 0
}

function doBackups() {
# Start a tray icon
exec 3> >( zenity --notification --listen \
--window-icon "/usr/share/icons/Humanity/actions/48/document-save.svg" \
--text "Backups are in progress." \
)
echo "message: Backups are in progress." >&3

# Run rsnapshot
rsnapshot myo5a || die

# Close the tray icon
echo "message: Backups have completed." >&3
exec 3>&-
}

# Use the default display
export DISPLAY=:0.0

# Prompt for action
action=$(zenity --list \
--title "Backups" \
--text "Please choose an action." \
--radiolist \
--column "Pick" --column "Action" \
TRUE "Run backups now." \
FALSE "Run backups now and then shut down." \
FALSE "Do nothing.")


# Execute action
case "$action" in
"Run backups now.")
doBackups;
;;
"Run backups now and then shut down.")
touch /var/opt/rsnapshot-should-shutdown
doBackups;
;;
*)
exit 0;
;;
esac

exit 0

touch /var/opt/rsnapshot-should-shutdown sets a marker that is read by rsnap­shot’s cmd_postexecscript:

#!/bin/bash

if [ -e /var/opt/rsnapshot-should-shutdown ]; then
# Unset marker
rm /var/opt/rsnapshot-should-shutdown

# Power off gracefully
export DISPLAY=:0.0
sudo -u ak gnome-session-save --shutdown-dialog
fi

exit 0

The end re­sult is a nice menu that ap­pears upon con­nec­tion of the backup drive:

rsnapshot prompt

and a tray icon to in­di­cate that a backup is in progress:

rsnapshot notification