X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=changer-src%2Fchg-zd-mtx.sh;h=dd26273daf9cdc607b6a35c0d3f2eb55d62c4f4f;hb=2627875b7d18858bc1f9f7652811e4d8c15a23eb;hp=464c07519537bdc4053e16dde5b0b92f11e124f9;hpb=fb2bd066c2f8b34addafe48d62550e3033a59431;p=debian%2Famanda diff --git a/changer-src/chg-zd-mtx.sh b/changer-src/chg-zd-mtx.sh index 464c075..dd26273 100644 --- a/changer-src/chg-zd-mtx.sh +++ b/changer-src/chg-zd-mtx.sh @@ -206,6 +206,9 @@ # initial_poll_delay=NN #### initial delay after load before polling for # #### readiness # +# slotinfofile=FILENAME #### record slot information to this file, in +# #### the line-based format "SLOT LABEL\n" +# #### #### @@ -376,7 +379,7 @@ Exit() { if [ $call_type = Return ]; then return $code fi - amgetconf dbclose.$argv0:$DBGFILE > /dev/null 2>&1 + amgetconf dbclose.$myname:$DBGFILE > /dev/null 2>&1 exit $code } @@ -411,7 +414,7 @@ Run() { IsNumeric() { test -z "$1" && return 1 - x="`expr "$1" : '\([-0-9][0-9]*\)' 2>/dev/null`" + x="`expr -- "$1" : "\([-0-9][0-9]*\)" 2>/dev/null`" return `expr X"$1" != X"$x"` } @@ -431,6 +434,11 @@ get_mtx_status() { if [ $status -eq 0 ]; then mtx_status_valid=1 fi + + # shim this in here so that we get a completely new slotinfofile + # every time we run mtx status + regenerate_slotinfo_from_mtx + return $status } @@ -443,6 +451,12 @@ get_mtx_status() { get_loaded_info() { test -n "$DEBUG" && set -x get_mtx_status + if [ $mtx_status_valid -eq 0 ]; then + Exit 2 \ + `_ ''` \ + `head -1 $mtx_status` + return $? + fi set x `sed -n ' /^Data Transfer Element:Empty/ { @@ -560,6 +574,12 @@ get_slot_list() { return fi get_mtx_status + if [ $mtx_status_valid -eq 0 ]; then + Exit 2 \ + `_ ''` \ + `head -1 $mtx_status` + return $? + fi slot_list=`sed -n ' /^Data Transfer Element:Full (Storage Element \([0-9][0-9]*\) Loaded)/ { s/.*(Storage Element \([0-9][0-9]*\) Loaded).*/\1/p @@ -628,7 +648,195 @@ get_slot_list() { slot_list="$amanda_slot_list" } -DBGFILE=`amgetconf dbopen.$argv0 2>/dev/null` +### +# Read the labelfile and scan for a particular entry. +### + +read_labelfile() { + labelfile_entry_found=0 + labelfile_label= + labelfile_barcode= + + lbl_search=$1 + bc_search=$2 + + line=0 + while read lbl bc junk; do + line=`expr $line + 1` + if [ -z "$lbl" -o -z "$bc" -o -n "$junk" ]; then + Log `_ 'ERROR -> Line %s malformed: %s %s %s' "$line" "$lbl" "$bc" "$junk"` + LogAppend `_ ' -> Remove %s and run "%s %s update"' "$labelfile" "$sbindir/amtape" "$config"` + Exit 2 \ + `_ ''` \ + `_ 'Line %s malformed in %s: %s %s %s' "$line" "$labelfile" "$lbl" "$bc" "$junk"` + return $? # in case we are internal + fi + if [ $lbl = "$lbl_search" -o $bc = "$bc_search" ]; then + if [ $labelfile_entry_found -ne 0 ]; then + Log `_ 'ERROR -> Duplicate entries: %s line %s' "$labelfile" "$line"` + LogAppend `_ ' -> Remove %s and run "%s %s update"' "$labelfile" "$sbindir/amtape" "$config"` + Exit 2 \ + `_ ''` \ + `_ 'Duplicate entries: %s line %s' "$labelfile" "$line"` + return $? # in case we are internal + fi + labelfile_entry_found=1 + labelfile_label=$lbl + labelfile_barcode=$bc + fi + done +} + +lookup_label_by_barcode() { + [ -z "$1" ] && return + read_labelfile "" "$1" < $labelfile + echo "$labelfile_label" +} + +lookup_barcode_by_label() { + [ -z "$1" ] && return + read_labelfile "$1" "" < $labelfile + echo "$labelfile_barcode" +} + +remove_from_labelfile() { + labelfile=$1 + lbl_search=$2 + bc_search=$3 + + internal_remove_from_labelfile "$lbl_search" "$bc_search" < $labelfile >$labelfile.new + if [ $labelfile_entry_found -ne 0 ]; then + mv -f $labelfile.new $labelfile + LogAppend `_ 'Removed Entry "%s %s" from barcode database' "$labelfile_label" "$labelfile_barcode"` + fi +} + +internal_remove_from_labelfile() { + labelfile_entry_found=0 + labelfile_label= + labelfile_barcode= + + lbl_search=$1 + bc_search=$2 + + line=0 + while read lbl bc junk; do + line=`expr $line + 1` + if [ -z "$lbl" -o -z "$bc" -o -n "$junk" ]; then + Log `_ 'ERROR -> Line %s malformed: %s %s %s' "$line" "$lbl" "$bc" "$junk"` + LogAppend `_ ' -> Remove %s and run "%s %s update"' "$labelfile" "$sbindir/amtape" "$config"` + Exit 2 \ + `_ ''` \ + `_ 'Line %s malformed in %s: %s %s %s' "$line" "$labelfile" "$lbl" "$bc" "$junk"` + return $? # in case we are internal + fi + if [ $lbl = "$lbl_search" -o $bc = "$bc_search" ]; then + if [ $labelfile_entry_found -ne 0 ]; then + Log `_ 'ERROR -> Duplicate entries: %s line %s' "$labelfile" "$line"` + LogAppend `_ ' -> Remove %s and run "%s %s update"' "$labelfile" "$sbindir/amtape" "$config"` + Exit 2 \ + `_ ''` \ + `_ 'Duplicate entries: %s line %s' "$labelfile" "$line"` + return $? # in case we are internal + fi + labelfile_entry_found=1 + labelfile_label=$lbl + labelfile_barcode=$bc + else + echo $lbl $bc + fi + done +} + +### +# Add a new slot -> label correspondance to the slotinfo file, removing any previous +# information about that slot. +### + +record_label_in_slot() { + [ -z "$slotinfofile" ] && return + newlabel="$1" + newslot="$2" + + ( + if [ -f "$slotinfofile" ]; then + grep -v "^$newslot " < "$slotinfofile" + fi + echo "$newslot $newlabel" + ) > "$slotinfofile~" + mv "$slotinfofile~" "$slotinfofile" +} + +### +# Remove a slot from the slotinfo file +### + +remove_slot_from_slotinfo() { + [ -z "$slotinfofile" ] && return + emptyslot="$1" + + ( + if [ -f "$slotinfofile" ]; then + grep -v "^$emptyslot " < "$slotinfofile" + fi + ) > "$slotinfofile~" + mv "$slotinfofile~" "$slotinfofile" +} + +### +# Assuming get_mtx_status has been run, +# - if we have barcodes, regenerate the slotinfo file completely by +# mapping barcodes in the status into labels using the labelfile +# - otherwise, remove all empty slots from the slotinfo file +### + +regenerate_slotinfo_from_mtx() { + [ -z "$slotinfofile" ] && return + [ "$mtx_status_valid" = "1" ] || return + + if [ "$havereader" = "1" ]; then + # rewrite slotinfo entirely based on the status, since it has barcodes + :> "$slotinfofile~" + sed -n '/.*Storage Element \([0-9][0-9]*\).*VolumeTag *= *\([^ ]*\) *$/{ +s/.*Storage Element \([0-9][0-9]*\).*VolumeTag *= *\([^ ]*\) *$/\1 \2/ +p +}' < $mtx_status | while read newslot newbarcode; do + newlabel=`lookup_label_by_barcode "$newbarcode"` + if [ -n "$newlabel" ]; then + echo "$newslot $newlabel" >> "$slotinfofile~" + fi + done + mv "$slotinfofile~" "$slotinfofile" + else + # just remove empty slots from slotinfo + + # first determine which slots are not really empty, but are + # loaded into a data transfer element +loadedslots=`sed -n '/.*(Storage Element \([0-9][0-9]*\) Loaded).*/{ +s/.*(Storage Element \([0-9][0-9]*\) Loaded).*/\1/g +p +}' < $mtx_status` + + # now look for any slots which are empty, but which aren't + # in the set of loaded slots + sed -n '/.*Storage Element \([0-9][0-9]*\): *Empty.*/{ +s/.*Storage Element \([0-9][0-9]*\): *Empty.*/\1/g +p +}' < $mtx_status | while read emptyslot; do + reallyempty=1 + if [ -n "$loadedslots" ]; then + for loadedslot in $loadedslots; do + [ "$loadedslot" = "$emptyslot" ] && reallyempty=0 + done + fi + if [ "$reallyempty" = "1" ]; then + remove_slot_from_slotinfo "$emptyslot" + fi + done + fi +} + +DBGFILE=`amgetconf dbopen.$myname 2>/dev/null` if [ -z "$DBGFILE" ] then DBGFILE=/dev/null # will try this again below @@ -698,6 +906,7 @@ cleanfile=$changerfile-clean accessfile=$changerfile-access slotfile=$changerfile-slot labelfile=$changerfile-barcodes +slotinfofile="" [ ! -s $cleanfile ] && echo 0 > $cleanfile [ ! -s $accessfile ] && echo 0 > $accessfile [ ! -s $slotfile ] && echo -1 > $slotfile @@ -723,6 +932,7 @@ varlist="$varlist driveslot" varlist="$varlist poll_drive_ready" varlist="$varlist initial_poll_delay" varlist="$varlist max_drive_wait" +varlist="$varlist slotinfofile" for var in $varlist do @@ -797,7 +1007,7 @@ initial_poll_delay=${initial_poll_delay:-'0'} # default: zero zeconds max_drive_wait=${max_drive_wait:-'120'} # default: two minutes # check MT and MTX for sanity -if test "${MTX:0:1}" = "/"; then +if test "${MTX%${MTX#?}}" = "/"; then if ! test -f "${MTX}"; then Exit 2 \ `_ ''` \ @@ -831,6 +1041,8 @@ for var in $varlist; do continue # old name elif [ $var = "AUTOCLEAN" ]; then continue # old name + elif [ $var = "slotinfofile" ]; then + continue # not numeric fi eval val=\"'$'$var\" if [ -z "$val" ]; then @@ -1132,7 +1344,7 @@ loadslot() { waittime=`expr $waittime + $poll_drive_ready` done if [ $ready -eq 0 ]; then - Exit 2 "$loadslot" `_ 'Drive not ready after %s seconds, rewind said "%s"' "$max_drive_wait" "$result"` + Exit 2 "$loadslot" `_ 'Drive not ready after %s seconds: %s' "$max_drive_wait" "$amdevcheck_message"` return $? # in case we are internal fi @@ -1179,45 +1391,6 @@ info() { return $? # in case we are internal } -### -# Read the labelfile and scan for a particular entry. -### - -read_labelfile() { - labelfile_entry_found=0 - labelfile_label= - labelfile_barcode= - - lbl_search=$1 - bc_search=$2 - - line=0 - while read lbl bc junk; do - line=`expr $line + 1` - if [ -z "$lbl" -o -z "$bc" -o -n "$junk" ]; then - Log `_ 'ERROR -> Line %s malformed: %s %s %s' "$line" "$lbl" "$bc" "$junk"` - LogAppend `_ ' -> Remove %s and run "%s %s update"' "$labelfile" "$sbindir/amtape" "$config"` - Exit 2 \ - `_ ''` \ - `_ 'Line %s malformed in %s: %s %s %s' "$line" "$labelfile" "$lbl" "$bc" "$junk"` - return $? # in case we are internal - fi - if [ $lbl = "$lbl_search" -o $bc = "$bc_search" ]; then - if [ $labelfile_entry_found -ne 0 ]; then - Log `_ 'ERROR -> Duplicate entries: %s line %s' "$labelfile" "$line"` - LogAppend `_ ' -> Remove %s and run "%s %s update"' "$labelfile" "$sbindir/amtape" "$config"` - Exit 2 \ - `_ ''` \ - `_ 'Duplicate entries: %s line %s' "$labelfile" "$line"` - return $? # in case we are internal - fi - labelfile_entry_found=1 - labelfile_label=$lbl - labelfile_barcode=$bc - fi - done -} - ### # Adds the label and barcode for the currently loaded tape to the # barcode file. Return an error if the database is messed up. @@ -1230,15 +1403,16 @@ addlabel() { return $? # in case we are internal fi tapelabel=$1 - if [ $havereader -eq 0 ]; then - Exit 2 `_ ''` `_ 'Not configured with barcode reader'` - return $? # in case we are internal - fi get_loaded_info if [ $loadedslot -lt 0 ]; then Exit 1 `_ ''` `_ 'No tape currently loaded'` return $? # in case we are internal fi + record_label_in_slot "$tapelabel" "$loadedslot" + if [ $havereader -eq 0 ]; then + Exit 0 "$loadedslot" "$rawtape" # that's all we needed + return $? # in case we are internal + fi if [ -z "$loadedbarcode" ]; then Exit 1 `_ ''` `_ 'No barcode found for tape %s.' $tapelabel` return $? # in case we are internal @@ -1261,14 +1435,16 @@ addlabel() { new_val=$tapelabel fi if [ -n "$lf_val" ]; then - LogAppend `_ 'ERROR -> !!! Label database corrupted !!!'` - LogAppend `_ ' -> "%s" conflicts with new %s "%s" for %s "%s"' "$old_val" "$val_type" "$new_val" "$lf_type" "$lf_val"` - Exit 2 \ - `_ ''` \ - `_ '%s: "%s" conflicts with new %s "%s" for %s "%s"' "$tapelabel" "$old_val" "$val_type" "$new_val" "$lf_type" "$lf_val"` - return $? # in case we are internal + if [ "$val_type" = "barcode" ]; then + remove_from_labelfile $labelfile "" "$old_val" + else + remove_from_labelfile $labelfile "$old_val" "" + fi + echo "$tapelabel $loadedbarcode" >> $labelfile + LogAppend `_ ' -> appended %s entry: %s %s' "$labelfile" "$tapelabel" "$loadedbarcode"` + else + LogAppend `_ " -> already synced"` fi - LogAppend `_ " -> already synced"` else echo "$tapelabel $loadedbarcode" >> $labelfile LogAppend `_ ' -> appended %s entry: %s %s' "$labelfile" "$tapelabel" "$loadedbarcode"` @@ -1305,6 +1481,12 @@ searchtape() { fi LogAppend `_ ' -> barcode is "%s"' "$labelfile_barcode"` get_mtx_status + if [ $mtx_status_valid -eq 0 ]; then + Exit 2 \ + `_ ''` \ + `head -1 $mtx_status` + return $? + fi foundslot=`sed -n ' /VolumeTag *= *'$labelfile_barcode' *$/ { s/.*Storage Element \([0-9][0-9]*\).*/\1/p