Imported Upstream version 3.3.3
[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 # Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
6 # All Rights Reserved.
7 #
8 # Permission to use, copy, modify, distribute, and sell this software and its
9 # documentation for any purpose is hereby granted without fee, provided that
10 # the above copyright notice appear in all copies and that both that
11 # copyright notice and this permission notice appear in supporting
12 # documentation, and that the name of U.M. not be used in advertising or
13 # publicity pertaining to distribution of the software without specific,
14 # written prior permission.  U.M. makes no representations about the
15 # suitability of this software for any purpose.  It is provided "as is"
16 # without express or implied warranty.
17 #
18 # U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
19 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
20 # BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
21 # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
22 # OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
23 # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
24 #
25 # Author: Jean-Christian SIMONETTI, System and Network Engineer
26 #                                   Wanadoo Portails
27 #                                   Sophia Antipolis, France
28 #
29 #       This changer script is based on a directory structure like:
30 #       slot_root_dir -|
31 #                      |- info
32 #                      |- data -> slot1
33 #                      |- slot1
34 #                      |- slot2
35 #                      |- ...
36 #                      |- slotn
37 #       where 'slot_root_dir' is the tapedev 'file:xxx' parameter and 'n'
38 #       is the LASTSLOT value of your changerfile config file. If LASTSLOT is
39 #       not defined, the value of the tapecycle parameter is used.
40 #
41 #       To use this driver, just put the line 'tpchanger "chg-disk"' in your
42 #       amanda.conf.
43 #
44 #       Example of use (amanda.conf):
45 #       --- cut here ---
46 #       tapedev  "file:/BACKUP2/slots/"
47 #       changerdev "/dev/null"
48 #       changerfile "chg-disk"
49 #       tpchanger "chg-disk"
50 #       changerfile "/usr/local/amanda/etc/changer"
51 #       tapetype HARD-DISK
52 #       define tapetype HARD-DISK {
53 #           length 12000 mbytes
54 #       }
55 #       --- cut here ---
56 #
57 #       Example changerfile (chg-disk.conf):
58 #       --- cut here ---
59 #       LASTSLOT=12
60 #       --- cut here ---
61 #
62 #       The number of slot is equal to your LASTSLOT or tapecycle.
63 #       You must create the slots and data directory.
64 #
65
66
67 prefix="@prefix@"
68 exec_prefix="@exec_prefix@"
69 sbindir="@sbindir@"
70 amlibexecdir="@amlibexecdir@"
71 . "${amlibexecdir}/amanda-sh-lib.sh"
72  
73 # add sbin and ucb dirs
74 PATH="$PATH:/usr/sbin:/sbin:/usr/ucb"
75 export PATH
76
77 MYNAME=$0
78
79 TAPE=`amgetconf tapedev`
80 if test X"$TAPE" = X""; then
81     echo `_ '<none> tapedev not specified in amanda.conf.'`
82     exit 2
83 fi
84 SLOTDIR=`echo $TAPE | sed 's/^file://'`
85
86 isinteger() {
87             # should be exactly one arg
88         [ $# = 1 ]  || return 1
89             # if arg is null, no expr needed
90         [ "${1}" = '' ] && return 1
91             # expr will return 0 on match
92         expr "$1" : '[0-9][0-9]*$' > /dev/null 2>&1
93 }
94
95 # Need rwx access to the virtual tape itself.
96 if ! test -d $SLOTDIR; then
97     echo `_ '<none> Virtual-tape directory %s does not exist.' "$SLOTDIR"`
98     exit 2
99 fi
100 if ! test -w $SLOTDIR; then
101     echo `_ '<none> Virtual-tape directory %s is not writable.' "$SLOTDIR"`
102     exit 2
103 fi
104
105
106 # need rwx access to directory of changer file
107 CHANGERFILE=`amgetconf changerfile`
108 conf_match=`expr "$CHANGERFILE" : .\*\.conf\$`
109 if [ $conf_match -ge 6 ]; then
110         CONFIGFILE=$CHANGERFILE
111         CHANGERFILE=`echo $CHANGERFILE | sed 's/.conf$//g'`
112 else
113         CONFIGFILE=$CHANGERFILE.conf
114 fi
115
116 CFDir=`dirname ${CHANGERFILE}`
117 [ -d ${CFDir} -a -r ${CFDir} -a -w ${CFDir} -a -x ${CFDir} ] ||
118         { echo `_ "<none> %s: need 'rwx' access to '%s'" "$MYNAME" "$CFDir"` ; exit 2 ; }
119
120 # check or create changer metadata files
121 ACCESSFILE=$CHANGERFILE-access
122 [ -f $ACCESSFILE -a -r $ACCESSFILE -a -w $ACCESSFILE ] ||
123         echo 0 > $ACCESSFILE ||
124         { echo `_ "<none> %s: could not access or create '%s'" "$MYNAME" "$ACCESSFILE"` ; exit 2; }
125 CLEANFILE=$CHANGERFILE-clean
126 [ -f $CLEANFILE -a -r $CLEANFILE -a -w $CLEANFILE ] ||
127         echo 0 > $CLEANFILE ||
128         { echo `_ "<none> %s: could not access or create '%s'" "$MYNAME" "$CLEANFILE"` ; exit 2 ; }
129 SLOTFILE=$CHANGERFILE-slot
130 [ -f $SLOTFILE -a -r $SLOTFILE -a -w $SLOTFILE ] ||
131         echo 0 > $SLOTFILE ||
132         { echo `_ "<none> %s: could not access or create '%s'" "$MYNAME" "$SLOTFILE"` ; exit 2; }
133
134 # read and check metadata
135 ACCESSCOUNT=`cat $ACCESSFILE`
136 isinteger $ACCESSCOUNT || { ACCESSCOUNT=0 ; echo 0 > $ACCESSFILE ; }
137 CLEANCOUNT=`cat $CLEANFILE`
138 isinteger $CLEANCOUNT || { CLEANCOUNT=0 ; echo 0 > $CLEANFILE ; }
139
140 FIRSTSLOT=1
141 LASTSLOT=`amgetconf tapecycle`
142 if test -r $CONFIGFILE; then
143     . $CONFIGFILE
144 fi
145 CURSLOT=0
146 CLEANSLOT=$LASTSLOT
147 NSLOT=`expr $LASTSLOT - $FIRSTSLOT + 1`
148
149 load() {
150   WHICHSLOT=$1;
151   # unload should have been called, but just in case ...
152   [ -h $SLOTDIR/data ] && unload
153   ln -s $SLOTDIR/slot$WHICHSLOT $SLOTDIR/data
154   echo $WHICHSLOT > $SLOTFILE
155 }
156
157 unload() {
158   rm -f $SLOTDIR/data
159   echo "0" > $SLOTFILE
160 }
161
162 readstatus() {
163   CURSLOT=`cat $SLOTFILE`
164 }
165
166 loadslot() {
167   WHICHSLOT=$1
168
169   TYPE=string   # default if not numeric
170   isinteger $WHICHSLOT && TYPE=digit
171
172   readstatus
173   NEWSLOT=0
174   if [ $WHICHSLOT = "current" ]; then
175     if [ $CURSLOT -le 0 ]; then
176       load $FIRSTSLOT
177       echo "$FIRSTSLOT $TAPE"
178       exit 0
179     else
180       echo "$CURSLOT $TAPE"
181       exit 0
182     fi
183   elif [ $WHICHSLOT = "next" -o $WHICHSLOT = "advance" ]; then
184     NEWSLOT=`expr $CURSLOT + 1`
185     [ $NEWSLOT -gt $LASTSLOT ] && NEWSLOT=$FIRSTSLOT
186   elif [ $WHICHSLOT = "prev" ]; then
187       NEWSLOT=`expr $CURSLOT - 1`
188       [ $NEWSLOT -lt $FIRSTSLOT ] && NEWSLOT=$LASTSLOT
189   elif [ $WHICHSLOT = "first" ]; then
190       NEWSLOT=$FIRSTSLOT
191   elif [ $WHICHSLOT = "last" ]; then
192       NEWSLOT=$LASTSLOT
193   elif [ $TYPE = "digit" ]; then
194     if [ $WHICHSLOT -ge $FIRSTSLOT -a $WHICHSLOT -le $LASTSLOT ]; then
195       NEWSLOT=$WHICHSLOT
196     else
197       echo `_ '%s illegal slot' "$WHICHSLOT"`
198       exit 1
199     fi
200   elif [ $WHICHSLOT = "clean" ]; then
201     NEWSLOT=$CLEANSLOT
202   else
203     echo `_ '%s illegal request' "$WHICHSLOT"`
204     exit 1
205   fi
206   if [ $NEWSLOT = $CURSLOT ]; then
207     echo "$CURSLOT $TAPE"
208     exit 0
209   fi
210   if [ $NEWSLOT = $CLEANSLOT ]; then
211     expr ${CLEANCOUNT:=0} + 1 > $CLEANFILE
212     echo 0 > $ACCESSFILE
213   else
214     expr ${ACCESSCOUNT:=0} + 1 > $ACCESSFILE
215     if [ $ACCESSCOUNT -gt $LASTSLOT ]; then
216       $MYNAME -slot clean >/dev/null
217     fi
218   fi
219
220   readstatus
221   if [ $CURSLOT -ne 0 ]; then
222     unload
223   fi
224
225   if [ $WHICHSLOT = "advance" ]; then
226     echo "$NEWSLOT /dev/null"
227     exit 0
228   fi
229   load $NEWSLOT
230   echo "$NEWSLOT $TAPE"
231   exit 0
232 }
233
234 info() {
235   readstatus
236   echo "$CURSLOT $NSLOT 1"
237   exit 0
238 }
239
240 reset() {
241   readstatus
242   [ $CURSLOT -gt 0 ] && unload
243   load $FIRSTSLOT
244   echo "$FIRSTSLOT $tape"
245   exit 0
246 }
247
248 eject() {
249   readstatus
250   if [ $CURSLOT -le 0 ]; then
251     echo `_ '0 Drive was not loaded'`
252     exit 1
253   else
254     unload
255     echo $CURSLOT
256     exit 0
257   fi
258 }
259
260
261 while [ $# -ge 1 ];do
262   case $1 in
263     -slot)
264            shift
265            loadslot $*
266            ;;
267     -clean)
268            shift
269            loadslot clean
270            ;;
271     -current)
272            shift
273            loadslot current
274            ;;
275     -next)
276            shift
277            loadslot next
278            ;;
279     -advance)
280            shift
281            loadslot advance
282            ;;
283     -prev)
284            shift
285            loadslot prev
286            ;;
287     -first)
288            shift
289            loadslot first
290            ;;
291     -last)
292            shift
293            loadslot last
294            ;;
295     -info)
296            shift
297            info
298            ;;
299     -reset)
300             shift
301             reset
302             ;;
303     -eject)
304             shift
305             eject
306             ;;
307     *)
308        echo `_ '<none> Unknown option %s' "$1"`
309        exit 2
310        ;;
311   esac
312 done
313