⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mtx.py

📁 通用SCSI设备备份/读写程序
💻 PY
字号:
# Copyright 2000 Enhanced Software Technologies Inc.# Released under Free Software Foundation's General Public License,# Version 2 or above## This is an example of how to parse the 'mtx' output from a scripting# language. ## Routine to call 'mtx' and read status, or# whatever.## We do this here rather than creating a Python "C" module because:#  1) Reduces complexity of compile environment#  2) Easier debugging.#  3) More in keeping with the Unix philosophy of things.#  4) Easier to add new functionality. ##import stringimport osimport time # we can do some waiting here...def readpipe(command):    result=""        infile=os.popen(command,"r")    try:        s=infile.read()    except:        s=""        pass    if not s:        return None  # didn't get anything :-(.     result=result+s    return result# these are returned by the mtx.status routine:class slotstatus:    def __init__(self,slotnum,middle,barcode=None):        middle=string.strip(middle)        try:            left,right=string.split(middle," ")        except:            left=middle            right=None            pass        # Note: We will not be able to test this at the moment since the        # 220 has no import/export port!        if right=="IMPORT/EXPORT":            self.importexport=1        else:            self.importexport=0            pass        self.slotnum=int(slotnum) # make sure it's an integer...        if left=="Full":            self.full=1        else:            self.full=None            pass        if not barcode:            self.voltag=None        else:            l=string.split(barcode,"=",1)            self.voltag=l[1]            pass        return    pass# Drive status lines have this format:#Data Transfer Element 0:Full (Storage Element 10 Loaded):VolumeTag = B0000009H#Data Transfer Element 1:Emptyclass drivestatus:    def __init__(self,slotnum,middle,barcode=None):        self.slotnum=slotnum        if middle=="Empty":            self.full=None            self.origin=None            self.voltag=None            return        else:            self.full=1            pass        # okay, we know we have a tape in the drive.         # split and find out our origin: we will always have        # an origin, even if the #$@% mtx program had to dig one        # out of the air:        l=string.split(middle," ")        self.origin=int(l[3])        if not barcode:            self.voltag=None # barcode of this element.        else:            l=string.split(barcode," ")            self.voltag=string.strip(l[2])            pass        return    pass# This is the return value for mtx.status. class mtxstatus:    def __init__(self):        self.numdrives=None        self.numslots=None        self.numexport=None        self.drives=[]  # a list of drivestatus instances.        self.slots=[]   # a list of slotstatus instances        self.export=[]  # another list of slotstatus instances        return    pass# call 'mtx' and get barcode info, if possible:# okay, we now have a string that consists of a number of lines.# we want to explode this string into its component parts.# Example format:# Storage Changer /dev/sgd:2 Drives, 21 Slots# Data Transfer Element 0:Full (Storage Element '5' Loaded) # Data Transfer Element 1:Empty# Storage Element 1:Full :VolumeTag=CLNA0001# Storage Element 2:Full :VolumeTag=B0000009# Storage Element 3:Full :VolumeTag=B0000010# ....# What we want to do, then, is:# 1) Turn it into lines by doing a string.split on newline.# 2) Split the 1st line on ":" to get left and right.# 3) Split the right half on space to get #drives "Drives," #slots# 4) process the drives (Full,Empty, etc.)# 5) For each of the remaining lines: Split on ':'# 6) Full/Empty status is in 2)#configdir="/opt/brupro/bin"  # sigh. def status(device):    retval=mtxstatus()    command="%s/mtx -f %s status" % (configdir,device)    result=readpipe(command)    if not result:        return None  # sorry!     # now to parse:    try:        lines=string.split(result,"\n")    except:        return None # sorry, no status!        # print "DEBUG:lines=",lines    try:        l=string.split(lines[0],":")    except:        return None # sorry, no status!        # print "DEBUG:l=",l    leftside=l[0]    rightside=l[1]    if len(l) > 2:        barcode=l[3]    else:        barcode=None        pass    t=string.split(rightside)    retval.numdrives=int(t[0])    retval.numslots=int(t[2])        for s in lines[1:]:        if not s:            continue # skip blank lines!        #print "DEBUG:s=",s        parts=string.split(s,":")        leftpart=string.split(parts[0])        rightpart=parts[1]        try:            barcode=parts[2]        except:            barcode=None            pass        #print "DEBUG:leftpart=",leftpart        if leftpart[0]=="Data" and leftpart[1]=="Transfer":            retval.drives.append(drivestatus(leftpart[3],rightpart,barcode))            pass        if leftpart[0]=="Storage" and leftpart[1]=="Element":            element=slotstatus(leftpart[2],rightpart,barcode)            if element.importexport:                retval.export.append(element)            else:                retval.slots.append(element)                pass            pass        continue    return retval# Output of a mtx inquiry looks like:##Product Type: Medium Changer#Vendor ID: 'EXABYTE '#Product ID: 'Exabyte EZ17    '#Revision: '1.07'#Attached Changer: No## We simply return a hash table with these values { left:right } format. def mtxinquiry(device):    command="%s/mtx -f %s inquiry" % (configdir,device)    str=readpipe(command) # calls the command, returns all its data.    str=string.strip(str)    lines=string.split(str,"\n")    retval={}    for l in lines:        # DEBUG #        l=string.strip(l)        print "splitting line: '",l,"'"        idx,val=string.split(l,':',1)        val=string.strip(val)        if val[0]=="'":            val=val[1:-1] # strip off single quotes, sigh.             pass         retval[idx]=val        continue    return retval# Now for the easy part:def load(device,slot,drive=0):    command="%s/mtx -f %s load %s %s >/dev/null " % (configdir,device,slot,drive)    status=os.system(command)    return statusdef unload(device,slot,drive=0):    command="%s/mtx -f %s unload %s %s >/dev/null " % (configdir,device,slot,drive)    return os.system(command)def inventory(device):    command="%s/mtx -f %s inventory >/dev/null " % (configdir,device)    return os.system(command)def wait_for_inventory(device):    # loop while we have an error return...    errcount=0    while inventory(device):        if errcount==0:            print "Waiting for loader '%s'" % device            pass        time.sleep(1)        try:            s=status(device)        except:            s=None            pass        if s:            return 0 # well, whatever we're doing, we're inventoried :-(        errcount=errcount+1        if errcount==600:   # we've been waiting for 10 minutes :-(            return 1 # sorry!        continue    return 0  # we succeeded!# RCS REVISION LOG:# $Log: mtx.py,v $# Revision 1.1.1.1  2001/06/05 17:10:51  elgreen# Initial import into SourceForge## Revision 1.2  2000/12/22 14:17:19  eric# mtx 1.2.11pre1## Revision 1.14  2000/11/12 20:35:29  eric# do string.strip on the voltag## Revision 1.13  2000/11/04 00:33:38  eric# if we can get an inventory on the loader after we send it 'mtx inventory',# then obviously we managed to do SOMETHING.## Revision 1.12  2000/10/28 00:04:34  eric# added wait_for_inventory command## Revision 1.11  2000/10/27 23:27:58  eric# Added inventory command...## Revision 1.10  2000/10/01 01:06:29  eric# evening checkin## Revision 1.9  2000/09/29 02:49:29  eric# evening checkin## Revision 1.8  2000/09/02 01:05:33  eric# Evening Checkin## Revision 1.7  2000/09/01 00:08:11  eric# strip lines in mtxinquiry## Revision 1.6  2000/09/01 00:05:33  eric# debugging## Revision 1.5  2000/08/31 23:46:01  eric# fix def:## Revision 1.4  2000/08/31 23:44:06  eric# =->==#

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -