How backup files to a specific external disk automatically when it is connected – [Linux]

A strong backup policy provides to keep an offline (not connect to any kind of device) copy of own files, protecting your data against ransomware, device failure, etc. We can use an external Hard Disk Drive (HDD) to connected every week to our server/workstation and automatically backup files and send an email at the end of the operation. We can also decide which files can be copied and also on which hard disk. For example if you have a family server, each users can backup their files on own external hard disk in a simple way.

Requirements:

  • Linux server/workstation (source of the backup)
  • Hard Disk Drive (don’t use Static Solid Drive (SDD) to backup files)

Steps:

We need to get the serial number of our external hard disk. So start to connect the external device to out server/workstation. We will use udevadm to get the information. Replace sdxy with your device.

# udevadm info -a /dev/sdxy | grep serial
E: ID_SERIAL_SHORT=000001D91CC3

Let’s create a rule to trigger when the external disk will be connected.

# nano /etc/udev/rules.d/10-local.rules
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
ACTION=="add", ENV{DEVTYPE}=="partition", SUBSYSTEMS=="usb", KERNEL=="sd?1", ATTRS{serial}==" 000001D91CC3", SYMLINK+="usbhddbackup", RUN+="/bin/bash /home/BACKUP/backupWrapper.sh" 

Some explanation about the string parameters of the rule:
ENV{DEVTYPE}==”partition” search valid partition
SUBSYSTEMS==”usb” search in USB devices
KERNEL==”sd?1″ = get the first partition (?=can be any letter)
ATTRS{serial} = serial of device, only if this device is found the rule is matched
ENV{DEVTYPE} = use this option to avoid udev exec twice the the action run.
SYMLINK = name of device, it will create a /dev/usbhddbackup useful to mount the device in the script
RUN = the script you have to exec, call a wrapper script because udev exec the process with a timeout

# systemctl restart udev

If you have some trouble or just for debug look inside /var/log/syslog.

Ok go on, create the script wrapper called in the rule above:

# mkdir /home/BACKUP
# cd /home/BACKUP
# touch backupWrapper.sh 
# chmod +x backupWrapper.sh

Edit the script adding just few lines.

# nano /home/BACKUP/backupWrapper.sh
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#!/bin/sh
at -f /home/BACKUP/backup_to_usb.sh now + 2 minutes
exit

Now we are ready to create the main script of the backup. Remind please that we have indicated to udev to use a symbolic link “/dev/usbhddbackup”. We create a folder /home/BACKUP that cointains script and a folder with the last backup named “BACKUP_DAILY”.

# touch backup_to_usb.sh
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#!/bin/sh
# Source folder
source=/home/BACKUP_DAILY
# Destination folder on external device
dest=/media/usb_backup
dest_full_path=$dest/BACKUP

# Use SYMLINK to mount the device
mount /dev/usbhddbackup /media/usb_backup

# Check if destination exist
if [ ! -d $dest_full_path ]; then
 echo "destination do not exist"
 exit
fi

# Backup the folder using rsync
rsync -aruzv --delete $source/ $dest_full_path 

# Change permission to all files on destination
chmod -R 777 $dest_full_path 

# Force an immediate write of all cached data to disk 
sync

# Umount the device
umount $dest

# Send email to alert the end of the operation
echo "Backup has just finished, you can detached the external disk safely" | mail -s "Backup finished" myemail@email.com

exit