Antoni Segura Puimedon has uploaded a new change for review.
Change subject: ipwrapper: Introduce the linkPool ......................................................................
ipwrapper: Introduce the linkPool
The linkPool is a Link object pool that is kept updated with the events from ip monitor link (with a daemon thread).
TODO: Find out why setting the ip monitor process as daemon has no effect and leaves orphan processes when exiting the interpreter.
Change-Id: I63e0e7e6938709b57509fce2efcd3d36d8bd1eb8 Signed-off-by: Antoni S. Puimedon asegurap@redhat.com --- M lib/vdsm/ipwrapper.py 1 file changed, 62 insertions(+), 8 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/16/22116/1
diff --git a/lib/vdsm/ipwrapper.py b/lib/vdsm/ipwrapper.py index 394e9a4..9183a7c 100644 --- a/lib/vdsm/ipwrapper.py +++ b/lib/vdsm/ipwrapper.py @@ -20,7 +20,9 @@ from collections import namedtuple from glob import iglob import errno +import logging import os +import threading
from netaddr.core import AddrFormatError from netaddr import IPAddress @@ -80,7 +82,7 @@ _hiddenNics = config.get('vars', 'hidden_nics').split(',') _hiddenVlans = config.get('vars', 'hidden_vlans').split(',')
- def __init__(self, address, index, linkType, mtu, name, qdisc, state, + def __init__(self, address, index, linkType, mtu, name, state, qdisc=None, vlanid=None, vlanprotocol=None, master=None, **kwargs): self.address = address self.index = index @@ -144,6 +146,14 @@ name, device = attrs['name'].split('@') attrs['name'] = name attrs['device'] = device + return cls(**attrs) + + @classmethod + def fromEvent(cls, event): + """Creates a Link object from an Event object.""" + attrs = event.attrs + if 'linkType' not in event.attrs: + attrs['linkType'] = cls._detectType(event.device) return cls(**attrs)
@staticmethod @@ -550,7 +560,7 @@
MonitorEvent = namedtuple('MonitorEvent', ['index', 'device', 'flags', - 'state']) + 'state', 'attrs'])
class Monitor(object): @@ -574,7 +584,9 @@ raise StopIteration elif self.proc.returncode is None: for line in self.proc.stdout: - yield self._parseLine(line) + event = self._parseLine(line) + if event: + yield event else: for event in self.events(): yield event @@ -595,8 +607,14 @@
data = Link._parse(line) # We can't get the type of a device no longer in the system - if (state != cls.LINK_STATE_DELETED and - not os.path.exists('/sys/class/net/' + data['name'])): + if state == cls.LINK_STATE_DELETED: + try: + link = linkPool[data['index']] + except KeyError: + # The link is not on the linkPool, no need for a delete event + return None + data['name'] = link.name + elif not os.path.exists('/sys/class/net/' + data['name']): try: data['name'] = _dev_get_by_index(data['index']) except OSError as ose: @@ -605,7 +623,8 @@ else: raise state = state if state or not 'state' in data else data['state'] - return MonitorEvent(data['index'], data['name'], data['flags'], state) + return MonitorEvent(data['index'], data['name'], data['flags'], state, + data)
@classmethod def _parse(cls, text): @@ -621,6 +640,41 @@ def _dev_get_by_index(ifindex): for filepath in iglob('/sys/class/net/*/ifindex'): with open(filepath) as ifFile: - if ifFile.read().strip() == ifindex: - return filepath.split('/')[-2] + try: + if ifFile.read().strip() == ifindex: + return filepath.split('/')[-2] + except IOError as ioe: + if ioe.errno in (errno.ENOENT, errno.EINVAL): + # The device is probably being removed + continue + raise + raise OSError(errno.ENOENT, 'No device found for index ' + ifindex) + + +linkPool = {} + + +def _linkPoolUpdater(): + mon = Monitor() + mon.start() + for event in mon: + if event.state == Monitor.LINK_STATE_DELETED: + try: + del linkPool[event.index] + except KeyError: + logging.debug('Failed to remove link pool device %s which was ' + 'not on the pool', event.device) + elif event.state is not None: # filter out typical wlan heartbeats + try: + linkPool[event.index] = Link.fromEvent(event) + except TypeError: + raise + + +# netinfo link pool handling +for link in getLinks(): + linkPool[link.index] = link +linkPoolThread = threading.Thread(target=_linkPoolUpdater, name='linkPool') +linkPoolThread.daemon = True +linkPoolThread.start()
Antoni Segura Puimedon has posted comments on this change.
Change subject: ipwrapper: Introduce the linkPool ......................................................................
Patch Set 1:
@Dan any idea about the execCmd proc object not having a working daemonic operation?
oVirt Jenkins CI Server has posted comments on this change.
Change subject: ipwrapper: Introduce the linkPool ......................................................................
Patch Set 1: Verified-1
Build Failed
http://jenkins.ovirt.org/job/vdsm_pep8_gerrit/5926/ : SUCCESS
http://jenkins.ovirt.org/job/vdsm_network_functional_tests/968/ : SUCCESS
http://jenkins.ovirt.org/job/vdsm_unit_tests_gerrit_el/5130/ : FAILURE
http://jenkins.ovirt.org/job/vdsm_unit_tests_gerrit/6018/ : FAILURE
Antoni Segura Puimedon has abandoned this change.
Change subject: ipwrapper: Introduce the linkPool ......................................................................
Abandoned
vdsm-patches@lists.fedorahosted.org