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