Make snapshotLC sh: Unterschied zwischen den Versionen
Framp (Diskussion | Beiträge) |
Yehudi (Diskussion | Beiträge) (angepasst) |
||
(7 dazwischenliegende Versionen von 2 Benutzern werden nicht angezeigt) | |||
Zeile 1: | Zeile 1: | ||
− | + | <pre> | |
+ | #!/bin/bash | ||
+ | # ---------------------------------------------------------------------- | ||
+ | ## (c) 2007, Pfalzwolf for www.linux-club.de | ||
+ | ## | ||
+ | ## Idea: | ||
+ | ## Mike Rubel 2004.01.04 (http://www.mikerubel.org/computers/rsync_snapshots/) | ||
+ | ## | ||
+ | ## License: | ||
+ | ## LGPL | ||
+ | ## | ||
+ | ## Disclaimer: | ||
+ | ## Use this software on your own risk, it works for me but there | ||
+ | ## are no guaranties at all | ||
+ | ## ---------------------------------------------- | ||
+ | ## | ||
+ | ## make_snapshotLC: | ||
+ | ## Backup Script based on rsync | ||
+ | ## It creates Generation Backups for the levels daily, weekly and montly | ||
+ | ## | ||
+ | ## Version: | ||
+ | ## 0.3 | ||
+ | ## | ||
+ | ## Synopsis: | ||
+ | ## make_snapshotLC [OPTIONS] | ||
+ | ## | ||
+ | ## Description: | ||
+ | ## This script was adopted from Mike Rubels documentation from | ||
+ | ## http://www.mikerubel.org/computers/rsync_snapshots/ | ||
+ | ## Based on Mikes handy rotating-filesystem-snapshot utility. | ||
+ | ## The basic idea is it makes rotating backup-snapshots of /home whenever called | ||
+ | ## A few elements came from | ||
+ | ## http://www.heinlein-support.de/web/support/wissen/rsync-backup/ | ||
+ | ## An exclude list avoids to backup superflous files. | ||
+ | ## | ||
+ | ## Changes: | ||
+ | ## Instead of hourly, daily and weekly snapshots, daily, weekly and monthly | ||
+ | ## snapshots are used. | ||
+ | ## Checking the available space on backup media | ||
+ | ## Free configurable number of snapshots for every single level | ||
+ | ## Everything packed into one script | ||
+ | ## | ||
+ | ## Options: | ||
+ | ## -d make the daily backup plus rotate | ||
+ | ## -w make the weekly backup | ||
+ | ## -m make the monthly backup | ||
+ | ## -h displays a short help text | ||
+ | ## | ||
+ | ## Changelog: | ||
+ | ## -------- | ||
+ | ######################################################################## | ||
+ | |||
+ | unset PATH # suggestion from H. Milz: avoid accidental use of $PATH | ||
+ | |||
+ | # ------------- System Commands used by this script -------------------- | ||
+ | ID=/usr/bin/id; | ||
+ | ECHO=/bin/echo; | ||
+ | MOUNT=/bin/mount; | ||
+ | RM=/bin/rm; | ||
+ | MV=/bin/mv; | ||
+ | CP=/bin/cp; | ||
+ | TOUCH=/bin/touch; | ||
+ | RSYNC=/usr/bin/rsync; | ||
+ | DF=/bin/df; | ||
+ | TAIL=/usr/bin/tail; | ||
+ | SED=/bin/sed; | ||
+ | SYNC=/bin/sync; | ||
+ | LOGGER=/bin/logger; | ||
+ | CHMOD=/bin/chmod; | ||
+ | MKDIR=/bin/mkdir; | ||
+ | |||
+ | # ======================= CUSTOMIZING SECTION ========================== | ||
+ | MOUNT_DEVICE=/dev/sda2; # Your Mount device | ||
+ | MOUNT_RO=false; # For write protection set to true | ||
+ | SNAPSHOT_RW=/DASI/TEST; # where to store the backups | ||
+ | EXCLUDES=/home/wolf/nobackup/backup_exclude; # Create the backup_exclude file first! | ||
+ | CHECK_HDMINFREE=true; # Check free space | ||
+ | HDMINFREE=93; # Make a backup up to this percentage | ||
+ | DAYS=3; # Number of daily backups -1 | ||
+ | WEEKS=2; # Number of weekly backups -1 | ||
+ | MONTHS=3; # Number of monthly backups -1 | ||
+ | # ====================================================================== | ||
+ | |||
+ | # Make sure we're running as root | ||
+ | if (( `$ID -u` != 0 )); then { $ECHO "Sorry, must be root. Exiting..."; exit; } fi | ||
+ | |||
+ | # Check Argument | ||
+ | if [ $# != 1 ] ; then { $ECHO "Error: Wrong number of arguments. \ | ||
+ | Vaild is one out of -d, -w, -m, -h" ; exit; } fi | ||
+ | |||
+ | # Check Customization | ||
+ | if ! [ -b $MOUNT_DEVICE ] ; then { $ECHO "Error: Mount device $EXCLUDES isn't valid" ; exit; } fi | ||
+ | if ! [ -d $SNAPSHOT_RW ] ; then | ||
+ | { $ECHO "Error: Backup Directory $SNAPSHOT_RW missing"; exit; } fi | ||
+ | if ! [ -d $SNAPSHOT_RW/home ] ; then $MKDIR -p $SNAPSHOT_RW/home; fi | ||
+ | if ! [ -f $EXCLUDES ] ; then { $ECHO "Error: Exclude File $EXCLUDES missing" ; exit; } fi | ||
+ | |||
+ | # Check free space on disk | ||
+ | GETPERCENTAGE='s/.* \([0-9]\{1,3\}\)%.*/\1/'; | ||
+ | if $CHECK_HDMINFREE ; then | ||
+ | KBISFREE=`$DF /$SNAPSHOT_RW | $TAIL -n1 | $SED -e "$GETPERCENTAGE"` | ||
+ | if [ $KBISFREE -ge $HDMINFREE ] ; then | ||
+ | $ECHO "Error: Not enough space left for rotating backups!" | ||
+ | $LOGGER "Error: Not enough space left for rotating backups!" | ||
+ | exit | ||
+ | fi | ||
+ | fi | ||
+ | |||
+ | # ------------- The Script itself -------------------------------------- | ||
+ | |||
+ | if $MOUNT_RO ; then | ||
+ | # Attempt to remount the RW mount point as RW; else abort | ||
+ | $MOUNT -o remount,rw $MOUNT_DEVICE $SNAPSHOT_RW ; | ||
+ | if (( $? )); then | ||
+ | $ECHO "Error: could not remount $SNAPSHOT_RW readwrite"; | ||
+ | exit; | ||
+ | fi; | ||
+ | fi; | ||
+ | |||
+ | |||
+ | case $1 in | ||
+ | # *********** Daily Backups ******************************************** | ||
+ | -d | -D) $ECHO "Starting Daily Backup..." | ||
+ | # Rotating daily snapshots of /home | ||
+ | |||
+ | # Step 1: Delete the oldest snapshot, if it exists: | ||
+ | # It is NOT moved to the weekly backups level since you can make hundreds of daily backups | ||
+ | if [ -d $SNAPSHOT_RW/home/daily.$DAYS ] ; then | ||
+ | $RM -rf $SNAPSHOT_RW/home/daily.$DAYS ; | ||
+ | fi; | ||
+ | |||
+ | # Step 2: Shift all other snapshots(s) by one, if they exist (e.g. 6->7...1->2) | ||
+ | OLD=$DAYS; | ||
+ | while [ $OLD -ge 2 ] ; do | ||
+ | OLD=$[$OLD-1] | ||
+ | if [ -d $SNAPSHOT_RW/home/daily.$OLD ] ; then | ||
+ | NEW=$[ $OLD + 1 ] | ||
+ | # Save date | ||
+ | $TOUCH $SNAPSHOT_RW/.timestamp -r $SNAPSHOT_RW/home/daily.$OLD | ||
+ | $MV $SNAPSHOT_RW/home/daily.$OLD $SNAPSHOT_RW/home/daily.$NEW | ||
+ | # Restore date | ||
+ | $TOUCH $SNAPSHOT_RW/home/daily.$NEW/.timestamp \ | ||
+ | -r $SNAPSHOT_RW/.timestamp | ||
+ | fi; | ||
+ | done | ||
+ | |||
+ | # Step 3: make a hard-link-only (except for dirs) copy of the latest snapshot, | ||
+ | # If that exists 0->1 | ||
+ | if ! [ -d $SNAPSHOT_RW/home/daily.0 ] ; then | ||
+ | $MKDIR -p $SNAPSHOT_RW/home/daily.0 | ||
+ | $TOUCH $SNAPSHOT_RW/home/daily.0/.timestamp | ||
+ | else | ||
+ | $CP -al $SNAPSHOT_RW/home/daily.0 $SNAPSHOT_RW/home/daily.1 ; | ||
+ | fi; | ||
+ | |||
+ | # Step 4: rsync from the system into the latest snapshot (notice that | ||
+ | # rsync behaves like cp --remove-destination by default, so the destination | ||
+ | # is unlinked first. If it were not so, this would copy over the other | ||
+ | # snapshot(s) too! | ||
+ | $RSYNC \ | ||
+ | -va --delete --delete-excluded \ | ||
+ | --exclude-from="$EXCLUDES" \ | ||
+ | /home/ $SNAPSHOT_RW/home/daily.0 ; | ||
+ | |||
+ | # Check return code | ||
+ | # 0 = ok, | ||
+ | # 24 is also ok. It appears if files were changed or deleted while this script runs | ||
+ | # Other return codes are Error -- see man (1) rsync | ||
+ | if ! [ $? = 24 -o $? = 0 ] ; then | ||
+ | $ECHO "Error: rsync finished on $MOUNT_DEVICE with errors!" | ||
+ | $LOGGER "Error: rsync finished on $MOUNT_DEVICE with errors!" | ||
+ | fi; | ||
+ | |||
+ | # Step 5: update the mtime of daily.0 to reflect the snapshot time | ||
+ | $TOUCH $SNAPSHOT_RW/home/daily.0 ; | ||
+ | |||
+ | # Finished! | ||
+ | $ECHO "Finished rsync backup on $MOUNT_DEVICE..." | ||
+ | $LOGGER "Finished rsync backup on $MOUNT_DEVICE..." | ||
+ | |||
+ | # For beeing on the secure site... | ||
+ | $SYNC;; | ||
+ | |||
+ | # And thats it for home. | ||
+ | |||
+ | # *********** Weekly Backup ******************************************** | ||
+ | -w | -W)$ECHO "Starting Weekly Backup..." | ||
+ | |||
+ | # Step 1: Delete the oldest snapshot, if it exists | ||
+ | if [ -d $SNAPSHOT_RW/home/weekly.$WEEKS ] ; then | ||
+ | $RM -rf $SNAPSHOT_RW/home/weekly.$WEEKS ; | ||
+ | fi; | ||
+ | |||
+ | # Step 2: shift the middle snapshots(s) by one, if they exist 3->4 ..0->1 | ||
+ | OLD=$WEEKS; | ||
+ | while [ $OLD -ge 1 ] ; do | ||
+ | OLD=$[$OLD-1] | ||
+ | if [ -d $SNAPSHOT_RW/home/weekly.$OLD ] ; then | ||
+ | NEW=$[ $OLD + 1 ] | ||
+ | $MV $SNAPSHOT_RW/home/weekly.$OLD $SNAPSHOT_RW/home/weekly.$NEW ; | ||
+ | fi; | ||
+ | done | ||
+ | |||
+ | # Step 3: Make a hard-link-only (except for dirs) copy of | ||
+ | # daily.(max), assuming that exists, into weekly.0 | ||
+ | if [ -d $SNAPSHOT_RW/home/daily.$DAYS ] ; then | ||
+ | $CP -al $SNAPSHOT_RW/home/daily.$DAYS $SNAPSHOT_RW/home/weekly.0 ; | ||
+ | fi;; | ||
+ | |||
+ | # *********** Monthly Backup ******************************************* | ||
+ | -m | -M)$ECHO "Starting Monthly Backup..." | ||
+ | |||
+ | # Step 1: Delete the oldest snapshot, if it exists | ||
+ | if [ -d $SNAPSHOT_RW/home/monthly.$MONTHS ] ; then | ||
+ | $RM -rf $SNAPSHOT_RW/home/monthly.$MONTHS ; | ||
+ | fi; | ||
+ | |||
+ | # Step 2: Shift the middle snapshots(s) by one, if they exist 6->7 ..0->1 | ||
+ | OLD=$MONTHS; | ||
+ | while [ $OLD -ge 1 ] ; do | ||
+ | OLD=$[$OLD-1] | ||
+ | if [ -d $SNAPSHOT_RW/home/monthly.$OLD ] ; then | ||
+ | NEW=$[ $OLD + 1 ] | ||
+ | $MV $SNAPSHOT_RW/home/monthly.$OLD $SNAPSHOT_RW/home/monthly.$NEW ; | ||
+ | fi; | ||
+ | done | ||
+ | |||
+ | # Step 3: Make a hard-link-only (except for dirs) copy of | ||
+ | # weekly.(max), assuming that exists, into monthly.0 | ||
+ | if [ -d $SNAPSHOT_RW/home/weekly.$WEEKS ] ; then | ||
+ | $CP -al $SNAPSHOT_RW/home/weekly.$WEEKS $SNAPSHOT_RW/home/monthly.0 ; | ||
+ | fi;; | ||
+ | |||
+ | -h | -H)$ECHO "Usage: | ||
+ | make_snapshot -d Initiates daily backup | ||
+ | make_snapshot -w Initiates weekly backup | ||
+ | make_snapshot -m Initiates monthly backup | ||
+ | make_snapshot -h Displays this text."; exit;; | ||
+ | |||
+ | *) $ECHO "Error: Wrong argument. Vaild is one out of -d, -w, -m, -h" ; exit;; | ||
+ | |||
+ | esac | ||
+ | |||
+ | $ECHO "Backup ended" | ||
+ | if $MOUNT_RO ; then | ||
+ | # Now remount the RW snapshot mountpoint as readonly | ||
+ | $MOUNT -o remount,ro $MOUNT_DEVICE $SNAPSHOT_RW ; | ||
+ | if (( $? )); then | ||
+ | $ECHO "Error: Could not remount $SNAPSHOT_RW readonly"; | ||
+ | exit; | ||
+ | fi; | ||
+ | fi; | ||
+ | </pre> | ||
+ | |||
+ | ---- | ||
+ | |||
+ | [[Backupprogramme]]<br /> | ||
+ | [[Backup|zurück zum Bauckup]] | ||
+ | [[Category:Backup]] |
Aktuelle Version vom 31. Juli 2007, 22:38 Uhr
#!/bin/bash # ---------------------------------------------------------------------- ## (c) 2007, Pfalzwolf for www.linux-club.de ## ## Idea: ## Mike Rubel 2004.01.04 (http://www.mikerubel.org/computers/rsync_snapshots/) ## ## License: ## LGPL ## ## Disclaimer: ## Use this software on your own risk, it works for me but there ## are no guaranties at all ## ---------------------------------------------- ## ## make_snapshotLC: ## Backup Script based on rsync ## It creates Generation Backups for the levels daily, weekly and montly ## ## Version: ## 0.3 ## ## Synopsis: ## make_snapshotLC [OPTIONS] ## ## Description: ## This script was adopted from Mike Rubels documentation from ## http://www.mikerubel.org/computers/rsync_snapshots/ ## Based on Mikes handy rotating-filesystem-snapshot utility. ## The basic idea is it makes rotating backup-snapshots of /home whenever called ## A few elements came from ## http://www.heinlein-support.de/web/support/wissen/rsync-backup/ ## An exclude list avoids to backup superflous files. ## ## Changes: ## Instead of hourly, daily and weekly snapshots, daily, weekly and monthly ## snapshots are used. ## Checking the available space on backup media ## Free configurable number of snapshots for every single level ## Everything packed into one script ## ## Options: ## -d make the daily backup plus rotate ## -w make the weekly backup ## -m make the monthly backup ## -h displays a short help text ## ## Changelog: ## -------- ######################################################################## unset PATH # suggestion from H. Milz: avoid accidental use of $PATH # ------------- System Commands used by this script -------------------- ID=/usr/bin/id; ECHO=/bin/echo; MOUNT=/bin/mount; RM=/bin/rm; MV=/bin/mv; CP=/bin/cp; TOUCH=/bin/touch; RSYNC=/usr/bin/rsync; DF=/bin/df; TAIL=/usr/bin/tail; SED=/bin/sed; SYNC=/bin/sync; LOGGER=/bin/logger; CHMOD=/bin/chmod; MKDIR=/bin/mkdir; # ======================= CUSTOMIZING SECTION ========================== MOUNT_DEVICE=/dev/sda2; # Your Mount device MOUNT_RO=false; # For write protection set to true SNAPSHOT_RW=/DASI/TEST; # where to store the backups EXCLUDES=/home/wolf/nobackup/backup_exclude; # Create the backup_exclude file first! CHECK_HDMINFREE=true; # Check free space HDMINFREE=93; # Make a backup up to this percentage DAYS=3; # Number of daily backups -1 WEEKS=2; # Number of weekly backups -1 MONTHS=3; # Number of monthly backups -1 # ====================================================================== # Make sure we're running as root if (( `$ID -u` != 0 )); then { $ECHO "Sorry, must be root. Exiting..."; exit; } fi # Check Argument if [ $# != 1 ] ; then { $ECHO "Error: Wrong number of arguments. \ Vaild is one out of -d, -w, -m, -h" ; exit; } fi # Check Customization if ! [ -b $MOUNT_DEVICE ] ; then { $ECHO "Error: Mount device $EXCLUDES isn't valid" ; exit; } fi if ! [ -d $SNAPSHOT_RW ] ; then { $ECHO "Error: Backup Directory $SNAPSHOT_RW missing"; exit; } fi if ! [ -d $SNAPSHOT_RW/home ] ; then $MKDIR -p $SNAPSHOT_RW/home; fi if ! [ -f $EXCLUDES ] ; then { $ECHO "Error: Exclude File $EXCLUDES missing" ; exit; } fi # Check free space on disk GETPERCENTAGE='s/.* \([0-9]\{1,3\}\)%.*/\1/'; if $CHECK_HDMINFREE ; then KBISFREE=`$DF /$SNAPSHOT_RW | $TAIL -n1 | $SED -e "$GETPERCENTAGE"` if [ $KBISFREE -ge $HDMINFREE ] ; then $ECHO "Error: Not enough space left for rotating backups!" $LOGGER "Error: Not enough space left for rotating backups!" exit fi fi # ------------- The Script itself -------------------------------------- if $MOUNT_RO ; then # Attempt to remount the RW mount point as RW; else abort $MOUNT -o remount,rw $MOUNT_DEVICE $SNAPSHOT_RW ; if (( $? )); then $ECHO "Error: could not remount $SNAPSHOT_RW readwrite"; exit; fi; fi; case $1 in # *********** Daily Backups ******************************************** -d | -D) $ECHO "Starting Daily Backup..." # Rotating daily snapshots of /home # Step 1: Delete the oldest snapshot, if it exists: # It is NOT moved to the weekly backups level since you can make hundreds of daily backups if [ -d $SNAPSHOT_RW/home/daily.$DAYS ] ; then $RM -rf $SNAPSHOT_RW/home/daily.$DAYS ; fi; # Step 2: Shift all other snapshots(s) by one, if they exist (e.g. 6->7...1->2) OLD=$DAYS; while [ $OLD -ge 2 ] ; do OLD=$[$OLD-1] if [ -d $SNAPSHOT_RW/home/daily.$OLD ] ; then NEW=$[ $OLD + 1 ] # Save date $TOUCH $SNAPSHOT_RW/.timestamp -r $SNAPSHOT_RW/home/daily.$OLD $MV $SNAPSHOT_RW/home/daily.$OLD $SNAPSHOT_RW/home/daily.$NEW # Restore date $TOUCH $SNAPSHOT_RW/home/daily.$NEW/.timestamp \ -r $SNAPSHOT_RW/.timestamp fi; done # Step 3: make a hard-link-only (except for dirs) copy of the latest snapshot, # If that exists 0->1 if ! [ -d $SNAPSHOT_RW/home/daily.0 ] ; then $MKDIR -p $SNAPSHOT_RW/home/daily.0 $TOUCH $SNAPSHOT_RW/home/daily.0/.timestamp else $CP -al $SNAPSHOT_RW/home/daily.0 $SNAPSHOT_RW/home/daily.1 ; fi; # Step 4: rsync from the system into the latest snapshot (notice that # rsync behaves like cp --remove-destination by default, so the destination # is unlinked first. If it were not so, this would copy over the other # snapshot(s) too! $RSYNC \ -va --delete --delete-excluded \ --exclude-from="$EXCLUDES" \ /home/ $SNAPSHOT_RW/home/daily.0 ; # Check return code # 0 = ok, # 24 is also ok. It appears if files were changed or deleted while this script runs # Other return codes are Error -- see man (1) rsync if ! [ $? = 24 -o $? = 0 ] ; then $ECHO "Error: rsync finished on $MOUNT_DEVICE with errors!" $LOGGER "Error: rsync finished on $MOUNT_DEVICE with errors!" fi; # Step 5: update the mtime of daily.0 to reflect the snapshot time $TOUCH $SNAPSHOT_RW/home/daily.0 ; # Finished! $ECHO "Finished rsync backup on $MOUNT_DEVICE..." $LOGGER "Finished rsync backup on $MOUNT_DEVICE..." # For beeing on the secure site... $SYNC;; # And thats it for home. # *********** Weekly Backup ******************************************** -w | -W)$ECHO "Starting Weekly Backup..." # Step 1: Delete the oldest snapshot, if it exists if [ -d $SNAPSHOT_RW/home/weekly.$WEEKS ] ; then $RM -rf $SNAPSHOT_RW/home/weekly.$WEEKS ; fi; # Step 2: shift the middle snapshots(s) by one, if they exist 3->4 ..0->1 OLD=$WEEKS; while [ $OLD -ge 1 ] ; do OLD=$[$OLD-1] if [ -d $SNAPSHOT_RW/home/weekly.$OLD ] ; then NEW=$[ $OLD + 1 ] $MV $SNAPSHOT_RW/home/weekly.$OLD $SNAPSHOT_RW/home/weekly.$NEW ; fi; done # Step 3: Make a hard-link-only (except for dirs) copy of # daily.(max), assuming that exists, into weekly.0 if [ -d $SNAPSHOT_RW/home/daily.$DAYS ] ; then $CP -al $SNAPSHOT_RW/home/daily.$DAYS $SNAPSHOT_RW/home/weekly.0 ; fi;; # *********** Monthly Backup ******************************************* -m | -M)$ECHO "Starting Monthly Backup..." # Step 1: Delete the oldest snapshot, if it exists if [ -d $SNAPSHOT_RW/home/monthly.$MONTHS ] ; then $RM -rf $SNAPSHOT_RW/home/monthly.$MONTHS ; fi; # Step 2: Shift the middle snapshots(s) by one, if they exist 6->7 ..0->1 OLD=$MONTHS; while [ $OLD -ge 1 ] ; do OLD=$[$OLD-1] if [ -d $SNAPSHOT_RW/home/monthly.$OLD ] ; then NEW=$[ $OLD + 1 ] $MV $SNAPSHOT_RW/home/monthly.$OLD $SNAPSHOT_RW/home/monthly.$NEW ; fi; done # Step 3: Make a hard-link-only (except for dirs) copy of # weekly.(max), assuming that exists, into monthly.0 if [ -d $SNAPSHOT_RW/home/weekly.$WEEKS ] ; then $CP -al $SNAPSHOT_RW/home/weekly.$WEEKS $SNAPSHOT_RW/home/monthly.0 ; fi;; -h | -H)$ECHO "Usage: make_snapshot -d Initiates daily backup make_snapshot -w Initiates weekly backup make_snapshot -m Initiates monthly backup make_snapshot -h Displays this text."; exit;; *) $ECHO "Error: Wrong argument. Vaild is one out of -d, -w, -m, -h" ; exit;; esac $ECHO "Backup ended" if $MOUNT_RO ; then # Now remount the RW snapshot mountpoint as readonly $MOUNT -o remount,ro $MOUNT_DEVICE $SNAPSHOT_RW ; if (( $? )); then $ECHO "Error: Could not remount $SNAPSHOT_RW readonly"; exit; fi; fi;