#
# Written by Kern Sibbald
#
-# Copyright (C) 2000-2010 Free Software Foundation Europe e.V.
+# Bacula® - The Network Backup Solution
#
-# The main author of Bacula is Kern Sibbald, with contributions from
-# many others, a complete list can be found in the file AUTHORS.
-# This program is Free Software; you can redistribute it and/or
-# modify it under the terms of version three of the GNU Affero General Public
-# License as published by the Free Software Foundation, which is
-# listed in the file LICENSE.
+# Copyright (C) 2000-2014 Free Software Foundation Europe e.V.
#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# General Public License for more details.
+# The main author of Bacula is Kern Sibbald, with contributions from many
+# others, a complete list can be found in the file AUTHORS.
#
-# You should have received a copy of the GNU Affero General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-# 02110-1301, USA.
+# You may use this file and others of this release according to the
+# license defined in the LICENSE file, which includes the Affero General
+# Public License, v3.0 ("AGPLv3") and some additional permissions and
+# terms pursuant to its AGPLv3 Section 7.
#
# Bacula® is a registered trademark of Kern Sibbald.
-# The licensor of Bacula is the Free Software Foundation Europe
-# (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
-# Switzerland, email:ftf@fsfeurope.org.
#
#
# If you set in your Device resource
# included.
#
# disk-changer "changer-device" "command" "slot" "archive-device" "drive-index" "volume"
-# $1 $2 $3 $4 $5 $6
+# $1 $2 $3 $4 $5 $6
#
# By default the autochanger has 10 Volumes and 1 Drive.
#
# Note: For this script to work, you *must" specify
-# Device Type = File
+# 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)
-#
+# 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
+# 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
# 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,
+# 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.
#
dbgfile="$wd/disk-changer.log"
debug() {
if test -f $dbgfile; then
- echo "`date +\"%Y%m%d-%H:%M:%S\"` $*" >> $dbgfile
+ echo "`date +\"%Y%m%d-%H:%M:%S\"` $*" >> $dbgfile
fi
}
if test x${TMPFILE} = x; then
TMPFILE="$wd/disk-changer.$$"
if test -f ${TMPFILE}; then
- echo "Temp file security problem on: ${TMPFILE}"
- exit 1
+ echo "Temp file security problem on: ${TMPFILE}"
+ exit 1
fi
fi
}
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
+ 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
}
dir=`echo "$device" | sed -e s%/$bn%%g`
if [ ! -d $dir ]; then
echo "ERROR: Autochanger directory \"$dir\" does not exist."
- echo " You must create it."
+ echo " You must create it."
exit 1
fi
}
maxslot=10
# Pull in conf file
-if [ -f $ctl ]; then
+if [ -f $ctl ]; then
. $ctl
fi
-# Check for special cases where only 2 arguments are needed,
+# Check for special cases where only 2 arguments are needed,
# all others are a minimum of 5
#
case $2 in
list|listall)
- check_parm_count $# 2
- ;;
+ check_parm_count $# 2
+ ;;
slots)
- check_parm_count $# 2
- ;;
+ check_parm_count $# 2
+ ;;
transfer)
- check_parm_count $# 4
- if [ $slot -gt $maxslot ]; then
- echo "Slot ($slot) out of range (1-$maxslot)"
- exit 1
- fi
- ;;
+ check_parm_count $# 4
+ if [ $slot -gt $maxslot ]; then
+ echo "Slot ($slot) out of range (1-$maxslot)"
+ debug "Error: Slot ($slot) out of range (1-$maxslot)"
+ exit 1
+ fi
+ ;;
*)
- 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
- ;;
+ check_parm_count $# 5
+ if [ $drive -gt $maxdrive ]; then
+ echo "Drive ($drive) out of range (0-$maxdrive)"
+ debug "Error: Drive ($drive) out of range (0-$maxdrive)"
+ exit 1
+ fi
+ if [ $slot -gt $maxslot ]; then
+ echo "Slot ($slot) out of range (1-$maxslot)"
+ debug "Error: Slot ($slot) out of range (1-$maxslot)"
+ exit 1
+ fi
+ ;;
esac
debug "Parms: $ctl $cmd $slot $device $drive $volume $havevol"
-case $cmd in
+case $cmd in
unload)
debug "Doing disk -f $ctl unload $slot $device $drive $volume"
get_dir
if [ -f $dir/loaded${drive} ]; then
- ld=`cat $dir/loaded${drive}`
- else
- echo "Storage Element $slot is Already Full"
- exit 1
+ ld=`cat $dir/loaded${drive}`
+ else
+ echo "Storage Element $slot is Already Full"
+ debug "Unload error: $dir/loaded${drive} is already unloaded"
+ exit 1
fi
if [ $slot -eq $ld ]; then
- echo "0" >$dir/loaded${drive}
- unlink $device 2>/dev/null >/dev/null
- rm -f $device
+ echo "0" >$dir/loaded${drive}
+ unlink $device 2>/dev/null >/dev/null
else
- echo "Storage Element $slot is Already Full"
- exit 1
+ echo "Storage Element $slot is Already Full"
+ debug "Unload error: $dir/loaded${drive} slot=$ld is already unloaded"
+ exit 1
fi
;;
debug "Doing disk $ctl load $slot $device $drive $volume"
get_dir
i=0
+ # Check if slot already in a drive
while [ $i -le $maxdrive ]; do
- if [ -f $dir/loaded${i} ]; then
- ld=`cat $dir/loaded${i}`
- else
- ld=0
- fi
- if [ $ld -eq $slot ]; then
- echo "Drive ${i} Full (Storage element ${ld} loaded)"
- exit 1
- fi
- i=`expr $i + 1`
+ if [ -f $dir/loaded${i} ]; then
+ ld=`cat $dir/loaded${i}`
+ else
+ ld=0
+ fi
+ if [ $ld -eq $slot ]; then
+ echo "Drive ${i} Full (Storage element ${ld} loaded)"
+ debug "Load error: Cannot load Slot=${ld} in drive=$drive. Already in drive=${i}"
+ exit 1
+ fi
+ i=`expr $i + 1`
done
# Check if we have a Volume name
get_vol
if [ $havevol -eq 0 ]; then
- # check if slot exists
- if [ ! -f $dir/slot${slot} ] ; then
- echo "source Element Address $slot is Empty"
- exit 1
- fi
+ # check if slot exists
+ if [ ! -f $dir/slot${slot} ] ; then
+ echo "source Element Address $slot is Empty"
+ debug "Load error: source Element Address $slot is Empty"
+ exit 1
+ fi
fi
if [ -f $dir/loaded${drive} ]; then
- ld=`cat $dir/loaded${drive}`
+ ld=`cat $dir/loaded${drive}`
else
- ld=0
+ ld=0
fi
if [ $ld -ne 0 ]; then
- echo "Drive ${drive} Full (Storage element ${ld} loaded)"
- exit 1
+ echo "Drive ${drive} Full (Storage element ${ld} loaded)"
+ echo "Load error: Drive ${drive} Full (Storage element ${ld} loaded)"
+ exit 1
fi
echo "0" >$dir/loaded${drive}
unlink $device 2>/dev/null >/dev/null
- rm -f $device
if [ $havevol -ne 0 ]; then
- ln -s $dir/$volume $device
- rtn=$?
+ ln -s $dir/$volume $device
+ rtn=$?
else
- ln -s $dir/slot${slot} $device
- rtn=$?
+ ln -s $dir/slot${slot} $device
+ rtn=$?
fi
if [ $rtn -eq 0 ]; then
- echo $slot >$dir/loaded${drive}
+ echo $slot >$dir/loaded${drive}
fi
exit $rtn
;;
- list)
+ list)
debug "Doing disk -f $ctl -- to list volumes"
- get_dir
+ get_dir
if [ -f $dir/barcodes ]; then
- cat $dir/barcodes
+ cat $dir/barcodes
else
- i=1
- while [ $i -le $maxslot ]; do
- slot=$i
- volume=
- get_vol
- if [ $havevol -eq 0 ]; then
- echo "$i:"
- else
- echo "$i:$volume"
- fi
- i=`expr $i + 1`
- done
+ i=1
+ while [ $i -le $maxslot ]; do
+ slot=$i
+ volume=
+ get_vol
+ if [ $havevol -eq 0 ]; then
+ echo "$i:"
+ else
+ echo "$i:$volume"
+ fi
+ i=`expr $i + 1`
+ done
fi
exit 0
;;
- listall)
+ listall)
# ***FIXME*** must add new Volume stuff
make_temp_file
debug "Doing disk -f $ctl -- to list volumes"
- get_dir
+ get_dir
if [ ! -f $dir/barcodes ]; then
- exit 0
+ exit 0
fi
# we print drive content seen by autochanger
# and we also remove loaded media from the barcode list
i=0
while [ $i -le $maxdrive ]; do
- if [ -f $dir/loaded${i} ]; then
- ld=`cat $dir/loaded${i}`
- v=`awk -F: "/^$ld:/"' { print $2 }' $dir/barcodes`
- echo "D:$i:F:$ld:$v"
- echo "^$ld:" >> $TMPFILE
- fi
- i=`expr $i + 1`
+ if [ -f $dir/loaded${i} ]; then
+ ld=`cat $dir/loaded${i}`
+ v=`awk -F: "/^$ld:/"' { print $2 }' $dir/barcodes`
+ echo "D:$i:F:$ld:$v"
+ echo "^$ld:" >> $TMPFILE
+ fi
+ i=`expr $i + 1`
done
# Empty slots are not in barcodes file
# When we detect a gap, we print missing rows as empty
# At the end, we fill the gap between the last entry and maxslot
grep -v -f $TMPFILE $dir/barcodes | sort -n | \
- perl -ne 'BEGIN { $cur=1 }
+ perl -ne 'BEGIN { $cur=1 }
if (/(\d+):(.+)?/) {
- if ($cur == $1) {
- print "S:$1:F:$2\n"
- } else {
- while ($cur < $1) {
- print "S:$cur:E\n";
- $cur++;
- }
- }
- $cur++;
- }
+ if ($cur == $1) {
+ print "S:$1:F:$2\n"
+ } else {
+ while ($cur < $1) {
+ print "S:$cur:E\n";
+ $cur++;
+ }
+ }
+ $cur++;
+ }
END { while ($cur < '"$maxslot"') { print "S:$cur:E\n"; $cur++; } } '
rm -f $TMPFILE
make_temp_file
slotdest=$device
if [ -f $dir/slot{$slotdest} ]; then
- echo "destination Element Address $slot is Full"
- exit 1
+ echo "destination Element Address $slot is Full"
+ exit 1
fi
if [ ! -f $dir/slot${slot} ] ; then
- echo "source Element Address $slot is Empty"
- exit 1
+ echo "source Element Address $slot is Empty"
+ exit 1
fi
echo "Transfering $slot to $slotdest"
mv $dir/slot${slot} $dir/slot{$slotdest}
if [ -f $dir/barcodes ]; then
- sed "s/^$slot:/$slotdest:/" > $TMPFILE
- sort -n $TMPFILE > $dir/barcodes
+ sed "s/^$slot:/$slotdest:/" > $TMPFILE
+ sort -n $TMPFILE > $dir/barcodes
fi
exit 0
;;
debug "Doing disk -f $ctl $drive -- to find what is loaded"
get_dir
if [ -f $dir/loaded${drive} ]; then
- cat $dir/loaded${drive}
+ a=`cat $dir/loaded${drive}`
else
- echo "0"
+ a="0"
fi
+ debug "Loaded: drive=$drive is $a"
+ echo $a
exit
;;