543d96d0a1a9a94f248e8b80d1ea5d5635f1ed9c
[debian/amanda] / changer-src / chg-disk.sh.in
1 #! @SHELL@
2 #
3 # Amanda, The Advanced Maryland Automatic Network Disk Archiver
4 # Copyright (c) 1991-1999 University of Maryland at College Park
5 # All Rights Reserved.
6 #
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.
16 #
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.
23 #
24 # Author: Jean-Christian SIMONETTI, System and Network Engineer
25 #                                   Wanadoo Portails
26 #                                   Sophia Antipolis, France
27 #
28 #       This changer script is based on a directory structure like:
29 #       slot_root_dir -|
30 #                      |- info
31 #                      |- data -> slot1
32 #                      |- slot1
33 #                      |- slot2
34 #                      |- ...
35 #                      |- slotn
36 #       where 'slot_root_dir' is the tapedev 'file:xxx' parameter and 'n'
37 #       is the tapecycle parameter.
38 #       
39 #       To use this driver, just put the line 'tpchanger "chg-disk"' in your
40 #       amanda.conf.
41 #
42 #       Example of use:
43 #       --- cut here ---
44 #       tapedev  "file:/BACKUP2/slots/"
45 #       rawtapedev "file:/BACKUP2/slots/"
46 #       changerdev "/dev/null"
47 #       tpchanger "chg-disk"
48 #       changerfile "/usr/local/amanda/etc/changer"
49 #       tapetype HARD-DISK
50 #       define tapetype HARD-DISK {
51 #           length 12000 mbytes
52 #       }
53 #       --- cut here ---
54 #
55 #       The number of slot is equal to your tapecyle.
56 #       You must create the slots and data directory.
57 #
58
59
60 prefix=@prefix@
61 exec_prefix=@exec_prefix@
62 sbindir=@sbindir@
63 libexecdir=@libexecdir@
64  
65 PATH=$sbindir:$libexecdir:/usr/bin:/bin:/usr/sbin:/sbin:/usr/ucb:/usr/local/bin
66 export PATH
67
68 USE_VERSION_SUFFIXES="@USE_VERSION_SUFFIXES@"
69 if test "$USE_VERSION_SUFFIXES" = "yes"; then
70     SUF="-@VERSION@"
71 else
72     SUF=
73 fi
74
75 MYNAME=$0
76
77 TAPE=`amgetconf$SUF tapedev`
78 SLOTDIR=`echo $TAPE | sed 's/^file://'`
79
80 isinteger() {
81             # should be exactly one arg
82         [ $# = 1 ]  || return 1
83             # if arg is null, no expr needed
84         [ "${1}" = '' ] && return 1
85             # expr will return 0 on match
86         expr "$1" : '[0-9][0-9]*$' > /dev/null 2>&1
87 }
88
89 # Need rwx access to the virtual tape itself.
90 if ! test -d $SLOTDIR; then
91     echo "Virtual-tape directory $SLOTDIR does not exist." 1>&2
92     exit 2
93 fi
94 if ! test -w $SLOTDIR; then
95     echo "Virtual-tape directory $SLOTDIR is not writable." 1>&2
96     exit 2
97 fi
98
99
100 # need rwx access to directory of changer file
101 CHANGERFILE=`amgetconf$SUF changerfile`
102 CFDir=`dirname ${CHANGERFILE}`
103 [ -d ${CFDir} -a -r ${CFDir} -a -w ${CFDir} -a -x ${CFDir} ] ||
104         { echo "$MYNAME: need 'rwx' access to '$CFDir'" 1>&2 ; exit 2 ; }
105
106 # check or create changer metadata files
107 ACCESSFILE=$CHANGERFILE-access
108 [ -f $ACCESSFILE -a -r $ACCESSFILE -a -w $ACCESSFILE ] ||
109         echo 0 > $ACCESSFILE ||
110         { echo "$MYNAME: could not access or create '$ACCESSFILE'" 1>&2 ; exit 2 ; }
111 CLEANFILE=$CHANGERFILE-clean
112 [ -f $CLEANFILE -a -r $CLEANFILE -a -w $CLEANFILE ] ||
113         echo 0 > $CLEANFILE ||
114         { echo "$MYNAME: could not access or create '$CLEANFILE'" 1>&2 ; exit 2 ; }
115 SLOTFILE=$CHANGERFILE-slot
116 [ -f $SLOTFILE -a -r $SLOTFILE -a -w $SLOTFILE ] ||
117         echo 0 > $SLOTFILE ||
118         { echo "$MYNAME: could not access or create '$SLOTFILE'" 1>&2 ; exit 2 ; }
119
120 # read and check metadata
121 ACCESSCOUNT=`cat $ACCESSFILE`
122 isinteger $ACCESSCOUNT || { ACCESSCOUNT=0 ; echo 0 > $ACCESSFILE ; }
123 CLEANCOUNT=`cat $CLEANFILE`
124 isinteger $CLEANCOUNT || { CLEANCOUNT=0 ; echo 0 > $CLEANFILE ; }
125
126 FIRSTSLOT=1
127 LASTSLOT=`amgetconf$SUF tapecycle`
128 CURSLOT=0
129 CLEANSLOT=$LASTSLOT
130 NSLOT=`expr $LASTSLOT - $FIRSTSLOT + 1`
131
132 load() {
133   WHICHSLOT=$1;
134   # unload should have been called, but just in case ...
135   [ -h $SLOTDIR/data ] && unload
136   ln -s $SLOTDIR/slot$WHICHSLOT $SLOTDIR/data
137   echo $WHICHSLOT > $SLOTFILE
138 }
139
140 unload() {
141   rm -f $SLOTDIR/data
142   echo "0" > $SLOTFILE
143 }
144
145 readstatus() {
146   CURSLOT=`cat $SLOTFILE`
147 }
148
149 loadslot() {
150   WHICHSLOT=$1
151
152   TYPE=string   # default if not numeric
153   isinteger $WHICHSLOT && TYPE=digit
154
155   readstatus
156   NEWSLOT=0
157   if [ $WHICHSLOT = "current" ]; then
158     if [ $CURSLOT -le 0 ]; then
159       load $FIRSTSLOT
160       echo "$FIRSTSLOT $TAPE"
161       exit 0
162     else
163       echo "$CURSLOT $TAPE"
164       exit 0
165     fi
166   elif [ $WHICHSLOT = "next" -o $WHICHSLOT = "advance" ]; then
167     NEWSLOT=`expr $CURSLOT + 1`
168     [ $NEWSLOT -gt $LASTSLOT ] && NEWSLOT=$FIRSTSLOT
169   elif [ $WHICHSLOT = "prev" ]; then
170       NEWSLOT=`expr $CURSLOT - 1`
171       [ $NEWSLOT -lt $FIRSTSLOT ] && NEWSLOT=$LASTSLOT
172   elif [ $WHICHSLOT = "first" ]; then
173       NEWSLOT=$FIRSTSLOT
174   elif [ $WHICHSLOT = "last" ]; then
175       NEWSLOT=$LASTSLOT
176   elif [ $TYPE = "digit" ]; then
177     if [ $WHICHSLOT -ge $FIRSTSLOT -a $WHICHSLOT -le $LASTSLOT ]; then
178       NEWSLOT=$WHICHSLOT
179     else
180       echo "$WHICHSLOT illegal slot"
181       exit 1
182     fi
183   elif [ $WHICHSLOT = "clean" ]; then
184     NEWSLOT=$CLEANSLOT
185   else
186     echo "$WHICHSLOT illegal request"
187     exit 1
188   fi
189   if [ $NEWSLOT = $CURSLOT ]; then
190     echo "$CURSLOT $TAPE"
191     exit 0
192   fi
193   if [ $NEWSLOT = $CLEANSLOT ]; then
194     expr ${CLEANCOUNT:=0} + 1 > $CLEANFILE
195     echo 0 > $ACCESSFILE
196   else
197     expr ${ACCESSCOUNT:=0} + 1 > $ACCESSFILE
198     if [ $ACCESSCOUNT -gt $LASTSLOT ]; then
199       $MYNAME -slot clean >/dev/null
200     fi
201   fi
202
203   readstatus
204   if [ $CURSLOT -ne 0 ]; then
205     unload
206   fi
207
208   if [ $WHICHSLOT = "advance" ]; then
209     echo "$NEWSLOT /dev/null"
210     exit 0
211   fi
212   load $NEWSLOT
213   echo "$NEWSLOT $TAPE"
214   exit 0
215 }
216
217 info() {
218   readstatus
219   echo "$CURSLOT $NSLOT 1"
220   exit 0
221 }
222
223 reset() {
224   readstatus
225   [ $CURSLOT -gt 0 ] && unload
226   load $FIRSTSLOT
227   echo "$FIRSTSLOT $tape"
228   exit 0
229 }
230
231 eject() {
232   readstatus
233   if [ $CURSLOT -le 0 ]; then
234     echo "0 Drive was not loaded"
235     exit 1
236   else
237     unload
238     echo $CURSLOT
239     exit 0
240   fi
241 }
242
243
244 while [ $# -ge 1 ];do
245   case $1 in
246     -slot)
247            shift
248            loadslot $*
249            ;;
250     -clean)
251            shift
252            loadslot clean
253            ;;
254     -current)
255            shift
256            loadslot current
257            ;;
258     -next)
259            shift
260            loadslot next
261            ;;
262     -advance)
263            shift
264            loadslot advance
265            ;;
266     -prev)
267            shift
268            loadslot prev
269            ;;
270     -first)
271            shift
272            loadslot first
273            ;;
274     -last)
275            shift
276            loadslot last
277            ;;
278     -info)
279            shift
280            info
281            ;;
282     -reset)
283             shift
284             reset
285             ;;
286     -eject)
287             shift
288             eject
289             ;;
290     *)
291        echo "Unknown option $1"
292        exit 2
293        ;;
294   esac
295 done
296