Full disk backup on the Raspberry Pi


RaspberryPiOne of the most important thing on the pi is to have decent backups, since our root is on an untrusted sd-card there will always be the risk of that corrupted filesystem. Over on raspberrypi.org I found a script that fits my needs and uses dd to make a copy of the sd-card and stores that on my NFS (FreeNas) Server that runs zfs raid over multiple disk. Also doing some test how the pi runs if the root is completely on nfs..(more on that later.)

I stored the backup script on my nfs share that is mounted to /mnt Backups are stored in /mnt/Pi-backups Script and logs are in /mnt/scripts Backup script runs twice a day and the backups for the last 7 days are stored. Here’s the script.(/mnt/scripts/backup.sh)

#!/bin/bash

Setting up backup directories

SUBDIR=Pi_backups DIR=/mnt/$SUBDIR

Setting up echo fonts

red=‘\e[0;31m’ green=‘\e[0;32m’ cyan=‘\e[0;36m’ yellow=‘\e[1;33m’ purple=‘\e[0;35m’ NC=‘\e[0m’ #No Color bold=tput bold normal=tput sgr0

#Screen clear clear

echo -e ”${green}${bold}Starting RaspberryPI backup process!${NC}${normal}” echo ""

First check if pv package is installed, if not, install it first

PACKAGESTATUS=dpkg -s pv | grep Status;

if [[ $PACKAGESTATUS == S* ]] then echo -e ”${cyan}${bold}Package ‘pv’ is installed${NC}${normal}” echo "" else echo -e ”${yellow}${bold}Package ‘pv’ is NOT installed${NC}${normal}” echo -e ”${yellow}${bold}Installing package ‘pv’ + ‘pv dialog’. Please wait…${NC}${normal}” echo "" sudo apt-get -y install pv && sudo apt-get -y install pv dialog fi

Check if backup directory exists

if [ ! -d “$DIR” ]; then echo -e ”${yellow}${bold}Backup directory $DIR doesn’t exist, creating it now!${NC}${normal}” sudo mkdir $DIR

fi

Create a filename with datestamp for our current backup (without .img suffix)

OFILE=“$DIR/backup_$(date +%Y%m%d_%H%M%S)”

Create final filename, with suffix

OFILEFINAL=$OFILE.img

First sync disks

sync; sync

Shut down some services before starting backup process

echo "" echo -e ”${purple}${bold}Stopping services before backup${NC}${normal}” sudo pkill deluged sudo pkill deluge-web sudo service deluge-daemon stop sudo service noip stop sudo service cron stop sudo service proftpd stop sudo service webmin stop sudo service xrdp stop

Begin the backup process, should take about 45 minutes hour from 8Gb SD card to NFS

echo "" echo -e ”${green}${bold}Backing up SD card to img file on NFS${NC}${normal}” SDSIZE=sudo blockdev --getsize64 /dev/mmcblk0; sudo pv -tpreb /dev/mmcblk0 -s $SDSIZE | dd of=$OFILE bs=1M conv=sync,noerror iflag=fullblock

Wait for DD to finish and catch result

RESULT=$?

Start services again that where shutdown before backup process

echo "" echo -e ”${purple}${bold}Starting the stopped services${NC}${normal}” sudo service deluge-daemon start sudo deluged sudo deluge-web sudo service noip start sudo service cron start sudo service proftpd start sudo service webmin start sudo service xrdp start

If command has completed successfully, if not, delete created files

if [ $RESULT = 0 ]; then sudo mv $OFILE $OFILEFINAL echo "" echo -e ”${green}${bold}RaspberryPI backup process completed! FILE: $OFILEFINAL${NC}${normal}” echo -e ”${yellow}Removing backups older than 7 days${NC}” sudo find $DIR -maxdepth 1 -name “*.img” -mtime +7 -exec rm {} ; echo -e ”${cyan}If any backups older than 7 days were found, they were deleted${NC}” exit 0

Else remove attempted backup file

else echo "" echo -e ”${red}${bold}Backup failed!${NC}${normal}” sudo rm -f $OFILE echo "" echo -e ”${purple}Last backups on NFS:${NC}” sudo find $DIR -maxdepth 1 -name “*.img” -exec ls {} ; echo "" echo -e ”${red}${bold}RaspberryPI backup process failed!${NC}${normal}” exit 1 fi

Make the script executable:

chmod +x /mnt/scripts/backup.sh
Add it to your crontab so it runs twice a day:
crontab -e
And add the following line:
0 4/16 * * * /mnt/scripts/backup.sh > /mnt/scripts/cron.log 2>&1
That's all for today, Let's make a test backup by running:
/mnt/scripts/backup.sh