#!/bin/csh -f # params: # -v verbose output # -c do full checksums (must be after -v) # Be very careful with -c. It will checksum EVERY file regardless of # timestamps. I added it as an emergency measure to discover files that were # damaged after a dead drive incident. The option should NOT be used for # normal backups. # figure out what backup we are... # I keep symlinks to this file as [hostname]_backup.csh so I can backup a # specific host without having multiple backup scripts. The script will also # get its backup and exclude list from $BackupName.tab and $BackupName.exclude # which can be symlinks or standalone files. # # The format of $BackupName.tab is: # [userid]@[hostname]:[filesystem] # one per line. # # The format of $BackupName.exclude is just a list of paths one per line set BackupName=`echo $0 | sed -e 's/\.csh//' | awk -F/ '{print $NF}'` # Where to backup to set BackupDIR="/backup/rsync" set ScriptDIR="/var/spool/backup" # get name of localhost #set LocalHostName=`uname -n` # things to be excluded set Excludes="--exclude-from=${ScriptDIR}/${BackupName}.excludes" # setup command line params setenv RSYNC_RSH "ssh -c arcfour -o Compression=no -x" if ("$1" == "-v" || "$2" == "-v" || "$3" == "-v" || "$1" == "-V" || "$2" == "-V" || "$3" == "-V") then set Verbose="y" set RMParams="-f" set FileRMParams="-fv" set RsyncParams="-vaHx --progress --numeric-ids --delete $Excludes --delete-excluded" set GetInfoParams="-v" if ("$BackupName" == "fq_backup") then # This is a special case backup that I do across the internet so I want # compression turned on in rsync. set RsyncParams="-vaHx -z --ignore-errors --progress --numeric-ids --delete $Excludes --delete-excluded" endif set ArchiveParams="-v" if ("$1" == "-V" || "$2" == "-V" || "$3" == "-V") then set ArchiveParams="-V" endif else set Verbose="n" set RMParams="-f" set FileRMParams="-f" set RsyncParams="-aHx --numeric-ids --delete $Excludes --delete-excluded" set GetInfoParams="" if ("$BackupName" == "fq_backup") then # This is a special case backup that I do across the internet so I want # compression turned on in rsync. set RsyncParams="-ax -z --ignore-errors --numeric-ids --delete $Excludes --delete-excluded" endif set ArchiveParams="" endif if ("$2" == "-c") then # read the top comment about the possible badness of this param. set RsyncParams="-c $RsyncParams" endif if ("$Verbose" == "y") then echo "Beginning $BackupName on `date`..." endif # list of stuff to backup in format [userid]@[hostname]:[filesystem] foreach f (`cat $ScriptDIR/$BackupName.tab | grep -v ^\#`) # split out the host and filesystem # Here is a good reason to convert this script to perl. I may do that some # day. set User=`echo "$f" | awk -F@ '{print $1}'` set Host=`echo "$f" | awk -F@ '{print $2}' | awk -F: '{print $1}'` set FS=`echo "$f" | awk -F: '{print $2}'` # see if the host is up and skip this backup if not. set Up="unknown" $ScriptDIR/uptest.csh $Host $User >& /dev/null && set Up="Y" || set Up="N" if ("$Up" != "Y") then echo "WARNING: Skipping backup and archive of ${Host}:${FS} because I can't ssh to it." endif if ("$Up" == "Y") then # replace '/' with '_' in $FS so I can have the FS name in my backup dir # without making a tree # IOW '/' becomes '_' and '/usr/local' becomes '_usr_local' set UFS=`echo $FS | sed -e 's/\//_/g'` set FFS="$UFS.`date +'%Y-%m-%d.%H-%M-%S'`" if ("$Verbose" == "y") then echo "Making archives of previous backups of ${Host}:${FS}..." endif # this script rotates the existing archives and creates a new one from the # last backup that was run. $ScriptDIR/archive.csh ${BackupDIR}/${Host}/${FFS} $ArchiveParams || echo "WARNING: There was a problem archiving ${Host}:${FS}." #this now done in archive.csh. #mkdir -p $BackupDIR/$Host/$FFS # I always tarball /dev on the remote box because different OS's use # different major/minor number schemes. This especially applys to Solaris # but it doesn't really apply to Linux anymore since most modern Linux # boxes use devfs. if ("$FS" == "/") then if ("$Verbose" == "y") then echo "Updating /dev tree on $Host..." endif ssh -x $Host rm $FileRMParams /dev.tar.gz ssh -x $Host tar -pczf /dev.tar.gz /dev |& grep -v "tar. Removing leading" |& grep -v "socket ignored" if ("$Host" == "madness") then # "madness" is my Solaris box. Since Solaris uses both /dev and # /devices I need to tarball /devices too. I could just detect the # existance of /devices but since I only have 1 Solaris box it is # easier to just hard code the name. if ("$Verbose" == "y") then echo "Updating /devices tree on $Host..." endif ssh -x $Host rm $FileRMParams /devices.tar.gz ssh -x $Host tar -pczf /devices.tar.gz /devices |& grep -v "tar. Removing leading" |& grep -v "socket ignored" endif if (-e ${ScriptDIR}/${BackupName}.getinfo.tab) then # This runs my getinfo.pl script which archives data that I think # might be usefull to have around even though it isn't stored in a # file. Partition tables would be a good example. RAID setups would # be another. Just remember, if a system is completely wiped you will # need more than a simple copy of it to put it back the way it was. if ("$Verbose" == "y") then ${ScriptDIR}/scripts/getinfo.pl ${ScriptDIR}/${BackupName}.getinfo.tab -v || echo "Problem getting host info." else ${ScriptDIR}/scripts/getinfo.pl ${ScriptDIR}/${BackupName}.getinfo.tab || echo "Problem getting host info." endif endif endif if ("$Verbose" == "y") then echo "Backing up $FS on $Host to $BackupDIR/$Host/$FFS" endif # after all of that code here comes the actual backup using rsync. rsync $RsyncParams ${User}\@${Host}:${FS}/ ${BackupDIR}/${Host}/${FFS}/ || echo "ERROR: There was a problem backing up ${Host}:${FS}." # create .current symlink... ln -s $FFS ${BackupDIR}/${Host}/${UFS}.current endif end if ("$Verbose" == "y") then echo "Ending $BackupName on `date`..." endif