Automatic backup in Linux

Some time ago I’ve started backing up my laptop hard drive in any case of failure. Until today I was simply connecting external back-up-drive and manually launching mount && rsync command from zsh history. But this requires that always after connecting this special device I need to go to terminal, log in as root then find this back up command and run it.

Recently I was wondering how this process could be improved or even done automatically. I had few requirements:

  • it should be fully automated
  • system should inform me that back up process was started and that it ends
  • this notification should be done as some system pop up in X windows

So I’ve come with a solution that connects udev, DBus notification and awesome wm naughty library … and it is really simple 😉

How it works ? When you connects back-up-device udev will pick up this event, create a symbolic link to /dev/backup, then launch backup script. This script will send a notification through DBus, this event will be received by naughty and displayed as a simple notification in Awesome WM. After sending notification signal the backup script will mount given device and launch rsync command. After successful synchronization backup device will be unmonted and another notification signal will be send to inform you that you can now disconnect it.

How to achieve this ?

First of all we need to figure out UUID of our back up device (I assume that /dev/sdb2 is yours back-up-partition) :

# blkid /dev/sdb2
/dev/sdb2: UUID="97377fed-edaf-407b-9e02-5c6cecd6dceb" SEC_TYPE="ext2" TYPE="ext3"

Then we need to create new udev rule in /etc/udev/rules.d we can call it 99-backup.rules:

ENV{ID_FS_UUID}=="97377fed-edaf-407b-9e02-5c6cecd6dceb", SYMLINK+="backup"
ACTION=="add", ENV{ID_FS_UUID}=="97377fed-edaf-407b-9e02-5c6cecd6dceb", RUN+="backup"

Of course you need to replace my UUID with one you get from blkid command. Those two lines are responsible for creating symbolic link called backup in /dev directory to device with given UUID; second line will launch backup script when device with given UUID is added.

Finally we need to create our backup script and put it into /lib/udev directory. Here is content of this script:

function show_notification() {
	su $USER -c "export DISPLAY=':0.0'; \
		export XAUTHORITY='/home/$USER/.Xauthority'; \
		/usr/bin/dbus-send --type=method_call --dest=org.freedesktop.Notifications \
			/org/freedesktop/Notifications  org.freedesktop.Notifications.Notify string:'' \
			uint32:0 string:'' string:'$1' string:'' array:string:'' array:string:'' int32:$MSG_TIMEOUT"
function backup() {
	show_notification "Backup process started! Do NOT disconnect backup device."
	mount /dev/backup /mnt/backup
	ionice -c 3 rsync -az --delete --exclude=/dev --exclude=/mnt --exclude=/media --exclude=/run --exclude=/proc --exclude=/tmp --exclude=/sys --exclude=/var/log --exclude=/var/run / /mnt/backup
	umount /mnt/backup
	show_notification "Backup process successed! You can disconnect backup device."
backup &

In this file you only need to change USER variable to yours UNIX user name, also you can adjust MSG_TIMEOUT to your needs (-1 means that default value will be taken). Most difficult part in this script was to figure out how to send DBus notification from root to regular user, since all window managers create and listen on theirs own session scoped buses. As you can notice we can force dbus-send command to send signal to proper bus instance by executing this command on behalf of  given user and with exported DISPLAY and XAUTHORITY variables.

Full source code is available on github. Have a nice and pleasant back up’s 😉