rbxi support for LVM Snapshot?
I install most servers using LVM mainly for the snapshot option in the filesystem as most data on servers I maintain is changing whilst backups run (Virtual Machines for Example).
I have my own scripts to operate LVM Snapshots but was curious as to whether rbxi would support LVM in the future? I am looking at wrapping rbxi up in a script the creates and removes snapshots before and after rbxi but it would be nice to have it all in the one script. I'm happy to provide scripts I have written to help out where possible but your scripting fu is far better than mine. Thanks techAdmin! Back to top |
since I have no idea what lvm really entails, or what code would look like to handle it, why not just post here, in two [code.. boxes the before and after stuff so I can see if it can be fitted in.
The main idea of rbxi is that each version is ideally stable, and that the engine can always be updated without having to change the config files at all. Back to top |
Here you go:
Before... :: Code :: /sbin/lvcreate -l 100%FREE -s -n lvm-snapshot vg00/root
/bin/mount -o nouuid vg00/lvm-snapshot /mnt/lvm-snapshot After... :: Code :: /bin/umount /mnt/lvm-snapshot
/sbin/lvremove -f vg00/lvm-snapshot The backup then needs to backup the data from /mnt/lvm-snapshot which is a snapshot of the filesystem. it may help to view it in the context of a full script that I wrote....don't laugh :) :: Code :: #!/bin/bash
#=======================================================================================# # INFORMATION #=======================================================================================# ## Name: lvsnapback ## Purpose: LVM Snapshot and backup using tar to USB ## Author: James Robertson ## Date: 04.06.2009 ## Modified: 21.08.2009 ## Company: 3rdmill Pty Ltd ## Depends: See command variables for dependencies ## Optional: ntfs-3g, xfs ## ## Details: The script backs up directories listed in DIRECTORIES using tar and gzip ## to an external USB disk but takes and LVM snapshot of the file system ## first. ## Could easily be adapted for rsync etc. ## This script is free to use, distribute and alter in any way. #=======================================================================================# # Variables #=======================================================================================# ## general variables DIRECTORIES="vmware" # backup directories BACKUPMNT="/media/backup" # backup disk mount point BACKUPDEV="/dev/sdb1" # backup disk device BACKUPOPT="-t ntfs-3g -o force" # backup disk mount options BACKUPROOT=BACKUPS # backup root directory BACKUPDIR=VM # backup destination directory LVMSNAPSHOT=var-data-snapshot # lvm snapshot name LVMSNAPMNT=/mnt # base mnt point LVMSNAPSIZE=100%FREE # lvm snapshot size LVMSNAPOPT="-o nouuid" # snapshot mount options (xfs) LVMSOURCE=var-data # lvm source VOLUMEGROUP=/dev/vg00 # volume group ERRORLOG=/tmp/backuperrors.txt # error log FAILLOG=/var/log/lvsnapback.log # fail log EMAILBODY=/tmp/backupbody.txt # success email body ## notification recipients ALERTS=alerts@example.com # email for urgent alerts BACKUPMON=backupmonitor@example.com # succesful backup reports ## command variables - based on Debian Lenny update for your distro HOST=$(/bin/hostname -s | awk '{print toupper($1)}') # hostname in CAPS CLIENT=Organistation Pty Ltd # client name TIMESTAMP=$(/bin/date +%Y%m%d%M%H) # yyyymmddMMHH MOUNT=/bin/mount UMOUNT=/bin/umount LVCREATE=/sbin/lvcreate LVREMOVE=/sbin/lvremove AWK=/usr/bin/awk TAC=/usr/bin/tac CAT=/bin/cat GREP=/bin/grep ECHO=/bin/echo MAIL=/usr/bin/mail TAR=/bin/tar RM=/bin/rm WC=/usr/bin/wc ## ensure error functions set to 0 errortest=0 errorset=0 #=======================================================================================# # Functions #=======================================================================================# ## check exit status of last command for errors and set errortmp ErrorTest () { if [ "$1" != "0" ]; then errortmp=1; fi } ## email alerts address if something went wrong and set errorset ErrorReport () { if [ "$errortmp" == "1" ]; then $ECHO "$TIMESTAMP ERROR: $1 " >> $ERRORLOG $TAC $ERRORLOG | $MAIL -s "$CLIENT $HOST BACKUP ENCOUNTERED AND ERROR!" $ALERTS $TAC $ERRORLOG >> $FAILLOG errorset=1 fi } ## unmount snapshot UnMountLVMSnap () { errortmp=0 $UMOUNT $LVMSNAPMNT/$LVMSNAPSHOT 2>$ERRORLOG; RETVAL="$?" ErrorTest $RETVAL ErrorReport "failed to umount $LVMSNAPMNT/$LVMSNAPSHOT" } ## remove snapshot RemoveLVMSnap () { errortmp=0 $LVREMOVE -f $VOLUMEGROUP/$LVMSNAPSHOT 2>$ERRORLOG; RETVAL="$?" ErrorTest $RETVAL ErrorReport "failed to remove LVM snapshot $VOLUMEGROUP/$LVMSNAPSHOT" } ## unmount backup disk UnMountBackup () { errortmp=0 $UMOUNT $BACKUPMNT 2>$ERRORLOG; RETVAL="$?" ErrorTest $RETVAL ErrorReport "the backup disk failed to unmount from $BACKUPMNT" } #=======================================================================================# # DISK MOUNT AND SNAPSHOT #=======================================================================================# ## mount backup disk errortmp=0 if [ "$errorset" == "0" ]; then if ! $MOUNT | grep $BACKUPDEV | grep $BACKUPMNT; then $MOUNT $BACKUPOPT $BACKUPDEV $BACKUPMNT 2>$ERRORLOG; RETVAL="$?" ErrorTest $RETVAL ErrorReport "the backup disk $BACKUPDEV failed to mount on $BACKUPMNT" fi fi # backup root directory check errortmp=0 if [ "$errorset" == "0" ]; then [ -d "$BACKUPMNT/$BACKUPROOT" ] 2>$ERRORLOG; RETVAL="$?" ErrorTest $RETVAL ErrorReport "the directory "$BACKUPROOT" must exist on the backup disk" fi if [ "$errortmp" == "1" ]; then UnMountBackup fi ## make lvm snapshot errortmp=0 if [ "$errorset" == "0" ]; then $LVCREATE -l $LVMSNAPSIZE -s -n $LVMSNAPSHOT $VOLUMEGROUP/$LVMSOURCE 2>$ERRORLOG; RETVAL="$?" ErrorTest $RETVAL ErrorReport "lvm snapshot failed creating $LVMSNAPSHOT from $VOLUMEGROUP/$LVMSOURCE" fi if [ "$errortmp" == "1" ]; then UnMountBackup fi # mount lvm snapshot errortmp=0 if [ "$errorset" == "0" ]; then $MOUNT $LVMSNAPOPT $VOLUMEGROUP/$LVMSNAPSHOT $LVMSNAPMNT/$LVMSNAPSHOT 2>$ERRORLOG; RETVAL="$?" ErrorTest $RETVAL ErrorReport "failed to mount $VOLUMEGROUP/$LVMSNAPSHOT on /mnt/$LVMSNAPSHOT" fi if [ "$errortmp" == "1" ]; then RemoveLVMSnap; UnMountBackup fi # remove previous backup directory errortmp=0 if [ "$errorset" == "0" ]; then if [ -d "$BACKUPMNT/$BACKUPROOT/$BACKUPDIR/$HOST" ]; then $RM -fr $BACKUPMNT/$BACKUPROOT/$BACKUPDIR/$HOST 2>$ERRORLOG; RETVAL="$?" ErrorTest $RETVAL ErrorReport "failed to remove directory $BACKUPMNT/$BACKUPROOT/$BACKUPDIR/$HOST" fi fi if [ "$errortmp" == "1" ]; then UnMountLVMSnap; RemoveLVMSnap; UnMountBackup fi # make new backup directory errortmp=0 if [ "$errorset" == "0" ]; then /bin/mkdir -p $BACKUPMNT/$BACKUPROOT/$BACKUPDIR/$HOST 2>$ERRORLOG; RETVAL="$?" ErrorTest $RETVAL ErrorReport "Failed to create directory $BACKUPMNT/$BACKUPROOT/$BACKUPDIR/$HOST" fi if [ "$errortmp" == "1" ]; then UnMountLVMSnap; RemoveLVMSnap; UnMountBackup fi #=======================================================================================# # BACKUP #=======================================================================================# ## cd into backup destination errortmp=0 if [ "$errorset" == "0" ]; then cd $BACKUPMNT/$BACKUPROOT/$BACKUPDIR/$HOST 2>$ERRORLOG; RETVAL="$?" ErrorTest $RETVAL ErrorReport "failed to change into directory $BACKUPMNT/$BACKUPROOT/$BACKUPDIR/$HOST" fi if [ "$errortmp" == "1" ]; then UnMountLVMSnap; RemoveLVMSnap; UnMountBackup fi ## run backup errortmp=0 if [ "$errorset" == "0" ]; then $TAR -cpzf $TIMESTAMP-$HOST-$LVMSOURCE.tar.gz -C $LVMSNAPMNT/$LVMSNAPSHOT $DIRECTORIES 2>$ERRORLOG; RETVAL="$?" cd /root/ fi if [ "$errortmp" == "1" ]; then UnMountLVMSnap; RemoveLVMSnap; UnMountBackup fi ## test archive and set variables for success report if [ "$errorset" == "0" ]; then NUMFILES=$($TAR -tzf $BACKUPMNT/$BACKUPROOT/$BACKUPDIR/$HOST/*-$HOST-$LVMSOURCE.tar.gz \ | $GREP -v '/$' | $WC -l | $AWK '{ gsub(/ /, ""); print }') TARSIZE=$(du -h $BACKUPMNT/$BACKUPROOT/$BACKUPDIR/$HOST/*-$HOST-$LVMSOURCE.tar.gz \ | cut -f 1) fi ## send success or failure reports errortmp=0 if [ "$errorset" == "1" ]; then $CAT $FAILLOG | $MAIL -s "$CLIENT $HOST Local Backup Failed!" $BACKUPMON exit 1 else $CAT > $EMAILBODY <<EOF The following directories were backed up successfully. $DIRECTORIES Total size of backup is $TARSIZE Total files backed up is $NUMFILES EOF $CAT $EMAILBODY | $MAIL -s "$CLIENT $HOST Local Backup Completed Successfully" $BACKUPMON UnMountLVMSnap; RemoveLVMSnap; UnMountBackup fi # END Back to top |
MOUNT_BU_DISK_1='/sbin/lvcreate -l 100%FREE -s -n lvm-snapshot && vg00/root /bin/mount -o nouuid vg00/lvm-snapshot $BACKUP_MOUNT_POINT'
UNMOUNT_BU_DISK_1='/bin/umount $BACKUP_MOUNT_POINT && /sbin/lvremove -f vg00/lvm-snapshot' should do it I think, since those variables are run with eval, the only loss would be that you'd have no error handling that was certain for umount/mount commands, I used to try to run two command in there but it's not super relilable, but for your needs, it should work. Note that the single quotes are very important, otherwise the dynamically set backup mount point variable would be filled in using the default value, instead of having that value assigned on eval later on. Back to top |
I realized that this syncs with an option I'd debated adding some time ago, triggered by pre mount, post mount, and pre umount functions declared by user in rbxi-values file.
That wouldn't be that hard to add, so I think I'll do it, I have needed such an option too at times, and I think it would provide a useful extension of functionality. I think I'd make it like the other features, where you have a default value, set to null, which if set to a function you define, would handle whatever you wanted done. The function would need to return 0 or 1 for error handling. In general this is too complicated for most users, but I think as a power user type option, it would add some nice flexibility to the script. It would be either hardcoded in to always run, or would be overridden by option args, which I'll think about a bit before implementing. The hardest thing about such updates is updating all the relevant documentation and so on, but there's another rbxi-values thing I need to add, an explicit statement about which argument triggers which variable sets, in the comments, that would be very useful for initial setup of jobs etc. For extra functions, they would be triggered by either hard coding or by using options, say: -P 2::2 which would be, use pre mount method 2, no post mount method, and use post umount method 2. This would be extremely flexible and allow for a great deal of control and options, but would of course require the ability to write a function that has return values. Back to top |
Please see the techpatterns.com/forums/about831.html rbxi home page for instructions on how to update to 2.6.0, which supports user defined functions to be run pre mount, post mount, and post umount.
Also make sure to see the setup instructions for samples and explanations: smxi.org/docs/rbxi-main.htm#rbxi-values-user-functions This should cover most of your needs should you choose to upgrade, it did the trick for me, hopefully this will be enough to cover it. Note that each function once defined can have as many operations, tests, and actions internally, with return error values that rbxi will handle as any other error event, so you can easily debug the events. This worked nicely, and actually let me find a recent firestarter bug bugs.debian.org/cgi-bin/bugreport.cgi?bug=542224 in Debian sid, which is another story. Back to top |
Late reply sorry..... Awesome! I'll try it out for myself soon and let you know how it goes.
Irony: Had to assist with a prospetive client this evening running an old Fedora Core 4 box that had a failed disk in a raid 5. Tech gets onsite and powers off the server to put a good drive in and then boots it up. Another disk had failed during his arrival....... data is gone... cactus.... seeya later. Luckily some guys managing some software on it had taken backups of the important data but the rest of the server was lost and dead. If only we were their IT provider before then and may have had rbxi on the box. Backups "ARE" the most important part of the server for anyone reading this that is not clear on that point. Its when a computers fails not if a computer fails Back to top |
For the emailer feature, keep in mind you can create a separate file, say rbxi-functions, in rbxi-data, then source it, to make managing the stuff more easily:
in rbxi-values add: source /usr/local/bin/rbxi-data/rbxi-functions then on the emailer variables, you could just do: EMAIL_START_ACTION='emailer_function "arg1" "$data"' which would keep it all nice and neat. The pre/post mount/umount functions will need to be written directly into rbxi-values I guess. This makes it about as extensible as I can, it gives 5 points you can inject actions into rbxi, plus an error pre exit case as well. Hint on backups, a very easy trick I learned recently, sort of by accident: to create a trivially simple redundant backup of the basic data that runs almost in real time, just do an rsync/rbxi 4x a day or so between the primary data source, say your raid array, and a single backup disk that runs always on. Given the low cost of disks now, this is cheap insurance, and you simply monitor that disk as well. Since it's a backup primarily, it doesn't matter that much if it dies, but the odds of disks dying all at once are quite low in my experience. But that way, if your array dies, or the array hardware dies, you can switch over very quickly to the single disk and use that while you repair the hardware or array. Other things I'm fond of is using cru dataport V removable sata trays for nightly backups, which, again, are always available as well to restore from. Back to top |
All times are GMT - 8 Hours |