#!/bin/sh # # $Id: nsr_clone_ssids,v 1.3 2003-06-03 09:50:48-07 rpr Exp $ # # nsr_clone_ssids - Clone Legato Networker Save Sets # Copyright (C) 1999 Rodney P. Rutherford # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #------------------------------------------------------------------------------ # Script: nsr_clone_ssids # # Purpose: This program clones all the save sets which have not been cloned # during the period specified. # # Author: Rodney P. Rutherford # # Born on Date: March 17, 1999 # # Modification History: # # 1.0 - Wed Mar 17 17:51:15 PST 1999 - Rodney Rutherford # - Original script created and tested # # 1.1 - Fri Mar 19 12:56:52 PST 1999 - Rodney Rutherford # - Cleaned up echo statements, checked into RCS # # 1.2 - Mon Mar 29 11:15:15 PST 1999 - Rodney Rutherford # - Updated the calls to the networker utilities to use NSRPATH # - Fixed lock routine, it was removing all lock files # # 1.3 - Thu Apr 1 12:44:58 PST 1999 - Rodney Rutherford # - updated lock info to report location of lock files #------------------------------------------------------------------------------ VERSION='1.3 -- Thu Apr 1 12:44:58 PST 1999' COPYRIGHT='Copyright (C) 1999' AUTHOR='Rodney P. Rutherford ' SCRIPT=`basename $0` #------------------------------------------------------------------------------ # #======================== Start of Configuration ============================== # # Admin environment variables. Update these per the local environment: # # ADMIN - The email address(es) to mail errors to # PAGER - The email address(es) for a pager # PRINTER - The printer you wish to print to # PRINT - The print command to use. If you do not want any special formatting # or pre-processing of the log, just use 'cat'. # COPIES - The number of copies to print # DESTDIR - The directory path for the log files # # Examples: # # ADMIN='root, user@domain.name' # PAGER=oncall # PRINTER=printer1 # PRINT='/usr/openwin/bin/mp -o' # COPIES=1 # DESTDIR=/nsr/logs/clones # # NOTE: # If you do not wish to have the script print, email the # admin(s), or page, then leave the variable set to null, # ie: PRINTER='' # ADMIN='root' PAGER='' PRINTER='' PRINT='cat' COPIES=1 DESTDIR=/nsr/logs/clones # #------------------------------------------------------------------------------ # Application environment variables. Update these per the local environment: # # NSRPATH - The path to the nsr utilities, such as mminfo. # SERVER - The networker server # EXCLUDE - The clients you do not wish to clone # PRIORITY - Mission critical clients that should be cloned first # PERIOD - The time period to look for save sets to clone, ie: since # 'yesterday', 'last week', 'last month', 'last year' # POOL - The tape pool to use for the cloning # QUERY - mminfo query to use for choosing save sets # FORMAT - mminfo format for logging save set info # STOP - The hour of day (24hr clock) to stop cloning. You would # normally set this to the hour before the start of scheduled backups. # # Examples: # # NSRPATH='/usr/sbin' # SERVER=nsrhost # EXCLUDE=host3 # PRIORITY='host1 host2' # PERIOD='last month' # POOL='Default Clone' # QUERY='level=full,copies<2,pssid=0,!incomplete,!ssrecycle' #(fulls only) # QUERY='copies<2,pssid=0,!incomplete,!ssrecycle' #(all levels) # FORMAT='ssid(8),sumsize,savetime,client,level,volume,name' # STOP='18' # NSRPATH='/usr/sbin' SERVER=localhost EXCLUDE='' PRIORITY='' PERIOD='last week' POOL='Default Clone' QUERY='level=full,copies<2,pssid=0,!incomplete,!ssrecycle' FORMAT='ssid(8),sumsize,savetime,client,level,volume,name' STOP=17 # #------------------------------------------------------------------------------ # Fixed environment variables. These normally should not need updating. # PATH=/usr/sbin:/usr/bin:/usr/ucb HOST=`hostname` DATE=`date +%m/%d/%y` DAY=`date +%d` HOUR=`date +%H` LOGDATE=`date +%Y%m%d` TIME=`date +%H%M` TTY=`tty` LOG=${DESTDIR}/${SCRIPT}_${LOGDATE}_${TIME}.log LOCK=/var/spool/locks/${SCRIPT}.lock.$$ TMP=/tmp/${SCRIPT}.$$ STATUS=0 # #========================= End of Configuration =============================== # #========================== Start of Functions ================================ # # Declare the functions # show_license () { echo "" echo " $SCRIPT version $VERSION" echo " $COPYRIGHT $AUTHOR" echo " This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. " } show_usage () { echo "" echo " $SCRIPT version $VERSION" echo " $COPYRIGHT $AUTHOR" echo "" echo " $SCRIPT will clone all the save sets which have not been cloned" echo " since ${PERIOD}. The default usage is to clone all clients." echo "" echo " Usage: $SCRIPT [ clientname ... ]" echo "\t[ clientname ... ] - will clone only the listed client(s)." echo "\t[ -h ] - show this usage message." echo "\t[ -l ] - show the license info." echo "" } error_check () { if [ $? -ne 0 ] then STATUS=255 export STATUS fi } echo_tty () { STRING=$1 echo "\n${STRING}" if [ "$TTY" != "not a tty" ] then echo "\n${STRING}" > $TTY fi } cleanup_exit () { # # Set message based on status and log # case $STATUS in 0) MESSAGE="Cloning has been completed.";; 15) MESSAGE="WARNING - past the cloning period, skipping clones.";; 25) MESSAGE="WARNING - backups are running, skipping clones.";; 35) MESSAGE="WARNING - backups are starting, stopping clones.";; 45) MESSAGE="WARNING - another lockfile exists, skipping clones!";; 55) MESSAGE="WARNING - nsrclone is running, skipping clones.";; 65) MESSAGE="ERROR - Networker is not running, cannot clone!";; 75) MESSAGE="ERROR - NSR utilities not found, cannot clone!";; 85) MESSAGE="ERROR - nsrclone had an error!";; 95) MESSAGE="ERROR - script aborted or killed!";; 255) MESSAGE="ERROR - script FAILED!";; esac echo_tty "\t$MESSAGE" # # Determine what save sets/clients were not completed and log # if [ -f ${TMP}.ssids.todo ] then if [ -f ${TMP}.ssids.done ] then for ssid in `cat ${TMP}.ssids.done` do sed "/$ssid/d" $TMP.ssids.todo > $TMP.ssids.todo.sed mv $TMP.ssids.todo.sed $TMP.ssids.todo done fi echo "\nThe following save sets for $client were not cloned:\n" for ssid in `cat $TMP.ssids.todo` do echo "\t${ssid}" done echo "" fi if [ -f ${TMP}.clients.todo ] then if [ -f ${TMP}.clients.done ] then for client in `cat ${TMP}.clients.done` do sed "/$client/d" $TMP.clients.todo > $TMP.clients.todo.sed mv $TMP.clients.todo.sed $TMP.clients.todo done fi echo "The following clients were not completed:\n" for client in `cat $TMP.clients.todo` do echo "\t${client}" done echo "" fi # # Cleanup tmp files # echo_tty "Removing temporary work files..." for file in `ls ${TMP}* 2>/dev/null` do test -f $file && rm $file done # # Echo exit messages # test -n "$PRINTER" && echo_tty "Printing logfile to printer ${PRINTER}..." echo_tty "Removing lock file and exiting..." echo_tty "$HOST: The $SCRIPT script exited `date`" echo_tty "See $LOG for details." echo_tty "" # # Now record results in /var/adm/messages and then email/page/print # the log and status as necessary. # SUBJECT="$HOST: $SCRIPT $MESSAGE $DATE" test -n "$ADMIN" && mailx -s "$SUBJECT" $ADMIN < $LOG test "$STATUS" -gt "55" && test -n "$PAGER" && echo "$SUBJECT" | mailx $PAGER test -n "$PRINTER" && $PRINT $LOG | lp -d $PRINTER -n $COPIES > /dev/null logger -p user.err "$SCRIPT - $MESSAGE" logger -p user.err "$SCRIPT - See $LOG for details." # # Remove lock file and exit with correct status # test -f $LOCK && rm $LOCK sleep 3 exit $STATUS } nsr_stats () { $NRSPATH/nsradmin -s $SERVER -i - << EOF show statistics print type: NSR EOF } nsr_clients () { $NRSPATH/nsradmin -s $SERVER -i - << EOF show name print type: NSR client quit EOF } # #========================= End of Functions =============================== # #====================== Start of Main Program ============================= # # # Get any command line arguments specified # if [ $# -gt 0 ] then for i in $*; do case $i in -h) show_usage; exit 0;; -l) show_license; exit 0;; -*) show_usage; exit 2;; esac done CLIENTS=$* fi # # Trap for HUP INT QUIT ABRT TERM # Execute the cleanup_exit function when trapped. # trap 'STATUS=95; cleanup_exit' 1 2 3 6 15 # # Clear the screen to easily see any messages # clear # # Redirect all output to a log file. This will overwrite any existing log # file of the same name. First we have to make sure the log directory exists. # if [ ! -d $DESTDIR ] then mkdir -m 755 -p $DESTDIR error_check fi exec > $LOG 2>&1 error_check # # Echo starting messages # logger -p user.err "$SCRIPT - script started." echo_tty "$HOST: The $SCRIPT script started `date`" # # Test to make sure there is not a lockfile # and that nsrclone is not running. # echo_tty "Checking/creating lock file..." if [ -f /var/spool/locks/${SCRIPT}.lock.* ] then STATUS=45 echo "\nA lockfile exists already. It appears that another $SCRIPT" echo "script may already be running. If not, remove the lockfile(s) and" echo "run $SCRIPT again. Be sure to cleanup any old tmp file(s)" echo "(/tmp/${SCRIPT}.*) that may have been left as well." echo "The current lockfiles are:\n" ls /var/spool/locks/${SCRIPT}.lock.* echo "" for id in `ls /var/spool/locks/${SCRIPT}.lock.*` do if [ $id != $LOCK ] then ID=`cat $id` echo "\nThe process ID referenced by the lockfile(s) is: ${ID}" fi done echo "\nProcess ID info is:\n" ps -ef | grep $SCRIPT | grep -v grep echo "" cleanup_exit elif [ "`ps -ef | grep nsrclone | grep -v grep | grep -c nsrclone`" -ne "0" ] then STATUS=55 echo "\nAn nsrclone process is already running." echo "\nProcess ID info is:\n" ps -ef | grep nsrclone | grep -v grep echo "" cleanup_exit else echo $$ > $LOCK fi # # Test to see if we are within the clone time window, exit if not. # echo_tty "Checking to see if it is too late to start clones..." if [ "$HOUR" -ge "$STOP" ] then STATUS=15 cleanup_exit fi # # Check to make sure that networker is running and that # the needed utilities are found. cleanup and exit if not. # echo_tty "Checking to see if Networker is running..." if [ "`ps -ef | grep nsrd | grep -v grep | grep -c nsrd`" -eq "0" ] then STATUS=65 cleanup_exit fi echo_tty "Checking to see if the nsr utilities exist..." if [ ! -f $NSRPATH/nsradmin ] || [ ! -f $NSRPATH/nsrclone ] || \ [ ! -f $NSRPATH/mminfo ] then STATUS=75 cleanup_exit fi # # Test to see if any saves are currently running # echo_tty "Checking to see if backups are still running..." SAVES="`nsr_stats|grep 'current saves'|awk -F, '{print $1}'|awk '{print $4}'`" ASAVES="`nsr_stats|grep 'current saves'|awk -F, '{print $2}'|awk '{print $5}'`" if [ "$SAVES" -gt "0" ] || [ "$ASAVES" -gt "0" ] then STATUS=25 cleanup_exit fi # # If clients were not specified on command line, get list of clients # if [ ! "$CLIENTS" ] then echo_tty "Getting list of clients to clone..." CLIENTS=`nsr_clients|sed '/^$/d'|sed 's/.*: //'|sed s'/[,;]//g'|sort|uniq` # # Now move any PRIORITY clients to top, and remove any EXCLUDE clients # if [ "$CLIENTS" = "" ] then echo_tty "\tWARNING: No clients to clone." else echo "$CLIENTS" > $TMP.clients.todo if [ "$EXCLUDE" != "" ] then echo_tty "The following clients are being excluded from the todo list:" for client in $EXCLUDE do echo_tty "\t${client}" sed "/$client/d" $TMP.clients.todo > $TMP.clients.todo.sed mv $TMP.clients.todo.sed $TMP.clients.todo done fi if [ "$PRIORITY" != "" ] then echo_tty "The following clients are being given priority:" cp /dev/null $TMP.clients.todo.new for client in $PRIORITY do echo_tty "\t${client}" echo $client >> $TMP.clients.todo.new sed "/$client/d" $TMP.clients.todo > $TMP.clients.todo.sed mv $TMP.clients.todo.sed $TMP.clients.todo done cat $TMP.clients.todo >> $TMP.clients.todo.new mv $TMP.clients.todo.new $TMP.clients.todo fi fi else echo_tty "Verifying list of clients to clone..." cp /dev/null $TMP.clients.todo for client in $CLIENTS do if [ `nsr_clients | grep -c $client` -eq 0 ] then echo_tty "\tWARNING: $client is not a valid client on this server." else echo $client >> $TMP.clients.todo fi done fi # # Now start cloning, 1 client at a time # Before starting each save set, check to # make sure backups are not due to start. # HEADER_FMT=`$NSRPATH/mminfo -r "${FORMAT}" | head -1` for client in `cat $TMP.clients.todo` do echo_tty "* Starting clones on ${client}..." SSIDS=`$NSRPATH/mminfo -c ${client} -r ssid -q "${QUERY}" -t "${PERIOD}" 2> /dev/null` if [ "$SSIDS" = "" ] then echo_tty "\tWARNING: No save sets to clone for ${client}." echo $client >> ${TMP}.clients.done else cp /dev/null ${TMP}.ssids.todo cp /dev/null ${TMP}.ssids.done for ssid in $SSIDS do echo $ssid >> ${TMP}.ssids.todo done for ssid in `cat ${TMP}.ssids.todo` do HOUR=`date +%H` if [ "$HOUR" -ge "$STOP" ] then STATUS=35 cleanup_exit fi SSID_INFO=`$NSRPATH/mminfo -c ${client} -q "${QUERY}" -t "$PERIOD" -r "${FORMAT}" | grep $ssid` echo_tty "\t- Cloning save set ID ${ssid}..." echo "\t$HEADER_FMT" echo "\t$SSID_INFO" $NSRPATH/nsrclone -b "$POOL" -S $ssid if [ "$?" -ne "0" ] then STATUS=85 cleanup_exit else echo_tty "\tSuccessfully cloned save set ID ${ssid}." echo $ssid >> ${TMP}.ssids.done fi done echo_tty "\t- The save sets for ${client} have all been cloned." echo $client >> ${TMP}.clients.done rm ${TMP}.ssids.todo rm ${TMP}.ssids.done fi done # # Remove the client tmp files # test -f $TMP.clients.todo && rm $TMP.clients.todo test -f $TMP.clients.todo && rm $TMP.clients.done # # Check for successful completion and log, cleanup tmp files, and exit # cleanup_exit