2
0
mirror of https://github.com/xcat2/confluent.git synced 2025-04-22 04:55:53 +00:00

Add auto-healing of incomplete SLP data

If a device handler indicates an SLP data as incomplete, schedule a
attempt to fixup that specific one.
This commit is contained in:
Jarrod Johnson 2018-11-13 15:37:41 -05:00
parent 8473cb1cf8
commit 39839a9f2a
6 changed files with 37 additions and 7 deletions

View File

@ -579,6 +579,10 @@ def detected(info):
break
else: # no nodehandler, ignore for now
return
if not handler.adequate(info) and info.get('protocol', None):
eventlet.spawn_after(10, info['protocol'].fix_info, info,
safe_detected)
return
try:
snum = info['attributes']['enclosure-serial-number'][0].strip()
if snum:
@ -1159,7 +1163,7 @@ def rescan():
if scanner:
return
else:
scanner = eventlet.spawn(slp.active_scan, safe_detected)
scanner = eventlet.spawn(slp.active_scan, safe_detected, slp)
def start_detection():
@ -1188,8 +1192,8 @@ def stop_autosense():
autosensors.discard(watcher)
def start_autosense():
autosensors.add(eventlet.spawn(slp.snoop, safe_detected))
autosensors.add(eventlet.spawn(pxe.snoop, safe_detected))
autosensors.add(eventlet.spawn(slp.snoop, safe_detected, slp))
autosensors.add(eventlet.spawn(pxe.snoop, safe_detected, pxe))
nodes_by_fprint = {}

View File

@ -40,6 +40,11 @@ class NodeHandler(object):
targsa = info['addresses'][0]
self.ipaddr = targsa[0]
def adequate(self, info):
# Check if the referenced info is really enough, if false, a rescan
# may occur against the target in a short while
return True
def scan(self):
# Do completely passive things to enhance data.
# Probe is permitted to for example attempt a login

View File

@ -21,6 +21,11 @@ import struct
class NodeHandler(bmchandler.NodeHandler):
devname = 'IMM'
def adequate(self, info):
# We can sometimes receive a partially initialized SLP packet
# This is not adequate for being satisfied
return bool(info['attributes'])
def scan(self):
slpattrs = self.info.get('attributes', {})
self.isdense = False

View File

@ -23,6 +23,11 @@ import pyghmi.ipmi.oem.lenovo.imm as imm
class NodeHandler(immhandler.NodeHandler):
devname = 'XCC'
def adequate(self, info):
# We can sometimes receive a partially initialized SLP packet
# This is not adequate for being satisfied
return bool(info['attributes'])
def preconfig(self):
ff = self.info.get('attributes', {}).get('enclosure-form-factor', '')
if ff not in ('dense-computing', [u'dense-computing']):

View File

@ -72,7 +72,7 @@ def find_info_in_options(rq, optidx):
return uuid, arch
return uuid, arch
def snoop(handler):
def snoop(handler, protocol=None):
#TODO(jjohnson2): ipv6 socket and multicast for DHCPv6, should that be
#prominent
#TODO(jjohnson2): IP_PKTINFO, recvmsg to get the destination ip, per

View File

@ -307,6 +307,15 @@ def _parse_attrs(data, parsed):
parsed['attributes'] = _parse_attrlist(attrstr)
def fix_info(info, handler):
if '_attempts' not in info:
info['_attempts'] = 10
if info['_attempts'] == 0:
return
info['_attempts'] -= 1
_add_attributes(info)
handler(info)
def _add_attributes(parsed):
attrq = _generate_attr_request(parsed['services'][0], parsed['xid'])
target = None
@ -383,7 +392,7 @@ def rescan(handler):
handler(scanned)
def snoop(handler):
def snoop(handler, protocol=None):
"""Watch for SLP activity
handler will be called with a dictionary of relevant attributes
@ -392,7 +401,7 @@ def snoop(handler):
:return:
"""
tracelog = log.Logger('trace')
active_scan(handler)
active_scan(handler, protocol)
net = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
net.setsockopt(IPPROTO_IPV6, socket.IPV6_V6ONLY, 1)
slpg = socket.inet_pton(socket.AF_INET6, 'ff01::123')
@ -469,13 +478,14 @@ def snoop(handler):
peerbymacaddress[mac]['xid'] = 1
_add_attributes(peerbymacaddress[mac])
peerbymacaddress[mac]['hwaddr'] = mac
peerbymacaddress[mac]['protocol'] = protocol
handler(peerbymacaddress[mac])
except Exception as e:
tracelog.log(traceback.format_exc(), ltype=log.DataTypes.event,
event=log.Events.stacktrace)
def active_scan(handler):
def active_scan(handler, protocol=None):
known_peers = set([])
for scanned in scan():
for addr in scanned['addresses']:
@ -486,6 +496,7 @@ def active_scan(handler):
break
known_peers.add(addr)
else:
scanned['protocol'] = protocol
handler(scanned)