summaryrefslogtreecommitdiff
path: root/sysutils/bareos23-server/files/chio-bareos
blob: f006ef78e6ce830f39983e51fbb81379c27bad01 (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
#!/bin/sh
#
# BAREOS interface to tape libraries and autoloaders for FreeBSD
# (by Rudolf Cejka <cej...@fit.vutbr.cz>, v1.2, 2012/11/14)
#
# If you set in your Device resource
#   Changer Command = "path-to-this-script/chio-changer %c %o %S %a %d"
# you will have the following input to this script:
#   chio-changer "changer-device" "command" "slot" "tape-device" "drive-index"
#                       $1           $2       $3         $4            $5
# for example (on a FreeBSD system):
#   chio-changer /dev/ch0 load 1 /dev/nsa0 0
#
# If you change the script, take care to return either the chio exit
# code or a 0. If the script exits with a non-zero exit code, BAREOS
# will assume the request failed.
#

PROGNAME=`basename $0`

# Uncomment the following line, if you want to log debug output.
#DEBUG=/var/run/bareos/${PROGNAME}.log

# Uncomment the following line, if you need to eject a tape before moving
# it from the drive.
#OFFLINE=yes

# Uncomment one or more of the following lines, if you need to wait for
# some time (in seconds) after unloading, loading or transferring a tape.
#OFFLINE_SLEEP=10
#LOAD_SLEEP=10
#MOVE_SLEEP=10

# Uncomment the following line, if you do not have a changer with volume
# reader.
#FAKE_BARCODES=/usr/local/etc/bareos-barcodes

usage()
{
  cat <<EOF
Usage: ${PROGNAME} <changer-device> <cmd> [slot] [tape-device] [drive-index]

Commands (<cmd>):
  unload          Unload a tape into the slot from where it was loaded
  load <slot>     Load a tape from the slot <slot> (1-based)
  transfer <slot> <slotdst> Transfer a tape from the slot <slot> to
                  the slot <slotdst> (1-based)
  list            List full storage slots
  listall         List all storage slots and drives with source information
  loaded          Give slot from where the tape was loaded (0 = empty drive)
  slots           Give number of available slots

Example:
  ${PROGNAME} /dev/ch0 load 1        Load a tape from the slot 1

EOF
  exit 1
}

# Default settings
CHANGER=/dev/ch0
TAPE=/dev/nsa0
DRIVE=0

CHIO=/bin/chio
MT=/usr/bin/mt

if [ -n "${DEBUG}" ]; then
  MSG=$0
  for PAR; do MSG="${MSG} \"${PAR}\""; done
  echo `date +"%Y/%m/%d %H:%M:%S"` ${MSG} >> ${DEBUG}
fi

if [ -n "$1" ]; then
  CHANGER=$1;
fi
COMMAND=$2
SLOT=$3
SLOTDST=$4
if [ -n "$4" ]; then
  TAPE=$4
fi
if [ -n "$5" ]; then
  DRIVE=$5
fi

case ${COMMAND} in
unload)
  if [ "${OFFLINE}" = yes ]; then
    ${MT} -f ${TAPE} offline
    if [ $? = 0 -a -n "${OFFLINE_SLEEP}" ]; then
      sleep ${OFFLINE_SLEEP}
    fi
  fi
  if [ -z "${SLOT}" ]; then
    ${CHIO} -f ${CHANGER} return drive ${DRIVE}
  else
    ${CHIO} -f ${CHANGER} move drive ${DRIVE} slot $((${SLOT} - 1))
  fi
  if [ $? -ne 0 ]; then
    # In case of an error, try to unload the cartridge to the first free slot
    FREE=`${CHIO} -f ${CHANGER} status slot | \
      sed -ne '/FULL/d;s/^slot *\([0-9]*\):.*/\1/p' | \
      awk 'BEGIN { n = 0 } { n = $1 + 1; exit } END { print n }'`
    if [ ${FREE} -gt 0 ]; then
      ${CHIO} -f ${CHANGER} move drive ${DRIVE} slot $((${FREE} - 1))
    else
      exit 1
    fi
  fi
  ;;
load)
  if [ -z "${SLOT}" ]; then
    usage
  fi
  ${CHIO} -f ${CHANGER} move slot $((${SLOT} - 1)) drive ${DRIVE}
  if [ $? -ne 0 ]; then
    exit 1
  fi
  if [ -n "${LOAD_SLEEP}" ]; then
    sleep ${LOAD_SLEEP}
  fi
  ;;
transfer)
  if [ -z "${SLOT}" -o -z "${SLOTDST}" ]; then
    usage
  fi
  ${CHIO} -f ${CHANGER} move slot $((${SLOT} - 1)) slot $((${SLOTDST} - 1))
  if [ $? -ne 0 ]; then
    exit 1
  fi
  if [ -n "${MOVE_SLEEP}" ]; then
    sleep ${MOVE_SLEEP}
  fi
  ;;
list)
  if [ -z "${FAKE_BARCODES}" ]; then
    ${CHIO} -f ${CHANGER} status -v slot | \
      sed -ne 's/^slot *\([0-9]*\):.*FULL.*voltag.*<\([^:]*\):.*/\1:\2/p' | \
      awk -F: '{ print $1 + 1 ":" $2 }'
  else
    if [ -f "${FAKE_BARCODES}" ]; then
      grep -v -e "^#" -e "^$" < ${FAKE_BARCODES}
    else
      echo "${PROGNAME}: Barcode file ${FAKE_BARCODES} is missing"
      exit 1
    fi
  fi
  ;;
listall)
  if [ -z "${FAKE_BARCODES}" ]; then
    ${CHIO} -f ${CHANGER} status -vS | \
      sed -ne '
      s/^slot *\([0-9]*\):.*ENAB.*FULL.*voltag.*<\([^:]*\):.*/I:\1:F:\2/p;t
      s/^slot *\([0-9]*\):.*FULL.*voltag.*<\([^:]*\):.*/S:\1:F:\2/p;t
      s/^drive *\([0-9]*\):.*FULL.*voltag.*<\([^:]*\):.*source.*<[^0-9]*\([0-9]*\)>.*/D:\1:F:\3:\2/p;t
      s/^slot *\([0-9]*\):.*ENAB.*voltag.*<\([^:]*\):.*/I:\1:E/p;t
      s/^slot *\([0-9]*\):.*voltag.*<\([^:]*\):.*/S:\1:E/p;t
      s/^drive *\([0-9]*\):.*voltag.*<\([^:]*\):.*/D:\1:E/p' | \
      awk -F: '{ for (n = 1; n <= NF; n++) printf "%s%s",
      (n == ($1 == "D" ? 4 : 2)) ? ($n == "" ? 0 : $n + 1) : $n,
      (n == NF) ? "\n" : ":" }'
  else
    if [ -f "${FAKE_BARCODES}" ]; then
      grep -v -e "^#" -e "^$" < ${FAKE_BARCODES} | \
        awk -F: '{ print "S:" $1 (match($2, "^ *$") ? ":E" : ":F:" $2) }'
    else
      echo "${PROGNAME}: Barcode file ${FAKE_BARCODES} is missing"
      exit 1
    fi
  fi
  ;;
loaded)
  # If a tape is loaded, but the source slot is unknown (for example,
  # after library reboot), try to report the first free slot
  FREE=`${CHIO} -f ${CHANGER} status slot | \
    sed -ne '/FULL/d;s/^slot *\([0-9]*\):.*/\1/p' | \
    awk 'BEGIN { n = 0 } { n = $1 + 1; exit } END { print n }'`
  ${CHIO} -f ${CHANGER} status -S drive | \
    sed -ne 's/^drive *'${DRIVE}':.*FULL.*source.*<[^0-9]*\([0-9]*\)>.*/\1/p' \
    | awk 'BEGIN { n = 0 } { n = ($1 == "") ? '${FREE}' : $1 + 1 } \
    END { print n }'
  ;;
slots)
  ${CHIO} -f ${CHANGER} status | grep -c "^slot "
  ;;
*)
  usage
  ;;
esac