From 017f3fb372ca118eb83197049d500219f829d57b Mon Sep 17 00:00:00 2001 From: Jarrod Johnson Date: Tue, 7 Apr 2020 11:32:52 -0400 Subject: [PATCH] Switch CP storage to SSDP from SLP The SLP behavior on CP storage BMC is problematic. Switch to SSDP to see if that provides more robust behavior. --- confluent_server/confluent/discovery/core.py | 12 +++++-- .../confluent/discovery/protocols/slp.py | 4 +-- .../confluent/discovery/protocols/ssdp.py | 35 +++++++++++++++---- 3 files changed, 41 insertions(+), 10 deletions(-) diff --git a/confluent_server/confluent/discovery/core.py b/confluent_server/confluent/discovery/core.py index 8e06b2f6..56ca9389 100644 --- a/confluent_server/confluent/discovery/core.py +++ b/confluent_server/confluent/discovery/core.py @@ -65,7 +65,7 @@ import base64 import confluent.config.configmanager as cfm import confluent.collective.manager as collective import confluent.discovery.protocols.pxe as pxe -#import confluent.discovery.protocols.ssdp as ssdp +import confluent.discovery.protocols.ssdp as ssdp import confluent.discovery.protocols.slp as slp import confluent.discovery.handlers.imm as imm import confluent.discovery.handlers.cpstorage as cpstorage @@ -1217,9 +1217,17 @@ def rescan(): if scanner: return else: - scanner = eventlet.spawn(slp.active_scan, safe_detected, slp) + scanner = eventlet.spawn(blocking_scan) +def blocking_scan(): + global scanner + slpscan = eventlet.spawn(slp.active_scan, safe_detected, slp) + ssdpscan = eventlet.spawn(ssdp.active_scan, safe_detected, ssdp) + slpscan.wait() + ssdpscan.wait() + scanner = None + def start_detection(): global attribwatcher global rechecker diff --git a/confluent_server/confluent/discovery/protocols/slp.py b/confluent_server/confluent/discovery/protocols/slp.py index 11fc0e54..215e5bfb 100644 --- a/confluent_server/confluent/discovery/protocols/slp.py +++ b/confluent_server/confluent/discovery/protocols/slp.py @@ -497,7 +497,7 @@ def snoop(handler, protocol=None): if len(srvurl) > 4: srvurl = srvurl[:-3] if srvurl.endswith('://Athena:'): - peerbymacaddress[mac]['services'] = ['service:thinkagile-storage'] + continue if 'service:ipmi' in peerbymacaddress[mac]['services']: continue if 'service:lightttpd' in peerbymacaddress[mac]['services']: @@ -574,7 +574,7 @@ def scan(srvtypes=_slp_services, addresses=None, localonly=False): if len(srvurl) > 4: srvurl = srvurl[:-3] if srvurl.endswith('://Athena:'): - rsps[id]['services'] = ['service:thinkagile-storage'] + continue if 'service:ipmi' in rsps[id]['services']: continue if localonly: diff --git a/confluent_server/confluent/discovery/protocols/ssdp.py b/confluent_server/confluent/discovery/protocols/ssdp.py index 288f733e..f8e0d219 100644 --- a/confluent_server/confluent/discovery/protocols/ssdp.py +++ b/confluent_server/confluent/discovery/protocols/ssdp.py @@ -32,6 +32,10 @@ import confluent.neighutil as neighutil import confluent.util as util import eventlet.green.select as select import eventlet.green.socket as socket +try: + from eventlet.green.urllib.request import urlopen +except (ImportError, AssertionError): + from eventlet.green.urllib2 import urlopen import struct mcastv4addr = '239.255.255.250' @@ -45,6 +49,20 @@ smsg = ('M-SEARCH * HTTP/1.1\r\n' 'MX: 3\r\n\r\n') +def active_scan(handler, protocol=None): + known_peers = set([]) + for scanned in scan(['urn:dmtf-org:service:redfish-rest:1']): + for addr in scanned['addresses']: + ip = addr[0].partition('%')[0] # discard scope if present + if ip not in neighutil.neightable: + continue + if addr in known_peers: + break + known_peers.add(addr) + else: + scanned['protocol'] = protocol + handler(scanned) + def scan(services, target=None): for service in services: for rply in _find_service(service, target): @@ -109,11 +127,11 @@ def snoop(handler, byehandler=None): known_peers.add(peer) newmacs.add(mac) if mac in peerbymacaddress: - peerbymacaddress[mac]['peers'].append(peer) + peerbymacaddress[mac]['addresses'].append(peer) else: peerbymacaddress[mac] = { 'hwaddr': mac, - 'peers': [peer], + 'addresses': [peer], } peerdata = peerbymacaddress[mac] for headline in rsp[1:]: @@ -185,7 +203,12 @@ def _find_service(service, target): timeout = 0 r, _, _ = select.select((net4, net6), (), (), timeout) for nid in peerdata: - yield peerdata[nid] + for url in peerdata[nid].get('urls', ()): + if url.endswith('/desc.tmpl'): + info = urlopen(url).read() + if 'Athena' in info: + peerdata[nid]['services'] = ['service:thinkagile-storage'] + yield peerdata[nid] def _parse_ssdp(peer, rsp, peerdata): @@ -203,11 +226,11 @@ def _parse_ssdp(peer, rsp, peerdata): if code == '200': if nid in peerdata: peerdatum = peerdata[nid] - if peer not in peerdatum['peers']: - peerdatum['peers'].append(peer) + if peer not in peerdatum['addresses']: + peerdatum['addresses'].append(peer) else: peerdatum = { - 'peers': [peer], + 'addresses': [peer], 'hwaddr': mac, } peerdata[nid] = peerdatum