Petr Horáček has uploaded a new change for review.
Change subject: network: ifcfg: synchronous ifup
......................................................................
network: ifcfg: synchronous ifup
Change-Id: I0c90a556f5fc52c1b8e675986ac39b6032ca0197
Signed-off-by: Petr Horáček <phoracek(a)redhat.com>
---
M vdsm/network/configurators/ifcfg.py
1 file changed, 63 insertions(+), 9 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/66/37366/1
diff --git a/vdsm/network/configurators/ifcfg.py b/vdsm/network/configurators/ifcfg.py
index 65e02b5..785c7f2 100644
--- a/vdsm/network/configurators/ifcfg.py
+++ b/vdsm/network/configurators/ifcfg.py
@@ -18,6 +18,7 @@
#
from __future__ import absolute_import
+from contextlib import contextmanager
import glob
import logging
import os
@@ -36,13 +37,14 @@
from vdsm import netinfo
from vdsm import utils
from vdsm.netconfpersistence import RunningConfig
+from vdsm.netlink import monitor
if utils.isOvirtNode():
from ovirt.node.utils import fs as node_fs
from . import Configurator, dhclient, getEthtoolOpts, libvirt
from ..errors import ConfigNetworkError, ERR_FAILED_IFUP
-from ..models import Nic, Bridge, IpConfig
+from ..models import Nic, Bridge, IpConfig, NetDevice
from ..sourceroute import StaticSourceRoute, DynamicSourceRoute
import dsaversion # TODO: Make parent package import when vdsm is a package
@@ -89,13 +91,13 @@
if bridge.port:
bridge.port.configure(**opts)
self._addSourceRoute(bridge)
- ifup(bridge.name, bridge.ipConfig.async)
+ ifup(bridge, bridge.ipConfig.async)
def configureVlan(self, vlan, **opts):
self.configApplier.addVlan(vlan, **opts)
vlan.device.configure(**opts)
self._addSourceRoute(vlan)
- ifup(vlan.name, vlan.ipConfig.async)
+ ifup(vlan, vlan.ipConfig.async)
def configureBond(self, bond, **opts):
self.configApplier.addBonding(bond, **opts)
@@ -105,7 +107,7 @@
for slave in bond.slaves:
slave.configure(**opts)
self._addSourceRoute(bond)
- ifup(bond.name, bond.ipConfig.async)
+ ifup(bond, bond.ipConfig.async)
if self.unifiedPersistence:
self.runningConfig.setBonding(
bond.name, {'options': bond.options,
@@ -142,11 +144,11 @@
if slave.name in nicsToAdd:
ifdown(slave.name) # nics must be down to join a bond
self.configApplier.addNic(slave)
- ifup(slave.name)
+ ifup(slave)
if bondIfcfgWritten:
ifdown(bond.name)
- ifup(bond.name)
+ ifup(bond)
if self.unifiedPersistence:
self.runningConfig.setBonding(
bond.name, {'options': bond.options,
@@ -158,7 +160,7 @@
if nic.bond is None:
if not netinfo.isVlanned(nic.name):
ifdown(nic.name)
- ifup(nic.name, nic.ipConfig.async)
+ ifup(nic, nic.ipConfig.async)
def removeBridge(self, bridge):
DynamicSourceRoute.addInterfaceTracking(bridge)
@@ -216,7 +218,7 @@
if to_be_removed:
self.configApplier.removeNic(nic.name)
if nic.name in netinfo.nics():
- ifup(nic.name)
+ ifup(nic)
else:
logging.warning('host interface %s missing', nic.name)
else:
@@ -804,7 +806,8 @@
def ifup(iface, async=False):
- "Bring up an interface"
+ """Bring up an interface. Parameter iface could be iface's name
or
+ a NetDevice object."""
def _ifup(netIf):
rc, out, err = utils.execCmd([constants.EXT_IFUP, netIf], raw=False)
@@ -815,17 +818,68 @@
return rc, out, err
if async:
+ iface = iface.name if isinstance(iface, NetDevice) else iface
+
# wait for dhcp in another thread,
# so vdsm won't get stuck (BZ#498940)
t = threading.Thread(target=_ifup, name='ifup-waiting-on-dhcp',
args=(iface,))
t.daemon = True
t.start()
+ elif isinstance(iface, NetDevice) and iface.master is None:
+ # TEMP NOTE: ip could be None or IpConfig(IPv4(None,...),
+ # IPv6(None,...)...)
+ if iface.ip and (iface.ip.ipv4.address or iface.ip.ipv6.address):
+ # TEMP NOTE: we have to call setupNetworks with IPv6 addr, prefix
+ # included
+ if iface.ip.ipv6.address:
+ expected_event = {'event': 'new_addr', 'label':
iface.name,
+ 'address': iface.ip.ipv6.address}
+ elif iface.ip.ipv4.address:
+ prefix = _netmask2prefix(iface.ip.ipv4.netmask)
+ expected_event = {'event': 'new_addr', 'label':
iface.name,
+ 'address': iface.ip.ipv4.address + '/' + prefix}
+ else:
+ expected_event = {'event': 'new_addr', 'label':
iface.name}
+
+ with _event_sniffer(expected_event):
+ rc, out, err = _ifup(iface.name)
+ return rc
else:
rc, out, err = _ifup(iface)
return rc
+def _netmask2prefix(netmask):
+ netmask = [int(octet) for octet in netmask]
+ return sum([sum([int(i) for i in list(bin(octet)[2:])])
+ for octet in netmask])
+
+
+@contextmanager
+def _event_sniffer(expected_event, timeout=10):
+ mon = monitor.Monitor(groups=('link', 'ipv4-ifaddr',
'ipv6-ifaddr'),
+ timeout=timeout)
+ mon.start()
+ try:
+ yield
+ finally:
+ try:
+ for event in mon:
+ if _is_subdict(expected_event, event):
+ mon.stop()
+ except monitor.MonitorError as e:
+ if e[0] == monitor.E_TIMEOUT:
+ logging.error('Expected event "%s" was not caught within
the '
+ 'given timeout.', expected_event)
+ else:
+ raise
+
+
+def _is_subdict(subset, superset):
+ return all(item in superset.items() for item in subset.items())
+
+
def configuredPorts(nets, bridge):
"""Returns the list of ports a bridge has"""
ports = []
--
To view, visit
http://gerrit.ovirt.org/37366
To unsubscribe, visit
http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I0c90a556f5fc52c1b8e675986ac39b6032ca0197
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Petr Horáček <phoracek(a)redhat.com>