Ok, I've changed over to the new version that was suggested, and I have 
also incorporated the suggestions of several people who's name escape 
me (sorry).  This now has the 'mt offline' variable of the newest
chg-zd-mtx, and tests whether your drives provides an 'offline', or an
'ONLINE' when changing from offline to online.  It is also in
chg-zd-mtx.sh.in form, so it can be linked in with the configure step.

I would appreciate it if some people can test this, both with a large
barcode reader, and also some more standard <10 slot drives.  I want to
be sure that I didn't break a working script just to add my parts.

Thanks...

--
   Jason Hollinden

   SMG Systems Admin
#!/bin/sh 
#
# Exit Status:
# 0 Alles Ok
# 1 Illegal Request
# 2 Fatal Error
#
# Contributed by Eric DOUTRELEAU <[EMAIL PROTECTED]>
# This is supposed to work with Zubkoff/Dandelion version of mtx
#
# Modified by Joe Rhett <[EMAIL PROTECTED]>
# to work with MTX 1.2.9 by Eric Lee Green http://mtx.sourceforge.net
#
# Modified by Jason Hollinden <[EMAIL PROTECTED]> on 13-Feb-2001
# to work with MTX 1.2.10, >9 slots, and added barcode support.
# NOTE:  Only tested the 2 additions with an ADIC Scalar 100.
# All my additions have a '#### Comment' close by.

######################################################################################

# You may need to customize these things
MT=@MT@
MTF=@MT_FILE_FLAG@
MTX=@MTX@
firstslot=1
lastslot=7                      # Don't forget to leave out the cleaning tape.
cleanslot=8                     # Which slot contains your cleaning tape?

OFFLINE_BEFORE_UNLOAD=0         # Does your tape driver require a 
                                # 'mt offline' before mtx unload?

        # Do you want to clean the drive after a certain number of accesses?
        # NOTE - This is unreliable, since 'accesses' aren't 'uses', and we
        #        have no reliable way to count this. A single amcheck could 
        #        generate as many accesses as slots you have, plus 1.
        # ALSO NOTE - many modern tape loaders handle this automatically.

AUTOCLEAN=0                     # Set to '1' or greater to enable
autocleancount=99

havereader=0                    #### If you have a barcode reader, set to 1.

offlinestatus=0                 #### Set to 0 if 'mt status' gives an 
                                #### "offline" when drive is offline.
                                #### Set to 1 or greater if 'mt status' 
                                #### doesn't give and offline, rather an
                                #### "ONLINE" when drive is online.
                                
#### Check the 'readyError' section if mt acts differently for you
#### as stated below.
#### See the 'readstatus' section below if using a different drive than 0.

######################################################################################

# No user-level customized required beyond this point.

# Paths
prefix=@prefix@
exec_prefix=@exec_prefix@
sbindir=@sbindir@
libexecdir=@libexecdir@

# try to hit all the possibilities here
PATH=$sbindir:$libexecdir:/usr/bin:/bin:/usr/sbin:/sbin:/usr/ucb:/usr/local/bin
export PATH

email=`amgetconf$SUF mailto`
mailer=@MAILER@

if [ -d "@AMANDA_DBGDIR@" ]; then
        DBGFILE=@AMANDA_DBGDIR@/changer.debug
else
        DBGFILE=/dev/null
fi

USE_VERSION_SUFFIXES="@USE_VERSION_SUFFIXES@"
if test "$USE_VERSION_SUFFIXES" = "yes"; then
        SUF="-@VERSION@"
else
        SUF=
fi

myname=$0
tape=`amgetconf$SUF tapedev`
TAPE=`amgetconf$SUF changerdev`; export TAPE # for mtx command
if [ "$tape" = "/dev/null" -o "$TAPE" = "/dev/null" ]; then
        echo "Both tapedev and changerdev must be specified in config file";
        exit 2;
fi

changerfile=`amgetconf$SUF changerfile`

cleanfile=$changerfile-clean
accessfile=$changerfile-access
slotfile=$changerfile-slot
labelfile=$changerfile-barcodes
[ ! -f $cleanfile ] && echo 0 > $cleanfile
[ ! -f $accessfile ] && echo 0 > $accessfile
[ ! -f $slotfile ] && echo 0 > $slotfile
[ ! -f $labelfile ] && echo 0 > $labelfile
cleancount=`cat $cleanfile`
accesscount=`cat $accessfile`

# Routines start here

        #### If using a different drive than /dev/nst0 (or whatever your OS
        #### calls the 0'th drive) change the 'Data Transfer Element 0' (there
        #### are 6 below, and 1 in searchtape().) to 'Data Transfer Element #' 
        #### where # = /dev/nst# (or whatever for your OS).

readstatus() {
        if [ $havereader -eq 1 ]; then
                tmpslot=`$MTX status | grep "Data Transfer Element 0"`
                usedslot=`echo $tmpslot |
                        sed -n 's/Data Transfer Element 0:Empty/-1/p;s/Data Transfer 
Element 0:Full (Storage Element \([1-9][0-9]*\) Loaded)\(.*\)/\1/p'`
                barcode=`echo $tmpslot |
                        sed -n 's/Data Transfer Element 0:Empty/-1/p;s/Data Transfer 
Element 0:Full (Storage Element \(.\) Loaded):VolumeTag = \(.*\)/\2/p'`
        else
                usedslot=`$MTX status |
                        sed -n 's/Data Transfer Element 0:Empty/-1/p;s/Data Transfer 
Element 0:Full (Storage Element \(.\) Loaded)/\1/p'`
        fi

        if [ "$usedslot" -eq "-1" ]; then
                echo '-1' > $slotfile
        fi
        echo "STATUS -> currently loaded slot = $usedslot" >> $DBGFILE
}


eject() {
        readstatus 
        echo "EJECT -> ejecting tape from slot $usedslot" >> $DBGFILE
        if [ $usedslot -gt 0 ]; then
                if [ $OFFLINE_BEFORE_UNLOAD -gt 0 ]; then
                        $MT $MTF $tape offline
                fi
                $MTX unload $usedslot 2>/dev/null
                echo "0 $tape"
                exit 0
        else
                echo "0 Drive was not loaded"
                exit 1
        fi
}

reset() {
        $myname -eject >/dev/null
        echo "RESET -> loading tape from 1st slot ($firstslot)" >> $DBGFILE
        result=`$MTX load $firstslot 2>&1`
        if [ $? -eq 0 ]; then
                echo "1 $tape"
                exit 0
        else
                echo "1 $result"
                exit 1
        fi
}

loadslot() {
        readstatus

        whichslot=$1
        numeric=`echo $whichslot | tr -cd 0-9`
        echo "LOADSLOT -> load tape from slot $whichslot" >> $DBGFILE
        case $whichslot in
                current)
                        if [ $usedslot -lt 0 ]; then
                                loadslot=$firstslot
                        else 
                                echo "$usedslot $tape"
                                exit 0
                        fi
                        ;;
                next|advance)
                        if [ $usedslot -lt 0 ]; then
                                loadslot=$firstslot
                        else
                                loadslot=`expr $usedslot + 1`
                                if [ $loadslot -gt $lastslot ]; then
                                        loadslot=$firstslot
                                fi
                        fi
                        ;;
                prev)
                        loadslot=`expr $usedslot - 1`
                        if [ $loadslot -lt $firstslot ]; then
                                loadslot=$lastslot
                        fi
                        ;;
                first)
                        loadslot=$firstslot
                        ;;
                last)
                        loadslot=$lastslot
                        ;;
                $numeric)
                        if [ $whichslot -gt $lastslot ] || [ $whichslot -lt $firstslot 
]; then
                                echo "0 Slot $whichslot is out of range ($firstslot - 
$lastslot)"
                                exit 1
                        else
                                loadslot=$whichslot
                        fi
                        ;;
                clean)
                        loadslot=$cleanslot
                        ;;
                *)
                        echo "0 illegal request"
                        exit 1
                        ;;
        esac

        # Is this already the current slot?
        if [ $loadslot = $usedslot ]; then
                echo "$usedslot $tape"
                exit 0
        fi

        # Is this a cleaning request?
        if [ $loadslot = $cleanslot ]; then
                expr $cleancount + 1 > $cleanfile
                echo 0 > $accessfile
        else
                expr $accesscount + 1 > $accessfile
                if [ $AUTOCLEAN -gt 0  -a  $accesscount -gt $autocleancount ]; then
                        $myname -slot clean >/dev/null

                        # Slot $cleanslot might contain an ordinary tape rather than a 
cleaning
                        # tape. A cleaning tape *MIGHT* auto-eject; an ordinary tape 
does not.
                        # We therefore have to read the status again to check what 
actually happened.
                        readstatus
                fi
        fi

        # Unload any previous tape
        if [ $usedslot -ne "-1" ]; then
                echo "         -> unload $usedslot" >> $DBGFILE
                if [ $OFFLINE_BEFORE_UNLOAD -gt 0 ]; then
                        $MT $MTF $tape offline
                fi
                result=`$MTX unload $usedslot 2>&1`
                status=$?
                echo "         -> status $status, result '$result'" >> $DBGFILE
                if [ $status -ne 0 ]; then
                        echo "$loadslot $result"
                        exit 2
                fi
        fi

        # Load the tape, finally!
        echo "         -> loading tape from slot $loadslot" >> $DBGFILE
        result=`$MTX load $loadslot 2>&1`
        status=$?
        echo "         -> status $status, result '$result'" >> $DBGFILE

        # If there is an error, abort unless the slot is simply empty
        if [ $status -ne 0 ]; then
                empty=`echo $result | grep "is Empty"`
                if [ -z "$empty" ]; then
                        echo "$loadslot $result"
                        exit 2
                else
                        loadslot next
                fi
        else
                #### The origional test if the drive is offline.  This depends on what
                #### 'mt -f <device> status returns different between being offline and
                #### online.  Aparently some drives report an 'offline' when offline, 
and
                #### it goes away when online.
                #### ADIC doesn't report an 'offline', rather an 'ONLINE' when it's up.
                #### Don't assume the drive is ready until we get an ONLINE
                #### This is tested by the variable $offlinestatus from the beginning.

                if [ $offlinestatus -eq 0 ]; then
                        readyError="offline"
                        while [ -n "$readyError" ]; do
                                readyStatus=`$MT $MTF $tape status 2>&1`
                                readyError=`echo $readyStatus | grep "offline"`
                        done
                else
                        readyError=""
                        while [ -z "$readyError" ]; do
                                readyStatus=`$MT $MTF $tape status 2>&1`
                                readyError=`echo $readyStatus | grep "ONLINE"`
                        done
                fi

                #### Moved this outside of the above while statements.
                echo "         -> readyStatus = $readyStatus" >> $DBGFILE

                # Now rewind and check
                echo "         -> rewind $loadslot" >> $DBGFILE
                $MT $MTF $tape rewind
                echo "$loadslot" > $slotfile
                echo "$loadslot $tape"
                exit 0
        fi
}

info() {
        readstatus
        echo "INFO -> current slot $usedslot, last slot $lastslot, can go backwards 1" 
>> $DBGFILE
        #### Checks if you have a barcode reader or not.  If so, it passes the 4th 
item in the echo
        #### back to amtape signifying it can search based on barcodes.
        if [ $havereader -eq 1 ]; then
                if [ $usedslot -lt 0 ]; then
                        #### added a variable to the end of the following 2 echos.
                        #### This indicates to amtape that it can/cannot read barcodes.
                        echo "0 $lastslot 1 1"
                else
                        echo "$usedslot $lastslot 1 1"
                fi
                exit 0
        else
                if [ $usedslot -lt 0 ]; then
                        echo "0 $lastslot 1"
                else
                        echo "$usedslot $lastslot 1"
                fi
                exit 0
        fi
}

#### Adds the amlabel and the barcode to the barcode file specified above.
#### If the database is messed up, it kills amtape (rather abruptly) and
#### dumps a message into changer.debug on what to do, then sends an email
#### of the changer.debug to the above set email addr.
addlabel() {
        readstatus
        tapelabel=$1
        labelfilesize=`ls -l $labelfile | awk '{print $5}'`
        case $tapelabel in
        $tapelabel)
                echo "LABEL -> Adding Barcode $barcode and amlabel $tapelabel for Slot 
$usedslot into $labelfile" >> $DBGFILE
                if [ $labelfilesize -eq 2 ]; then
                        echo "$tapelabel $barcode" > $labelfile
                        echo "0 $usedslot $tape"
                else
                        included=`grep $tapelabel $labelfile | awk '{print $1}'`
                        if [ -z $included ]; then
                                echo "$tapelabel $barcode" >> $labelfile
                                echo "0 $usedslot $tape"
                        else
                                oldbarcode=`grep $tapelabel $labelfile | awk '{print 
$2}'`
                                if [ $oldbarcode -eq $barcode ]; then
                                        echo "      -> Barcode $barcode $oldbarcode 
already synced for $tapelabel" >> $DBGFILE
                                        echo "0 $usedslot $tape"

                                else
                                        echo "      -> WARNING!!!  Label database 
corrupted!!!" >> $DBGFILE
                                        echo "      -> $tapelabel $oldbarcode 
conflicts with new barcode $barcode" >> $DBGFILE
                                        echo "      -> Remove file $labelfile and run 
/usr/sbin/amtape <config> update" >> $DBGFILE
                                        `cat $DBGFILE | $mailer -s "Error with barcode 
reader on \`date\`" $email`
                                        `killall amtape`
                                fi
                        fi
                fi
                ;;
        esac
        exit 0
}

#### Looks for the amlabel in the barcode file.  If found, it locates the
#### slot it's in by looking for the barcode in the mtx output.  It then
#### loads that tape, and returns to amtape the device the tape is loaded in.
#### If the amlabel is not found, it kills amtape and dumps a message to
#### changer.debug on what to do, then sends an email of the changer.debug
#### to the above set email addr.
searchtape() {
        # readstatus
        tapelabel=$1
        includedtag=`grep $tapelabel $labelfile | awk '{print $1}'`
        includedbar=`grep $tapelabel $labelfile | awk '{print $2}'`
        tmpincludedslot=`$MTX status | grep $includedbar`
        #### The horrid sed statement below returns the slot number.
        #### The origional was in shell script, so I didn't want to change that,
        #### Which give the below puke for a number between 1-999.
        includedslot=`echo $tmpincludedslot | sed -n 's/\(.*\)Storage Element 
\([1-9][0-9]*\):\(.*\)/\2/p;s/Data Transfer Element 0:Full (Storage Element \(.\) 
Loaded)\(.*\)/\1/p'`
        case $tapelabel in
        $tapelabel)
                if [ $tapelabel == $includedtag ]; then
                        shift 
                        loadslot $includedslot
                        echo "$tape"
                else
                        echo "SEARCH -> WARNING!!!  $tapelabel not found in current 
ADIC-barcodes database." >> $DBGFILE
                        echo "       -> WARNING!!!  Check your typing, and/or update 
the database." >> $DBGFILE
                        `cat $DBGFILE | $mailer -s "Error with barcode reader on 
\`date\`" $email`
                        `killall amtape`
                fi
                exit 0
        esac
}


# Program invocation begins here
echo "`date` Invoked with args '$@'" >> $DBGFILE
while [ $# -ge 1 ];do
        case $1 in
                -slot)
                        shift
                        loadslot $*
                        ;;
                -info)
                        shift
                        info
                        ;;
                -reset)
                        shift
                        reset
                        ;;
                -eject)
                        shift
                        eject
                        ;;
#### Added the below flags, for barcode support
                -label) 
                        shift
                        addlabel $*
                        ;;
                -search)
                        shift
                        searchtape $*
                        ;;
                -clean)
                        shift
                        loadslot $cleanslot
                        ;;
                *)
                        echo "Unknown option $1"
                        exit 2
                        ;;
        esac
done

Reply via email to