#!/bin/ksh # # Solaris and Digital Unix tape backup script. # # This script will dump all local mounted file systems on a system to tape. # It can send output to a log file and via email. If the output is sent # to a log file, the log file is copied to the end of the tape via tar for # documentation purposes. This script can backup UFS and Veritas filesystems # under Solaris 2.x and can backup UFS and ADVFS file systems under # Digital/Compaq Unix 4.0x. # # Because of differences in the underlying "ufsdump" and "vdump" commands, # this script has different capabilities between Sun and DEC. # # Solaris: # Because it uses device names rather than mount points in the vxdump/ufsdump # command, it can be run as a non-root user. vxdump and ufsdump support being # run as a user in the "sys" group because the disk device files are # readable by the "sys" group. This is especially useful when performing # network based backups. This allows a the central computer controlling # the backups to run it's "rsh" commands as a non root user. # # Sun supports the use of a tape drive over the network in the ufsdump # program, which allows the use of a central tape host. # # And because the central tape host does not need a root user id for # allowing inbound tape requests, this also helps security. # # Digital / Compaq Unix # As of Digital Unix 4.0D, the "vdump" command can backup either UFS or ADVFS # file systems. So this script assumes that "vdump" will work on whatever # file systems are locally mounted. If you are running UFS file systems on a # pre 4.0D system, you can modify the "OSF1_dump" script to check for the # fstype. # # Unfortunatly, Digital Unix does not lend itself as easily to network based # tape backups as Solaris. So this script makes no provisions for network # backups for a Digital host. # # One way to use vdump to a remote tape drive is using this command: # vdump -b64 0uf - /somefilesystem | rsh tapehost dd of=/dev/nrmt0h bs=64k # The block size parameters are needed to make sure the sending and receiving # programs are in sync as to what block size to use. # # Options: # -l|-logfile # Write output to the specified log file. # -mail|-email # Send log file output to the specified email address # -d|-dev # Specifies the tape device to use. Must be the non-rewinding # device for the script to work properly. Default device is # $TAPE if set, or /dev/nrmt0h # -unload # Unloads the tape from the drive when the backup is done. # # Andrew Welter # www.the-welters.com # 6/22/1999 # # Modifications: # 10/18/1999 Andy Welter # Added support for Veritas file systems # ######################################################################## ### Define functions ######################################################################## sendlog () { for ID in $SENDTO; do /usr/bin/mailx -s "$SUBJECT" $ID < $LOG done }; bad_cmd () { echo "error, bad parameters: $1" echo "usage: $USAGE" exit 1 }; SunOS_fslist () { # # Get the list of file systems to backup. For Solaris, # this is a list of disk device names. # if [ -z "$EXCLUDE" ]; then mount -p | grep '^/dev/' | \ while read FS JUNK; do FSLIST="$FSLIST $FS" done else mount -p | egrep -v "$EXCLUDE" | grep '^/dev/' | \ while read FS JUNK; do FSLIST="$FSLIST $FS" done fi }; OSF1_fslist () { # # Get the list of file systems to backup. For OSF1, # this is a list of mount points. We only want to backup # AdvFS or UFS file systems. This excludes things such as # mounted CDs, NFS mounts, and the /proc file system. # if [ -z "$EXCLUDE" ]; then (mount -t advfs;mount -t ufs) | \ while read DEVICE JUNK FS JUNK2; do FSLIST="$FSLIST $FS" done else (mount -t advfs;mount -t ufs) | egrep -v "$EXCLUDE" | \ while read DEVICE JUNK FS JUNK2; do FSLIST="$FSLIST $FS" done fi echo "backup $FSLIST" }; # # Read parameters from command line or from a config file. getparms () { NUMPARMS=0; # # Extract parms from command line while [ $# -gt 0 ]; do PARMS[$NUMPARMS]="$1" shift NUMPARMS=`expr $NUMPARMS + 1` done # # if no command line parms were used, try to get parms from a # configuration file. if [ $NUMPARMS -eq 0 -a -f $CFGFILE ]; then cat $CFGFILE | while read LINE; do for WORD in $LINE; do PARMS[$NUMPARMS]=$WORD NUMPARMS=`expr $NUMPARMS + 1` done done fi # # Process the parms the same way whether they came from the command # line or from a configuration file. SENDTO="" UNLOAD="" DUMPOPTS="$DEFOPTS" if [ -n "$TAPE" ]; then DEV=$TAPE else DEV=$DEFTAPE fi II=0 while [ $II -lt $NUMPARMS ]; do case "${PARMS[$II]}" in -unload|-u|-offline) # Unload tape when backup is done UNLOAD=yes ;; -o) # Backup options II=`expr $II + 1` if [ $II -eq $NUMPARMS ]; then bad_cmd "missing value" fi DUMPOPTS="${PARMS[$II]}" ;; -d|-dev) # Backup device II=`expr $II + 1` if [ $II -eq $NUMPARMS ]; then bad_cmd "missing value" fi DEV="${PARMS[$II]}" ;; -log|-l) # log file name II=`expr $II + 1` if [ $II -eq $NUMPARMS ]; then bad_cmd "missing value" fi LOG="${PARMS[$II]}" cat /dev/null > $LOG ;; -mail|-m|-email) # email receipient II=`expr $II + 1` if [ $II -eq $NUMPARMS ]; then bad_cmd "missing value" fi SENDTO="$SENDTO ${PARMS[$II]}" ;; -x|-exclude) # exclude a file system from the backup II=`expr $II + 1` if [ $II -eq $NUMPARMS ]; then bad_cmd "missing value" fi if [ -z "$EXCLUDE" ]; then EXCLUDE=" ${PARMS[$II]} " else EXCLUDE="$EXCLUDE| ${PARMS[$II]} " fi ;; *) bad_cmd "unknown parameter ${PARMS[$II]}" ;; esac II=`expr $II + 1` done }; SunOS_dump () { # # Use ufsdump or vxdump to backup a Solaris file system. # "FS" must be set prior to calling this function. For # Solaris, FS is a device name. The mountpoint name is # obtained to make the script output more useful. # # ufsdump is the standard Solaris utility for backing up # ufs filesystems. vxdump is part of Veritas, and is used # for Veritas file systems. MOUNTPT=`df $FS | (read mountpt junk;echo $mountpt)` echo date +"Starting backup of $FS mounted on $MOUNTPT: %D %T" # # Determine which backup program to use. case $FS in /dev/vx/*) /usr/sbin/vxdump $DUMPOPTS $DEV $FS ;; /dev/md/*|/dev/dsk/*) /usr/sbin/ufsdump $DUMPOPTS $DEV $FS ;; *) echo "WARNING: Unknown File system type." echo "WARNING: Using ufsdump by default." /usr/sbin/ufsdump $DUMPOPTS $DEV $FS ;; esac if [ $? -eq 0 ]; then date +"Backup complete $MOUNTPT: %D %T" >> $HEADER date +"Backup complete $MOUNTPT: %D %T" else RC=$? date +"ERROR: bad return code from ufsdump $MOUNTPT %D %T" >> $HEADER date +"ERROR: bad return code from ufsdump $MOUNTPT %D %T" fi } OSF1_dump () { # # For OSF1, "FS" is a mountpoint name, and it is set prior to calling # the function. echo date +"Starting backup of $FS: %D %T" /sbin/vdump $DUMPOPTS $DEV $FS if [ $? -eq 0 ]; then date +"Backup complete $FS: %D %T" >> $HEADER date +"Backup complete $FS: %D %T" >> $LOG else RC=$? date +"ERROR: bad return code from vdump $FS %D %T" >> $HEADER date +"ERROR: bad return code from vdump $FS %D %T" >> $LOG fi } ######################################################################## ### Start mainline of the script ######################################################################## # # Set default variables. # OSERR="ERROR: this script only supports Digital Unix 4.0x and Solaris 2.X." USAGE="dumpall [-l ] [-mail ] [-d ] [ -unload ]" OSTYPE=`uname -s` HOSTNAME=`uname -n | cut -f1 -d.` PATH="/bin:/usr/bin:/etc:/usr/sbin:/sbin" case $OSTYPE in OSF1) DEFOPTS="0uf" DEFTAPE=/dev/nrmt0h ;; SunOS) DEFOPTS="0uf" DEFTAPE=/dev/rmt/0n ;; *) echo "$OSERR" exit 1 ;; esac LOG="" # # If there is a host specific rc file, use that. Otherwise default to # dumpall.rc. The getparms routine will make sure this file exists. if [ -f "$0.$HOSNAME.rc" ]; then CFGFILE="$0.$HOSTNAME.rc" else CFGFILE="$0.rc" fi HEADER=/tmp/backuplog.$$ SUBJECT=`date +"## System backup $HOSTNAME %D %T"` # # get parameters from command line or from config file getparms $* # # Redirect standard out and standard error to LOG if specified. if [ -n "$LOG" ]; then exec > $LOG 2>&1 fi echo >> $HEADER RC=0 uname -a # # Get list of file systems case $OSTYPE in OSF1) OSF1_fslist ;; SunOS) SunOS_fslist ;; *) echo "$OSERR" exit 1 ;; esac echo "Backing up $FSLIST" echo "to device $DEV" if [ -n "$EXCLUDE" ]; then echo "Excluding $EXCLUDE from the backup." else echo "Backing up all local file systems." fi if [ -n "$LOG" ]; then echo "Saving results to $LOG" fi echo "Emailing results to $SENDTO" for FS in $FSLIST; do case $OSTYPE in OSF1) OSF1_dump ;; SunOS) SunOS_dump ;; *) echo "$OSERR" exit 1 ;; esac done if [ -n "$LOG" ]; then echo "=================================" >> $HEADER cat $LOG >> $HEADER mv $HEADER $LOG sendlog cp $LOG $LOG.`date +"%y%m%d"` DIRNAME=`dirname $LOG` BASENAME=`basename $LOG` cd $DIRNAME tar -cvf $DEV $BASENAME fi if [ "$UNLOAD" = "yes" ]; then mt -f $DEV offline fi exit $RC