📄 mtx.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 + -