📄 mtx-changer
字号:
#! /bin/sh################################################################################ AMANDA Tape Changer script for use with the MTX tape changer program# Version 1.0 - Tue Feb 20 13:59:39 CST 2001# # Based on 'stc-changer' by Eric Berggren (eric@ee.pdx.edu)# Updated by Tim Skirvin (tskirvin@ks.uiuc.edu)# # Given that there's no license...let's make this the Perl Artistic License.# Just make sure you give me and Eric credit if you modify this. ################################################################################## USER CONFIGURATION# Name of the tape drive (takes place of "tapedev" option in amanda.conf)# and default driver number in library (usu 0) that DRIVE_NAME points toDRIVE_NAME="/dev/rmt/0n"DRIVE_NUM=0# Location of "STC" command and control deviceMTX_CMD="/usr/local/sbin/mtx";MTX_CONTROL="/dev/scsi/changer/c4t1d0";# Whether tape drive must eject tape before changer retrieves# (ie, EXB-2x0). Usually okay if set while not necessary, bad if# required but not set.DRIVE_MUST_EJECT=1# How long to check drive readiness (in seconds) after mounting (or# ejecting) a volume (on some libraries, the motion or eject command may# complete before the drive has the volume fully mounted and online,# or ready for retrieval, resulting in "Drive not ready"/"Media not# ready" errors). Do an "mt status" command every 5 seconds upto this# time.DRIVE_READY_TIME_MAX=120# tape "mt" command location...MT_CMD="/usr/bin/mt" # called via "MT_CMD -f DRIVE_NAME rewind" & # "MT_CMD -f DRIVE_NAME offline" to eject # and "MT_CMD -f DRIVE_NAME status" to get ready info###############################################################################NumDrives=-1NumSlots=-1LastSlot=-1LoadedTape=-1## Usage information#usage(){ echo echo "Usage: $Progname <command> [arg...]" echo " -info reports capability and loaded tape" echo " -slot <slot> loads specified tape into drive" echo " current reports current mounted tape" echo " next loads logically next tape (loops to top)" echo " prev loads logically previous tape (loops to bot)" echo " first loads first tape" echo " last loads last tape" echo " 0..99 loads tape from specified slot#" echo " -eject uloads current mounted tape" echo " -reset resets changer (and drive); loads first tape" echo exit 5}## Perform "stc" changer command (& handle the "fatal" errors)# else, set 'CommandResStr' and 'CommandRawResStr' to the result string # and 'CommandResCode' to the exit code#dotapecmd(){ cmd=$1 arg=$2 CommandResStr=`$MTX_CMD $MTX_CONTROL $cmd $arg 2>&1` CommandRawResStr=$CommandResStr CommandResCode=$? CommandResStr=`echo $CommandResStr | head -1 | sed 's/^[^:]*: //'` if [ $CommandResCode -gt 1 ]; then echo "0 $Progname: returned $CommandResStr" exit 2 fi}## Unload tape from drive (a drive command; "ejecttape" is a changer command# to actually retrieve the tape). Needed by some changers (controlled by# setting "DRIVE_MUST_EJECT")#ejectdrive(){ # Tell drive to eject tape before changer retrieves; req'd by some # drives (ie, EXB-2x0). Not needed by QDLT-4x00. Do a "rewind" # command first, then "offline" to eject (instead of "rewoffl") # if [ "$DRIVE_MUST_EJECT" -ne 0 ]; then mtresstr=`$MT_CMD -f $DRIVE_NAME rewind 2>&1` mtrescode=$? if [ $mtrescode -ne 0 ]; then if echo "$mtresstr" | egrep -s 'no tape'; then :; # no tape mounted; assume okay... else # can't eject tape, bad; output: <tape#> reason echo "0 $mtresstr" exit 1 fi else mtresstr=`$MT_CMD -f $DRIVE_NAME offline 2>&1` mtrescode=$? checkdrive 1 fi fi}## Check drive readiness after (un)mounting a volume (which may take a while# after the volume change command completes)#checkdrive(){ unmounting=$1 if [ "$DRIVE_READY_TIME_MAX" -gt 0 ]; then # sleep time between checks pausetime=5 # number of interations to check numchecks=`expr $DRIVE_READY_TIME_MAX / $pausetime` if [ "$numchecks" -eq 0 ]; then numchecks=1 fi # check until success, or out of attempts... while [ "$numchecks" -gt 0 ]; do mtresstr=`$MT_CMD -f $DRIVE_NAME status 2>&1` mtrescode=$? if [ $mtrescode -eq 0 ]; then # Success ? return 0 else # pause, before trying again.... if [ "$numchecks" -gt 1 ]; then sleep $pausetime # if unmounting a volume, check for 'mt' command # failure; (sleep first for additional comfort) if [ "$unmounting" -ne 0 ]; then return 0 fi fi fi numchecks=`expr $numchecks - 1` done # failed; output: -1 reason echo "-1 drive won't report ready" exit 1 fi}## Get changer parameters#getchangerparms(){ dotapecmd status if [ $CommandResCode -eq 0 ] && \ echo "$CommandResStr" | egrep -s '^Storage Changer'; then NumDrives=`echo $dspec | wc -l` NumDrives=`echo "$CommandRawResStr" | \ grep 'Data Transfer Element' | wc -l` if [ "$NumDrives" -le "$DRIVE_NUM" ]; then echo "$Program: Invalid drive # specified ($DRIVE_NUM > $NumDrives)" exit 3 fi # grep 'Data Transfer Element $DRIVE_NUM' | \ LoadedTape=`echo "$CommandRawResStr" | \ grep 'Data Transfer Element' | \ grep 'Storage Element [0-9]' | \ awk '{ print $7 }' ` if [ -z "$LoadedTape" -o "$LoadedTape" = "e" ]; then LoadedTape=-1 fi NumSlots=`echo "$CommandRawResStr" | \ grep 'Storage Element [0-9]\{1,\}:' | \ grep -v 'Data Element' | \ wc -l | sed -e 's/ //g' ` LastSlot=`expr $NumSlots - 1` else echo \ "$Progname: Can't get changer parameters; Result was $CommandResStr" exit 3 fi} ## Display changer info#changerinfo(){ getchangerparms # output status string: currenttape numslots randomaccess? echo "$LoadedTape $NumSlots 1" exit 0}## Eject current mounted tape#ejecttape(){ getchangerparms ct=$LoadedTape # If no tape reported mounted, assume success (could be bad if changer # lost track of tape) # if [ $ct -lt 0 ]; then CommandResCode=0 else ejectdrive dotapecmd unload fi if [ $CommandResCode -ne 0 ]; then # failed; output: <tape#> reason echo "$ct $CommandResStr" exit 1 else # success; output: <tape#> drive echo "$ct $DRIVE_NAME" exit 0 fi}## Move specified tape into drive (operation level)#doloadtape(){ slot=$1 if [ "$slot" -eq "$LoadedTape" ]; then return 0 fi ejectdrive dotapecmd load $slot return $CommandResCode}## Load next available tape into drive#loadnexttape(){ curslot=$1 direction=$2 startslot=$curslot while true; do if doloadtape $curslot; then return 0 else if echo $CommandResStr | egrep -s 'Slot.*reported empty'; then if [ "$direction" -lt 0 ]; then curslot=`expr $curslot - 1` if [ "$curslot" -lt 0 ]; then curslot=$LastSlot fi else curslot=`expr $curslot + 1` if [ "$curslot" -gt "$LastSlot" ]; then curslot=0 fi fi # Check if we're back to where we started... if [ "$curslot" = "$startslot" ]; then if [ "$direction" -lt 0 ]; then CommandResStr="No previous volume available" else CommandResStr="No subsequent volume available" fi return 1 fi else return 1 fi fi done}## Report loadtape() status#reportstatus(){ if [ $CommandResCode -eq 0 ]; then # success; output currenttape drivename echo "$LoadedTape $DRIVE_NAME" exit 0 else # failed (empty slot?); output currenttape reason echo "$LoadedTape $CommandResStr" exit 1 fi}## Move specified tape into drive (command level)#loadtape(){ slot=$1 getchangerparms case "$slot" in current) if [ $LoadedTape -lt 0 ]; then CommandResStr="Can't determine current tape; drive empty ?" CommandResCode=1 fi ;; prev) if [ $LoadedTape -le 0 ]; then loadnexttape $LastSlot -1 else loadnexttape `expr $LoadedTape - 1` -1 fi ;; next) if [ $LoadedTape -ge $LastSlot -o $LoadedTape -lt 0 ]; then loadnexttape 0 1 else loadnexttape `expr $LoadedTape + 1` 1 fi ;; first) loadnexttape 0 1 ;; last) loadnexttape $LastSlot -1 ;; [0-9]*) doloadtape $slot ;; *) # error; no valid slot specified echo "$Progname: No valid slot specified" exit 1 ;; esac if [ $CommandResCode -eq 0 ]; then getchangerparms checkdrive fi reportstatus}## Reset changer to known state#resetchanger(){ ejectdrive dotapecmd reset if [ $CommandResCode -ne 0 ]; then # failed; output: failed? reason echo "-1 $CommandResStr" exit 2; else loadtape first fi}############################################################################### MAIN#Progname=`basename $0`if [ ! -x "$MTX_CMD" ]; then echo "-1 $Progname: cannot run STC command ($MTX_CMD)" exit 2fiif [ -n "$MTX_CONTROL" ]; then if echo "$MTX_CONTROL" | egrep -s '^-f'; then :; else MTX_CONTROL="-f $MTX_CONTROL" fifiif [ -n "$DRIVE_NUM" ]; then DRIVE_NUM=0fiif [ $# -ge 1 ]; then command=$1; else command="-usage"; ficase "$command" in -info) changerinfo ;; -slot) loadtape $2 ;; -eject) ejecttape ;; -reset) resetchanger ;; *) usage ;;esacexit 0
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -