#!/bin/sh
#
# Bacula interface to virtual autoloader using disk storage
#
# $Id: disk-changer.in 4982 2007-06-05 16:58:53Z kerns $
#
# If you set in your Device resource
#
# Changer Command = "path-to-this-script/disk-changer %c %o %S %a %d"
# you will have the following input to this script:
#
# So Bacula will always call with all the following arguments, even though
# in come cases, not all are used.
#
# disk-changer "changer-device" "command" "slot" "archive-device" "drive-index"
# $1 $2 $3 $4 $5
#
# By default the autochanger has 10 Volumes and 1 Drive.
#
# Note: For this script to work, you *must" specify
# Device Type = File
# in each of the Devices associated with your AutoChanger resource.
#
# changer-device is the name of a file that overrides the default
# volumes and drives. It may have:
# maxslot=n where n is one based (default 10)
# maxdrive=m where m is zero based (default 1 -- i.e. 2 drives)
#
# This code can also simulate barcodes. You simply put
# a list of the slots and barcodes in the "base" directory/barcodes.
# See below for the base directory definition. Example of a
# barcodes file:
# /var/bacula/barcodes
# 1:Vol001
# 2:Vol002
# ...
#
# archive-device is the name of the base directory where you want the
# Volumes stored appended with /drive0 for the first drive; /drive1
# for the second drive, ... For example, you might use
# /var/bacula/drive0 Note: you must not have a trailing slash, and
# the string (e.g. /drive0) must be unique, and it must not match
# any other part of the directory name. These restrictions could be
# easily removed by any clever script jockey.
#
# Full example: disk-changer /var/bacula/conf load 1 /var/bacula/drive0 0
#
# The Volumes will be created with names slot1, slot2, slot3, ... maxslot in the
# base directory. In the above example the base directory is /var/bacula.
# However, as with tapes, their Bacula Volume names will be stored inside the
# Volume label. In addition to the Volumes (e.g. /var/bacula/slot1,
# /var/bacula/slot3, ...) this script will create a /var/bacula/loadedn
# file to keep track of what Slot is loaded. You should not change this file.
#
#
wd=@working_dir@
#
# log whats done
#
# to turn on logging, uncomment the following line
#touch $wd/disk-changer.log
#
dbgfile="$wd/disk-changer.log"
debug() {
if test -f $dbgfile; then
echo "`date +\"%Y%m%d-%H:%M:%S\"` $*" >> $dbgfile
fi
}
#
# Create a temporary file
#
make_temp_file() {
TMPFILE=`mktemp -t mtx.XXXXXXXXXX`
if test x${TMPFILE} = x; then
TMPFILE="$wd/disk-changer.$$"
if test -f ${TMPFILE}; then
echo "Temp file security problem on: ${TMPFILE}"
exit 1
fi
fi
}
# check parameter count on commandline
#
check_parm_count() {
pCount=$1
pCountNeed=$2
if test $pCount -lt $pCountNeed; then
echo "usage: disk-changer ctl-device command [slot archive-device drive-index]"
echo " Insufficient number of arguments arguments given."
if test $pCount -lt 2; then
echo " Mimimum usage is first two arguments ..."
else
echo " Command expected $pCountNeed arguments"
fi
exit 1
fi
}
#
# Strip off the final name in order to get the Directory ($dir)
# that we are dealing with.
#
get_dir() {
bn=`basename $device`
dir=`echo "$device" | sed -e s%/$bn%%g`
if [ ! -d $dir ]; then
echo "ERROR: Autochanger directory \"$dir\" does not exist.\n"
echo " You must create it.\n"
exit 1
fi
}
# Setup arguments
ctl=$1
cmd="$2"
slot=$3
device=$4
drive=$5
# set defaults
maxdrive=1
maxslot=10
# Pull in conf file
if [ -f $ctl ]; then
. $ctl
fi
# Check for special cases where only 2 arguments are needed,
# all others are a minimum of 5
#
case $2 in
list)
check_parm_count $# 2
;;
slots)
check_parm_count $# 2
;;
*)
check_parm_count $# 5
if [ $drive -gt $maxdrive ]; then
echo "Drive ($drive) out of range (0-$maxdrive)"
exit 1
fi
if [ $slot -gt $maxslot ]; then
echo "Slot ($slot) out of range (1-$maxslot)"
exit 1
fi
;;
esac
debug "Parms: $ctl $cmd $slot $device $drive"
case $cmd in
unload)
debug "Doing disk -f $ctl unload $slot $device $drive"
get_dir
ld=`cat $dir/loaded${drive}`
if [ $slot -eq $ld ]; then
echo "0" >$dir/loaded${drive}
unlink $device 2>/dev/null >/dev/null
rm -f $device
else
echo "Storage Element $slot is Already Full"
exit 1
fi
;;
load)
debug "Doing disk $ctl load $slot $device $drive"
get_dir
if [ -f $dir/loaded${drive} ]; then
ld=`cat $dir/loaded${drive}`
else
ld=0
fi
if [ $ld -eq 0 ]; then
echo "0" >$dir/loaded${drive}
unlink $device 2>/dev/null >/dev/null
rm -f $device
ln -s $dir/slot${slot} $device
rtn=$?
if [ $rtn -eq 0 ]; then
echo $slot >$dir/loaded${drive}
fi
exit $rtn
else
echo "Drive ${drive} Full (Storage element ${ld} loaded)"
exit 1
fi
;;
list)
debug "Doing disk -f $ctl -- to list volumes"
get_dir
if [ -f $dir/barcodes ]; then
cat $dir/barcodes
else
i=1
while [ $i -le $maxslot ]; do
echo "$i:"
i=`expr $i + 1`
done
fi
exit 0
;;
loaded)
debug "Doing disk -f $ctl $drive -- to find what is loaded"
get_dir
if [ -f $dir/loaded${drive} ]; then
cat $dir/loaded${drive}
else
echo "0"
fi
exit
;;
slots)
debug "Doing disk -f $ctl -- to get count of slots"
echo $maxslot
;;
esac
syntax highlighted by Code2HTML, v. 0.9.1