abb0a1a1f761667cf22d247f34eae724fdbf67e7
[debian/amanda] / changer-src / chg-juke.sh.in
1 #!/bin/sh
2
3 # chg-juke
4 #
5 # This assumes we have possibly rait-striped drives in several
6 # jukeboxes, controlled by the Fermilab "juke" package
7 #
8 # So we could have 3 drives in 3 jukeboxes:
9 #   changerscript="chg-juke"
10 #   changerfile=/some/file
11 #   tapedev="rait:/dev/nst{1,2,3}"
12 #   changerdev="myjuke{0,1,2}"
13 # Or, if the jukebox has multiple drives:
14 #   changerscript="chg-juke"
15 #   changerfile=/some/file
16 #   tapedev="rait:/dev/nst{1,2,3}"
17 #   changerdev="myjuke"
18 # We need therefore to generate lists with csh to expand the tapedev 
19 # and changerdev, and deal with the possibility that there are several 
20 # jukeboxes and several drives in each jukebox involved.
21
22 #
23 # debugging...
24 #
25 if [ -d "@AMANDA_DBGDIR@" ]; then
26         DBGFILE=@AMANDA_DBGDIR@/changer.debug
27 else
28         DBGFILE=/dev/null
29 fi
30 exec 2>$DBGFILE
31 echo "args: $0 $*" >&2
32 set -x 
33
34 #
35 # the usual config fun
36 #
37 prefix=@prefix@
38 exec_prefix=@exec_prefix@
39 sbindir=@sbindir@
40 libexecdir=@libexecdir@
41 MT=ammt
42
43 USE_VERSION_SUFFIXES="@USE_VERSION_SUFFIXES@"
44 if test "$USE_VERSION_SUFFIXES" = "yes"; then
45         SUF="-@VERSION@";
46 else
47         SUF=
48 fi
49 getconf=$sbindir/amgetconf$SUF
50
51 #
52 # make sure we can find JUKE later
53 #
54 JUKE_DIR=/usr/local
55 # Fermilab specific
56 if [ -f /usr/local/etc/setups.sh ]
57 then
58     . /usr/local/etc/setups.sh
59     setup juke
60 fi
61
62 PATH=$sbindir:$libexecdir:$JUKE_DIR/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/ucb
63 export PATH JUKE_DIR
64
65 build_drivelists() {
66     #
67     # figure out which drives are in which jukebox
68     #
69     count=0
70     for juke in $jlist
71     do
72         for d in $dlist
73         do
74             if juke list -j $juke drive $d | grep 'drive [0-9]' >&2
75             then
76                 eval "drives_in_$juke=\"\$drives_in_$juke $d\""
77             fi
78         done
79     done
80 }
81
82 unload_drive_n_clean() {
83
84     #
85     # $1 is whether to clean it
86     #
87     cleanit=$1
88
89     #
90     # if the drive is ONLINE, mt unload it
91     #
92     if $MT -t $tapedev status | egrep "$ONLINEREGEX" >&2
93     then
94         $MT -t $tapedev offline >&2 || true
95     fi
96
97     #
98     # unload any tapes present, maybe load/unload a cleaning cartridge
99     #
100     for juke in $jlist
101     do
102         eval "jdlist=\"\$drives_in_$juke\""
103         for drive in $jdlist
104         do
105             juke unload -j $juke drive $drive >&2 || true
106             if juke list -j $juke drive $drive | grep '(empty)' >&2
107             then
108                 :
109             else
110                 echo "$slot $tapedev unable to empty preceding tape from drive $drive"
111                 exit 1
112             fi
113
114             if $cleanit
115             then
116                 juke load -j $juke drive $drive clean
117                 sleep 120
118                 juke unload -j $juke drive $drive
119             fi
120         done
121     done
122 }
123
124 load_drives() {
125     #
126     # load slots.  If it's a stripe, load several...
127     #
128     for juke in $jlist
129     do
130         eval "jdlist=\"\$drives_in_$juke\""
131         jndrives=`echo $jdlist | wc -w`
132         count=0
133         for drive in $jdlist
134         do
135             rslot=`expr $newslot '*' $jndrives + $count`
136             juke load -j $changerdev drive $drive slot $rslot >&2
137             if juke list -j $changerdev drive $drive | grep '(empty)' >&2
138             then
139                 echo "$slot $tapedev unable to load tape into drive"
140                 exit 1
141             fi
142             count=`expr $count + 1`
143         done
144     done
145
146     #
147     # wait for drive(s) to come online
148     #
149     count=0
150     until  $MT -t $tapedev status | egrep "$ONLINEREGEX" >&2
151     do
152         count=`expr $count + 1`
153         if [ $count -gt 24 ] 
154         then
155             echo "$slot $tapedev never came online"
156             exit 1
157         fi
158         sleep 5
159     done
160 }
161
162
163 ONLINEREGEX="ONLINE|READY|sense[_ ]key[(]0x0[)]|sense key error = 0|^er=0$"
164
165 #
166 # get config variables
167 #
168 changerfile=`$getconf changerfile`
169     tapedev=`$getconf tapedev`
170  changerdev=`$getconf changerdev`
171       dlist=`csh -c "echo $tapedev" | sed -e 's/rait://g' -e 's/tape://g'`
172     ndrives=`echo $dlist | wc -w`
173       jlist=`csh -c "echo $changerdev"`
174      njukes=`echo $jlist | wc -w`
175  totalslots=`for juke in $jlist ; do juke list -j $juke; done | 
176                 grep -v '^clean' | 
177                 grep 'slot [0-9]' | 
178                 wc -l`
179
180 if [ $ndrives -gt 1 ]
181 then
182    #
183    # if it's a 3 tape stripe and we have 30 actual slots
184    # we only have 10 virtual slots...
185    #
186    totalslots=`expr $totalslots / $ndrives`
187 fi
188
189 build_drivelists
190
191 #
192 # get current slot if we have one
193 #
194 if [ -f "$changerfile" ] 
195 then
196     slot="`cat $changerfile`"
197 else
198     slot=0
199     echo $slot > $changerfile
200 fi
201
202 #
203 # We treat -reset just like -slot 0
204 #
205 if [ x$1 = 'x-reset' ]
206 then
207     set : -slot 0
208     shift
209 fi
210
211 case x$1 in
212
213 x-slot) 
214
215     #
216     # handle special slots...
217     #
218     case "$2" in
219     current)    newslot=$slot           ; load=true;;
220     next)       newslot=`expr $slot + 1`; load=true;;
221     advance)    newslot=`expr $slot + 1`; load=false;;
222     prev)       newslot=`expr $slot - 1`; load=true;;
223     first)      newslot=0               ; load=true;;
224     last)       newslot=-1              ; load=true;;
225     *)          newslot=$2              ; load=true;;
226     esac
227
228     if [ $newslot = "clean" ]
229     then
230         unload_drive_n_clean true
231     else 
232         if [ 0 -gt $newslot ]
233         then
234             newslot=`expr $totalslots - 1`
235         fi
236
237         if [ $totalslots -le  $newslot ]
238         then
239             newslot=0
240         fi
241
242         echo $newslot > $changerfile
243         slot=$newslot
244
245         if $load
246         then
247             unload_drive_n_clean false
248             load_drives
249         fi
250     fi
251
252     echo $slot $tapedev
253     ;;
254
255 x-info)
256     echo $slot $totalslots 1
257     exit 0
258     ;;
259
260 x-eject)
261     unload_drive_n_clean false
262     echo $slot $tapedev
263     ;;
264 esac
265
266 exit $rc