Files
dsnap-sync/bin/tape-admin
Ralf Zerres 31a6d467ef tape-admin: new functionality, version bump
* get_mediapool_name(): extract mediapool for given volume_name
* ltfs_reformat(): wipe given volume_name and remaster for LTFS
* media_change(): update lastwrite date for new volume_name
* mtx_unload(): write only once to ERRFILE
* parse_params(): update for given new functionality, reorder
* prepare options for remote calls (ssh)
* typo updates

Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
2018-10-03 17:00:39 +02:00

2237 lines
63 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.9"
# global variables
color=0
date_cmd="date -u +%Y%m%d%H%M%S" # use universial time
date_iso=""
date_seconds=""
default_changer_device="/dev/changer"
dryrun=0
ltfs_mountpoint="/media/tape"
ltfs_devname="/dev/sg9"
mediapools_json="/etc/dsnap-sync/MediaPools.json"
mediapool_name=""
timezone="Europe/Berlin"
use_mtx=0
verbose=0
volume_name=""
volume_name_active=""
volume_name_next=""
# helper programms
ATTR=attr
JQ=jq
LTFS=ltfs
LTFSCK=ltfsck
MKLTFS=mkltfs
MTX=mtx
SSH=ssh
# ascii color
BLUE=
GREEN=
MAGENTA=
RED=
YELLOW=
NO_COLOR=
###
# functions
###
check_prerequisites () {
# requested binaries:
which ${ATTR} >/dev/null 2>&1 || { printf "'%s' is not installed.\n" ${ATTR} && exit 1; }
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 findmnt >/dev/null 2>&1 || { printf "'findmnt' is not installed." && 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; }
which perl >/dev/null 2>&1 || { printf "'%s' is not installed.\n" perl && exit 1; }
which awk >/dev/null 2>&1 || { printf "'%s' is not installed.\n" awk && exit 1; }
which sed >/dev/null 2>&1 || { printf "'%s' is not installed.\n" sed && 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
}
date_iso_to_seconds () {
local date_string=$1
year=$(echo $date_string | cut -c 1-4)
month=$(echo $date_string | cut -c 5-6)
day=$(echo $date_string | cut -c 7-8)
hour=$(echo $date_string | cut -c 9-10)
minute=$(echo $date_string | cut -c 11-12)
second=$(echo $date_string | cut -c 13-14)
test ${month#0} -gt 12 && printf "${RED}Error:${NO_COLOR} Invalid argument month: '%s'\n" $month && return 1
test ${day#0} -gt 31 && printf "${RED}Error:${NO_COLOR} Invalid argument day: '%s'\n" $day && return 1
test ${hour#0} -gt 23 && printf "${RED}Error:${NO_COLOR} Invalid argument hour: '%s'\n" $hour && return 1
test ${minute#0} -gt 59 && printf "${RED}Error:${NO_COLOR} Invalid argument minute: '%s'\n" $minute && return 1
test ${second#0} -gt 50 && printf "${RED}Error:${NO_COLOR} Invalid argument second: '%s'\n" $second && return 1
date_iso=$(printf "%s-%s-%s %s:%s:%s\n" \
${year} ${month} ${day} ${hour} ${minute} ${second})
date_seconds=$(date --date="$date_iso" +"%s")
}
date_seconds_to_iso () {
local date_string=$1
date_iso=$(date --date="@$date_string" +"%Y-%m-%d %H:%M:%S")
}
date_seconds_to_string () {
local date_string=$1
date_iso=$(date --date="@$date_string" +"%Y%m%d%H%M%S")
}
date_string_to_iso () {
local date_string=$1
year=$(echo $date_string | cut -c 1-4)
month=$(echo $date_string | cut -c 5-6)
day=$(echo $date_string | cut -c 7-8)
hour=$(echo $date_string | cut -c 9-10)
minute=$(echo $date_string | cut -c 11-12)
second=$(echo $date_string | cut -c 13-14)
test ${month#0} -gt 12 && printf "${RED}Error:${NO_COLOR} Invalid argument month: '%s'\n" $month && return 1
test ${day#0} -gt 31 && printf "${RED}Error:${NO_COLOR} Invalid argument day: '%s'\n" $day && return 1
test ${hour#0} -gt 23 && printf "${RED}Error:${NO_COLOR} Invalid argument hour: '%s'\n" $hour && return 1
test ${minute#0} -gt 59 && printf "${RED}Error:${NO_COLOR} Invalid argument minute: '%s'\n" $minute && return 1
test ${second#0} -gt 59 && printf "${RED}Error:${NO_COLOR} Invalid argument second: '%s'\n" $second && return 1
date_iso=$(printf "%s-%s-%s %s:%s:%s\n" \
${year} ${month} ${day} ${hour} ${minute} ${second})
}
die () {
error "$@"
exit 1
}
error () {
printf "\n==> ERROR: %s\n" "$@"
notify_error 'Error' 'Check journal for more information.'
} >&2
get_lastwrite () {
local mediapools_json=${mediapools:-$mediapools_json}
local mediapool_name=${1}
#local volume_name=${2}
if [ $verbose -ge 1 ]; then
printf "${BLUE}get_lastwrite...${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
if [ ${#volume_name} -ge 1 ]; then
# select last write date for given volume
cmd="jq --monochrome-output --ascii-output ' .MediaPool[] \
| select(.Name == \"${mediapool_name}\") \
| .Member[] \
| select(.VolumeName == \"${volume_name}\") \
| .LastWrite ' \
${mediapools_json}"
else
# select volume with latest write date
cmd="jq --monochrome-output --ascii-output ' .MediaPool[] \
| select(.Name == \"${mediapool_name}\") \
| .Member \
| map({ \"VolumeName\" : .VolumeName, \"LastWrite\" : ( .LastWrite | scan(\"[0-9]{14}\")) }) \
| sort_by(.LastWrite) \
| .[-1] \
| .VolumeName ' \
${mediapools_json}"
volume_name=$(eval $cmd)
volume_name=$(echo $volume_name | sed -e 's/"//g')
cmd="jq --monochrome-output --ascii-output ' .MediaPool[] \
| select(.Name == \"${mediapool_name}\") \
| .Member \
| map({ \"VolumeName\" : .VolumeName, \"LastWrite\" : ( .LastWrite | scan(\"[0-9]{14}\")) }) \
| sort_by(.LastWrite) \
| .[-1] \
| .LastWrite ' \
${mediapools_json}"
fi
volume_lastwrite=$(eval $cmd)
if [ ${#volume_lastwrite} -gt 1 ]; then
volume_lastwrite=$(echo $volume_lastwrite | sed -e 's/"//g')
if [ $verbose -ge 3 ]; then
printf "${MAGENTA}volume_lastwrite for volume ${GREEN}'%s'${MAGENTA} in media-pool ${GREEN}'%s'${MAGENTA} is: ${NO_COLOR}%s${NO_COLOR}\n" \
"$volume_name" "$mediapool_name" "$volume_lastwrite"
fi
else
return 1
fi
}
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)
volume_mediapolicy=$(echo $volume_mediapolicy | sed -e 's/"//g')
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_mediapool_name () {
local mediapools_json=${mediapools:-$mediapools_json}
local volume_name=${1}
if [ $verbose -ge 1 ]; then
printf "${BLUE}get_mediapool_name...${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[] \
| .Name as \$MediaPoolName \
| .Member[].VolumeName \
| select(. == \"${volume_name}\") \
| \$MediaPoolName'
${mediapools_json}"
mediapool_name=$(eval $cmd)
mediapool_name=$(echo $mediapool_name | sed -e 's/"//g')
if [ $verbose -ge 3 ]; then
printf "${MAGENTA}Media-pool name for VolumeName %s: ${GREEN}'%s'${NO_COLOR}\n" \
"$volume_name" "$mediapool_name"
fi
}
get_mediapool_names () {
local mediapools_json=${mediapools:-$mediapools_json}
#local mediapool_name=${1}
if [ $verbose -ge 1 ]; then
printf "${BLUE}get_mediapools...${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[] \
| .Name ' \
${mediapools_json}"
mediapool_names=$(eval $cmd)
mediapool_names=$(echo $mediapool_names | sed -e 's/"//g')
if [ $verbose -ge 3 ]; then
printf "${MAGENTA}Media-pool names: ${GREEN}'%s'${NO_COLOR}\n" \
"$mediapool_names"
fi
}
get_mediapool_retensiondays () {
local mediapools_json=${mediapools:-$mediapools_json}
local mediapool_name=${1}
if [ $verbose -ge 1 ]; then
printf "${BLUE}get_mediapool_retensiondays...${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
if [ ${#mediapool_name} -ge 1 ]; then
# select default retension days for given pool
cmd="jq --monochrome-output --ascii-output ' .MediaPool[] \
| select(.Name == \"${mediapool_name}\") \
| .DefaultRetensionDays ' \
${mediapools_json}"
fi
mediapool_defaultretensiondays=$(eval $cmd)
mediapool_defaultretensiondays=$(echo $mediapool_defaultretensiondays | sed -e 's/"//g')
if [ ${#mediapool_defaultretensiondays} -ge 1 ]; then
if [ $verbose -ge 3 ]; then
printf "${MAGENTA}default retension days for media-pool ${GREEN}'%s'${MAGENTA} is: ${NO_COLOR}%s${NO_COLOR}\n" \
"$mediapool_name" "$mediapool_defaultretensiondays"
fi
else
if [ $verbose -ge 1 ]; then
printf "${RED}Error: ${MAGENTA}No retension days for media-pool ${GREEN}'%s'${NO_COLOR}\n" \
"$mediapool_name" "$mediapool_defaultretensiondays"
fi
return 1
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 --ascii-output '.MediaPool[] \
| select(.Name == \"${mediapool_name}\") \
| .Member[].VolumeName' \
${mediapools_json}"
poolmember=$(eval $cmd)
poolmember=$(echo $poolmember | sed -e 's/"//g')
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:-"none"}
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 \
| map({ \"VolumeName\" : .VolumeName, \"LastWrite\" : ( .LastWrite | scan(\"[0-9]{14}\")) }) \
| sort_by(.LastWrite) \
| .[0] \
| .VolumeName ' \
${mediapools_json}"
volume_poolmember=$(eval $cmd)
volume_poolmember=$(echo $volume_poolmember | sed -e 's/"//g')
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} -ge 1 ]; then
if [ $member = $volume_name ]; then
volume_index=$(($i+1))
fi
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 [ ${#volume_retensiondate} -gt 1 ]; then
volume_retensiondate=$(echo $volume_retensiondate | sed -e 's/"//g')
if [ $verbose -ge 3 ]; then
printf "${MAGENTA}RetensionDate in UTC 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
else
return 1
fi
}
ltfs_get_attribute () {
local ltfs_devname=${ltfs_devname}
local ltfs_attribute_name=${1:-volumeName}
if [ $verbose -ge 1 ]; then
printf "${BLUE}ltfs_get_attribute...${NO_COLOR}\n"
fi
make_err_file
# Reference: https://www.ibm.com/support/knowledgecenter/en/STQNYL_2.4.0/ltfs_hints_virtual_extended_attribute.html
# eg: ltfs.indexCreator
# ltfs.volumeBlocksize
# ltfs.volumeName, ltfs.volumeSerial, ltfs.volumeUUID
ltfs_attribute_value=$(${ATTR} -g ltfs.$ltfs_attribute_name $ltfs_mountpoint 2>${ERRFILE})
rm -f ${ERRFILE}
if [ $? -eq 0 ]; then
ltfs_attribute_value=$(echo ${ltfs_attribute_value##*:} | sed -e 's/\r\n//g')
if [ $verbose -ge 2 ]; then
printf "${MAGENTA}LTFS attribute ${GREEN}'%s'${MAGENTA} is: ${GREEN}'%s'${NO_COLOR}\n" \
"$ltfs_attribute_name" "$ltfs_attribute_value"
fi
return 0
else
if [ $verbose -ge 2 ]; then
printf "${MAGENTA}LTFS attribute ${GREEN}'%s'${MAGENTA} isn't valid${NO_COLOR}\n" \
"$ltfs_attribute_name"
fi
fi
return $?
}
ltfs_format () {
local ltfs_devname=${ltfs_devname}
local volume_name=${1}
local volume_serial=${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=${volume_serial} 2>${ERRFILE}
RET=$?
rm -f ${ERRFILE}
return $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 is 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
make_err_file
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 1>/dev/null 2>${ERRFILE}
else
${LTFS} -o devname=$ltfs_devname -o verbose=0 $ltfs_mountpoint 1>/dev/null 2>${ERRFILE}
fi
if [ $? -eq 0 ]; then
return 0
else
# format tape if needed
if [ -z $volume_name_active ]; then
slot_source="0"
mtx_getlabel $slot_source
fi
need_format=$(grep "medium is not partitioned" ${ERRFILE})
rm -f ${ERRFILE}
if [ ${#need_format} -ge 1 ]; then
tape_id=$(echo $volume_name_active | sed -e 's/\([[:alpha:]]*-\)//g')
# TODO: tape_id needs to be exactly 6 character long
volume_serial=$(printf "%0.s0" $(seq 1 $((6 - ${#tape_id}))))
volume_serial="${volume_serial}${tape_id}"
ltfs_format ${volume_name_active} ${volume_serial}
ltfs_mount
fi
return $?
fi
else
if [ $verbose -ge 2 ]; then
printf "${MAGENTA}LTFS tape ${GREEN}'%s'${MAGENTA} is mounted to ${GREEN}'%s'${NO_COLOR}\n" \
"$ltfs_devname" "$ltfs_mountpoint"
fi
fi
}
ltfs_reformat () {
local volume_name=${1}
if [ $verbose -ge 1 ]; then
printf "${BLUE}ltfs_reformat...${NO_COLOR}\n"
fi
ltfs_is_mounted
if [ $? -eq 0 ]; then
if [ $verbose -ge 2 ]; then
printf "${MAGENTA}LTFS tape ${GREEN}'%s'${MAGENTA} is mounted to ${GREEN}'%s'${NO_COLOR}\n" \
"$ltfs_devname" "$ltfs_mountpoint"
fi
slot_source="0"
mtx_getlabel $slot_source
if [ ${#volume_name} -gt 0 ] && [ $volume_name_active != $volume_name ]; then
get_mediapool_name $volume_name
if [ $? -eq 0 ]; then
ltfs_umount
if [ $? -eq 0 ]; then
mtx_unload
if [ $? -eq 0 ]; then
mount_tape "${mediapool_name}" "${volume_name}"
fi
fi
fi
fi
else
if [ ! -d $ltfs_mountpoint ]; then
mkdir -p $ltfs_mountpoint
fi
make_err_file
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 1>/dev/null 2>${ERRFILE}
else
${LTFS} -o devname=$ltfs_devname -o verbose=0 $ltfs_mountpoint 1>/dev/null 2>${ERRFILE}
fi
if [ $? -ge 0 ]; then
if [ -z $volume_name_active ]; then
slot_source="0"
mtx_getlabel $slot_source
fi
need_format=$(grep "medium is not partitioned" ${ERRFILE})
rm -f ${ERRFILE}
fi
fi
if [ ${#volume_name} -eq 0 ] || [ $volume_name_active = $volume_name ]; then
tape_id=$(echo $volume_name_active | sed -e 's/\([[:alpha:]]*-\)//g')
# tape_id needs to be exactly 6 character long
volume_serial=$(printf "%0.s0" $(seq 1 $((6 - ${#tape_id}))))
volume_serial="${volume_serial}${tape_id}"
if [ ${#need_format} -ge 1 ]; then
ltfs_format ${volume_name_active} ${volume_serial}
else
ltfs_wipe
ltfs_format ${volume_name_active} ${volume_serial}
fi
ltfs_mount
fi
return $?
}
ltfs_umount () {
if [ $verbose -ge 1 ]; then
printf "${BLUE}ltfs_umount...${NO_COLOR}\n"
fi
ltfs_is_mounted
if [ $? -eq 0 ]; then
if [ $verbose -ge 3 ]; then
printf "${MAGENTA}unmounting LTFS tape ${GREEN}'%s'${NO_COLOR}.\n" \
"$ltfs_mountpoint"
fi
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_mountpoint"
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
}
media_change () {
local mediapools_json=${mediapools:-$mediapools_json}
local mediapool_name=${1}
local volume_name=${2}
if [ $verbose -ge 1 ]; then
printf "${BLUE}media_change...${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
if [ ${#mediapool_name } -ge 1 ]; then
if [ ${#volume_name } -eq 0 ]; then
get_lastwrite "${mediapool_name}"
fi
add_retensiondays_to_retensiondate "${mediapool_name}" "${volume_name}" "${retension_days}"
if test $? -eq 0; then
if [ $verbose -ge 1 ]; then
date_string_to_iso "${volume_retensiondate}"
if [ $? -eq 0 ]; then
volume_date=$(date --date="${date_iso}Z")
printf "${MAGENTA}Updated RetensionDate date for ${GREEN}'%s'${MAGENTA} to: ${NO_COLOR}'%s'.\n" \
"${volume_name}" "${volume_date}"
fi
fi
fi
get_poolmember_next "${mediapool_name}"
if test $? -eq 0; then
if [ $verbose -ge 1 ]; then
printf "${MAGENTA}MediaPool: ${GREEN}%s${NO_COLOR} (next tape: ${GREEN}%s${NO_COLOR})\n" \
"${mediapool_name}" "${volume_name_next}"
fi
update_lastwrite "${mediapool_name}" "${volume_name_next}" "${date_string}"
fi
fi
}
mount_tape () {
local mediapool_name=${1}
local volume_name=${2}
if [ $verbose -ge 1 ]; then
printf "${BLUE}mount_tape...${NO_COLOR}\n"
fi
if [ $verbose -ge 2 ]; then
if [ ${#volume_name } -ge 1 ]; then
printf "${MAGENTA}MediaPool: ${GREEN}%s${NO_COLOR} (mounting tape: ${GREEN}%s${NO_COLOR})\n" \
"${mediapool_name}" "${volume_name}"
else
printf "${MAGENTA}MediaPool: ${GREEN}%s${NO_COLOR} (mounting next tape)\n" \
"${mediapool_name}"
fi
fi
ltfs_is_mounted
if test $? -eq 0; then
if [ $verbose -ge 1 ]; then
printf "${MAGENTA}LTFS Tape is mounted.${NO_COLOR}\n"
fi
# get date from last written tape in given mediapool
if [ "${#volume_name}" -eq 0 ]; then
get_lastwrite ${mediapool_name}
if [ $? != 0 ]; then
exit 1
fi
fi
# get label from tape in given drive slot
slot_source="0"
mtx_getlabel $slot_source
if [ $? -eq 0 ]; then
if [ $verbose -ge 2 ]; then
printf "${MAGENTA}Tape in drive: ${GREEN}%s${NO_COLOR}\n" \
"${volume_name_active}"
fi
if [ "${#volume_name_active}" -ge 1 ] && [ "${volume_name_active}" != "${volume_name}" ]; then
if [ $verbose -ge 1 ]; then
printf "${MAGENTA}Re-Mounting Tape: ${GREEN}%s${NO_COLOR}\n" \
"${volume_name}"
fi
ltfs_umount
if [ $? -eq 0 ]; then
mtx_unload
if [ $? -eq 0 ]; then
mount_tape "${mediapool_name}" "${volume_name}"
return 0
else
return $?
fi
else
return $?
fi
fi
fi
# check if given tape is poolmember of selected pool
get_poolmember ${mediapool_name} ${volume_name}
if [ $? -eq 0 ]; then
# volume_name is member of given mediapool
get_mediapolicy ${mediapool_name} ${volume_name_active}
if [ ${#volume_mediapolicy} -gt 0 ]; then
if [ ${volume_mediapolicy} = "append" ] ; then
if [ $verbose -ge 1 ]; then
printf "${MAGENTA}Valid tape mediapolicy: ${GREEN}%s${NO_COLOR}\n" \
"${volume_mediapolicy}"
fi
volume_retensiondate="20180101000000"
get_retensiondate ${mediapool_name} ${volume_name}
if [ $? -eq 0 ]; then
date_now=$($date_cmd)
compare_date $date_now $volume_retensiondate
if [ $? -eq 2 ]; then
# retensiondate has exposed: use it
return 0
fi
if [ $? -eq 1 ]; then
# respect active retensiondate: unload given tape
ltfs_umount
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
if [ $? -eq 0 ]; then
return 0
fi
fi
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
if [ $? -eq 0 ]; then
return 0
fi
fi
if [ $? -eq 1 ]; then
# respect active retensiondate: unload given tape
ltfs_umount
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
if [ $? -eq 0 ]; then
return 0
fi
fi
fi
fi
fi
else
# volume_name is not member of given pool
ltfs_umount
if [ $? -eq 0 ]; then
mtx_unload
if [ $? -eq 0 ]; then
if [ "${#volume_name}" -eq 0 ]; then
get_lastwrite ${mediapool_name}
fi
get_poolmember_next ${mediapool_name} ${volume_name}
if [ $? -eq 0 ]; then
mtx load ${volume_name_next}
ltfs_mount
fi
else
return $?
fi
else
return $?
fi
fi
else
if [ $verbose -ge 1 ]; then
printf "${MAGENTA}No LTFS Tape mounted...${NO_COLOR}\n"
fi
if [ "${#volume_name}" -eq 0 ]; then
# set volume_name and last write date
#get_lastwrite ${mediapool_name}
get_poolmember_next ${mediapool_name}
if [ "${#volume_name_next}" -ge 1 ]; then
volume_name=${volume_name_next}
fi
fi
# check label of tape in given drive slot (slot=0)
slot_source="0"
mtx_getlabel $slot_source
if [ $? -eq 0 ] && [ "${#volume_name_active}" -gt 1 ]; then
if [ $verbose -ge 1 ]; then
printf "${MAGENTA}Tape in drive: ${GREEN}%s${NO_COLOR}\n" \
"${volume_name_active}"
fi
if [ "${#volume_name_active}" -gt 1 ] && [ "${volume_name_active}" != "${volume_name}" ]; then
mtx_unload
if [ $? -eq 0 ]; then
mount_tape "${mediapool_name}" "${volume_name}"
return 0
else
return $?
fi
fi
else
# mount new tape
get_slot ${mediapool_name} ${volume_name}
mtx_load ${volume_slot}
fi
# volume_name is member of given mediapool
get_mediapolicy ${mediapool_name} ${volume_name}
if [ ${#volume_mediapolicy} -gt 0 ]; then
if [ ${volume_mediapolicy} = "append" ] ; then
if [ $verbose -ge 1 ]; then
printf "${MAGENTA}Valid tape mediapolicy: ${GREEN}%s${NO_COLOR}\n" \
"${volume_mediapolicy}"
fi
volume_retensiondate="20180101000000"
get_retensiondate ${mediapool_name} ${volume_name}
date_now=$($date_cmd)
compare_date $date_now $volume_retensiondate
RET=$?
if [ $RET -eq 2 ]; then
if [ $verbose -ge 1 ]; then
printf "${MAGENTA}RetensionDate has exposed, mount the tape\n"
fi
ltfs_mount
return 0
elif [ $RET -eq 1 ]; then
if [ $verbose -ge 1 ]; then
printf "${MAGENTA}Tape is bocked via RetensionDate.\n"
fi
ltfs_mount
return 0
fi
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_mount
if [ $? -eq 0 ]; then
ltfs_wipe
if [ $? -eq 0 ]; then
return 0
fi
fi
fi
if [ $? -eq 1 ]; then
# respect active retensiondate: unload given tape
mtx_unload
if [ $? -eq 0 ]; then
# use next volume_name from pool
get_poolmember_next ${mediapool_name} ${volume_name}
mount_tape "${mediapool_name}" "${volume_name}"
return 0
else
return $?
fi
fi
fi
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=$?
rm -f ${ERRFILE}
}
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}mtx_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_active=$(perl -ne '
/Data Transfer Element (\d+):Full \(Storage Element (\d+) Loaded\)(:VolumeTag =\s*(.+))?/ && print "$4\n";' ${TMPFILE})
volume_name_active=$(echo $volume_name_active | sed -e 's/ *$//g')
;;
[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=$?
rm -f ${ERRFILE}
}
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=$?
rm -f ${ERRFILE}
}
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
${MTX} -f $changer_device unload $slot_source $drive 2>${ERRFILE}
for i in 1 2 3 4 5 ; do
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${NO_COLOR}\n" \
"${MTX}" "${changer_device}" "${slot_source}" "${drive}"
fi
fi
return $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
;;
--add-retensiondays)
shift 1
pool_params=${*}
pool_params="${pool_params%% -*}"
params=$*
set -- $pool_params
count=$#
test $count -lt 2 && usage
mediapool_name="$1"
volume_name="$2"
test $count -ge 3 && retension_days="$3"
set -- $params
shift $count
cmd=add-retensiondays
;;
--dry-run|--dryrun)
dryrun=1
shift 1
;;
--get-lastwrite)
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-lastwrite
;;
--get-mediapool-name)
volume_name=$2
shift 2
cmd=get-mediapool-name
;;
--get-mediapools)
shift 1
cmd=get-mediapools
;;
--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-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-retensiondate)
shift 1
pool_params=${*}
pool_params="${pool_params%% -*}"
params=$*
set -- $pool_params
count=$#
test $count -ge 1 && mediapool_name="$1"
set -- $params
shift $count
cmd=get-retensiondays
;;
--get-retensiondays)
shift 1
pool_params=${*}
pool_params="${pool_params%% -*}"
params=$*
set -- $pool_params
count=$#
test $count -lt 1 && usage
mediapool_name="$1"
set -- $params
shift $count
cmd=get-mediapool-retensiondays
;;
--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
;;
--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-reformat)
volume_name="$2"
shift 2
cmd=ltfs-reformat
;;
--ltfs-umount)
shift 1
cmd=ltfs-umount
;;
--media-change)
shift 1
tape_params=${*}
tape_params="${tape_params%% -*}"
params=$*
set -- $tape_params
count=$#
test $count -lt 1 && usage
mediapool_name="$1"
test $count -ge 2 && volume_name="$2"
set -- $params
shift $count
cmd=media-change
;;
--mount)
shift 1
tape_params=${*}
tape_params="${tape_params%% -*}"
params=$*
set -- $tape_params
count=$#
test $count -lt 1 && usage
mediapool_name="$1"
test $count -ge 2 && volume_name="$2"
set -- $params
shift $count
cmd=mount
;;
--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
;;
-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-getattribute)
shift 1
ltfs_params=${*}
ltfs_params="${ltfs_params%% -*}"
params=$*
set -- $ltfs_params
count=$#
test $count -eq 0 && ltfs_attribute_name="volumeName"
shift $count
cmd=ltfs-getattribute
;;
--update-lastwrite)
shift 1
pool_params=${*}
pool_params="${pool_params%% -*}"
params=$*
set -- $pool_params
count=$#
test $count -lt 2 && usage
mediapool_name="$1"
volume_name="$2"
test $count -ge 3 && date_string="$3"
set -- $params
shift $count
cmd=update-lastwrite
;;
--update-retensiondate)
shift 1
pool_params=${*}
pool_params="${pool_params%% -*}"
params=$*
set -- $pool_params
count=$#
test $count -lt 2 && usage
mediapool_name="$1"
volume_name="$2"
test $count -ge 3 && date_string="$3"
set -- $params
shift $count
cmd=update-retensiondate
;;
--update-retensiondays)
shift 1
pool_params=${*}
pool_params="${pool_params%% -*}"
params=$*
set -- $pool_params
count=$#
test $count -lt 2 && usage
mediapool_name="$1"
mediapool_defaultretensiondays="$2"
set -- $params
shift $count
cmd=update-mediapool-retensiondays
;;
-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 $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 [ ${#remote} -ge 1 ]; then
printf "Remote Settings\n"
printf " remote host: '%s'\n" "$remote"
printf " ssh options: '%s'\n" "$ssh"
fi
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
}
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
}
update_lastwrite () {
local mediapools_json=${mediapools:-$mediapools_json}
local mediapool_name=${1:-0}
local volume_name=${2}
local date_string=${3:-now}
if [ $verbose -ge 1 ]; then
printf "${BLUE}update_lastwrite...${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
else
json_path=${mediapools_json%/*}
json_file=${mediapools_json##*/}
cp "$mediapools_json" $XDG_RUNTIME_DIR/$json_file
fi
if [ ${#volume_name} -ge 1 ]; then
# update last write date for given volume (date field in utc)
if [ "${date_string}" = "now" ]; then
volume_lastwrite=$($date_cmd)
else
volume_lastwrite=$date_string
fi
cmd="jq --monochrome-output --ascii-output '.MediaPool[] \
| select(.Name == \"$mediapool_name\") \
| .Member \
| map(.VolumeName == \"$volume_name\") | index(true)' \
${mediapools_json}"
tape_index=$(eval $cmd)
if [ $? -eq 0 ]; then
cmd="jq --monochrome-output --ascii-output '(.MediaPool[] \
| select(.Name == \"$mediapool_name\") \
| .Member[$tape_index] \
| .LastWrite) \
|= \"$volume_lastwrite\" ' \
${mediapools_json} > $XDG_RUNTIME_DIR/$json_file"
$(eval $cmd)
if [ $? -eq 0 ]; then
cp "$XDG_RUNTIME_DIR/$json_file" "$mediapools_json"
else
return 1
fi
else
return 1
fi
if [ $verbose -ge 3 ]; then
printf "${MAGENTA}LastWrite in UTC for for volume ${GREEN}'%s'${MAGENTA} is: ${NO_COLOR}%s${NO_COLOR}\n" \
"$volume_name" "$volume_lastwrite"
fi
fi
}
update_mediapool_retensiondays () {
local mediapools_json=${mediapools:-$mediapools_json}
local mediapool_name=${1:-0}
local mediapool_defaultretensiondays=${2}
if [ $verbose -ge 1 ]; then
printf "${BLUE}update_mediapool_retensiondays..${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
else
json_path=${mediapools_json%/*}
json_file=${mediapools_json##*/}
cp "$mediapools_json" $XDG_RUNTIME_DIR/$json_file
fi
if [ ${mediapool_defaultretensiondays} -ge 0 ]; then
cmd="jq --monochrome-output --ascii-output '(.MediaPool[] \
| select(.Name == \"$mediapool_name\") \
| .DefaultRetensionDays) \
|= \"${mediapool_defaultretensiondays}\" ' \
${mediapools_json} > $XDG_RUNTIME_DIR/$json_file"
$(eval $cmd)
if [ $? -eq 0 ]; then
cp "$XDG_RUNTIME_DIR/$json_file" "$mediapools_json"
else
return 1
fi
else
return 1
fi
}
add_retensiondays_to_retensiondate () {
local mediapools_json=${mediapools:-$mediapools_json}
local mediapool_name=${1:-0}
local volume_name=${2}
local retension_days=${3:-0}
if [ $verbose -ge 1 ]; then
printf "${BLUE}add_retensiondays_to_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
else
json_path=${mediapools_json%/*}
json_file=${mediapools_json##*/}
cp "$mediapools_json" $XDG_RUNTIME_DIR/$json_file
fi
if [ $retension_days -eq 0 ]; then
# get default retensiondays form given mediapool
get_mediapool_retensiondays $mediapool_name
if [ $? -eq 0 ]; then
retension_days=${mediapool_defaultretensiondays}
fi
fi
if [ $verbose -ge 3 ]; then
printf "${MAGENTA}New RetensionDays: ${NO_COLOR}'%s'.\n" \
"${retension_days}"
fi
# get active retensiondate for given tape
get_retensiondate $mediapool_name $volume_name
if [ $? -eq 0 ]; then
# calculate retensiondate in seconds
date_iso_to_seconds "${volume_retensiondate}"
if [ $? -eq 0 ]; then
volume_retensiondate_seconds=$(($date_seconds + $retension_days * 24 * 60 * 60))
if [ $verbose -ge 3 ]; then
printf "${MAGENTA}New RetensionDate in seconds is: ${NO_COLOR}'%s'.\n" \
"${volume_retensiondate_seconds}"
fi
# format to iso
date_seconds_to_string "${volume_retensiondate_seconds}"
if [ $? -eq 0 ]; then
volume_retensiondate=${date_iso}
if [ $verbose -ge 2 ]; then
date_string_tz=$(echo $volume_retensiondate | cut -c 1-8)
volume_date=$(date --date="${date_string_tz}Z")
printf "${MAGENTA}RetensionDate is: ${NO_COLOR}'%s'.\n" \
"${volume_date}"
fi
fi
fi
fi
# update retensionsdate
if [ ${#volume_name} -ge 1 ]; then
cmd="jq --monochrome-output --ascii-output '.MediaPool[] \
| select(.Name == \"$mediapool_name\") \
| .Member \
| map(.VolumeName == \"$volume_name\") | index(true)' \
${mediapools_json}"
tape_index=$(eval $cmd)
if [ $? -eq 0 ]; then
cmd="jq --monochrome-output --ascii-output '(.MediaPool[] \
| select(.Name == \"$mediapool_name\") \
| .Member[$tape_index] \
| .RetensionDate) \
|= \"$volume_retensiondate\" ' \
${mediapools_json} > $XDG_RUNTIME_DIR/$json_file"
$(eval $cmd)
if [ $? -eq 0 ]; then
cp "$XDG_RUNTIME_DIR/$json_file" "$mediapools_json"
else
return 1
fi
else
return 1
fi
if [ $verbose -ge 3 ]; then
printf "${MAGENTA}New RetensionDate in UTC for volume ${GREEN}'%s'${MAGENTA} is: ${NO_COLOR}%s${NO_COLOR}\n" \
"$volume_name" "$volume_retensiondate"
fi
fi
}
update_retensiondate () {
local mediapools_json=${mediapools:-$mediapools_json}
local mediapool_name=${1:-0}
local volume_name=${2}
local date_string=${3:-now}
if [ $verbose -ge 1 ]; then
printf "${BLUE}update_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
else
json_path=${mediapools_json%/*}
json_file=${mediapools_json##*/}
cp "$mediapools_json" $XDG_RUNTIME_DIR/$json_file
fi
if [ ${#volume_name} -ge 1 ]; then
# update retension date for given volume (date field in utc)
if [ "${date_string}" = "now" ]; then
volume_retensiondate=$($date_cmd)
else
volume_retensiondate=$date_string
fi
cmd="jq --monochrome-output --ascii-output '.MediaPool[] \
| select(.Name == \"$mediapool_name\") \
| .Member \
| map(.VolumeName == \"$volume_name\") | index(true)' \
${mediapools_json}"
tape_index=$(eval $cmd)
if [ $? -eq 0 ]; then
cmd="jq --monochrome-output --ascii-output '(.MediaPool[] \
| select(.Name == \"$mediapool_name\") \
| .Member[$tape_index] \
| .RetensionDate) \
|= \"$volume_retensiondate\" ' \
${mediapools_json} > $XDG_RUNTIME_DIR/$json_file"
$(eval $cmd)
if [ $? -eq 0 ]; then
cp "$XDG_RUNTIME_DIR/$json_file" "$mediapools_json"
else
return 1
fi
else
return 1
fi
if [ $verbose -ge 3 ]; then
printf "${MAGENTA}RetensionDate for for volume ${GREEN}'%s'${MAGENTA} is: ${NO_COLOR}%s${NO_COLOR}\n" \
"$volume_name" "$volume_retensiondate"
fi
fi
}
usage () {
cat <<EOF
$progname $version
Usage: $progname [options]
Options:
--add-retensiondays add RetensionDays to LastWrite attribute for given TapeName in Pool (JSON-File)
(input attribute: <mediapool> <volume_name> <days>)
--color Enable colored output messages
--get-lastwrite extract LastWrite attribute from given Pool member (JSON-File)
(input attribute: <mediapool> [<volume_name>])
without given volume_name, extract Pool member that was last witten to
--get-mediapool-name extract MediaPool name for given VolumeName from configuration (JSON-File)
(input attribute: <volume_name>)
--get-mediapools extract MediaPool names from configuration (JSON-File)
--get-mediapolicy extract MediaPolicy attribute from Pool configuration (JSON-File)
(input attribute: <mediapool> [<volume_name>])
--get-poolmember extract VolumeName attribute from Pool configuration (JSON-File)
(input attribute: <mediapool> [<volume_name>])
--get-poolmember-next extract VolumeName for next usable Pool member (JSON-File)
(input attribute: <mediapool> [volume_name])
--get-retensiondate extract RetensionDate attribute from Pool configuration (JSON-File)
(input attribute: <mediapool> [<volume_name>])
--get-retensiondays extract DefaultRetensionDays attribute from Pool configuration (JSON-File)
(input attribute: <mediapool>)
--get-slot extract Slot attribute from Pool configuration (JSON-File)
(input attribute: <mediapool> [<volume_name>])
--ltfs-getattribute report ltfs extended attribute for mounted tape
(input attribute: <ltfs_attribute>)
--ltfs-format format tape
(input attribute: <volume_name> <tape_id>)
--ltfs-is-mounted returns true, if ltfs tape is already mounted
--ltfs-mount mount a ltfs tape (returns true on success)
--ltfs-reformat reformat mounted tape
(input attribute: [<volume_name>])
--ltfs-umount unmount a ltfs tape (returns true on success)
--media-change Update RetensionDate for last written Pool-Tape and und exchange tapes in slots
(input attribute: <mediapool> [<volume_name>])
--mtx-exchange exchange tapes in slots
(input attribute: <slot_source> <slot_target>)
--mtx-getlabel report tape label/barcode for tape in drive
(input attribute: <slot_source>)
--mtx-inventory run inquriy task for tape-changer
--mtx-load load a tape to target slot
(input attribute: <slot_source>)
--mtx-status list changer slot status
--mtx-transfer transfer a tape to target slot
(input attribute: <slot_source> <slot_target>)
--mtx-unload unload a tape
(input attribute: slot_source drive)
--mount make tape accessible for OS
(input attribute: <mediapool_name> [<volume_name>])
-r, --remote <host> 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.
--update-lastwrite update LastWrite attribute for given TapeName in Pool (JSON-File)
(input attribute: <mediapool> <volume_name> [<YYYYMMDDHHMMSS> )
--update-retensiondate update RetensionDate attribute for given TapeName in Pool (JSON-File)
(input attribute: <mediapool> <volume_name> [<YYYYMMDDHHMMSS> )
--update-retensiondays update DefaultRetensionDays attribute for given Pool (JSON-File)
(input attribute: <mediapool>)
--use-mtx use mtx loader handling. If not specified, all mtx commands will use
default device ($default_changer_device)
-v, --verbose Be verbose on what's going on (min: --verbose=1, max: --verbose=3)
--version show program version
EOF
--dry-run perform a trial run where no changes are made.
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
add-retensiondays)
add_retensiondays_to_retensiondate "${mediapool_name}" "${volume_name}" "${retension_days}"
if test $? -eq 0; then
date_string_to_iso "${volume_retensiondate}"
if [ $? -eq 0 ]; then
volume_date=$(date --date="${date_iso}Z")
printf "${MAGENTA}New RetensionDate date for ${GREEN}'%s'${MAGENTA} is: ${NO_COLOR}'%s'.\n" \
"${volume_name}" "${volume_date}"
fi
else
if [ $verbose -ge 1 ]; then
printf "${RED}Error: ${MAGENTA}No RetensionDate for ${GREEN}'%s'${MAGENTA} in media-pool ${GREEN}%s${NO_COLOR}\n" \
"${mediapool_name}" "${volume_name}"
fi
fi
return $?
;;
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
return $?
;;
get-mediapool-name)
get_mediapool_name "${volume_name}"
if test $? -eq 0; then
if [ $verbose -ge 1 ]; then
printf "${MAGENTA}MediaPool name: ${GREEN}'%s'${NO_COLOR}\n" \
"${mediapool_name}"
fi
fi
return $?
;;
get-mediapools)
get_mediapool_names
if test $? -eq 0; then
if [ $verbose -ge 1 ]; then
printf "${MAGENTA}MediaPool names: ${GREEN}'%s'${NO_COLOR}\n" \
"${mediapool_names}"
fi
fi
return $?
;;
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
return $?
;;
get-lastwrite)
valid_member=0
get_lastwrite "${mediapool_name}" "${volume_name}"
if test $? -eq 0; then
if [ $verbose -ge 1 ]; then
date_string_to_iso ${volume_lastwrite}
if [ $? -eq 0 ]; then
volume_date=$(date --date="${date_iso}Z")
printf "${MAGENTA}Last write date for Volume ${GREEN}'%s'${MAGENTA} from media-pool ${GREEN}'%s'${MAGENTA} is : ${NO_COLOR}'%s'.\n" \
"${volume_name}" "${mediapool_name}" "${volume_date}"
fi
fi
else
return 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
return $?
;;
get-retensiondate)
get_retensiondate "${mediapool_name}" "${volume_name}"
if test $? -eq 0; then
date_string_to_iso "${volume_retensiondate}"
volume_date=$(date --date="${date_iso}Z")
if [ $verbose -ge 1 ]; then
printf "${MAGENTA}RetensionDate for ${GREEN}'%s'${MAGENTA} is:${NO_COLOR} %s.\n" \
"${volume_name}" "${volume_date}"
fi
else
return 1
fi
;;
get-mediapool-retensiondays)
get_mediapool_retensiondays "${mediapool_name}"
if test $? -eq 0; then
if [ $verbose -ge 1 ]; then
printf "${MAGENTA}Default retension days for tapes in mediapool ${GREEN}'%s'${MAGENTA} is:${NO_COLOR} %s.\n" \
"${mediapool_name}" "${mediapool_defaultretensiondays}"
fi
else
return 1
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
return $?
;;
ltfs-format)
ltfs_format "${volume_name}" "${tape_id}"
;;
ltfs-getattribute)
ltfs_is_mounted
if test $? -eq 0; then
ltfs_get_attribute "${ltfs_attribute_name}"
if test $? -eq 0; then
if [ $verbose -ge 1 ]; then
printf "${MAGENTA}LTFS attribute ${GREEN}'%s'${MAGENTA} is: ${GREEN}'%s'${NO_COLOR}\n" \
"${ltfs_attribute_name}" "${ltfs_attribute_value}"
fi
fi
fi
return $?
;;
ltfs-is-mounted)
ltfs_is_mounted
if test $? -eq 0; then
if [ $verbose -ge 1 ]; then
printf "${MAGENTA}LTFS Tape is-mounted: ${GREEN}true${NO_COLOR}\n"
fi
fi
return $?
;;
ltfs-mount)
ltfs_mount
if test $? -eq 0; then
if [ $verbose -ge 1 ]; then
printf "${MAGENTA}LTFS Tape mount: ${GREEN}true${NO_COLOR}\n"
fi
fi
return $?
;;
ltfs-reformat)
ltfs_reformat "${volume_name}"
if test $? -eq 0; then
if [ $verbose -ge 1 ]; then
printf "${MAGENTA}LTFS Tape reformat: ${GREEN}%s${NO_COLOR}\n" \
"${volume_name}"
fi
fi
return $?
;;
ltfs-umount)
ltfs_umount
if test $? -eq 0; then
if [ $verbose -ge 1 ]; then
printf "${MAGENTA}LTFS Tape unmount: ${GREEN}true${NO_COLOR}\n"
fi
fi
return $?
;;
media-change)
media_change $mediapool_name $volume_name
if [ $verbose -ge 1 ]; then
if [ ${#volume_name} -ge 1 ]; then
printf "${MAGENTA}Media changed in pool: ${GREEN}%s${NO_COLOR} (Volume-Name: ${GREEN}%s${NO_COLOR})\n" \
"${mediapool_name}" "${volume_name}"
else
printf "${MAGENTA}Media changed in pool: ${GREEN}%s${NO_COLOR}\n" \
"${mediapool_name}"
fi
fi
return $?
;;
mount)
mount_tape $mediapool_name $volume_name
return $?
;;
mtx-exchange)
mtx_exchange "${slot_source}" "${slot_target}"
return $?
;;
mtx-getlabel)
mtx_getlabel $slot_source
if [ $verbose -ge 1 ]; then
printf "${MAGENTA}Tape Label: ${GREEN}%s${NO_COLOR}\n" \
"${volume_name_active}"
fi
return $?
;;
mtx-inventory)
mtx_inventory
return $?
;;
mtx-load)
mtx_load "${slot_source}" "${drive}"
return $?
;;
mtx-transfer)
mtx_transfer "${slot_source}" "${slot_target}"
return $?
;;
mtx-unload)
mtx_unload "${slot_source}" "${drive}"
return $?
;;
mount)
mount_tape "${mediapool_name}" "${volume_name}"
if test $? -eq 0; then
if [ $verbose -ge 1 ]; then
printf "${MAGENTA}Tape ${GREEN}'%s'${MAGENTA} for ${GREEN}'%s'${MAGENTA} mounted${NO_COLOR}\n" \
"${volume_name}" "${mediapool_name}"
fi
fi
return $?
;;
update-lastwrite)
update_lastwrite "${mediapool_name}" "${volume_name}" "${date_string}"
if test $? -eq 0; then
if [ $verbose -ge 1 ]; then
date_string_to_iso "${volume_lastwrite}"
if [ $? -eq 0 ]; then
volume_date=$(date --date="${date_iso}Z")
printf "${MAGENTA}LastWrite date for ${GREEN}'%s'${MAGENTA} is: ${NO_COLOR}'%s'.\n" \
"${volume_name}" "${volume_date}"
fi
fi
fi
return $?
;;
update-mediapool-retensiondays)
update_mediapool_retensiondays "${mediapool_name}" "${mediapool_defaultretensiondays}"
if test $? -eq 0; then
if [ $verbose -ge 1 ]; then
printf "${MAGENTA}New DefaultRetensionDays attribute for ${GREEN}'%s'${MAGENTA} is: ${NO_COLOR}'%s'.\n" \
"${mediapool_name}" "${mediapool_defaultretensiondays}"
fi
fi
return $?
;;
update-retensiondate)
update_retensiondate "${mediapool_name}" "${volume_name}" "${date_string}"
if test $? -eq 0; then
if [ $verbose -ge 1 ]; then
date_string_to_iso "${volume_retensiondate}"
if [ $? -eq 0 ]; then
volume_date=$(date --date="${date_iso}Z")
printf "${MAGENTA}RetensionDate date for ${GREEN}'%s'${MAGENTA} is: ${NO_COLOR}'%s'.\n" \
"${volume_name}" "${volume_date}"
fi
fi
fi
return $?
;;
esac