Files
dsnap-sync/bin/tape-admin

1077 lines
26 KiB
Bash
Executable File

#! /bin/dash
# tape_admin
# https://github.com/rzerres/dsnap-sync
# Copyright (C) 2017, 2018 Ralf Zerres
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
# 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.
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# -------------------------------------------------------------------------
# Helper routines for tape handling
progname="${0##*/}"
version="0.0.1"
# global variables
color=0
date_cmd="date -u +%Y%M%d%H%M%S"
default_changer_device="/dev/changer"
dryrun=0
ltfs_mountpoint="/media/tape"
ltfs_devname="/dev/sg9"
mediapools_json="/etc/dsnap-sync/MediaPools.json"
mediapool_name=""
use_mtx=0
verbose=0
volume_name=""
#
MTX=mtx
JQ=jq
LTFS=ltfs
LTFSCK=ltfsck
MKLTFS=mkltfs
# ascii color
BLUE=
GREEN=
MAGENTA=
RED=
YELLOW=
NO_COLOR=
###
# functions
###
check_prerequisites () {
# requested binaries:
which ${MTX} >/dev/null 2>&1 || { printf "'%s' is not installed.\n" ${MTX} && exit 1; }
which ${LTFS} >/dev/null 2>&1 || { printf "'%s' is not installed.\n" ${LTFS} && exit 1; }
which ${MKLTFS} >/dev/null 2>&1 || { printf "'%s' is not installed.\n" ${MKLTFS} && exit 1; }
which ${JQ} >/dev/null 2>&1 || { printf "'%s' is not installed.\n" ${JQ} && exit 1; }
}
compare_date () {
local date1=${1}
local date2=${2}
if [ $date1 -eq $date2 ]; then
if [ $verbose -ge 2 ]; then
printf "${MAGENTA}date1 ${GREEN}'%s'${MAGENTA} is equal to date2 ${GREEN}'%s'${NO_COLOR}\n" \
"$date1" "$date2"
fi
return 0
elif [ $date1 -lt $date2 ]; then
if [ $verbose -ge 2 ]; then
printf "${MAGENTA}date1 ${GREEN}'%s'${MAGENTA} is lower then date2 ${GREEN}'%s'${NO_COLOR}\n" \
"$date1" "$date2"
fi
return 1
elif [ $date1 -gt $date2 ]; then
if [ $verbose -ge 2 ]; then
printf "${MAGENTA}date1 ${GREEN}'%s'${MAGENTA} is greater then date2 ${GREEN}'%s'${NO_COLOR}\n" \
"$date1" "$date2"
fi
return 2
fi
}
die () {
error "$@"
exit 1
}
error () {
printf "\n==> ERROR: %s\n" "$@"
notify_error 'Error' 'Check journal for more information.'
} >&2
get_mediapolicy () {
local mediapools_json=${mediapools:-$mediapools_json}
local mediapool_name=${1}
local volume_name=${2}
if [ $verbose -ge 1 ]; then
printf "${BLUE}get_mediapolicy...${NO_COLOR}\n"
fi
if test ! -r ${mediapools_json}; then
if [ $verbose -ge 1 ]; then
printf "${RED}Error:${MAGENTA} media-pool file ${GREEN}'%s'${MAGENTA} can't be opend!${NO_COLOR}}\n" \
"$mediapools_json"
fi
exit 1
fi
cmd="jq --monochrome-output --ascii-output ' .MediaPool[] \
| select(.Name == \"${mediapool_name}\") \
| .Member[] \
| select(.VolumeName == \"${volume_name}\") \
| .MediaPolicy ' \
${mediapools_json}"
volume_mediapolicy=$(eval $cmd)
if [ $verbose -ge 3 ]; then
printf "${MAGENTA}MediaPolicy for volume_name ${GREEN}'%s'${MAGENTA} in media-pool ${GREEN}'%s'${MAGENTA}: ${NO_COLOR}%s${NO_COLOR}\n" \
"$volume_name" "$mediapool_name" "$volume_mediapolicy"
fi
}
get_poolmember () {
# return: 0-> volume_name match; 1 -> volume_name does not match
local mediapools_json=${mediapools:-$mediapools_json}
local mediapool_name=${1}
local volume_name=${2:-any}
if [ $verbose -ge 1 ]; then
printf "${BLUE}get_poolmember...${NO_COLOR}\n"
fi
if test ! -r ${mediapools_json}; then
if [ $verbose -ge 1 ]; then
printf "${RED}Error:${MAGENTA} media-pool file ${GREEN}'%s'${MAGENTA} can't be opend!${NO_COLOR}}\n" \
"$mediapools_json"
fi
exit 1
fi
#cmd="jq --monochrome-output --join-output --ascii-output '.MediaPool[] \
cmd="jq --monochrome-output --ascii-output '.MediaPool[] \
| select(.Name == \"${mediapool_name}\") \
| .Member[].VolumeName' \
${mediapools_json}"
poolmember=$(eval $cmd)
if [ $verbose -ge 2 ]; then
printf "${MAGENTA}poolmembers for media-pool ${GREEN}'%s'${MAGENTA} are:\n${NO_COLOR}%s${NO_COLOR}\n" \
"$mediapool_name" "$poolmember"
fi
for i in $poolmember ; do
if test "$i" = "\"${volume_name}\""; then
if [ $verbose -ge 3 ]; then
printf "${MAGENTA}volume_name ${GREEN}'%s'${MAGENTA} is member of media-pool ${GREEN}'%s'${NO_COLOR}}\n" \
"$i" "$mediapool_name"
fi
return 0
break
fi
done
return 1
}
get_poolmember_next () {
local mediapools_json=${mediapools:-$mediapools_json}
local mediapool_name=${1}
local volume_name=${2}
if [ $verbose -ge 1 ]; then
printf "${BLUE}get_poolmember_next...${NO_COLOR}\n"
fi
if test ! -r ${mediapools_json}; then
if [ $verbose -ge 1 ]; then
printf "${RED}Error:${MAGENTA} media-pool file ${GREEN}'%s'${MAGENTA} can't be opend!${NO_COLOR}}\n" \
"$mediapools_json"
fi
exit 1
fi
cmd="jq --monochrome-output --ascii-output ' .MediaPool[] \
| select(.Name == \"${mediapool_name}\") \
| .Member[] \
| .VolumeName ' \
${mediapools_json}"
volume_poolmember=$(eval $cmd)
i=0
volume_index=-1
for member in $volume_poolmember; do
if [ $i -eq 0 ]; then
volume_name_next=$(echo $member | sed -e 's/"//g')
fi
if [ $i -eq $volume_index ]; then
if [ ${#member} -ge 1 ]; then
volume_name_next=$(echo $member | sed -e 's/"//g')
break;
fi
fi
if [ $member = \"$volume_name\" ]; then
volume_index=$(($i+1))
fi
i=$(($i + 1))
done
if [ $verbose -ge 3 ]; then
printf "${MAGENTA}poolmember_next for media-pool ${GREEN}'%s'${MAGENTA} is: ${NO_COLOR}%s${NO_COLOR}\n" \
"$mediapool_name" "$volume_name_next"
fi
}
get_slot () {
local mediapools_json=${mediapools:-$mediapools_json}
local mediapool_name=${1}
local volume_name=${2}
if [ $verbose -ge 1 ]; then
printf "${BLUE}get_slot...${NO_COLOR}\n"
fi
if test ! -r ${mediapools_json}; then
if [ $verbose -ge 1 ]; then
printf "${RED}Error:${MAGENTA} media-pool file ${GREEN}'%s'${MAGENTA} can't be opend!${NO_COLOR}}\n" \
"$mediapools_json"
fi
exit 1
fi
cmd="jq --monochrome-output --ascii-output ' .MediaPool[] \
| select(.Name == \"${mediapool_name}\") \
| .Member[] \
| select(.VolumeName == \"${volume_name}\") \
| .Slot ' \
${mediapools_json}"
volume_slot=$(eval $cmd)
volume_slot=$(echo $volume_slot | sed -e 's/"//g')
if [ $verbose -ge 3 ]; then
printf "${MAGENTA}Slot for volume_name ${GREEN}'%s'${MAGENTA} from media-pool ${GREEN}'%s'${MAGENTA}: ${NO_COLOR}%s${NO_COLOR}\n" \
"$volume_name" "$mediapool_name" "$volume_slot"
fi
}
get_retensiondate () {
local mediapools_json=${mediapools:-$mediapools_json}
local mediapool_name=${1}
local volume_name=${2}
if [ $verbose -ge 1 ]; then
printf "${BLUE}get_retensiondate...${NO_COLOR}\n"
fi
if test ! -r ${mediapools_json}; then
if [ $verbose -ge 1 ]; then
printf "${RED}Error:${MAGENTA} media-pool file ${GREEN}'%s'${MAGENTA} can't be opend!${NO_COLOR}}\n" \
"$mediapools_json"
fi
exit 1
fi
cmd="jq --monochrome-output --ascii-output ' .MediaPool[] \
| select(.Name == \"${mediapool_name}\") \
| .Member[] \
| select(.VolumeName == \"${volume_name}\") \
| .RetensionDate ' \
${mediapools_json}"
volume_retensiondate=$(eval $cmd)
if [ $verbose -ge 3 ]; then
printf "${MAGENTA}RetensionDate for volume_name ${GREEN}'%s'${MAGENTA} in media-pool ${GREEN}'%s'${MAGENTA}: ${NO_COLOR}%s${NO_COLOR}\n" \
"$volume_name" "$mediapool_name" "$volume_retensiondate"
fi
}
ltfs_format () {
local ltfs_devname=${ltfs_devname}
local volume_name=${1}
local tape_id=${2}
if [ $verbose -ge 1 ]; then
printf "${BLUE}ltfs_format...${NO_COLOR}\n"
fi
make_err_file
${MKLTFS} --device=$ltfs_devname --volume-name=${volume_name} --tape-serial=${tape_id} 2>${ERRFILE}
RET=$?
}
ltfs_is_mounted () {
local ltfs_devname
if [ $verbose -ge 1 ]; then
printf "${BLUE}ltfs_is_mounted...${NO_COLOR}\n"
fi
ltfs_devname=$(findmnt -n -T $ltfs_mountpoint -o source | awk -F ':' '{print $2}')
if [ ${#ltfs_devname} -gt 1 ]; then
if [ $verbose -ge 2 ]; then
printf "${MAGENTA}LTFS tape mounted via ${GREEN}'%s'${MAGENTA} at ${GREEN}'%s'${NO_COLOR}\n" \
"$ltfs_devname" "$ltfs_mountpoint"
fi
return 0
else
return 1
fi
}
ltfs_mount () {
if [ $verbose -ge 1 ]; then
printf "${BLUE}ltfs_mount...${NO_COLOR}\n"
fi
ltfs_is_mounted
if [ $? -eq 1 ]; then
if [ ! -d $ltfs_mountpoint ]; then
mkdir -p $ltfs_mountpoint
fi
if [ $verbose -ge 2 ]; then
printf "${MAGENTA}LTFS mounting tape ${GREEN}'%s'${MAGENTA} to ${GREEN}'%s'${NO_COLOR}\n" \
"$ltfs_devname" "$ltfs_mountpoint"
${LTFS} -o devname=$ltfs_devname -o verbose=$verbose $ltfs_mountpoint
else
${LTFS} -o devname=$ltfs_devname -o verbose=0 $ltfs_mountpoint
fi
if [ $? -eq 0 ]; then
return 0
else
return $?
fi
fi
}
ltfs_umount () {
if [ $verbose -ge 1 ]; then
printf "${BLUE}ltfs_unmount...${NO_COLOR}\n"
fi
ltfs_is_mounted
if [ $? -eq 0 ]; then
ret=$(umount $ltfs_mountpoint 2>/dev/null)
if [ $? -eq 0 ]; then
if [ $verbose -ge 2 ]; then
printf "${MAGENTA}LTFS tape ${GREEN}'%s'${MAGENTA} unmounted.${NO_COLOR}\n" \
"$ltfs_devname"
fi
return 0
else
return 1
fi
fi
}
ltfs_wipe () {
local ltfs_devname=${ltfs_devname}
local volume_name=${1}
local tape_id=${2}
if [ $verbose -ge 1 ]; then
printf "${BLUE}ltfs_wipe...${NO_COLOR}\n"
fi
rm -rf $ltfs_mountpoint/*
}
make_err_file() {
ERRFILE=`mktemp $XDG_RUNTIME_DIR/mtx.err.XXXXXXXXXX`
if test x${ERRFILE} = x; then
ERRFILE="$XDG_RUNTIME_DIR/mtx.err.$$"
if test -f ${ERRFILE}; then
echo "ERROR: Temp file security problem on: ${ERRFILE}"
exit 1
fi
fi
}
make_temp_file() {
TMPFILE=`mktemp $XDG_RUNTIME_DIR/mtx.XXXXXXXXXX`
if test x${TMPFILE} = x; then
TMPFILE="$XDG_RUNTIME_DIR/mtx.$$"
if test -f ${TMPFILE}; then
echo "ERROR: Temp file security problem on: ${TMPFILE}"
exit 1
fi
fi
}
mtx_exchange () {
local changer_device=${changer_device:-$default_changer_device}
#export changer_device
local slot_source=${1}
local slot_target=${2}
if [ $verbose -ge 1 ]; then
printf "${BLUE}mtx_exchange...${NO_COLOR}\n"
fi
make_err_file
${MTX} -f $changer_device exchange $slot_source $slot_target 2>${ERRFILE}
RET=$?
}
mtx_getlabel () {
local changer_device=${changer_device:-$default_changer_device}
local slot_source=${slot_source:-99}
export slot_source
if [ $verbose -ge 1 ]; then
printf "${BLUE}Tape get-label...${NO_COLOR}\n"
fi
make_temp_file
${MTX} -f $changer_device status >${TMPFILE}
RET=$?
case ${slot_source} in
0)
if [ $verbose -ge 2 ]; then
printf "Calling: ${GREEN}%s${MAGENTA} -f ${GREEN}%s${MAGENTA} %s${NO_COLOR}\n" \
"${MTX}" "${changer_device}" "${slot_source}"
fi
volume_name=$(perl -ne '
/Data Transfer Element (\d+):Full \(Storage Element (\d+) Loaded\)(:VolumeTag =\s*(.+))?/ && print "$4\n";' ${TMPFILE})
#/Data Transfer Element (\d+):Full \(Storage Element (\d+) Loaded\)(:VolumeTag =\s*(.+))?/ && print "Drive:$1:Slot:$2:$4\n";' ${TMPFILE}
;;
[0-9][0-8] | [0-9])
if [ $verbose -ge 2 ]; then
printf "Calling: ${GREEN}%s${MAGENTA} -f ${GREEN}%s${MAGENTA} %s${NO_COLOR}\n" \
"${MTX}" "${changer_device}" "${slot_source}"
fi
perl -ne '
/Storage Element ($ENV{"slot_source"}):Full( :VolumeTag=(.+))?/ && print "$3\n";' ${TMPFILE}
;;
*)
if [ $verbose -ge 2 ]; then
printf "Calling: ${GREEN}%s${MAGENTA} -f ${GREEN}%s${MAGENTA} -- to list all slots${NO_COLOR}\n" \
"${MTX}" "${changer_device}"
fi
# can be converted to awk+sed+cut, see below
perl -ne '
/Data Transfer Element (\d+):Empty/ && print "Drive:$1:empty\n";
/Data Transfer Element (\d+):Full \(Storage Element (\d+) Loaded\)(:VolumeTag =\s*(.+))?/ && print "Drive:$1:Slot:$2:$4\n";
/Storage Element (\d+):Empty/ && print "Slot:$1:empty\n";
/Storage Element (\d+):Full( :VolumeTag=(.+))?/ && print "Slot:$1:$3\n";
/Storage Element (\d+) IMPORT.EXPORT:Empty/ && print "Import:$1:empty\n";
/Storage Element (\d+) IMPORT.EXPORT:Full( :VolumeTag=(.+))?/ && print "Import:$1:$3\n";' ${TMPFILE}
;;
esac
# If perl isn't installed, you can use by those commands
#cat ${TMPFILE} | grep "Data Transfer Element" | awk "{print \"D:\"\$4 \$7 \$9 \$10}" | sed "s/=/:/" | sed "s/Full/F:/" | sed "s/Empty/E/"
#cat ${TMPFILE} | grep -v "Data Transfer Element" | grep "Storage Element" | grep -v "IMPORT/EXPORT" | awk "{print \"S:\"\$3 \$4 \$5}" | sed "s/IMPORT\/EXPORT//" | sed "s/Full *:VolumeTag=/F:/" | sed "s/Empty/E/"
#cat ${TMPFILE} | grep -v "Data Transfer Element" | grep "Storage Element" | grep "IMPORT/EXPORT" | awk "{print \"I:\"\$3 \$4 \$5}" | sed "s/IMPORT\/EXPORT//" | sed "s/Full *:VolumeTag=/F:/" | sed "s/Empty/E/"
rm -f ${TMPFILE} >/dev/null 2>&1
return $RET
}
mtx_inventory () {
local changer_device=${changer_device:-$default_changer_device}
if [ $verbose -ge 1 ]; then
printf "${BLUE}mtx_inventory...${NO_COLOR}\n"
fi
${MTX} -f $changer_device inventory
RET=$?
}
mtx_load () {
local changer_device=${changer_device:-$default_changer_device}
local slot_source=${1}
local drive=${2}
if [ $verbose -ge 1 ]; then
printf "${BLUE}mtx_load...${NO_COLOR}\n"
fi
make_err_file
${MTX} -f $changer_device load $slot_source $drive 2>${ERRFILE}
RET=$?
}
mtx_status () {
local changer_device=${changer_device:-$default_changer_device}
if [ $verbose -ge 1 ]; then
printf "${BLUE}Tape status...${NO_COLOR}\n"
fi
${MTX} -f $changer_device status
}
mtx_transfer () {
local changer_device=${changer_device:-$default_changer_device}
#export changer_device
local slot_source=${1##slot_source=}
local slot_target=${2##slot_target=}
if [ $verbose -ge 1 ]; then
printf "${BLUE}Tape transfer...${NO_COLOR}\n"
fi
make_err_file
${MTX} -f $changer_device transfer $slot_source $slot_target 2>${ERRFILE}
RET=$?
}
mtx_unload () {
local changer_device=${changer_device:-$default_changer_device}
local slot_source=${1}
local drive=${2}
if [ $verbose -ge 1 ]; then
printf "${BLUE}Tape unload...${NO_COLOR}\n"
fi
make_err_file
for i in 1 2 3 4 5 ; do
${MTX} -f $changer_device unload $slot_source $drive 2>${ERRFILE}
RET=$?
if test $RET -eq 0; then
break
fi
grep "Error Code=" ${ERRFILE} 2>/dev/null 1>/dev/null
if test $? -ne 0 ; then
break
fi
sleep $i
done
cat ${ERRFILE}
rm -f ${ERRFILE} >/dev/null 2>&1
if test $RET -ne 0 ; then
if [ $verbose -ge 2 ]; then
printf "${RED}Fail: %s -f %s unload slot=%s drive=%s${NOCOLOR}\n" \
"${MTX}" "${changer_device}" "${slot_source}" "${drive}"
fi
fi
exit $RET
}
parse_params () {
#printf "\n${BLUE}Parse arguments...${NO_COLOR}\n"
# Evaluate given call parameters
while [ $# -gt 0 ]; do
key="$1"
case $key in
-h | --help | \-\? | --usage)
# Call usage() function.
usage
;;
--dry-run|--dryrun)
dryrun=1
shift 1
;;
--get-retensiondate)
shift 1
pool_params=${*}
pool_params="${pool_params%% -*}"
params=$*
set -- $pool_params
count=$#
test $count -ge 1 && mediapool_name="$1"
test $count -ge 2 && volume_name="$2"
set -- $params
shift $count
cmd=get-retensiondate
;;
--get-poolmember)
shift 1
pool_params=${*}
pool_params="${pool_params%% -*}"
params=$*
set -- $pool_params
count=$#
test $count -ge 1 && mediapool_name="$1"
test $count -ge 2 && volume_name="$2"
set -- $params
shift $count
cmd=get-poolmember
;;
--get-poolmember-next)
shift 1
pool_params=${*}
pool_params="${pool_params%% -*}"
params=$*
set -- $pool_params
count=$#
test $count -ge 1 && mediapool_name="$1"
test $count -ge 2 && volume_name="$2"
set -- $params
shift $count
cmd=get-poolmember-next
;;
--get-slot)
shift 1
pool_params=${*}
pool_params="${pool_params%% -*}"
params=$*
set -- $pool_params
count=$#
test $count -ge 1 && mediapool_name="$1"
test $count -ge 2 && volume_name="$2"
set -- $params
shift $count
cmd=get-slot
;;
--mount-tape)
shift 1
tape_params=${*}
tape_params="${tape_params%% -*}"
params=$*
set -- $tape_params
count=$#
test $count -lt 2 && usage
test $count -ge 1 && mediapool_name="$1"
test $count -ge 2 && volume_name="$2"
set -- $params
shift $count
cmd=mount-tape
;;
-p|--port)
port=$2
shift 2
;;
--remote)
remote=$2
shift 2
;;
--use-mtx)
use_mtx=1
shift 1
;;
--ltfs-devname)
ltfs_devname="$2"
shift 2
;;
--ltfs-format)
shift 1
ltfs_params=${*}
ltfs_params="${ltfs_params%% -*}"
params=$*
set -- $ltfs_params
count=$#
test $count -ge 1 && volume_name="$1"
test $count -ge 2 && tape_id="$2"
set -- $params
shift $count
cmd=ltfs-format
;;
--ltfs-is-mounted)
shift 1
cmd=ltfs-is-mounted
;;
--ltfs-mount)
shift 1
cmd=ltfs-mount
;;
--ltfs-mountpoint)
ltfs_mountpoint="$2"
shift 2
;;
--ltfs-umount)
shift 1
cmd=ltfs-umount
;;
--mtx-exchange)
shift
slots=${*}
slots="${slots%% -*}"
params=$*
set -- $slots
count=$#
test $count -lt 2 && usage
slot_source="$1"
slot_target="$2"
set -- $params
shift $count
cmd=mtx-exchange
;;
--mtx-getlabel)
shift
slots=${*}
slots="${slots%% -*}"
params=$*
set -- $slots
count=$#
test $count -eq 1 && slot_source="$1"
set -- $params
shift $count
slot_getlabel=1
cmd=mtx-getlabel
;;
--mtx-inventory|mtx-inquiry)
shift
cmd=mtx-inventory
;;
--mtx-load)
shift
slots=${*}
slots="${slots%% -*}"
params=$*
set -- $slots
count=$#
test $count -lt 1 && usage
slot_source="$1"
test $count -eq 2 && drive="$2"
set -- $params
shift $count
cmd=mtx-load
;;
--mtx-transfer)
shift
slots=${*}
slots="${slots%% -*}"
params=$*
set -- $slots
count=$#
test $count -lt 2 && usage
slot_source="${1}"
slot_target="${2}"
set -- $params
shift $count
cmd=mtx-transfer
;;
--mtx-unload)
shift
slots=${*}
slots="${slots%% -*}"
params=$*
set -- $slots
count=$#
test $count -lt 1 && usage
slot_source="$1"
test $count -eq 2 && drive="$2"
set -- $params
shift $count
cmd=mtx-unload
;;
-v|--verbose)
verbose=$(($verbose + 1))
shift 1
;;
--version)
printf "%s v%s\n" "$progname" "$version"
exit 0
;;
--ltfs-devname=*)
ltfs_devname="${1#*=}"
shift
;;
--ltfs-mountpoint=*)
ltfs_mountpoint="${1#*=}"
shift
;;
--color=*)
case ${1#*=} in
yes | Yes | True | true)
color=1;
;;
*)
;;
esac
shift
;;
--remote=*)
remote=${1#*=}
shift
;;
--v=* | --verbose=*)
verbose=${1#*=}
shift
;;
--) # End of all options
shift
break
;;
-*)
printf "WARN: Unknown option (ignored): $1" >&2
die "Unknown option"
;;
*)
printf "Unknown option: %s\nRun '%s -h' for valid options.\n" $key $progname
die "Unknown option"
;;
esac
done
if [ -z "$remote" ]; then
ssh=""
else
ssh="ssh -T $remote"
if [ ! -z "$port" ]; then
ssh="$ssh -p $port"
fi
fi
if [ "$color" ]; then
# ascii color
BLUE='\033[0;34m'
GREEN='\033[0;32m'
MAGENTA='\033[0;35m'
RED='\033[0;31m'
YELLOW='\033[0;33m'
NO_COLOR='\033[0m'
fi
if [ $verbose -ge 2 ]; then
printf "${BLUE}$progname (runtime arguments)...${NO_COLOR}\n"
printf "LTFS Settings\n"
printf " ltfs device-name: '%s'\n" "$ltfs_devname"
printf " ltfs mount-point: '%s'\n" "$ltfs_mountpoint"
printf "MTX Settings\n"
printf " def changer-name: '%s'\n" "$default_changer_device"
if [ $verbose -ge 1 ]; then tape_options="verbose_level=$verbose"; fi
if [ $dryrun -eq 1 ]; then tape_options="${tape_options} dry-run=true"; fi
if [ $color -eq 1 ]; then tape_options="${tape_options} color=true"; fi
if [ $use_mtx -eq 1 ]; then tape_options="${tape_options} use-mtx=true"; fi
printf "Options: '%s'\n\n" "${tape_options}"
fi
}
mount_tape () {
local mediapool_name=${1}
local volume_name=${2}
if [ $verbose -ge 1 ]; then
printf "${BLUE}mount_tape...${NO_COLOR}\n"
fi
ltfs_is_mounted
if test $? -eq 0; then
if [ $verbose -ge 1 ]; then
printf "${MAGENTA}LTFS Tape is-mounted: ${GREEN}%d${NO_COLOR}\n" \
"$?"
fi
# get label from tape in given drive slot
mtx_getlabel 0
if [ $verbose -ge 1 ]; then
printf "${MAGENTA}Tape Label: ${GREEN}%s${NO_COLOR}\n" \
"${volume_name}"
fi
# check if given tape is poolmember of selected pool
get_poolmember ${mediapool_name} ${volume_name}
if [ $? -eq 0 ]; then
# volume_name match
get_mediapolicy ${mediapool_name} ${volume_name}
if [ ${#volume_mediapolicy} -gt 0 ]; then
if [ ${volume_mediapolicy} = "append" ] || [ ${volume_mediapolicy} = "overwrite" ] ; then
return 0
fi
if [ ${volume_mediapolicy} = "overwrite" ] ; then
volume_retensiondate="20180101000000"
get_retensiondate ${mediapool_name} ${volume_name}
date_now=$($date_cmd)
compare_date $date_now $volume_retensiondate
if [ $? -eq 2 ]; then
# retensiondate has exposed: wipe given tape
ltfs_wipe
return 0
fi
if [ $? -eq 1 ]; then
# respect active retensiondate: unload given tape
ltfs_unmount
mtx_unload
# use next volume_name from pool
get_poolmember_next ${mediapool_name} ${volume_name}
get_slot ${mediapool_name} ${volume_name_next}
mtx_load ${volume_slot}
ltfs_mount
return 0
fi
fi
fi
else
# volume_name does not match
ltfs_umount
mtx_unload 0
# TODO
get_poolmember
get_poolmember_next ${mediapool_name} ${volume_name}
#mtx load ${volume_name_next}
fi
else
if [ $verbose -ge 1 ]; then
printf "${MAGENTA}No LTFS Tape mounted...${NO_COLOR}\n"
fi
get_slot ${mediapool_name} ${volume_name}
mtx_load ${volume_slot}
ltfs_mount
return 0
fi
}
traperror () {
printf "Exited due to error on line %s.\n" $1
printf "exit status: %s\n" "$2"
#printf "command: %s\n" "$3"
#printf "bash line: %s\n" "$4"
#printf "function name: %s\n" "$5"
exit 1
}
trapkill () {
printf "Exited due to user intervention.\n"
#run_cleanup
exit 0
}
usage () {
cat <<EOF
$progname $version
Usage: $progname [options]
Options:
--use-mtx use mtx loader handling
--color Enable colored output messages
-r, --remote <address> Send the snapshot backup to a remote machine. The snapshot will be sent via ssh.
You should specify the remote machine's hostname or ip address. The 'root' user
must be permitted to login on the remote machine.
-p, --port <port> The remote port.
--dry-run perform a trial run where no changes are made.
-v, --verbose Be verbose on what's going on (min: --verbose=1, max: --verbose=3)
--version show program version
EOF
exit 0
}
###
# Main
###
cwd=`pwd`
# can't be ported to dash (ERR is not supported)
trap trapkill TERM INT
check_prerequisites
# validate commandline options, set resonable defaults
parse_params $@
case $cmd in
get-mediapolicy)
get_mediapolicy "${mediapool_name}" "${volume_name}"
if test $? -eq 0; then
if [ $verbose -ge 1 ]; then
printf "${MAGENTA}MediaPolicy for ${GREEN}'%s'${MAGENTA} is:${NO_COLOR} %s.\n" \
"${volume_name}" "${volume_mediapolicy}"
fi
fi
;;
get-poolmember)
valid_member=0
get_poolmember "${mediapool_name}" "${volume_name}"
if test $? -eq 0; then
if [ $verbose -ge 1 ]; then
printf "${MAGENTA}Volume-Name ${GREEN}'%s'${MAGENTA} is a valid mediapool member.${NO_COLOR}\n" \
"${volume_name}"
fi
valid_member=1
fi
;;
get-poolmember-next)
valid_member=0
get_poolmember_next "${mediapool_name}" "${volume_name}"
if test $? -eq 0; then
if [ $verbose -ge 1 ]; then
printf "${MAGENTA}Next Volume-Name from media-pool ${GREEN}'%s'${MAGENTA} is: ${NO_COLOR}'%s'\n" \
"${mediapool_name}" "${volume_name_next}"
fi
fi
;;
get-retensiondate)
get_retensiondate "${mediapool_name}" "${volume_name}"
if test $? -eq 0; then
if [ $verbose -ge 1 ]; then
printf "${MAGENTA}RetensionDate for ${GREEN}'%s'${MAGENTA} is:${NO_COLOR} %s.\n" \
"${volume_name}" "${volume_retensiondate}"
fi
fi
;;
get-slot)
get_slot "${mediapool_name}" "${volume_name}"
if test $? -eq 0; then
if [ $verbose -ge 1 ]; then
printf "${MAGENTA}Slot location for ${GREEN}'%s'${MAGENTA} is:${NO_COLOR} %s.\n" \
"${volume_name}" "${volume_slot}"
fi
fi
;;
ltfs-format)
ltfs_format "${volume_name}" "${tape_id}"
;;
ltfs-is-mounted)
ltfs_is_mounted
if test $? -eq 0; then
if [ $verbose -ge 1 ]; then
printf "${MAGENTA}LTFS Tape is-mounted: ${GREEN}%d${NO_COLOR}\n" \
"$?"
fi
fi
;;
ltfs-mount)
ltfs_mount
if test $? -eq 0; then
if [ $verbose -ge 1 ]; then
printf "${MAGENTA}LTFS Tape mount: ${GREEN}%d${NO_COLOR}\n" \
"$?"
fi
fi
;;
ltfs-umount)
ltfs_umount
if test $? -eq 0; then
if [ $verbose -ge 1 ]; then
printf "${MAGENTA}LTFS Tape unmount: ${GREEN}%d${NO_COLOR}\n" \
"$?"
fi
fi
;;
mtx-exchange)
mtx_exchange "${slot_source}" "${slot_target}"
;;
mtx-getlabel)
mtx_getlabel $slot_source
if [ $verbose -ge 1 ]; then
printf "${MAGENTA}Tape Label: ${GREEN}%s${NO_COLOR}\n" \
"${volume_name}"
fi
;;
mtx-inventory)
mtx_inventory
;;
mtx-load)
mtx_load "${slot_source}" "${drive}"
;;
mtx-transfer)
mtx_transfer "${slot_source}" "${slot_target}"
;;
mtx-unload)
mtx_unload "${slot_source}" "${drive}"
;;
mount-tape)
mount_tape "${mediapool_name}" "${volume_name}"
if test $? -eq 0; then
if [ $verbose -ge 1 ]; then
printf "${MAGENTA}mount tape ${GREEN}'%s'${MAGENTA} for ${GREEN}'%s'${MAGENTA}:${NO_COLOR} %s.\n" \
"${volume_name}" "${mediapool_name}" "$?"
fi
fi
;;
esac
# return: 0 = equal, 1 = lower, 2 = greater
#compare_date "20180824090000" "20180824090000"
exit 0