3 # Amanda, The Advanced Maryland Automatic Network Disk Archiver
4 # Copyright (c) 1991-1999 University of Maryland at College Park
7 # Permission to use, copy, modify, distribute, and sell this software and its
8 # documentation for any purpose is hereby granted without fee, provided that
9 # the above copyright notice appear in all copies and that both that
10 # copyright notice and this permission notice appear in supporting
11 # documentation, and that the name of U.M. not be used in advertising or
12 # publicity pertaining to distribution of the software without specific,
13 # written prior permission. U.M. makes no representations about the
14 # suitability of this software for any purpose. It is provided "as is"
15 # without express or implied warranty.
17 # U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
18 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
19 # BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
20 # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
21 # OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
22 # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
24 # Author: James da Silva, Systems Design and Analysis Group
25 # Computer Science Department
26 # University of Maryland at College Park
30 # chg-multi.sh - generic tape changer script
33 # source utility functions and values from configure
34 exec_prefix=@exec_prefix@
35 libexecdir=@libexecdir@
36 . ${libexecdir}/chg-lib.sh
40 if [ -d "@AMANDA_DBGDIR@" ]; then
41 logfile=@AMANDA_DBGDIR@/changer.debug
46 echo `_ "arguments ->"` "$@" >> $logfile
48 ourconf=`amgetconf changerfile`
50 if ! error=try_find_mt; then
56 # EXPR=/usr/local/bin/expr # in case you need a more powerful expr...
58 # read in some config parameters
60 if [ ! -f "$ourconf" ]; then
61 answer=`_ '<none> %s: %s does not exist' "$pname" "$ourconf"`
62 echo `_ 'Exit ->'` $answer >> $logfile
67 firstslot=`awk '$1 == "firstslot" {print $2}' $ourconf 2>/dev/null`
68 if [ -z "$firstslot" ]; then
69 answer=`_ '<none> %s: firstslot not specified in %s' "$pname" "$ourconf"`
70 echo `_ 'Exit ->'` $answer >> $logfile
75 lastslot=`awk '$1 == "lastslot" {print $2}' $ourconf 2>/dev/null`
76 if [ -z "$lastslot" ]; then
77 answer=`_ '<none> %s: lastslot not specified in %s' "$pname" "$ourconf"`
78 echo `_ 'Exit ->'` $answer >> $logfile
83 nslots=`$EXPR $lastslot - $firstslot + 1`
85 gravity=`awk '$1 == "gravity" {print $2}' $ourconf 2>/dev/null`
86 if [ -z "$gravity" ]; then
87 answer=`_ '<none> %s: gravity not specified in %s' "$pname" "$ourconf"`
88 echo `_ 'Exit ->'` $answer >> $logfile
93 needeject=`awk '$1 == "needeject" {print $2}' $ourconf 2>/dev/null`
94 if [ -z "$needeject" ]; then
95 answer=`_ '<none> %s: needeject not specified in %s' "$pname" "$ourconf"`
96 echo `_ 'Exit ->'` $answer >> $logfile
101 multieject=`awk '$1 == "multieject" {print $2}' $ourconf 2>/dev/null`
102 if [ -z "$multieject" ]; then
103 echo `_ 'Note: setting multieject to a default of zero'` >> $logfile
107 ejectdelay=`awk '$1 == "ejectdelay" {print $2}' $ourconf 2>/dev/null`
108 if [ -z "$ejectdelay" ]; then
109 echo `_ 'Note: setting ejectdelay to a default of zero'` >> $logfile
113 posteject=`awk '$1 == "posteject" {print $2}' $ourconf 2>/dev/null`
114 if [ -z "$posteject" ]; then
115 echo `_ 'Note: setting posteject to a default of "true"'` >> $logfile
119 ourstate=`awk '$1 == "statefile" {print $2}' $ourconf 2>/dev/null`
120 if [ -z "$ourstate" ]; then
121 answer=`_ '<none> %s: statefile not specified in %s' "$pname" "$ourconf"`
122 echo `_ 'Exit ->'` $answer >> $logfile
127 # needeject and multieject are incompatible
128 if [ $needeject -eq 1 ] && [ $multieject -eq 1 ] ; then
129 answer=`_ '<none> %s: needeject and multieject cannot be both enabled in %s' "$pname" "$ourconf"`
130 echo `_ 'Exit ->'` $answer >> $logfile
135 # read in state: only curslot and curloaded at the present time
137 curslot=`awk '$1 == "curslot" {print $2}' $ourstate 2>/dev/null`
138 if [ -z "$curslot" ]; then
142 curloaded=`awk '$1 == "curloaded" {print $2}' $ourstate 2>/dev/null`
143 if [ -z "$curloaded" ]; then
148 # process the command-line
150 # control vars to avoid code duplication: not all shells have functions!
158 if [ $# -ge 1 ]; then command=$1; else command="-usage"; fi
162 -info) # return basic information about changer
164 backwards=`$EXPR 1 - $gravity`
165 answer="$curslot $nslots $backwards"
166 echo `_ 'Exit ->'` $answer >> $logfile
171 -reset) # reset changer. Actually, we only reset changer state. We
172 # trust that the operator has reloaded a stack and reset the
173 # hardware. In most cases, we do not want to actually do
174 # anything: if the operator has done something with the
175 # hardware, we have no way to know what the actual current
176 # slot is. If the hardware state has not changed, and what is
177 # really wanted is to load the first slot, use "slot first"
184 # XXX put changer-specific reset here, if applicable
187 -eject) # eject tape if loaded. Note that if multieject is set, this
188 # only can make sense if the position is last and gravity 1
195 if [ $multieject -eq 1 ] && \
196 ([ $gravity -eq 0 ] || [ $curslot -ne $lastslot ]) ; then
197 # Can't do this: if we eject, the stacker is going to
198 # load the next tape, and our state will be botched
199 answer=`_ '%s %s: Cannot use -eject with multieject/nogravity/notlastslot' "$curslot" "$pname"`
200 echo `_ 'Exit ->'` $answer >> $logfile
204 if [ $curloaded -eq 0 ]; then
205 answer=`_ '%s %s: slot already empty' "$curslot" "$pname"`
206 echo `_ 'Exit ->'` $answer >> $logfile
212 -slot) # change to slot
221 if [ $newslot -gt $lastslot ] || \
222 [ $newslot -lt $firstslot ] ; then
223 answer=`_ '%s %s: no slot %s: legal range is %s ... %s' "$newslot" "$pname" "$newslot" "$firstslot" "$lastslot"`
224 echo `_ 'Exit ->'` $answer >> $logfile
239 newslot=`$EXPR $curslot + 1`
240 if [ $newslot -gt $lastslot ]; then
243 if [ $slotparm = advance ]; then
248 newslot=`$EXPR $curslot - 1`
249 if [ $newslot -lt $firstslot ]; then
254 answer=`_ '<none> %s: bad slot name "%s"' "$pname" "$slotparm"`
255 echo `_ 'Exit ->'` $answer >> $logfile
267 if [ $usage -eq 1 ]; then
268 answer=`_ '<none> usage: %s {-reset | -slot [<slot-number>|current|next|prev|advance] | -info | -eject}' "$pname"`
269 echo `_ 'Exit ->'` $answer >> $logfile
275 # check for legal move
277 if [ $checkgravity -eq 1 ] && [ $gravity -ne 0 ] ; then
278 if [ $newslot -lt $curslot ] || [ "$slotparm" = "prev" ] ; then
279 answer=`_ '%s %s: cannot go backwards in gravity stacker' "$newslot" "$pname"`
280 echo `_ 'Exit ->'` $answer >> $logfile
286 # Do the 'mt offline' style of stacker control if applicable
287 if [ $multieject -eq 1 ] && [ $loadslot -eq 1 ] && [ $newslot -ne $curslot ]
289 # XXX put changer-specific load command here, if applicable
291 curloaded=0 # unless something goes wrong
294 while [ $curslot -ne $newslot ]; do
295 device=`awk '$1 == "slot" && $2 == '$curslot' {print $3}' $ourconf 2>/dev/null`
296 if [ "$device" = "" ]; then
297 answer=`_ '%s %s: slot %s device not specified in %s' "$curslot" "$pname" "$curslot" "$ourconf"`
298 echo `_ 'Exit ->'` $answer >> $logfile
302 echo `_ ' -> offline'` "$device" >> $logfile
303 if ! try_eject_device $device; then
304 answer=`_ '%s %s: %s: unable to change to slot %s' "$newslot" "$pname" "$device" "$curslot"`
305 echo `_ 'Exit ->'` $answer >> $logfile
309 [ $ejectdelay -gt 0 ] && sleep $ejectdelay
310 echo `_ ' -> running'` $posteject $device >> $logfile
311 $posteject $device >> $logfile 2>&1
313 if [ $status -ne 0 ]; then
314 answer=`_ '%s %s: %s %s failed: %s' "$newslot" "$pname" "$posteject" "$device" "$status"`
315 echo `_ 'Exit ->'` $answer >> $logfile
319 curslot=`$EXPR $curslot + 1`
320 if [ $curslot -gt $lastslot ] ; then
326 if [ $ejectonly -eq 1 ] \
327 || ([ $needeject -eq 1 ] \
328 && [ $loadslot -eq 1 ] \
329 && [ $curloaded -eq 1 ] \
330 && [ $newslot -ne $curslot ])
332 # XXX put changer-specific load command here, if applicable
334 curloaded=0 # unless something goes wrong
337 # try to unload the current device
338 device=`awk '$1 == "slot" && $2 == '$curslot' {print $3}' $ourconf 2>/dev/null`
339 if [ "$device" = "" ]; then
340 answer=`_ '%s %s: slot %s device not specified in %s' "$curslot" "$pname" "$curslot" "$ourconf"`
341 echo `_ 'Exit ->'` $answer >> $logfile
345 echo `_ ' -> offline'` $device >> $logfile
346 try_eject_device $device
347 if [ $? -ne 0 ]; then
349 # XXX if the changer-specific eject command can distinguish
350 # betweeen "slot empty" and more serious errors, return 1
351 # for the first case, 2 for the second case. Generically,
352 # we just presume an error signifies an empty slot.
356 [ $ejectonly -eq 0 ] && [ $ejectdelay -gt 0 ] && sleep $ejectdelay
357 echo `_ ' -> running '` $posteject $device >> $logfile
358 $posteject $device >> $logfile 2>&1
360 if [ $status -ne 0 ]; then
361 answer=`_ '%s %s: %s %s failed: %s' "$newslot" "$pname" "$posteject" "$device" "$status"`
362 echo `_ 'Exit ->'` $answer >> $logfile
369 if [ $loadslot -eq 1 ]; then # load the tape from the slot
371 # XXX put changer-specific load command here, if applicable
373 curloaded=1 # unless something goes wrong
377 # try to rewind the device
378 device=`awk '$1 == "slot" && $2 == '$curslot' {print $3}' $ourconf 2>/dev/null`
379 if [ "$device" = "" ]; then
380 answer=`_ '%s %s: slot %s device not specified in %s' "$curslot" "$pname" "$curslot" "$ourconf"`
381 echo `_ 'Exit ->'` $answer >> $logfile
385 amdevcheck_status $device
386 if [ $? -ne 0 ]; then
388 # XXX if the changer-specific load command can distinguish
389 # betweeen "slot empty" and more serious errors, return 1
390 # for the first case, 2 for the second case. Generically,
391 # we just presume an error signifies an empty slot.
400 echo `_ '# multi-changer state cache: DO NOT EDIT!'` > $ourstate
401 echo curslot $newslot >> $ourstate
402 echo curloaded $curloaded >> $ourstate
406 if [ $slotempty -eq 1 ]; then
407 answer=`_ '%s %s: slot is empty' "$newslot" "$pname"`
408 echo `_ 'Exit ->'` $answer >> $logfile
413 if [ "$command" = -slot -a "$slotparm" = advance ]; then
417 answer="$newslot $device"
418 echo `_ 'Exit ->'` $answer >> $logfile