Imported Upstream version 2.6.0p2
[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 USE_VERSION_SUFFIXES="@USE_VERSION_SUFFIXES@"
77 if test "$USE_VERSION_SUFFIXES" = "yes"; then
78     SUF="-@VERSION@"
79 else
80     SUF=
81 fi
82
83 MYNAME=$0
84
85 TAPE=`amgetconf$SUF tapedev`
86 if test X"$TAPE" = X""; then
87     echo `_ '<none> tapedev not specified in amanda.conf.'`
88     exit 2
89 fi
90 SLOTDIR=`echo $TAPE | sed 's/^file://'`
91
92 isinteger() {
93             # should be exactly one arg
94         [ $# = 1 ]  || return 1
95             # if arg is null, no expr needed
96         [ "${1}" = '' ] && return 1
97             # expr will return 0 on match
98         expr "$1" : '[0-9][0-9]*$' > /dev/null 2>&1
99 }
100
101 # Need rwx access to the virtual tape itself.
102 if ! test -d $SLOTDIR; then
103     echo `_ '<none> Virtual-tape directory %s does not exist.' "$SLOTDIR"`
104     exit 2
105 fi
106 if ! test -w $SLOTDIR; then
107     echo `_ '<none> Virtual-tape directory %s is not writable.' "$SLOTDIR"`
108     exit 2
109 fi
110
111
112 # need rwx access to directory of changer file
113 CHANGERFILE=`amgetconf$SUF changerfile`
114 conf_match=`expr "$CHANGERFILE" : .\*\.conf\$`
115 if [ $conf_match -ge 6 ]; then
116         CONFIGFILE=$CHANGERFILE
117         CHANGERFILE=`echo $CHANGERFILE | sed 's/.conf$//g'`
118 else
119         CONFIGFILE=$CHANGERFILE.conf
120 fi
121
122 CFDir=`dirname ${CHANGERFILE}`
123 [ -d ${CFDir} -a -r ${CFDir} -a -w ${CFDir} -a -x ${CFDir} ] ||
124         { echo `_ "<none> %s: need 'rwx' access to '%s'" "$MYNAME" "$CFDir"` ; exit 2 ; }
125
126 # check or create changer metadata files
127 ACCESSFILE=$CHANGERFILE-access
128 [ -f $ACCESSFILE -a -r $ACCESSFILE -a -w $ACCESSFILE ] ||
129         echo 0 > $ACCESSFILE ||
130         { echo `_ "<none> %s: could not access or create '%s'" "$MYNAME" "$ACCESSFILE"` ; exit 2; }
131 CLEANFILE=$CHANGERFILE-clean
132 [ -f $CLEANFILE -a -r $CLEANFILE -a -w $CLEANFILE ] ||
133         echo 0 > $CLEANFILE ||
134         { echo `_ "<none> %s: could not access or create '%s'" "$MYNAME" "$CLEANFILE"` ; exit 2 ; }
135 SLOTFILE=$CHANGERFILE-slot
136 [ -f $SLOTFILE -a -r $SLOTFILE -a -w $SLOTFILE ] ||
137         echo 0 > $SLOTFILE ||
138         { echo `_ "<none> %s: could not access or create '%s'" "$MYNAME" "$SLOTFILE"` ; exit 2; }
139
140 # read and check metadata
141 ACCESSCOUNT=`cat $ACCESSFILE`
142 isinteger $ACCESSCOUNT || { ACCESSCOUNT=0 ; echo 0 > $ACCESSFILE ; }
143 CLEANCOUNT=`cat $CLEANFILE`
144 isinteger $CLEANCOUNT || { CLEANCOUNT=0 ; echo 0 > $CLEANFILE ; }
145
146 FIRSTSLOT=1
147 LASTSLOT=`amgetconf$SUF tapecycle`
148 if test -r $CONFIGFILE; then
149     . $CONFIGFILE
150 fi
151 CURSLOT=0
152 CLEANSLOT=$LASTSLOT
153 NSLOT=`expr $LASTSLOT - $FIRSTSLOT + 1`
154
155 load() {
156   WHICHSLOT=$1;
157   # unload should have been called, but just in case ...
158   [ -h $SLOTDIR/data ] && unload
159   ln -s $SLOTDIR/slot$WHICHSLOT $SLOTDIR/data
160   echo $WHICHSLOT > $SLOTFILE
161 }
162
163 unload() {
164   rm -f $SLOTDIR/data
165   echo "0" > $SLOTFILE
166 }
167
168 readstatus() {
169   CURSLOT=`cat $SLOTFILE`
170 }
171
172 loadslot() {
173   WHICHSLOT=$1
174
175   TYPE=string   # default if not numeric
176   isinteger $WHICHSLOT && TYPE=digit
177
178   readstatus
179   NEWSLOT=0
180   if [ $WHICHSLOT = "current" ]; then
181     if [ $CURSLOT -le 0 ]; then
182       load $FIRSTSLOT
183       echo "$FIRSTSLOT $TAPE"
184       exit 0
185     else
186       echo "$CURSLOT $TAPE"
187       exit 0
188     fi
189   elif [ $WHICHSLOT = "next" -o $WHICHSLOT = "advance" ]; then
190     NEWSLOT=`expr $CURSLOT + 1`
191     [ $NEWSLOT -gt $LASTSLOT ] && NEWSLOT=$FIRSTSLOT
192   elif [ $WHICHSLOT = "prev" ]; then
193       NEWSLOT=`expr $CURSLOT - 1`
194       [ $NEWSLOT -lt $FIRSTSLOT ] && NEWSLOT=$LASTSLOT
195   elif [ $WHICHSLOT = "first" ]; then
196       NEWSLOT=$FIRSTSLOT
197   elif [ $WHICHSLOT = "last" ]; then
198       NEWSLOT=$LASTSLOT
199   elif [ $TYPE = "digit" ]; then
200     if [ $WHICHSLOT -ge $FIRSTSLOT -a $WHICHSLOT -le $LASTSLOT ]; then
201       NEWSLOT=$WHICHSLOT
202     else
203       echo `_ '%s illegal slot' "$WHICHSLOT"`
204       exit 1
205     fi
206   elif [ $WHICHSLOT = "clean" ]; then
207     NEWSLOT=$CLEANSLOT
208   else
209     echo `_ '%s illegal request' "$WHICHSLOT"`
210     exit 1
211   fi
212   if [ $NEWSLOT = $CURSLOT ]; then
213     echo "$CURSLOT $TAPE"
214     exit 0
215   fi
216   if [ $NEWSLOT = $CLEANSLOT ]; then
217     expr ${CLEANCOUNT:=0} + 1 > $CLEANFILE
218     echo 0 > $ACCESSFILE
219   else
220     expr ${ACCESSCOUNT:=0} + 1 > $ACCESSFILE
221     if [ $ACCESSCOUNT -gt $LASTSLOT ]; then
222       $MYNAME -slot clean >/dev/null
223     fi
224   fi
225
226   readstatus
227   if [ $CURSLOT -ne 0 ]; then
228     unload
229   fi
230
231   if [ $WHICHSLOT = "advance" ]; then
232     echo "$NEWSLOT /dev/null"
233     exit 0
234   fi
235   load $NEWSLOT
236   echo "$NEWSLOT $TAPE"
237   exit 0
238 }
239
240 info() {
241   readstatus
242   echo "$CURSLOT $NSLOT 1"
243   exit 0
244 }
245
246 reset() {
247   readstatus
248   [ $CURSLOT -gt 0 ] && unload
249   load $FIRSTSLOT
250   echo "$FIRSTSLOT $tape"
251   exit 0
252 }
253
254 eject() {
255   readstatus
256   if [ $CURSLOT -le 0 ]; then
257     echo `_ '0 Drive was not loaded'`
258     exit 1
259   else
260     unload
261     echo $CURSLOT
262     exit 0
263   fi
264 }
265
266
267 while [ $# -ge 1 ];do
268   case $1 in
269     -slot)
270            shift
271            loadslot $*
272            ;;
273     -clean)
274            shift
275            loadslot clean
276            ;;
277     -current)
278            shift
279            loadslot current
280            ;;
281     -next)
282            shift
283            loadslot next
284            ;;
285     -advance)
286            shift
287            loadslot advance
288            ;;
289     -prev)
290            shift
291            loadslot prev
292            ;;
293     -first)
294            shift
295            loadslot first
296            ;;
297     -last)
298            shift
299            loadslot last
300            ;;
301     -info)
302            shift
303            info
304            ;;
305     -reset)
306             shift
307             reset
308             ;;
309     -eject)
310             shift
311             eject
312             ;;
313     *)
314        echo `_ '<none> Unknown option %s' "$1"`
315        exit 2
316        ;;
317   esac
318 done
319