#! /bin/sh # # Amanda, The Advanced Maryland Automatic Network Disk Archiver # Copyright (c) 1991-1999 University of Maryland at College Park # All Rights Reserved. # # Permission to use, copy, modify, distribute, and sell this software and its # documentation for any purpose is hereby granted without fee, provided that # the above copyright notice appear in all copies and that both that # copyright notice and this permission notice appear in supporting # documentation, and that the name of U.M. not be used in advertising or # publicity pertaining to distribution of the software without specific, # written prior permission. U.M. makes no representations about the # suitability of this software for any purpose. It is provided "as is" # without express or implied warranty. # # U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M. # BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION # OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. # # Author: Jean-Christian SIMONETTI, System and Network Engineer # Wanadoo Portails # Sophia Antipolis, France # # This changer script is based on a directory structure like: # slot_root_dir -| # |- info # |- data -> slot1 # |- slot1 # |- slot2 # |- ... # |- slotn # where 'slot_root_dir' is the tapedev 'file:xxx' parameter and 'n' # is the tapecycle parameter. # # To use this driver, just put the line 'tpchanger "chg-disk"' in your # amanda.conf. # # Example of use: # --- cut here --- # tapedev "file:/BACKUP2/slots/" # rawtapedev "file:/BACKUP2/slots/" # changerdev "/dev/null" # tpchanger "chg-disk" # changerfile "/usr/local/amanda/etc/changer" # tapetype HARD-DISK # define tapetype HARD-DISK { # length 12000 mbytes # } # --- cut here --- # # The number of slot is equal to your tapecyle. # You must create the slots and data directory. # prefix=@prefix@ exec_prefix=@exec_prefix@ sbindir=@sbindir@ libexecdir=@libexecdir@ PATH=$sbindir:$libexecdir:/usr/bin:/bin:/usr/sbin:/sbin:/usr/ucb:/usr/local/bin export PATH USE_VERSION_SUFFIXES="@USE_VERSION_SUFFIXES@" if test "$USE_VERSION_SUFFIXES" = "yes"; then SUF="-@VERSION@" else SUF= fi MYNAME=$0 TAPE=`amgetconf$SUF tapedev` SLOTDIR=`echo $TAPE | sed 's/^file://'` isinteger() { # should be exactly one arg [ $# = 1 ] || return 1 # if arg is null, no expr needed [ "${1}" = '' ] && return 1 # expr will return 0 on match expr "$1" : '[0-9][0-9]*$' > /dev/null 2>&1 } # need rwx access to directory of changer file CHANGERFILE=`amgetconf$SUF changerfile` CFDir=`dirname ${CHANGERFILE}` [ -d ${CFDir} -a -r ${CFDir} -a -w ${CFDir} -a -x ${CFDir} ] || { echo "$MYNAME: need 'rwx' access to '$CFDir'" ; exit 2 ; } # check or create changer metadata files ACCESSFILE=$CHANGERFILE-access [ -f $ACCESSFILE -a -r $ACCESSFILE -a -w $ACCESSFILE ] || echo 0 > $ACCESSFILE || { echo "$MYNAME: could not access or create '$ACCESSFILE'" ; exit 2 ; } CLEANFILE=$CHANGERFILE-clean [ -f $CLEANFILE -a -r $CLEANFILE -a -w $CLEANFILE ] || echo 0 > $CLEANFILE || { echo "$MYNAME: could not access or create '$CLEANFILE'" ; exit 2 ; } SLOTFILE=$CHANGERFILE-slot [ -f $SLOTFILE -a -r $SLOTFILE -a -w $SLOTFILE ] || echo 0 > $SLOTFILE || { echo "$MYNAME: could not access or create '$SLOTFILE'" ; exit 2 ; } # read and check metadata ACCESSCOUNT=`cat $ACCESSFILE` isinteger $ACCESSCOUNT || { ACCESSCOUNT=0 ; echo 0 > $ACCESSFILE ; } CLEANCOUNT=`cat $CLEANFILE` isinteger $CLEANCOUNT || { CLEANCOUNT=0 ; echo 0 > $CLEANFILE ; } FIRSTSLOT=1 LASTSLOT=`amgetconf$SUF tapecycle` CURSLOT=0 CLEANSLOT=$LASTSLOT load() { WHICHSLOT=$1; # unload should have been called, but just in case ... [ -h $SLOTDIR/data ] && unload ln -s $SLOTDIR/slot$WHICHSLOT $SLOTDIR/data echo $WHICHSLOT > $SLOTFILE } unload() { rm -f $SLOTDIR/data echo "0" > $SLOTFILE } readstatus() { CURSLOT=`cat $SLOTFILE` } loadslot() { WHICHSLOT=$1 TYPE=string # default if not numeric isinteger $WHICHSLOT && TYPE=digit readstatus NEWSLOT=0 if [ $WHICHSLOT = "current" ]; then if [ $CURSLOT -le 0 ]; then load $FIRSTSLOT echo "$FIRSTSLOT $TAPE" exit 0 else echo "$CURSLOT $TAPE" exit 0 fi elif [ $WHICHSLOT = "next" -o $WHICHSLOT = "advance" ]; then NEWSLOT=`expr $CURSLOT + 1` [ $NEWSLOT -gt $LASTSLOT ] && NEWSLOT=$FIRSTSLOT elif [ $WHICHSLOT = "prev" ]; then NEWSLOT=`expr $CURSLOT - 1` [ $NEWSLOT -lt $FIRSTSLOT ] && NEWSLOT=$LASTSLOT elif [ $WHICHSLOT = "first" ]; then NEWSLOT=$FIRSTSLOT elif [ $WHICHSLOT = "last" ]; then NEWSLOT=$LASTSLOT elif [ $TYPE = "digit" ]; then if [ $WHICHSLOT -ge $FIRSTSLOT -a $WHICHSLOT -le $LASTSLOT ]; then NEWSLOT=$WHICHSLOT else echo "0 illegal request" exit 1 fi elif [ $WHICHSLOT = "clean" ]; then NEWSLOT=$CLEANSLOT else echo "0 illegal request" exit 1 fi if [ $NEWSLOT = $CURSLOT ]; then echo "$CURSLOT $TAPE" exit 0 fi if [ $NEWSLOT = $CLEANSLOT ]; then expr ${CLEANCOUNT:=0} + 1 > $CLEANFILE echo 0 > $ACCESSFILE else expr ${ACCESSCOUNT:=0} + 1 > $ACCESSFILE if [ $ACCESSCOUNT -gt $LASTSLOT ]; then $MYNAME -slot clean >/dev/null fi fi readstatus if [ $CURSLOT -ne 0 ]; then unload fi if [ $WHICHSLOT = "advance" ]; then echo "$NEWSLOT /dev/null" exit 0 fi load $NEWSLOT echo "$NEWSLOT $TAPE" exit 0 } info() { readstatus echo "$CURSLOT $LASTSLOT $FIRSTSLOT" exit 0 } reset() { readstatus [ $CURSLOT -gt 0 ] && unload load $FIRSTSLOT echo "$FIRSTSLOT $tape" exit 0 } eject() { readstatus if [ $CURSLOT -le 0 ]; then echo "0 Drive was not loaded" exit 1 else unload echo $CURSLOT exit 0 fi } while [ $# -ge 1 ];do case $1 in -slot) shift loadslot $* ;; -clean) shift loadslot clean ;; -current) shift loadslot current ;; -next) shift loadslot next ;; -advance) shift loadslot advance ;; -prev) shift loadslot prev ;; -first) shift loadslot first ;; -last) shift loadslot last ;; -info) shift info ;; -reset) shift reset ;; -eject) shift eject ;; *) echo "Unknown option $1" exit 2 ;; esac done