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