#!/bin/bash # ---------------------------------------------------------------------- # mikes handy rotating-filesystem-snapshot utility # ---------------------------------------------------------------------- # RCS info: $Id: make_snapshot.sh,v 1.6 2002/04/06 04:20:00 mrubel Exp $ # ---------------------------------------------------------------------- # this needs to be a lot more general, but the basic idea is it makes # rotating backup-snapshots of /home whenever called # ---------------------------------------------------------------------- # ------------- 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; MKDIR=/bin/mkdir; TOUCH=/bin/touch; RSYNC=/usr/bin/rsync; # ------------- file locations ----------------------------------------- MOUNT_DEVICE=/dev/hdb1; SNAPSHOT_RW=/snapshots; EXCLUDES=/home/craig/backup_exclude; TOBACKUP=( root@big:/etc root@big:/home/craig root@big:/home/cajones root@big:/var/spool/mail ); # Bash array ${BACKUP[0]} ... # ------------- the script itself -------------------------------------- # make sure we're running as root if (( `$ID -u` != 0 )); then { $ECHO "Sorry, must be root. Exiting..."; exit; } fi # attempt to remount the RW mount point as RW; else abort #$MOUNT -o remount,rw $MOUNT_DEVICE $SNAPSHOT_RW ; #if (( $? )); then #{ # $ECHO "snapshot: could not remount $SNAPSHOT_RW readwrite"; # exit; #} #fi; # step 1: delete the oldest snapshot, if it exists: echo "Deleting $SNAPSHOT_RW/hourly.3" if [ -d $SNAPSHOT_RW/hourly.3 ] ; then \ $RM -rf $SNAPSHOT_RW/hourly.3 ; \ fi ; # rotating snapshots of /home (fixme: this should be more general) # step 2: shift the middle snapshots(s) back by one, if they exist if [ -d $SNAPSHOT_RW/hourly.2 ] ; then \ if [ ! -d $SNAPSHOT_RW/hourly.3 ] ; then \ $MKDIR $SNAPSHOT_RW/hourly.3 ; \ fi; echo "Moving $SNAPSHOT_RW/hourly.2 -> $SNAPSHOT_RW/hourly.3"; \ $MV $SNAPSHOT_RW/hourly.2 $SNAPSHOT_RW/hourly.3 ; \ fi; if [ -d $SNAPSHOT_RW/hourly.1 ] ; then \ if [ ! -d $SNAPSHOT_RW/hourly.2 ] ; then \ $MKDIR $SNAPSHOT_RW/hourly.2 ; \ fi; \ echo "Moving $SNAPSHOT_RW/hourly.2 -> $SNAPSHOT_RW/hourly.3" ; \ $MV $SNAPSHOT_RW/hourly.2 $SNAPSHOT_RW/hourly.3 ; \ fi; # step 3: make a hard-link-only (except for dirs) copy of the latest snapshot, # if that exists if [ -d $SNAPSHOT_RW/hourly.0 ] ; then \ # if [ ! -d $SNAPSHOT_RW/hourly.1 ] ; then \ # $MKDIR -p $SNAPSHOT_RW/hourly.1 ; \ # fi; $CP -al $SNAPSHOT_RW/hourly.0 $SNAPSHOT_RW/hourly.1 ; \ fi; if [ ! -d $SNAPSHOT_RW/hourly.0 ] ; then \ $MKDIR $SNAPSHOT_RW/hourly.0 ; \ 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! # # will backup all the dirs in the array $BACKUP echo "Doing rsync" for x in ${TOBACKUP[*]} ; do \ BACKUPNAME=${x/:/}; \ MACHINE=`echo $x | cut -s -d: -f1`; \ echo "Making directory $SNAPSHOT_RW/hourly.0/$BACKUPNAME ..."; \ $MKDIR -p $SNAPSHOT_RW/hourly.0/$BACKUPNAME; \ $RSYNC \ -va --delete --delete-excluded \ -e ssh \ --exclude-from="$EXCLUDES" \ ${x}/ $SNAPSHOT_RW/hourly.0/$BACKUPNAME ; # step 5: update the mtime of hourly.0 to reflect the snapshot time $TOUCH $SNAPSHOT_RW/hourly.0/$BACKUPNAME ; \ done echo "Done rsync" # and thats it for home. # now remount the RW snapshot mountpoint as readonly #$MOUNT -o remount,ro $MOUNT_DEVICE $SNAPSHOT_RW ; #if (( $? )); then #{ # $ECHO "snapshot: could not remount $SNAPSHOT_RW readonly"; # exit; #} fi;