> 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