#!/usr/bin/ksh # Written By : Kynan Dent # Written On : 06/08/04 VERSION=1.0 # Function : This is an alternative for the "amtape BACKUP_NAME show" command # as blank tapes cause the whole thing to go into a tail spin. If # it runs across an unlabelled tape it will label it as a monthly # if the -label flag has been set. # Tape library data is output to stdout in the following format: # # check the command line for arguments while getopts :dl:ns ARG do case $ARG in l) # labelling on LABEL_PREFIX=BACKUP-NAME-`date +%Y%M` LABEL_SUFFIX="a" if [ $OPTARG = "s" ];then SUSPICIOUS="ON" elif [ $OPTARG != "n" ];then USAGE="please explain" fi ;; d) if [ -z "$DEBUG" ];then DEBUG="ON" else DEBUG="REALLY ON" fi ;; \?|:) USAGE="please explain" ;; esac done if [ -n "$USAGE" ];then cat<] [-d[d]] -l label If blank tapes are encountered they are labelled. The label BACKUP-NAME-YYYYMMa is applied to the first blank tape, the letter at the end is incremented for each blank tape so the next blank tape would be BACKUP-NAME-YYYYMMb and so on. The -l option MUST be accompanied by either n for normal mode or s for suspicious mode. In normal mode any blank tapes will be labelled. In suspicious mode only tapes in slots 15 and 16 will be labelled. The default mode (without -l specified) is to report the presence of blank tapes, no labelling will happen. -d[d] debug Output detailing what is going on is sent to STDOUT. If a second d is specified then set -x is turned on as well. Example: To run `basename $0` in suspicious mode with standard debugging `basename $0` -ls -d EOF return 1 fi if [ "$DEBUG" = "REALLY ON" ];then set -x fi # first things first - make sure there are no other amanda processes running PROCS=`ps -ef | grep amanda | grep -v $$` if [ -n "$PROCS" ];then # something else might be using the tape drive, bail out cat< $STATUS STATUS_SIZE=`ls -l $STATUS_FILE | awk '{print $5}'` [ -n "$DEBUG" ] && echo "STATUS_SIZE=$STATUS_SIZE" echo "Started scanning on `date`" while [ $KEEP_LOOPING -eq 0 ] do # is there a process running? if [ -z "$SCAN_PROC" ];then # no - kick off a tape change /opt/local/amanda/sbin/amtape $BACKUP_TYPE slot $CUR_SLOT > /dev/null 2>&1 & SCAN_PROC=$! [ -n "$DEBUG" ] && echo "Kicked off amtape $BACKUP_TYPE slot $CUR_SLOT (pid=$SCAN_PROC)" else # make sure the process is still out there [ -n "$DEBUG" ] && echo "Looking for PID $SCAN_PROC..." ps -e | /usr/xpg4/bin/grep -qe "^ *$SCAN_PROC" if [ $? = 0 ];then # still there - check the slot file [ -n "$DEBUG" ] && echo "Found $SCAN_PROC, checking $STATUS_FILE" NEW_SIZE=`ls -l $STATUS_FILE | awk '{print $5}'` # there can be a size diff of 1155 bytes - this is output everytime the # robot does something without screwing up ACCEPTABLE_SIZE=$(($STATUS_SIZE+1156)) if [ $STATUS_SIZE -ne $NEW_SIZE ] && [ $NEW_SIZE -gt $ACCEPTABLE_SIZE ];then [ -n "$DEBUG" ] && echo "$STATUS_FILE was $STATUS_SIZE, now $NEW_SIZE!" [ -n "$DEBUG" ] && echo "Killing pids..." # kill the procs and try again. Have to kill the amtape process and # the /opt/local/amanda/libexec/chg-scsi process which is actually # doing the work and writing to the error file #SCSI_PID=`echo \`fuser $STATUS_FILE 2>/dev/null\`` SCSI_PID=`ps -eo pid,ppid,args | egrep "${SCAN_PROC}.*scsi" | awk '{print $1}'` for PROC_TO_KILL in $SCAN_PROC $SCSI_PID do kill $PROC_TO_KILL LOOP_COUNT=0 # wait for it to die while [ $PROC_TO_KILL -ne 0 ] do LOOP_COUNT=$(($LOOP_COUNT+1)) ps -e | /usr/xpg4/bin/grep -q $PROC_TO_KILL if [ $? = 1 ];then PROC_TO_KILL=0 else if [ $LOOP_COUNT -eq 10 ];then # hmm, doesn't want to die kill -9 $PROC_TO_KILL PROC_TO_KILL=0 else sleep 1 fi #[ $LOOP_COUNT -eq 10 ] fi #[ $? = 1 ] done #while [ $PROC_TO_KILL -ne 0 ] done #for PROC_TO_KILL in $SCAN_PROC $SCSI_PID # do a scsi reset, to be sure, to be sure - first the L20 /usr/local/bin/cdrecord dev=2,0,0 -reset > /dev/null 2>&1 sleep 5 # now the DLT7000 /usr/local/bin/cdrecord dev=2,1,0 -reset > /dev/null 2>&1 sleep 5 # clean out the err file and reset the status file size again cat /dev/null > $STATUS_FILE STATUS_SIZE=`ls -l $STATUS_FILE | awk '{print $5}'` SCAN_PROC="" # all done, the next iteration will start up amtape again [ -n "$DEBUG" ] && echo "Done...Going back to try again." else # give it a chance to do something useful sleep 10 fi #[ $STATUS_SIZE -ne $NEW_SIZE ] && [ $NEW_SIZE -ne $ACCEPTABLE_SIZE ] else # hmmm, amtape process has disappeared, hopefully it finished nicely. # try to get the label # First, check for a tape. This is what comes back if there is a tape in the drive: #Quantum DLT8000 tape drive: # sense key(0x12)= EOF residual= 0 retries= 0 # file no= 0 block no= 0 # # and this is with no tape: # #/dev/rmt/0: no tape loaded or drive offline [ -n "$DEBUG" ] && echo "Scan finished, checking tape..." SCAN_PROC="" mt -f /dev/rmt/0 status >/dev/null 2>&1 RETVAL=$? if [ $RETVAL -eq 0 ];then # get the label LABEL=`dd if=/dev/rmt/0 bs=32k 2>/dev/null | tr -d '\014' | head -1` # blank tape? if [ -z "$LABEL" ];then echo "Physical Slot=$CUR_SLOT:BLANK tape in slot" # are we meant to be labelling? if [ -n "$LABEL_PREFIX" ];then # yes, are we in suspicious mode? if [ -z "$SUSPICIOUS" ];then # no - just label the tape echo "Labeling blank tape in slot $CUR_SLOT as ${LABEL_PREFIX}${LABEL_SUFFIX}" amlabel BACKUP-NAME ${LABEL_PREFIX}${LABEL_SUFFIX} elif [ $CUR_SLOT -eq 15 ] || [ $CUR_SLOT -eq 16 ]; then # yes, we are suspicious and the tape is in the right slot so label the tape echo "Labeling blank tape in slot $CUR_SLOT as ${LABEL_PREFIX}${LABEL_SUFFIX}" amlabel BACKUP_NAME ${LABEL_PREFIX}${LABEL_SUFFIX} else echo "Blank tape in slot $CUR_SLOT has NOT been labeled, I only expect blank tapes in slot 15 and 16" fi # increment the suffix, should only ever reach 'b' but # better safe than sorry LABEL_SUFFIX=`perl -e 'print ord($ARGV[0]), "\n"' $LABEL_SUFFIX` LABEL_SUFFIX=$(($LABEL_SUFFIX+1)) LABEL_SUFFIX=`perl -e 'printf "%c\n", $ARGV[0]' $LABEL_SUFFIX` fi else # print the slot number and the tape label TYPE=`echo $LABEL | sed 's/.*\(BACKUP-NAME.*\)$/\1/'` echo "Physical Slot=$CUR_SLOT:Label=`echo $LABEL | cut -f4 -d' '` label $TYPE" fi #[ -z "$LABEL" ] else echo "Physical Slot=$CUR_SLOT:No tape in slot" fi #[ $RETVAL -eq 0 ] # now increment the slot number for the next amtape run CUR_SLOT=`cat $SLOT_FILE` if [ "$CUR_SLOT" = "$MAX_SLOTS" ];then # we're done KEEP_LOOPING=1 #echo 0>$SLOT_FILE else CUR_SLOT=$(($CUR_SLOT+1)) fi [ -n "$DEBUG" ] && echo "Slot changed to $CUR_SLOT..." fi #[ $? = 0 ] fi #[ -z "$SCAN_PROC" ] done #[ $KEEP_LOOPING -eq 0 ] echo "Scanning completed on `date`" return 0