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