1 # Copyright 2000 Enhanced Software Technologies Inc.
2 # Released under Free Software Foundation's General Public License,
5 # This is an example of how to parse the 'mtx' output from a scripting
8 # Routine to call 'mtx' and read status, or
11 # We do this here rather than creating a Python "C" module because:
12 # 1) Reduces complexity of compile environment
13 # 2) Easier debugging.
14 # 3) More in keeping with the Unix philosophy of things.
15 # 4) Easier to add new functionality.
21 import time # we can do some waiting here...
23 def readpipe(command):
26 infile=os.popen(command,"r")
34 return None # didn't get anything :-(.
41 # these are returned by the mtx.status routine:
43 def __init__(self,slotnum,middle,barcode=None):
44 middle=string.strip(middle)
46 left,right=string.split(middle," ")
51 # Note: We will not be able to test this at the moment since the
52 # 220 has no import/export port!
53 if right=="IMPORT/EXPORT":
58 self.slotnum=int(slotnum) # make sure it's an integer...
67 l=string.split(barcode,"=",1)
73 # Drive status lines have this format:
74 #Data Transfer Element 0:Full (Storage Element 10 Loaded):VolumeTag = B0000009H
75 #Data Transfer Element 1:Empty
78 def __init__(self,slotnum,middle,barcode=None):
89 # okay, we know we have a tape in the drive.
90 # split and find out our origin: we will always have
91 # an origin, even if the #$@% mtx program had to dig one
94 l=string.split(middle," ")
98 self.voltag=None # barcode of this element.
100 l=string.split(barcode," ")
101 self.voltag=string.strip(l[2])
106 # This is the return value for mtx.status.
112 self.drives=[] # a list of drivestatus instances.
113 self.slots=[] # a list of slotstatus instances
114 self.export=[] # another list of slotstatus instances
118 # call 'mtx' and get barcode info, if possible:
119 # okay, we now have a string that consists of a number of lines.
120 # we want to explode this string into its component parts.
122 # Storage Changer /dev/sgd:2 Drives, 21 Slots
123 # Data Transfer Element 0:Full (Storage Element '5' Loaded)
124 # Data Transfer Element 1:Empty
125 # Storage Element 1:Full :VolumeTag=CLNA0001
126 # Storage Element 2:Full :VolumeTag=B0000009
127 # Storage Element 3:Full :VolumeTag=B0000010
129 # What we want to do, then, is:
130 # 1) Turn it into lines by doing a string.split on newline.
131 # 2) Split the 1st line on ":" to get left and right.
132 # 3) Split the right half on space to get #drives "Drives," #slots
133 # 4) process the drives (Full,Empty, etc.)
134 # 5) For each of the remaining lines: Split on ':'
135 # 6) Full/Empty status is in 2)
137 configdir="/opt/brupro/bin" # sigh.
141 command="%s/mtx -f %s status" % (configdir,device)
142 result=readpipe(command)
148 lines=string.split(result,"\n")
150 return None # sorry, no status!
152 # print "DEBUG:lines=",lines
155 l=string.split(lines[0],":")
157 return None # sorry, no status!
167 t=string.split(rightside)
168 retval.numdrives=int(t[0])
169 retval.numslots=int(t[2])
173 continue # skip blank lines!
175 parts=string.split(s,":")
176 leftpart=string.split(parts[0])
183 #print "DEBUG:leftpart=",leftpart
184 if leftpart[0]=="Data" and leftpart[1]=="Transfer":
185 retval.drives.append(drivestatus(leftpart[3],rightpart,barcode))
187 if leftpart[0]=="Storage" and leftpart[1]=="Element":
188 element=slotstatus(leftpart[2],rightpart,barcode)
189 if element.importexport:
190 retval.export.append(element)
192 retval.slots.append(element)
199 # Output of a mtx inquiry looks like:
201 #Product Type: Medium Changer
202 #Vendor ID: 'EXABYTE '
203 #Product ID: 'Exabyte EZ17 '
205 #Attached Changer: No
207 # We simply return a hash table with these values { left:right } format.
209 def mtxinquiry(device):
210 command="%s/mtx -f %s inquiry" % (configdir,device)
211 str=readpipe(command) # calls the command, returns all its data.
213 str=string.strip(str)
214 lines=string.split(str,"\n")
219 print "splitting line: '",l,"'"
220 idx,val=string.split(l,':',1)
221 val=string.strip(val)
223 val=val[1:-1] # strip off single quotes, sigh.
229 # Now for the easy part:
231 def load(device,slot,drive=0):
232 command="%s/mtx -f %s load %s %s >/dev/null " % (configdir,device,slot,drive)
233 status=os.system(command)
236 def unload(device,slot,drive=0):
237 command="%s/mtx -f %s unload %s %s >/dev/null " % (configdir,device,slot,drive)
238 return os.system(command)
240 def inventory(device):
241 command="%s/mtx -f %s inventory >/dev/null " % (configdir,device)
242 return os.system(command)
244 def wait_for_inventory(device):
245 # loop while we have an error return...
247 while inventory(device):
249 print "Waiting for loader '%s'" % device
258 return 0 # well, whatever we're doing, we're inventoried :-(
260 if errcount==600: # we've been waiting for 10 minutes :-(
263 return 0 # we succeeded!
267 # Revision 1.1 2001/06/05 17:10:51 elgreen
270 # Revision 1.2 2000/12/22 14:17:19 eric
273 # Revision 1.14 2000/11/12 20:35:29 eric
274 # do string.strip on the voltag
276 # Revision 1.13 2000/11/04 00:33:38 eric
277 # if we can get an inventory on the loader after we send it 'mtx inventory',
278 # then obviously we managed to do SOMETHING.
280 # Revision 1.12 2000/10/28 00:04:34 eric
281 # added wait_for_inventory command
283 # Revision 1.11 2000/10/27 23:27:58 eric
284 # Added inventory command...
286 # Revision 1.10 2000/10/01 01:06:29 eric
289 # Revision 1.9 2000/09/29 02:49:29 eric
292 # Revision 1.8 2000/09/02 01:05:33 eric
295 # Revision 1.7 2000/09/01 00:08:11 eric
296 # strip lines in mtxinquiry
298 # Revision 1.6 2000/09/01 00:05:33 eric
301 # Revision 1.5 2000/08/31 23:46:01 eric
304 # Revision 1.4 2000/08/31 23:44:06 eric