Good Backup script

I’ve a local home server that works as a local RAID storage with some virtual machines that serve different services to me and to some friends. The most known service to most of you is the XMPP service for chat.cat-hackers.net that enables all the H4ck3rZ Foundation members to communicate in an efficient way.

Another thing is that this server hold all of my important data that represents my own work throughout the years, so it’s very important to keep them secure and safe. I’d a bad experience of losing a 2.5GB harddrive that had all of my programming work. That experience taught me how to spend more money to keep your data safe and secure.

So :) I got an external 500GB USB hard drive to have it mainly as a backup drive for my 500GB RAID local home server, and as you can see it’s 500GB too, so I can’t do incremental backups on that disk because it too small for such a plan, so I decided to rsync the data on the storage server to the USB hard drive and I wrote a nice script that does some smart stuff….

Let’s post the script first then I’ll describe more about it..

#AhmedSoliman.com snippets
#let's define some variables
USB_DISK_UUID="c71e0a65-9569-409d-8b7c-5f0c76406217"
USB_DISK_VENDOR="Western"
DEST_BACKUP_DIR="storage_backup"
SNAPSHOT_NAME="storage_snap"
VOLUME_GROUP="storage"
SRC_VOLUME="mystorage"
if (/sbin/lsusb| /bin/grep "$USB_DISK_VENDOR")
then
  #get device name first
  NAME=`/sbin/blkid | grep "$USB_DISK_UUID" |cut -d: -f1`
  if [ -z $NAME ]
  then
    echo "Device was found but UUID doesn't match, we can't detect device node"
    exit 2
  fi

  #check if mounted...

  if /bin/mount | /bin/grep $NAME
  then
    #get the mount point
    MOUNT_POINT=`mount | awk '/'${NAME#/dev/}'/ { print $3}'`
    echo "Usb Disk is already mounted at $MOUNT_POINT"
  else
    #mount manually
    mkdir /tmp/mount.$$
    mount $NAME /tmp/mount.$$
    echo "USB Disk Mounted at /tmp/mount.$$";
    MOUNT_POINT=/tmp/mount.$$
  fi
  #take a snapshot of the source logical volume
  SRC_MOUNT_POINT="/tmp/snapmount.$$"
  mkdir $SRC_MOUNT_POINT
  if /usr/sbin/lvdisplay | grep $SNAPSHOT_NAME
  then
    #snapshot already exists

    mount -o ro /dev/${VOLUME_GROUP}/${SNAPSHOT_NAME} ${SRC_MOUNT_POINT}
    echo "Snapshot of volume $SRC_VOLUME is now mounted at $SRC_MOUNT_POINT";
  else

    if /usr/sbin/lvcreate --size 3gb --snapshot --name $SNAPSHOT_NAME  /dev/${VOLUME_GROUP}/${SRC_VOLUME}
    then
      #created
      mount -o ro /dev/$VOLUME_GROUP/$SNAPSHOT_NAME $SRC_MOUNT_POINT
      echo "Snapshot of volume $SRC_VOLUME is now mounted at $SRC_MOUNT_POINT";
    else
      echo "Couldn't create snapshot for device /dev/$VOLUME_GROUP/$SRC_VOLUME"
      exit 3 ;
    fi

  fi
  rsync -av ${SRC_MOUNT_POINT}/ ${MOUNT_POINT}/${DEST_BACKUP_DIR}/
  sync
  umount $SRC_MOUNT_POINT
  umount $MOUNT_POINT
  echo "Removing snapshot"
  if /usr/sbin/lvremove -f /dev/${VOLUME_GROUP}/${SNAPSHOT_NAME}
  then
    echo "Done"
  else
    echo "Failed!"
    exit 4 ;
  fi
  exit 0
else
  #disk not there...
  echo "USB Storage Couldn't be located...quitting"
  exit 1;
fi 

So, let’s describe the script features.

1- The script uses some variables that define the behaviour, those variables are defined like follows:

USB_DISK_UUID=”c71e0a65-9569-409d-8b7c-5f0c76406217″
“This variable defines the destination USB disk UUID to make sure that we are mounting the correct disk and if you have more than one USB disk attached we want to make sure that we are not destroying the wrong disk. you can know the UUID of the disk using ‘blkid’ command”

USB_DISK_VENDOR=”Western”
“This is the vendor to ensure that we are not wrong detecting the UUID, so we check the output of lspci to make sure that this disk vendor exists in the output”

DEST_BACKUP_DIR=”storage_backup”
“This is the directory that will be created in the destination usb disk that would contain the backup”

SNAPSHOT_NAME=”storage_snap”
“This variables define the snapshot name that would be taken from the storage logical volume, you can set whatever you like here” 

VOLUME_GROUP=”storage”
“This is volume group that contains the storage logical volume”

SRC_VOLUME=”mystorage”
“This is the source logical volume to be backed up”

2- The script makes sure that the usb disk is not already mounted, and if mounted it will detect the current mount point and will work on it.

3- It takes a LVM snapshot of the source storage volume to make sure that the backup is consistent.

4- The script is very efficient in copying changed files (rsync), it takes 2 minutes to make sure that 500GB are in sync (very good timing).

5- There are some other features in the script that you would discover yourself.

I’ll publish a few snippets I wrote gradually… so please don’t hesitate to give me feedback..

12 Comments »

  1. Ahmed Madkour said,

    June 14, 2008 @ 4:29 pm

    I didn’t read all the script, but it seems nice

  2. kamasheto said,

    June 14, 2008 @ 8:21 pm

    Honestly I can understand very little of it, but either way, and if I may, I would suggest you pay more attention to your indentation. I’ve took the courtesy to tweak your script. Hope you don’t mind!

  3. kamasheto said,

    June 14, 2008 @ 8:31 pm

    May I suggest you use the tag somewhere in your post? It’ll make things look neater =D

    Just a heads up.

  4. Ahmed S. Farghal said,

    June 14, 2008 @ 8:51 pm

    lol @kamasheto :)

    The script is already indented but the problem is here, I have hard times formatting this here…

    i’ll try to do manually by adding some spaces…

  5. kamasheto said,

    June 14, 2008 @ 9:55 pm

    Woops, zalamtak.

    My second post was suggesting you use the tag in your post 3ashan your home page.

    Just out of curiosity, bash’s conditions could either be embraced by (), [], or not embraced at all - sa7 wala is there some sort of rule each should be used in?

  6. kamasheto said,

    June 14, 2008 @ 9:57 pm

    Grrr :@

    <!–more–>

    this is the so-called tag I’m referring to but wordpress removed it.. the first time it was just commented out traditionally. Darn formatting, no wonder you didn’t bother with the indentation any more - it’s exhausting.

    Anyway, apologies for the fuss =D

  7. Ahmed S. Farghal said,

    June 14, 2008 @ 10:45 pm

    Ok :)

  8. GaMaL said,

    June 15, 2008 @ 2:40 pm

    Aywa .. el UUID ..

    why you use UUID and not the device name ..
    in some mount scripts i used to visit while facing problems mounting my old fedora drives if found scripts using UUID and others were using the path /dev/deviceName/ ..

    Is it Unique for each hardware device or .. the system just assigns a Unique ID every time you plugs your device ..

    in other words .. to apply your script .. I should plug the flash then
    blkid the customize the script based on the resultant UUID
    or I can use the path for the Device ..

    Note: if my questions represents lack of information .. I really don’t have enough and you can ignore it …
    w2lf salama 3leek :)

  9. Ahmed S. Farghal said,

    June 15, 2008 @ 2:48 pm

    you should use the UUID always because it’s unique to this device and will remain unique and presistant, but the device node is assigned automatically, so it doesn’t have to be the same each time…

  10. 3ABED said,

    June 16, 2008 @ 11:15 am

    i’ve kind of understood the script and it seems to be very nice
    thanks for sharing
    salam

  11. BooDy said,

    June 16, 2008 @ 5:34 pm

    wah … it’s really useful!!
    but
    i couldn’t understand it all cause i’m not very good in bash scripting :|

    hope i’ll understand this script someday :D

    thnx 4 sharing :)

  12. jo said,

    June 28, 2008 @ 3:12 pm

    thank you very much! this skript tought me a lot!

RSS feed for comments on this post · TrackBack URI

Leave a Comment