blob: 30f6dba8f75f14b3048ec7b20f916597178716f9 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
|
#!/bin/sh
#
# Bacula interface to FreeBSD chio autoloader command with
# multiple drive support
# (By Lars Köller, lars+bacula@koellers.net, 2004)
#
# If you set in your Device resource
#
# Changer Command = "path-to-this-script/chio-bacula" %c %o %S %a
# you will have the following input to this script:
#
# chio-bacula "changer-device" "command" "slot" "archive-device" "drive-index"
# $1 $2 $3 $4 $5
# for example:
#
# chio-bacula /dev/sg0 load 1 /dev/nst0 0 (on a FreeBSD system)
#
# If you need to to an offline, refer to the drive as $4
# e.g. mt -f $f offline
#
# Many changers need an offline after the unload. Also many
# changers need a sleep 60 after the mtx load.
#
# N.B. If you change the script, take care to return either
# the mtx exit code or a 0. If the script exits with a non-zero
# exit code, Bacula will assume the request failed.
#
me=$(basename $0)
# Debug output, take care: this file is writable by user bacula!
#LOG=/var/db/bacula/chio-bacula.log
#exec 2>>$LOG
#echo "------------------------- $(date) Start $(basename $0) -------------------------" >> $LOG
#set -x
# Debug
logger -p user.err "$me $@"
# This simulates a barcode reader in the changer.
# The labels of the virtual barcode reader are located in the BARCODE_FILE
SIMULATE_BARCODE=true
BARCODE_FILE=/usr/local/etc/bacula/bacula-barcodes
MTX=/bin/chio
# Set default values (see case statement below for
# free mapping of drive index and tape device
# We have a double drive Qualstar where drive 1 is the default bacula drive
#TAPE=/dev/bacula-tape
TAPE=/dev/nrsa0
DRIVE=0
# Time to wait for (un)loading
SLEEP=20
usage()
{
echo ""
echo "The $me script for bacula"
echo "--------------------------------------"
echo ""
echo "usage: $me <changer-device> <command> [slot] [devicename of tapedrive] [drive index]"
echo ""
echo "Valid commands:"
echo ""
echo "unload Unloads a tape into the slot"
echo " from where it was loaded."
echo "load <slot> Loads a tape from the slot <slot>"
echo " (slot-base is calculated to 1 as first slot)"
echo "list Lists full storage slots"
echo "loaded Gives slot from where the tape was loaded."
echo " 0 means the tape drive is empty."
echo "slots Gives number of available slots."
echo ""
echo "Example:"
echo " $me /dev/changer load 1 loads a tape from slot 1"
echo ""
exit 2
}
# The changer device
if [ -z "$1" ] ; then
usage;
else
CHANGER=$1
fi
# The command
if [ -z "$2" ] ; then
usage;
else
COMMAND=$2
fi
# The slot number
if [ ! -z "$3" ]; then
SLOT=$3
# btape fill says "... slot 1 drive 0" :-(
if [ "$SLOT" = "slot" ]; then
shift
SLOT=$3
fi
fi
# Set tape device
if [ ! -z "$4" ]; then
TAPE=$4
fi
# Here you can map bacula drive number to any tape device
# DRIVE is the chio drive number used below by chio!
case $5 in
0)
# First Drive in Changer is Bacula drive
DRIVE=0
#TAPE=/dev/bacula-tape
TAPE=/dev/nrsa0
;;
1)
DRIVE=1
#TAPE=/dev/bacula-tape2
TAPE=/dev/nrsa1
;;
esac
#
# Main
#
case ${COMMAND} in
unload)
# enable the following line if you need to eject the cartridge
mt -f ${TAPE} off
sleep 2
# if we have a slot, try it
if [ ! -z "$SLOT" ]; then
${MTX} -f ${CHANGER} move drive ${DRIVE} slot $((${SLOT}-1))
exit $?
fi
# Try other way (works if source element information is valid for drive)
${MTX} -f ${CHANGER} return drive ${DRIVE}
# If the changer is power cycled with a tape loaded in a drive
# we can compute the slot in case of a complete filled magazine, with
# one slot free.
if [ "$?" != "0" ]; then
free_slot=`${MTX} -f ${CHANGER} stat | grep "^slot " | grep -v "FULL" | awk '{print $2}'`
free_slot=${free_slot%:}
${MTX} -f ${CHANGER} move drive ${DRIVE} slot $free_slot
fi
;;
load)
${MTX} -f ${CHANGER} move slot $((${SLOT}-1)) drive ${DRIVE}
rtn=$?
# Increase the sleep time if you have a slow device
sleep $SLEEP
exit $rtn
;;
list)
if [ "${SIMULATE_BARCODE}" = "true" ]; then
if [ -f "$BARCODE_FILE" ]; then
cat $BARCODE_FILE | grep -v -e "^#" -e "^$"
exit 0
else
echo "Barcode file $BARCODE_FILE missing ... exiting!"
exit 1
fi
else
${MTX} -f ${CHANGER} status | grep "^slot .*: .*FULL>" | awk '{print $2}' | awk -F: '{print $1+1" "}' | tr -d "[\r\n]"
fi
;;
loaded)
# echo "Request loaded"
${MTX} -f ${CHANGER} status -S > /tmp/mtx.$$
rtn=$?
# Try to get chio slot source from drive entry
SLOT=$(cat /tmp/mtx.$$ | grep "^drive ${DRIVE}: <FULL> .*slot" | awk '{print $6+1}' | tr -d ">")
if [ -z "$SLOT" ]; then
# This handles the case a source slot is not available (power on
# of the changer with a drive loaded) and all other slots are
# occupied with a tape!
SLOT=$(cat /tmp/mtx.$$ | grep "^slot .*: <ACCESS>" | awk '{print $2+1}')
if [ -z "$SLOT" ]; then
echo 0
else
echo $SLOT
fi
else
echo $SLOT
fi
# All tapes are in the slots
#cat /tmp/mtx.$$ | grep "^drive ${DRIVE}: .* source: <>" | awk "{print 0}"
rm -f /tmp/mtx.$$
exit $rtn
;;
slots)
# echo "Request slots"
${MTX} -f ${CHANGER} status | grep "^slot " | tail -1 | awk '{print $2+1}' | tr -d ":"
;;
*)
usage
;;
esac
|