A backup script I created some years ago and still use for different projects.
It's a combined tar'ing + LVM snapshot script. It'll read /var/backup/backuplist for a list of backup-dirs and /var/backup/excludelist for a list of excludes (e.g. include /var/www but exclude /var/www/cache).
The LVM volumes need to be named correctly for the script to work. The explanation is in the script, but I'll paste it here too:
### LVM partition explanation # swap volumes = <machine>_swap # Linux volumes = <machine>_root # Windows volumes = <machine> # Snapshot volumes = <machine>_snapshot
swap and snapshot volumes will of course be ignored in the backup process, which is why you need to name the volumes correctly upon VPS installation.
I can recommend using pigz to pack the images instead of gzip.
Here's the script:
#!/bin/bash # Author: Biggi # Where would you like the data stored etc. # Note: No trailing slashes. TIMESTAMP=`date +%Y%m%d` YESTERDAY=`date --date=yesterday +%Y%m%d` BACKUPLIST="/var/backup/backuplist" EXCLUDELIST="/var/backup/excludelist" CIFSDIR="/mnt/novell" LOGFILE=$CIFSDIR/$TIMESTAMP.log TMPDIR="/var/backup/tmp" LVMNAME="vservers" # No touchie! LOOPED=0 #echo "touching $BACKUPLIST" #echo "touching $EXCLUDELIST" ### LVM partition explanation # swap volumes = <machine>_swap # Linux volumes = <machine>_root # Windows volumes = <machine> # Snapshot volumes = <machine>_snapshot ######################################## # CTRL+C trap (to cleanup in case of script break) function ctrl_c() { echo " -----------------------------------------------------------------------" echo " [`date +%X`] Please wait while removing snapshots + unmounting cifs mount." echo " -----------------------------------------------------------------------" /bin/sleep 1 # Remove all snapshot volumes (if any) echo " [`date +%X`] Removing snapshot volumes (if any)" for x in `/sbin/lvdisplay | grep "LV Name" | grep "_snapshot" | awk {'print $3'} | cut -f4 -d'/'`; do echo "Removing snapshot: $x" /sbin/lvremove -f /dev/$LVMNAME/$x LOOPED=1 done # No snapshots removed? if [ $LOOPED -eq 0 ]; then echo " [`date +%X`] No active snapshots found, moving on." fi echo "" # Unmount CIFS mount echo " [`date +%X`] Unmounting cifs mount" if [ `df -h | grep $CIFSDIR | awk {'print $5'} | wc -l` -gt 0 ]; then /bin/umount -f $CIFSDIR fi exit } # Define the actual trap key trap ctrl_c SIGINT # Pack local files for backup to begin with. echo " -----------------------------------------------------------------------" echo " [`date +%X`] Backing up local files." echo " -----------------------------------------------------------------------" # Pack config files and other files. if [ ! -f $BACKUPLIST ]; then echo " [`date +%X`] ERROR! Backuplist at $BACKUPLIST was not found!" fi if [ ! -f $EXCLUDELIST ]; then echo " [`date +%X`] ERROR! Excludelist at $EXCLUDELIST was not found!" fi # Create filelist for compression for x in `cat $BACKUPLIST`; do ACTBACKUPLIST="$ACTBACKUPLIST $x" done # OM-NOM-NOM! DATA! AAAAAAAAARRRRRRRHHH! tar -zcvf $BACKUPDIR/$TIMESTAMP.tar.gz -X $EXCLUDELIST $ACTBACKUPLIST 2>&1 echo " -----------------------------------------------------------------------" echo " [`date +%X`] Backing up VM's." echo " -----------------------------------------------------------------------" # Mount our backupdrive #echo "MKDIR" mkdir -p $CIFSDIR #echo "MOUNT" /sbin/mount.cifs //SERVER.TLD/path/ -o username=USERNAME,password=PASSWORD $CIFSDIR /bin/sleep 3 #echo "DO_NOT_REMOVE check" # Is the DO_NOT_REMOVE file present? If not, something is wrong (or some IDIOT deleted it :P) #ls -lah $CIFSDIR if [ `ls -lah $CIFSDIR"/DO_NOT_REMOVE" | wc -l` -eq 1 ]; then #echo "DELETE" rm $CIFSDIR/*-`date --date="yesterday" +%Y%m%d`* else #echo "ERRORHANDLER" # ERROR HANDLER (a simple one, but an error handler none the less :D) wget "http://xxxxxxxxx/backupreport.php?box=`hostname`&msg=Remote%20storage%20not%20mounted.%20Verify%20login%20credentials." -O dev/null exit fi #echo "LOOPINGLVM" #echo `/sbin/lvdisplay | grep "LV Name" | egrep -v "_swap|_snapshot" | awk {'print $3'} | cut -f4 -d'/'` # Find LVM volumes, leave out _swap for x in `/sbin/lvdisplay | grep "LV Name" | egrep -v "_swap|_snapshot" | awk {'print $3'} | cut -f4 -d'/'`; do echo " [`date +%X`] Creating snapshot volume for: $x" # Create a tmp snapshot volume /sbin/lvcreate -L 5G -s -n "$x"_snapshot /dev/$LVMNAME/$x # Sweet sweet zZz :D /bin/sleep 1 # dd + gzip /bin/dd if=/dev/$LVMNAME/"$x"_snapshot bs=4096k | pigz -9 -b 4096 -c > $CIFSDIR/$x.gz # zZz before moving file. Just in case of random events. /bin/sleep 2 # Move file to backup destination, overwriting the backup from the day before # /bin/mv $TMPDIR/$x.gz $CIFSDIR/. # Mo' zZz, just in case :D # /bin/sleep 3 # Destroy tmp snapshot volume /sbin/lvremove -f /dev/$LVMNAME/"$x"_snapshot done # Move logfile to cifsdir /bin/mv /root/backuplog.txt "$CIFSDIR"/"$LOGFILE" sleep 3 # Unmount remote storage #echo "UNMOUNT" #/bin/sleep 5 # More secure check. Let's verify that $CIFSDIR is not in use with lsof. while [ `lsof | grep $CIFSDIR | wc -l` -gt 0 ]; do sleep 5 done # Dir available, let's unmount this sucker then. /bin/umount -f $CIFSDIR