2 ###############################################################################
3 # AMANDA Tape Changer script for use with the MTX tape changer program
4 # Version 1.0 - Tue Feb 20 13:59:39 CST 2001
6 # Based on 'stc-changer' by Eric Berggren (eric@ee.pdx.edu)
7 # Updated by Tim Skirvin (tskirvin@ks.uiuc.edu)
9 # Given that there's no license...let's make this the Perl Artistic License.
10 # Just make sure you give me and Eric credit if you modify this.
11 ###############################################################################
13 ### USER CONFIGURATION
14 # Name of the tape drive (takes place of "tapedev" option in amanda.conf)
15 # and default driver number in library (usu 0) that DRIVE_NAME points to
16 DRIVE_NAME="/dev/rmt/0n"
19 # Location of "STC" command and control device
20 MTX_CMD="/usr/local/sbin/mtx";
21 MTX_CONTROL="/dev/scsi/changer/c4t1d0";
23 # Whether tape drive must eject tape before changer retrieves
24 # (ie, EXB-2x0). Usually okay if set while not necessary, bad if
25 # required but not set.
28 # How long to check drive readiness (in seconds) after mounting (or
29 # ejecting) a volume (on some libraries, the motion or eject command may
30 # complete before the drive has the volume fully mounted and online,
31 # or ready for retrieval, resulting in "Drive not ready"/"Media not
32 # ready" errors). Do an "mt status" command every 5 seconds upto this
34 DRIVE_READY_TIME_MAX=120
36 # tape "mt" command location...
37 MT_CMD="/usr/bin/mt" # called via "MT_CMD -f DRIVE_NAME rewind" &
38 # "MT_CMD -f DRIVE_NAME offline" to eject
39 # and "MT_CMD -f DRIVE_NAME status" to get ready info
41 ##############################################################################
54 echo "Usage: $Progname <command> [arg...]"
55 echo " -info reports capability and loaded tape"
56 echo " -slot <slot> loads specified tape into drive"
57 echo " current reports current mounted tape"
58 echo " next loads logically next tape (loops to top)"
59 echo " prev loads logically previous tape (loops to bot)"
60 echo " first loads first tape"
61 echo " last loads last tape"
62 echo " 0..99 loads tape from specified slot#"
63 echo " -eject uloads current mounted tape"
64 echo " -reset resets changer (and drive); loads first tape"
70 # Perform "stc" changer command (& handle the "fatal" errors)
71 # else, set 'CommandResStr' and 'CommandRawResStr' to the result string
72 # and 'CommandResCode' to the exit code
79 CommandResStr=`$MTX_CMD $MTX_CONTROL $cmd $arg 2>&1`
80 CommandRawResStr=$CommandResStr
83 CommandResStr=`echo $CommandResStr | head -1 | sed 's/^[^:]*: //'`
84 if [ $CommandResCode -gt 1 ]; then
85 echo "0 $Progname: returned $CommandResStr"
91 # Unload tape from drive (a drive command; "ejecttape" is a changer command
92 # to actually retrieve the tape). Needed by some changers (controlled by
93 # setting "DRIVE_MUST_EJECT")
97 # Tell drive to eject tape before changer retrieves; req'd by some
98 # drives (ie, EXB-2x0). Not needed by QDLT-4x00. Do a "rewind"
99 # command first, then "offline" to eject (instead of "rewoffl")
101 if [ "$DRIVE_MUST_EJECT" -ne 0 ]; then
102 mtresstr=`$MT_CMD -f $DRIVE_NAME rewind 2>&1`
105 if [ $mtrescode -ne 0 ]; then
106 if echo "$mtresstr" | egrep -s 'no tape'; then
107 :; # no tape mounted; assume okay...
109 # can't eject tape, bad; output: <tape#> reason
114 mtresstr=`$MT_CMD -f $DRIVE_NAME offline 2>&1`
123 # Check drive readiness after (un)mounting a volume (which may take a while
124 # after the volume change command completes)
130 if [ "$DRIVE_READY_TIME_MAX" -gt 0 ]; then
132 # sleep time between checks
135 # number of interations to check
136 numchecks=`expr $DRIVE_READY_TIME_MAX / $pausetime`
137 if [ "$numchecks" -eq 0 ]; then
141 # check until success, or out of attempts...
142 while [ "$numchecks" -gt 0 ]; do
143 mtresstr=`$MT_CMD -f $DRIVE_NAME status 2>&1`
146 if [ $mtrescode -eq 0 ]; then
150 # pause, before trying again....
151 if [ "$numchecks" -gt 1 ]; then
154 # if unmounting a volume, check for 'mt' command
155 # failure; (sleep first for additional comfort)
156 if [ "$unmounting" -ne 0 ]; then
161 numchecks=`expr $numchecks - 1`
164 # failed; output: -1 reason
165 echo "-1 drive won't report ready"
171 # Get changer parameters
176 if [ $CommandResCode -eq 0 ] && \
177 echo "$CommandResStr" | egrep -s '^Storage Changer'; then
179 NumDrives=`echo $dspec | wc -l`
180 NumDrives=`echo "$CommandRawResStr" | \
181 grep 'Data Transfer Element' | wc -l`
182 if [ "$NumDrives" -le "$DRIVE_NUM" ]; then
183 echo "$Program: Invalid drive # specified ($DRIVE_NUM > $NumDrives)"
186 # grep 'Data Transfer Element $DRIVE_NUM' | \
187 LoadedTape=`echo "$CommandRawResStr" | \
188 grep 'Data Transfer Element' | \
189 grep 'Storage Element [0-9]' | \
191 if [ -z "$LoadedTape" -o "$LoadedTape" = "e" ]; then
194 NumSlots=`echo "$CommandRawResStr" | \
195 grep 'Storage Element [0-9]\{1,\}:' | \
196 grep -v 'Data Element' | \
197 wc -l | sed -e 's/ //g' `
198 LastSlot=`expr $NumSlots - 1`
201 "$Progname: Can't get changer parameters; Result was $CommandResStr"
207 # Display changer info
213 # output status string: currenttape numslots randomaccess?
214 echo "$LoadedTape $NumSlots 1"
219 # Eject current mounted tape
226 # If no tape reported mounted, assume success (could be bad if changer
227 # lost track of tape)
229 if [ $ct -lt 0 ]; then
236 if [ $CommandResCode -ne 0 ]; then
237 # failed; output: <tape#> reason
238 echo "$ct $CommandResStr"
241 # success; output: <tape#> drive
242 echo "$ct $DRIVE_NAME"
248 # Move specified tape into drive (operation level)
253 if [ "$slot" -eq "$LoadedTape" ]; then
258 return $CommandResCode
262 # Load next available tape into drive
271 if doloadtape $curslot; then
274 if echo $CommandResStr | egrep -s 'Slot.*reported empty'; then
276 if [ "$direction" -lt 0 ]; then
277 curslot=`expr $curslot - 1`
278 if [ "$curslot" -lt 0 ]; then
282 curslot=`expr $curslot + 1`
283 if [ "$curslot" -gt "$LastSlot" ]; then
288 # Check if we're back to where we started...
289 if [ "$curslot" = "$startslot" ]; then
290 if [ "$direction" -lt 0 ]; then
291 CommandResStr="No previous volume available"
293 CommandResStr="No subsequent volume available"
305 # Report loadtape() status
309 if [ $CommandResCode -eq 0 ]; then
310 # success; output currenttape drivename
311 echo "$LoadedTape $DRIVE_NAME"
314 # failed (empty slot?); output currenttape reason
315 echo "$LoadedTape $CommandResStr"
322 # Move specified tape into drive (command level)
332 if [ $LoadedTape -lt 0 ]; then
333 CommandResStr="Can't determine current tape; drive empty ?"
338 if [ $LoadedTape -le 0 ]; then
339 loadnexttape $LastSlot -1
341 loadnexttape `expr $LoadedTape - 1` -1
345 if [ $LoadedTape -ge $LastSlot -o $LoadedTape -lt 0 ]; then
348 loadnexttape `expr $LoadedTape + 1` 1
355 loadnexttape $LastSlot -1
361 # error; no valid slot specified
362 echo "$Progname: No valid slot specified"
367 if [ $CommandResCode -eq 0 ]; then
375 # Reset changer to known state
381 if [ $CommandResCode -ne 0 ]; then
382 # failed; output: failed? reason
383 echo "-1 $CommandResStr"
390 #############################################################################
394 Progname=`basename $0`
396 if [ ! -x "$MTX_CMD" ]; then
397 echo "-1 $Progname: cannot run STC command ($MTX_CMD)"
400 if [ -n "$MTX_CONTROL" ]; then
401 if echo "$MTX_CONTROL" | egrep -s '^-f'; then
404 MTX_CONTROL="-f $MTX_CONTROL"
407 if [ -n "$DRIVE_NUM" ]; then
411 if [ $# -ge 1 ]; then command=$1; else command="-usage"; fi