Listing 1: server_backup
#!/bin/sh
#
# @(#) server_backup v3.2 Benjamin J. Anello 950328
#
# Copyright (C) 1995 Benjamin J. Anello
# You may use this code freely but you must
# keep the copyright notice in this code.
#
# @(#) script to do the backups of the
# @(#) Network Workstations.
#
#######################################################
#
# Defined information
#
SCRATCHDIR="/server/admin/backups"
BUDEV="/dev/nrbackup"
DATESTAMP=`date "+%a - %h %d, 19%y"`
DEBUG="OFF"
DISKINFO="/tmp/diskinfo$$"
DUMP="/usr/etc/dump"
DUMPLEVEL=`cat $SCRATCHDIR/.cur_dump_level`
DUMPLEVELDEF=8
ECHO="/usr/bin/echo"
FIRSTONE="YES"
HOSTDEV=`hostname`
JUKEDIR="/usr/local/vjuke"
LOGFILE="/tmp/dumpmsg$$"
MAILLIST="sysgroup@${HOSTDEV}"
MAXTAPES=10
MAXTAPESIZE=4200 # High density mode
MT="/usr/bin/mt"
NETNAME=`cat $SCRATCHDIR/.netname`
PAGECOUNT=1
PING="/usr/etc/ping"
PRINTR="lp"
RDUMP="/usr/etc/rdump"
REMOVE="/usr/bin/rm"
RSH="/usr/ucb/rsh"
SCHEDFILE="/tmp/schedfile$$"
SCHEDTEMP1="/tmp/busched1$$"
SCHEDTEMP2="/tmp/busched2$$"
STIMESTAMP=`date "+%T"`
TAPELOG="/tmp/tapelog$$"
TAPENUM=`cat $SCRATCHDIR/.cur_bu_tape`
TAPESET=`cat $SCRATCHDIR/.cur_tape_set`
TIMEOUT=5
#
##### Functions #######################################
#
##### cleanup() #####
#
# Function to clean up this process
#
cleanup()
{
/usr/ucb/Mail -s "Server Backup Log File" \
operator@${HOSTDEV} < $LOGFILE
$REMOVE -f $LOGFILE
$ECHO \
"---------------------------------------------------" \
>> $TAPELOG
$ECHO "" >> $TAPELOG
$ECHO " Backup Completed: `date "+%T"`" \
>> $TAPELOG
lpr -P${PRINTR} $TAPELOG
/usr/ucb/Mail -s "$NETNAME Network Backup Log" \
$MAILLIST < $TAPELOG
$REMOVE -f $TAPELOG
#
# Remove our flag that says we are dumping
#
if [ `cat $SCRATCHDIR/.dumping` -eq $$ ]; then
$REMOVE -f $SCRATCHDIR/.dumping
fi
}
#
##### init_juke() #####
#
# Function to initialize the jukebox drivers
#
init_juke()
{
$ECHO "" >> $LOGFILE 2>&1
$ECHO "Verifying JukeBox tape drivers" \
>> $LOGFILE 2>&1
$JUKEDIR/vjuke -j1 online >> $LOGFILE 2>&1
$JUKEDIR/vjuke -d1 online >> $LOGFILE 2>&1
}
#
##### get_diskinfo() #####
#
# Function to pull the disk information together
#
get_diskinfo()
{
$REMOVE -f $DISKINFO
cat $SCRATCHDIR/.bu_clients |
while read client
do
if [ "$client" = $HOSTDEV ]; then
df -t 4.2 | tail +2 | awk -f diskinfo.nawk \
HOST=$client >> $DISKINFO
else
$PING $client $TIMEOUT > /dev/null
if [ $? -eq 0 ]; then
$RSH -n $client /usr/ucb/rdate $HOSTDEV \
> /dev/null
$RSH -n $client df -t 4.2 | tail +2 | \
awk -f diskinfo.nawk \
HOST=$client >> $DISKINFO
else
$ECHO \
"WARNING: Unable to find remote host ${client}." \
>> $LOGFILE 2>&1
fi
fi
done
}
#
##### set_bu_sched() #####
#
# Function to set the tape schedule
#
set_bu_sched()
{
schedHost=""
tapeCount=`expr $TAPENUM + 1`
if [ $tapeCount -gt $MAXTAPES ]; then
tapeCount=1
fi
sectionCount=0
cumTapeSize=0
#
# Check for level 0 dump
#
if [ $0 = "/admin/backups/server_backup_0" ]; then
#
# Level 0 so just use the df disk usage values
#
$REMOVE -f $SCHEDTEMP2
cp $DISKINFO $SCHEDTEMP2
else
#
# Incremental so calculate the size of
# incremental backups
#
$REMOVE -f $SCHEDTEMP1
$ECHO "### $SCHEDTEMP1 ###" > $SCHEDTEMP1 2>&1
nawk '{print $1, $2, $3}' $DISKINFO |
while read buhost bupart bufs
do
$ECHO "HOST $buhost" >> $SCHEDTEMP1 2>&1
if [ "$buhost" = $HOSTDEV ]; then
$DUMP ${DUMPLEVEL}dsbf 54000 13000 126 \
/dev/null $bupart >> $SCHEDTEMP1 2>&1
else
$RSH -n $buhost \
"$RDUMP ${DUMPLEVEL}dsbf 54000 13000 126 \
/dev/null $bupart" >> $SCHEDTEMP1 2>&1
fi
done
$REMOVE -f $SCHEDTEMP2
nawk -f dumpsize.nawk $SCHEDTEMP1 > $SCHEDTEMP2
fi
cat $SCHEDTEMP2 |
while read buhost bupart bufs busize
do
cumTapeSize=`expr $cumTapeSize + $busize`
if [ $cumTapeSize -ge $MAXTAPESIZE ]; then
tapeCount=`expr $tapeCount + 1`
if [ $tapeCount -gt $MAXTAPES ]; then
tapeCount=1
fi
sectionCount=1
cumTapeSize=0
else
sectionCount=`expr $sectionCount + 1`
fi
$ECHO "$buhost $tapeCount $sectionCount \
$bupart $bufs $busize" \
>> $SCHEDFILE
done
}
#
#### incr_dump() ####
#
# Increments the weekly dump level
#
incr_dump()
{
dumplevel=$2
dumpout=`expr $dumplevel + 1`
$ECHO "Changing dump level from $dumplevel to \
$dumpout" >> $LOGFILE 2>&1
$REMOVE -f $SCRATCHDIR/.cur_dump_level
$ECHO "$dumpout" > $SCRATCHDIR/.cur_dump_level
eval $1=$dumpout
}
#
##### incr_tape() #####
#
# Function to increment the tape counter
#
incr_tape()
{
tapelabel=$2
tapeout=`expr $tapelabel + 1`
if [ $tapeout -gt $MAXTAPES ]; then
incr_tapeset
tapeout=1
fi
$ECHO "Changing tape from $tapelabel to $tapeout" \
>> $LOGFILE 2>&1
$REMOVE -f $SCRATCHDIR/.cur_bu_tape
$ECHO "$tapeout" > $SCRATCHDIR/.cur_bu_tape
eval $1=$tapeout
}
#
##### incr_tapeset() #####
#
# Function to increment the tape set
#
incr_tapeset()
{
oldset=$TAPESET
if [ $TAPESET = "A" ]; then
TAPESET="B"
elif [ $TAPESET = "B" ]; then
TAPESET="C"
elif [ $TAPESET = "C" ]; then
TAPESET="A"
fi
$ECHO "Changing tape set from $oldset to $TAPESET" \
>> $LOGFILE 2>&1
$REMOVE -f $SCRATCHDIR/.cur_tape_set
$ECHO "$TAPESET" > $SCRATCHDIR/.cur_tape_set
}
#
##### tape_com() #####
#
# Function to send tape commands to the tape device
#
tape_com()
{
tapecommand=$1
tapeno=$2
if [ $DEBUG = "ON" ]; then
$ECHO ""
$ECHO "----- Tape Change -----"
$ECHO "$MT -f ${BUDEV}${tapeno} $tapecommand"
$ECHO ""
else
$MT -f ${BUDEV}${tapeno} $tapecommand
fi
stat=$?
$ECHO "Command sent to tape number $tapeno was \
$tapecommand" >> $LOGFILE 2>&1
if [ $stat -ne 0 ]; then
$ECHO "ERROR in tape command. Status: $stat" \
>> $LOGFILE 2>&1
retry=1
fi
#
# check for tape problems
#
while [ $stat -ne 0 ];
do
sleep 300
$MT -f ${BUDEV}${tapeno} $tapecommand
stat=$?
$ECHO \
"Retry $retry - Command sent to tape number \
$tapeno was $tapecommand" \
>> $LOGFILE 2>&1
if [ $stat -ne 0 ]; then
$ECHO "ERROR in tape command. Status: $stat" \
>> $LOGFILE 2>&1
retry=`expr $retry + 1`
fi
done
}
#
##### send_request() #####
#
# Function to send the backup request out
#
send_request()
{
$ECHO "Sending backup request to machine $name" \
>> $LOGFILE 2>&1
if [ "$name" = $HOSTDEV ]; then
$ECHO \
"REQUEST: CLIENT: $name (TAPEHOST), PART: \
$partition, TAPE: $TAPENUM" \
>> $LOGFILE 2>&1
if [ $DEBUG = "ON" ]; then
$ECHO "$DUMP ${DUMPLEVEL}dsbfu 54000 13000 \
126 ${BUDEV}${TAPENUM} $partition"
else
$DUMP ${DUMPLEVEL}dsbfu 54000 13000 126 \
${BUDEV}${TAPENUM} \
$partition >> $LOGFILE 2>&1
fi
$ECHO "Backup of $name - $partition completed." \
>> $LOGFILE 2>&1
else
$ECHO \
"REQUEST: CLIENT: $name, PART: $partition, \
TAPE: $TAPENUM" \
>> $LOGFILE 2>&1
if [ $DEBUG = "ON" ]; then
$ECHO -n "$RSH -n $name $RDUMP \
${DUMPLEVEL}dsbfu 54000 13000 126 "
$ECHO "${HOSTDEV}:${BUDEV}${TAPENUM} \
$partition"
else
$RSH -n $name "$RDUMP ${DUMPLEVEL}dsbfu \
54000 13000 126 \
${HOSTDEV}:${BUDEV}${TAPENUM} $partition" \
>> $LOGFILE 2>&1
fi
$ECHO "Backup of $name - $partition \
completed." >> $LOGFILE 2>&1
fi
$ECHO "" >> $LOGFILE 2>&1
}
#
##### print_header() #####
#
# Function to print the header
#
print_header()
{
pc=$2
$ECHO "$NETNAME Network Backup of $DATESTAMP" \
>> $TAPELOG
if [ $DEBUG = "ON" ]; then
$ECHO "*** NOTE: TEST RUN ***" >> $TAPELOG
fi
$ECHO " Backup Dump Level: $DUMPLEVEL" \
>> $TAPELOG
$ECHO " Backup Start: $STIMESTAMP" \
>> $TAPELOG
$ECHO \
"
Page $pc" \
>> $TAPELOG
$ECHO \
"---------------------------------------------------" \
>> $TAPELOG
$ECHO "Tape Section Time Completed Size \
Host Partition FS Name" \
>> $TAPELOG
$ECHO \
"---------------------------------------------------" \
>> $TAPELOG
pcout=`expr $pc + 1`
eval $1=$pcout
}
#
##### Main Program ####################################
#
##### main() #####
#
# setup the clean up function for when we exit
#
trap cleanup 0
#
# Create the log file
#
$ECHO "Server Backup Script Log File" > $LOGFILE 2>&1
$ECHO "" >> $LOGFILE 2>&1
$ECHO "Start time is `date`" >> $LOGFILE 2>&1
#
# Check that root is running this script
#
name=`whoami`
case "$name" in
"root" )
break;;
* )
if [ $DEBUG = "ON" ]; then
$ECHO "$0:DEBUG-> You are not running as root."
else
$ECHO "$0:ERROR-> May only run as root, \
Please log in as root"
exit 1
fi
break;;
esac
#
# Be sure that we are not already running
#
if [ -f $SCRATCHDIR/.dumping ]; then
$ECHO "" >> $LOGFILE 2>&1
$ECHO "Tried to start another backup job" \
>> $LOGFILE 2>&1
$ECHO "while job `cat $SCRATCHDIR/.dumping` \
was running..." >> $LOGFILE 2>&1
$ECHO "" >> $LOGFILE 2>&1
$ECHO "" > $TAPELOG 2>&1
$ECHO "Tried to start another backup job" \
>> $TAPELOG 2>&1
$ECHO "while job `cat $SCRATCHDIR/.dumping` \
was running..." >> $TAPELOG 2>&1
$ECHO "" >> $TAPELOG 2>&1
exit 1
fi
#
# Okay, we are going to run. Lock us in.
#
$ECHO "$$" > $SCRATCHDIR/.dumping
#
# Let the console know we are GO
#
if [ $DEBUG = "ON" ]; then
$ECHO "$NETNAME Network Backups testing starting \
at `date`" >> $LOGFILE 2>&1
/usr/5bin/echo "\\n\\r$NETNAME Network Backups \
testing starting at `date`\\n\\r" \
> /dev/console
else
$ECHO "$NETNAME Network Backups starting at `date`" \
>> $LOGFILE 2>&1
/usr/5bin/echo "\\n\\r$NETNAME Network Backups \
starting at `date`\\n\\r" > /dev/console
fi
#
# Be sure that the jukebox is running
#
init_juke
#
# Get the disk information for the hosts to
# be backed up
#
cd $SCRATCHDIR
get_diskinfo
#
# If this is 0 file, then all bets are off.
# We will do a level 0 backup.
#
if [ $0 = "/server/admin/backups/server_backup_0" ]; \
then
DUMPLEVEL=0
# reset the weekly (Friday) backup level file
$REMOVE -f $SCRATCHDIR/.cur_dump_level
$ECHO "1" > $SCRATCHDIR/.cur_dump_level
# reset the tape counters for level 0s
$REMOVE -f $SCRATCHDIR/.cur_tape_set
$ECHO "A" > $SCRATCHDIR/.cur_tape_set
TAPESET="Full-"
$REMOVE -f $SCRATCHDIR/.cur_bu_tape
$ECHO "0" > $SCRATCHDIR/.cur_bu_tape
TAPENUM=0
else
#
# Check for forced dump level
#
if [ -f $SCRATCHDIR/forcedump ]; then
DUMPLEVEL=`cat $SCRATCHDIR/forcedump`
$REMOVE -f $SCRATCHDIR/forcedump
$ECHO "NOTE: User forcing dump level at level \
$DUMPLEVEL" >> $LOGFILE 2>&1
$REMOVE -f $SCRATCHDIR/.cur_dump_level
$ECHO "$DUMPLEVEL" > $SCRATCHDIR/.cur_dump_level
else
#
# If weekly, increment the dump level
#
dow=`date "+%w"`
if [ $dow -eq 6 ]; then
incr_dump newdump $DUMPLEVEL
DUMPLEVEL=$newdump
else
#
# daily, so do the daily dump
#
DUMPLEVEL=$DUMPLEVELDEF
fi
fi
fi
#
# Set the backup schedule
#
set_bu_sched
#
# Increment tape to start on a new tape
#
incr_tape newtape $TAPENUM
TAPENUM=$newtape
#
# Get ready to loop through list to do backups
#
cumdsize=0
sectioncount=1
$REMOVE -f $TAPELOG
#
# print header
#
$ECHO "" > $TAPELOG
print_header newpc $PAGECOUNT
PAGECOUNT=$newpc
if [ $DEBUG = "ON" ]; then
lc=8
else
lc=7
fi
#
# Loop through list to do backups
#
cat $SCHEDFILE |
while read name tapeCount sectionCount partition \
fileSys size
do
#
# Fake out first time through
#
if [ $FIRSTONE = "YES" ]; then
FIRSTONE="NO"
TCOUNT=$tapeCount
fi
#
# If the tape counter is different, then
#
if [ $tapeCount -ne $TCOUNT ]; then
#
# increment the tape
#
tape_com offline $TAPENUM
incr_tape newtape $TAPENUM
TAPENUM=$newtape
tape_com rewind $TAPENUM
TCOUNT=$tapeCount
$ECHO "" >> $TAPELOG
lc=`expr $lc + 1`
if [ $lc -gt 63 ]; then
/usr/5bin/echo "\\f" >> $TAPELOG
print_header newpc $PAGECOUNT
PAGECOUNT=$newpc
if [ $DEBUG = "ON" ]; then
lc=8
else
lc=7
fi
fi
sectioncount=1
fi
if [ $DEBUG = "ON" ]; then
$ECHO "Host: $name"
$ECHO "Tape: ${TAPESET}${TAPENUM}"
$ECHO "Section: $sectionCount"
$ECHO "Partition: $partition"
$ECHO "File System: $fileSys"
$ECHO "Size: $size"
$ECHO ""
fi
#
# Backup the partition to tape
#
if [ $name = $HOSTDEV ]; then
send_request
else
$PING "$name" > /dev/null && send_request || \
$ECHO "NOTE: Client machine $name was not \
found on the network" >> $LOGFILE 2>&1
fi
timestamp=`date "+%T"`
$ECHO "${TAPESET}${TAPENUM} $sectionCount \
$timestamp $size $name $partition \
$fileSys" >> $TAPELOG
lc=`expr $lc + 1`
if [ $lc -gt 63 ]; then
/usr/5bin/echo "\\f" >> $TAPELOG
print_header newpc $PAGECOUNT
PAGECOUNT=$newpc
if [ $DEBUG = "ON" ]; then
lc=8
else
lc=7
fi
fi
done
#
# All backups are done, remove the last tape and update
# the tape counter file
#
TAPENUM=`cat $SCRATCHDIR/.cur_bu_tape`
tape_com offline $TAPENUM
if [ $DEBUG = "ON" ]; then
$REMOVE -f $DISKINFO
$REMOVE -f $SCHEDFILE
$REMOVE -f $SCHEDTEMP1
$REMOVE -f $SCHEDTEMP2
fi
if [ $0 = "/server/admin/backups/server_backup_0" ]; \
then
$REMOVE -f $SCRATCHDIR/.cur_bu_tape
$ECHO "0" > $SCRATCHDIR/.cur_bu_tape
fi
if [ $DEBUG = "ON" ]; then
$ECHO "$NETNAME Network Backups testing completed \
at `date`" >> $LOGFILE 2>&1
/usr/5bin/echo "$NETNAME Network Backups testing \
completed at `date`\\n\\r" \
> /dev/console
else
$ECHO "$NETNAME Network Backups completed \
at `date`" >> $LOGFILE 2>&1
/usr/5bin/echo "$NETNAME Network Backups \
completed at `date`\\n\\r" > /dev/console
fi
exit 0
#
##### End of Script server_backup #####################
# End of File
|