#!/usr/bin/env python
import logging
import os
from pprint import pformat
from otto.lib.otypes import Namespace
instance = os.environ.get('instance') or ''
logger = logging.getLogger('otto' + instance + '.intitiators')
logger.addHandler(logging.NullHandler())
[docs]class Ethdrv(object):
"""
A class for interacting with initiator's debug files.
Requires get_ethdrv call back function. This callback function
must return the contents of the specified entity (filename) under the
ethdrv parent (directory).
Basic Usage::
from otto.initiators.solaris import Solaris
i = solaris.Solaris(uname, host, passwd, prompt=None)
i.connect()
print i.ethdrv.release
i.disconnect()
"""
def __init__(self, get_ethdrv):
self.get_ethdrv = get_ethdrv
@property
def acbs(self):
"""
Returns a dictionary of acbs in the following format::
{'141.2': {'arcnt': 0,
'index': 186,
'out': 0,
'qcnt': 0,
'resent': 0,
'sent': 5403,
'state': 4,
'target': '141.2',
'unex': 0,
'wnd': 16}
}
"""
dev = dict()
head = ['index', 'state', 'target', 'out', 'wnd', 'qcnt', 'arcnt', 'sent', 'resent', 'unex']
out = self.get_ethdrv('acbs')
m = out.message.splitlines()
for l in m:
w = l.split()
for i in range(len(w)):
if w[i].isdigit():
w[i] = int(w[i])
dev[w[2]] = Namespace(dict(zip(head, w)))
return dev
@property
def ca(self):
"""
Returns a dictionary of ca in the following format::
{'141.2': {'cwnd': 16,
'index': 186,
'out': 0,
'rttavg': 3.8,
'rttdev': 2.9,
'ssthresh': 8,
'target': '141.2',
'wnd': 16}}
"""
dev = dict()
head = ['index', 'target', 'out', 'cwnd', 'wnd', 'ssthresh', 'rttavg', 'rttdev']
out = self.get_ethdrv('ca')
m = out.message.splitlines()
for l in m:
w = l.split()
for i in [0, 2, 3, 4, 5]:
w[i] = int(w[i])
for i in [6, 7]:
w[i] = float(w[i])
dev[w[1]] = Namespace(dict(zip(head, w)))
return dev
@property
def config(self):
"""
Returns a dictionary of config in the following format::
{'140.17': {'config': 'N/A',
'target': '140.17'},
'55.203': {'config': 'com.myco.hba hosts=MEGADETH',
'target': '55.203'}}
"""
dev = dict()
head = ['target', 'config']
out = self.get_ethdrv('config')
m = out.message.splitlines()
for l in m:
w = l.split(None, 1)
try:
dev[w[0]] = Namespace(dict(zip(head, w)))
except IndexError:
logger.critical("can't index %s" % pformat(w))
return dev
@property
def corestats(self):
"""
Returns a dictionary of corestats in the following format::
{'arallocfail': 0,
'arcnt': 0,
'badcap': 0,
'badcappair': 0,
'cecdr': 0,
'cecrx': 0,
'cectx': 0,
'ioqueue': 0,
'iorequest': 0,
'ioretire': 0,
'iosend': 0,
'iosubmit': 0,
'sgallocfail': 0,
'sgbufallocfail': 0,
'sgbufcnt': 32778,
'sgcnt': 23,
'shortcap': 0,
'srallocfail': 0,
'srcnt': 0}
"""
dev = dict()
out = self.get_ethdrv('corestats')
m = out.message.splitlines()
for l in m:
w = l.split()
for i in w:
j = i.split('=')
dev[j[0]] = int(j[1])
return Namespace(dev)
@property
def ctl(self):
"""
Returns a dictionary of ctl in the following format::
{'tdeadsecs': 180, 'rqsize': 8192, 'srdebug': 'off',
'qdepth': 'n/a', 'trace': 'off'}
"""
dev = dict()
out = self.get_ethdrv('ctl')
m = out.message.splitlines()
for l in m:
w = l.split()
if w[1].isdigit():
dev[w[0]] = int(w[1])
else:
dev[w[0]] = w[1]
return Namespace(dev)
@property
def devices(self):
"""
Returns a dictionary of devices in the following format::
{'141.2': {'device': 'sd66',
'target': '141.2',
'size': '1000.204GB'}
}
"""
dev = dict()
head = ['device', 'target', 'size']
out = self.get_ethdrv('devices')
m = out.message.splitlines()
for l in m:
w = l.split()
dev[w[1]] = Namespace(dict(zip(head, w)))
return dev
@property
def elstats(self):
"""
Returns a dictionary of elstats in the following format::
{'ArpIn': 18510,
'ArpOut': 16786,
'DropNoAvail': 0,
'DropNoMatch': 0,
'DropNoSync': 0,
'DropNoWait': 0,
'DropQpass': 0,
'DropReject': 0,
'DropSeq': 0,
'HlenErrs': 0,
'InMsgs': 0,
'LenErrs': 0,
'OutMsgs': 0,
'Retrans': 0,
'elarp': {0: {'creason': '',
'crto': 90,
'deathtime': 30000,
'delayedack': 0,
'flags': 0,
'id0': 2093,
'local': '510000100401336a!17007',
'next': 2093,
'opens': 0,
'outqlen': 0,
'rcvd': 0,
'remote': '0000000000000000!0',
'resends': 0,
'rid0': 0,
'rqlen': 0,
'rto': 90,
'rttseq': 0,
'rxidle': 84429880,
'sa': 50,
'state': 'Listen',
'sv': 10,
'txidle': 84429880,
'unack': 2094},
1: {'creason': 'connection closed: ecbclose',
'crto': 90,
'deathtime': 30000,
'delayedack': 0,
'flags': 0,
'id0': 2093,
'local': '510000100401336a!7',
'next': 2093,
'opens': 0,
'outqlen': 0,
'rcvd': 0,
'remote': '0000000000000000!0',
'resends': 0,
'rid0': 0,
'rqlen': 0,
'rto': 90,
'rttseq': 0,
'rxidle': 84429880,
'sa': 50,
'state': 'Closed',
'sv': 10,
'txidle': 84429880,
'unack': 2094}},
'myeladdr': '510000100401336a'}
"""
dev = dict()
out = self.get_ethdrv('elstats')
stats, arp = out.message.split('el arp table:')
m = stats.splitlines()
for line in m:
w = line.split(':')
if len(w) < 2:
continue
v = w[1].strip()
if v.startswith('5100') and len(v) == 16:
dev[w[0]] = v
elif v.isdigit():
dev[w[0]] = int(v)
elarp = dict()
dev['elarp'] = elarp
dev = Namespace(dev)
m = arp.splitlines()
elstates = ('Avail', 'Closed', 'Syncer', 'Syncee', 'Estab', 'Closing', 'Listen', 'Initing')
for line in m:
if not line:
continue
if not line.startswith(elstates):
continue
r = line.rsplit('[', 1)[1].strip(']') # Extract creason before split
k = int(line.split()[1].strip('[]')) # This will extract just the number from [0]
v = line.split()[2:]
d = dict()
d['state'] = line.split()[0]
d['local'] = v[0]
d['remote'] = v[1]
for i in range(2, len(v), 2):
if v[i] == 'creason':
d[v[i]] = r
break
d[v[i]] = int(v[i + 1])
elarp[k] = Namespace(d)
dev.elarp = elarp
return dev
@property
def ifstats(self):
"""
See `HBA Namespace documentation`_. Some fields are chipset depentdent. Some fields are only
present when non-zero.
Returns a dictionary of ifstats in the following format::
{'1': {'Broadcast Packets Transmitted': 2216, 'drdh': 470, ... }}
"""
dev = dict()
hwords = ['reg', 'seen', 'icr', 'ims', 'im', 'Rdbal', 'Rdbah', 'Tdbal', 'Tdbah', 'Rxdctl']
out = self.get_ethdrv('ifstats')
t = out.message.split('***')[1:]
for i in range(0, len(t), 2):
w = t[i].split()
w[0] = int(w[0])
head = ['port', 'model', 'reg']
d = dict(zip(head, w))
m = t[i + 1].split('\r\n')
for l in m:
l = l.strip()
if not l:
continue
if l.startswith('link'): # assume last line
w = l.split(':')
d[w[0]] = int(w[1].strip())
break
elif l.startswith('speeds'):
w = l.split()
for i in w[1:]:
j = i.split(':')
d['link%s' % j[0]] = int(j[1])
elif l.find('=') is not -1:
w = l.split()
for i in w:
j = i.split('=')
if j[0] in hwords:
d[j[0]] = j[1] # XXX Store this as int?
elif j[1].isdigit():
d[j[0]] = int(j[1])
else:
d[j[0]] = j[1]
else:
w = l.split(':')
v = w[1].strip()
if v.isdigit():
d[w[0]] = int(v)
else:
d[w[0]] = v
dev[d['port']] = Namespace(d)
return dev
@property
def ports(self):
"""
Returns a dictionary of ports in the following format::
{0: {'currentlink': 0,
'ea': '00100401336a',
'index': 0,
'maxlink': 10000,
'name': 'EHBA-20-E-SFP'},
1: {'currentlink': 10000,
'ea': '00100401336b',
'index': 1,
'maxlink': 10000,
'name': 'EHBA-20-E-SFP'}}
"""
dev = dict()
head = ['index', 'name', 'ea', 'currentlink', 'maxlink']
out = self.get_ethdrv('ports')
m = out.message.splitlines()
for l in m:
w = l.split()
w[0] = int(w[0])
x = w[3]
w.pop()
w.append(int(x.split('/')[0]))
w.append(int(x.split('/')[1]))
dev[w[0]] = Namespace(dict(zip(head, w)))
return dev
@property
def release(self):
"""
Returns release string
"""
return self.get_ethdrv('release').message.splitlines()[0]
@property
def targets(self):
"""
Returns a dictionary list of targets in the following format::
{'200.135': [{'active': 1, 'targ': '200.135', 'ea': '0025906694a9', 'ports': 2},
{'active': 1, 'targ': '200.135', 'ea': '0025906694a8', 'ports': 2}]
"""
dev = dict()
head = ['targ', 'ea', 'ports', 'active']
out = self.get_ethdrv('targets')
m = out.message.splitlines()
for l in m:
w = l.split()
w[2] = int(w[2])
w[3] = int(w[3])
if not dev.get(w[0]):
dev[w[0]] = list()
dev[w[0]].append(Namespace(dict(zip(head, w))))
return dev
@property
def units(self):
"""
Returns a dictionary of units in the following format::
{'ea': '002590c23e63', 'product': 'SRX',
'eladdr': '5100002590c15a6a', 'ports': 2}
"""
head = ['eladdr', 'product', 'ea', 'ports']
out = self.get_ethdrv('units')
l = out.message.splitlines()[0]
w = l.split()
w[3] = int(w[3])
return Namespace(dict(zip(head, w)))