> Message: 16
>    Date: Sun, 24 Mar 2002 02:22:47 -0500
>    From: Derrick Miller <[EMAIL PROTECTED]>
> Subject: ADIC / Dell Powervault 120T changer problems under 
> Linux (Pt 2)
> 
> 1)  Does anyone have this changer working with Amanda?  I 
> would give just 
> about anything to get my hands on copies of working config 
> and chg-zd-mtx 
> files.

I am using a different changer script supplied by Chris Pascoe and once
upon a time posted to this list (in a slightly earlier version). I have
attached my current copy (I hope you don't mind, Chris). Beware of line
endings - I read email on a windows box, even though most of our servers
are unix/linux.

With this tape drive running alone on the SCSI bus from an adaptec 2944,
amverify gets occasional "Unexpected busfree in Data-in phase". It would
be interesting to know if anyone else with this hardware combination
gets this error when running amverify or not. If you have not bothered
with amverify, I would urge you to try it, lest your tapes are
unreadable when you need them most.
#!/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 Chris Pascoe <[EMAIL PROTECTED]> to work with a 
# Dell PowerVault 120T, MTX 1.2.10 and add some intelligence to
# exit when all slots are empty.  (Jan 2001).  Fixed introduced 
# bugs when going backwards and potential problem with changers having
# more than 9 slots (July 2001).
#

# You may need to customize these things
MT=/bin/mt
MTF=-f
MTX=/sbin/mtx
DD=/bin/dd
cleanslot=-1
accessbeforeclean=119
ONLINEREGEX="ONLINE|READY|sense[_ ]key[(]0x0[)]|sense key error = 0|^er=0$"
# No user-level customized required beyond this point.

# try to hit all the possibilities here
prefix=/usr/local/amanda/2.4.2p1
exec_prefix=${prefix}
sbindir=${exec_prefix}/sbin
libexecdir=${exec_prefix}/libexec
 
PATH=$sbindir:$libexecdir:/usr/bin:/bin:/usr/sbin:/sbin:/opt/local/bin
export PATH

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

if [ ! -f "amanda.conf" ]; then
        echo "No amanda config in current directory"
        exit 2;
fi

USE_VERSION_SUFFIXES="no"
if test "$USE_VERSION_SUFFIXES" = "yes"; then
        SUF="-2.4.2p1"
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`
if [ -z "$changerfile" ];
then
        echo "changerfile not specified in amanda config?"
        exit 2
fi

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

# Routines start here
readstatus() {
        usedslot=`$MTX status |
                sed -n 's/Data Transfer Element 0:Empty/-1/p;s/Data Transfer Element 
0:Full (Storage Element \([0-9]\+\) Loaded)/\1/p'`

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

getslots() {
        slotlist=`$MTX status | 
                sed -n 's/Storage Element \([0-9]\+\):\(Empty\|Full\)/\1/p'`
        fullslots=`$MTX status | 
                sed -n 's/Storage Element \([0-9]\+\):Full/\1/p;s/Data Transfer 
Element 0:Full (Storage Element \([0-9]\+\) Loaded)/\1/p'`
        dataslots=`$MTX status | 
                sed -n 's/Storage Element \([0-9]\+\):Full/\1/p;s/Data Transfer 
Element 0:Full (Storage Element \([0-9]\+\) Loaded)/\1/p' | 
                fgrep -v "^${cleanslot}$" | sort -n`
        numdataslots=`echo $dataslots | wc -w | awk '{print $1}'`
        if [ -z "$dataslots" ]; then
                dataslots="-1"
        fi
        firstslot=`echo $slotlist | awk '{print $1}'`
        lastslot=`echo $slotlist | awk '{print $NF}'`
        firstdataslot=`echo $dataslots | awk '{print $1}'`
        lastdataslot=`echo $dataslots | awk '{print $NF}'`
        nextdataslot=`echo $dataslots | awk -v CURR=$usedslot 'BEGIN { P=0 }; { for 
(i=1; i <= NF; i++) { if ($i > CURR && P == 0) { P=1; print $i } }; if (P == 0) { P=1; 
print $1 } }'`
        prevdataslot=`echo $dataslots | awk -v CURR=$usedslot 'BEGIN { P=0 }; { for 
(i=NF; i >= 1; i--) { if ($i < CURR && P == 0) { P=1; print $i } }; if (P == 0) { P=1; 
print $NF } }'`
        echo "GETSLOTS -> data slot list = `echo $dataslots`" >> $DBGFILE
        echo "         -> first data slot = $firstdataslot" >> $DBGFILE
        echo "         -> last data slot = $lastdataslot" >> $DBGFILE
        echo "         -> next data slot = $nextdataslot" >> $DBGFILE
        echo "         -> prev data slot = $prevdataslot" >> $DBGFILE
}

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

reset() {
        readstatus
        if [ $usedslot -gt 0 ]; then
                echo "RESET -> ejecting tape from slot $usedslot" >> $DBGFILE
                echo "         -> rewoffl" >> $DBGFILE
                $MT $MTF $tape rewoffl >> $DBGFILE 2>&1
                echo "         -> unload $usedslot" >> $DBGFILE
                $MTX unload $usedslot >> $DBGFILE 2>&1
        fi

        echo "RESET -> loading tape from slot 1" >> $DBGFILE
        result=`$MTX load 1 2>&1`
        if [ $? -eq 0 ]; then
                echo "1 $tape"
                exit 0
        else
                echo "1 $result"
                exit 1
        fi
}

loadslot() {
        whichslot=$1
        echo "LOADSLOT -> load tape from slot $whichslot" >> $DBGFILE
        readstatus
        getslots

        case $whichslot in
                current)
                        if [ $usedslot -lt 0 ]; then
                                loadslot=$firstdataslot
                        else 
                                loadslot=$usedslot
                        fi
                        ;;
                next|advance)
                        loadslot=$nextdataslot
                        ;;
                prev)
                        loadslot=$prevdataslot
                        ;;
                first)
                        loadslot=$firstdataslot
                        ;;
                last)
                        loadslot=$lastdataslot
                        ;;
                clean)
                        loadslot=$cleanslot
                        if [ $cleanslot -lt $firstslot -o $cleanslot -gt $lastslot ]; 
then
                                echo "$tape no cleaning tape configured"
                                exit 2
                        fi
                        ;;
                [0-9]|[0-9][0-9]|[0-9][0-9][0-9])
                        if [ $whichslot -ge $firstslot -a $whichslot -le $lastslot ]; 
then
                                loadslot=$whichslot
                        fi
                        ;;
                *)
                        echo "0 illegal request"
                        exit 1
                        ;;
        esac

        # Is this already the current slot?
        if [ $loadslot = $usedslot -a $loadslot -ge 0 ]; then
                if [ $whichslot != "current" ]; then
                        echo "         -> already the current slot: $usedslot $tape" 
>> $DBGFILE
                fi
                echo "$usedslot $tape"
                exit 0
        fi

        # If the tape to load is not valid (because the changer was empty), then abort 
straight away
        if [ $loadslot = "-1" ]; then
                echo "         -> changer is empty" >> $DBGFILE
                echo "ANY changer is empty"
                exit 2
        fi

        # Is there a tape in the requested slot?
        tapepresent=`echo "$fullslots" | egrep '(^| )'"$loadslot"'( |$)'`
        if [ -z "$tapepresent" ]; then
                echo "         -> requested slot $loadslot is empty" >> $DBGFILE
                echo "$loadslot slot is empty"
                exit 2
        fi

        # Is this a cleaning request?
        if [ $loadslot = $cleanslot ]; then
                ### XXX This should only be done if there REALLY was a cleaning tape 
in the slot to start with XXX ###
                cleanpresent=`echo $fullslots | egrep '(^| )'"$cleanslot"'( |$)'`
                if [ -n "$cleanpresent" ]; then
                        expr $cleancount + 1 > $cleanfile
                        echo 0 > $accessfile
                fi
        else
                expr $accesscount + 1 > $accessfile
                ### XXX This should only be done if there REALLY was a cleaning tape 
in the slot to start with XXX ###
                cleanpresent=`echo $fullslots | egrep '(^| )'"$cleanslot"'( |$)'`
                if [ $accesscount -gt $accessbeforeclean -a -n "$cleanpresent" ]; then
                        $myname -slot clean >> $DBGFILE

                        # 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 "         -> rewoffl" >> $DBGFILE
                $MT $MTF $tape rewoffl >> $DBGFILE 2>&1
                echo "         -> unload $usedslot" >> $DBGFILE
                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 with the error
        if [ $status -ne 0 ]; then
                echo "$loadslot $result"
                exit 2
        else
                # 
                # Wait for the tape drive to become ready
                #
                tries=60
                readyOnline=""
                echo "         -> waiting for drive to come online" >> $DBGFILE
                sleep 32        # takes at least this long
                while [ -z "$readyOnline" -a $tries -gt 0 ]; do
                        readyStatus=`$MT $MTF $tape status 2>&1`
                        echo "         -> readyStatus = $readyStatus" >> $DBGFILE
                        readyOnline=`echo $readyStatus | egrep "$ONLINEREGEX"`
#                       echo "         -> readyOnline = $readyOnline" >> $DBGFILE
                        if [ -z "$readyOnline" ]; then
                                sleep 2;
                                let 'tries=tries-1'
                                if [ $tries -gt 0 ]; then
                                        echo "         -> retrying, tries left: 
$tries" >> $DBGFILE
                                fi
                        fi
                done
                if [ $tries -eq 0 ]; then
                        echo "         -> out of tries - aborting" >> $DBGFILE
                        echo "$loadslot changer-script: timed out waiting for tape to 
go online"
                        exit 2
                fi

                # Now rewind and check
                echo "         -> rewind $loadslot" >> $DBGFILE
                $MT $MTF $tape rewind
                # Read the label
                if [ "$DBGFILE" != "/dev/null" ]; then
                        tapeLabel=`$DD if=$tape count=1 bs=32768 2> /dev/null | head 
-1`
                        echo "         -> label $tapeLabel" >> $DBGFILE
                        $MT $MTF $tape rewind
                fi
                echo "$loadslot" > $slotfile
                echo "$loadslot $tape"
                exit 0
        fi
}

info() {
        readstatus
        getslots
        echo "INFO -> current slot $usedslot, last slot $numdataslots, can go 
backwards 1" >> $DBGFILE
        if [ $usedslot -lt 0 ]; then
                echo "0 $numdataslots 1"
        else
                echo "$usedslot $numdataslots 1"
        fi
        exit 0
}

# Program invocation begins here
echo -e "\n`date` Invoked with args '$@'" >> $DBGFILE
while [ $# -ge 1 ];do
        case $1 in
                -slot)
                        shift
                        loadslot $*
                        ;;
                -info)
                        shift
                        info
                        ;;
                -clean)
                        shift
                        loadslot clean
                        ;;
                -reset)
                        shift
                        reset
                        ;;
                -eject)
                        shift
                        eject
                        ;;
                *)
                        echo "Unknown option $1"
                        exit 2
                        ;;
        esac
done


Reply via email to