From fb2f233d5156a3516b309336a310570c368c7a89 Mon Sep 17 00:00:00 2001
From: Miguel Duarte Barroso <mdbarroso@redhat.com>
Date: Thu, 22 Aug 2019 10:39:10 +0200
Subject: [PATCH] nm.applier: Prioritize master interfaces activaction
The master interfaces - that are not slaves themselves - must be
activated first, otherwise NetworkManager fails with errors such
as:
"""
NetworkManager[858]: <debug>
[1565960861.2223] manager: Activation of <slave> requires master
device <master device>
"""
The supplied test fails roughly >= 50% of the times without this
patch - it all comes to the timing.
Signed-off-by: Miguel Duarte Barroso <mdbarroso@redhat.com>
Signed-off-by: Gris Ge <fge@redhat.com>
---
libnmstate/nm/applier.py | 25 ++++++++++++++++++++++---
1 file changed, 22 insertions(+), 3 deletions(-)
diff --git a/libnmstate/nm/applier.py b/libnmstate/nm/applier.py
index 750ca3d..974460b 100644
--- a/libnmstate/nm/applier.py
+++ b/libnmstate/nm/applier.py
@@ -41,6 +41,7 @@ from . import wired
MASTER_METADATA = '_master'
MASTER_TYPE_METADATA = '_master_type'
+MASTER_IFACE_TYPES = ovs.BRIDGE_TYPE, bond.BOND_TYPE, LB.TYPE
BRPORT_OPTIONS_METADATA = '_brport_options'
@@ -111,6 +112,7 @@ def set_ifaces_admin_state(ifaces_desired_state, con_profiles=()):
leaving it to choose the correct profile.
In order to activate correctly the interfaces, the order is significant:
+ - Master-less master interfaces.
- New interfaces (virtual interfaces, but not OVS ones).
- Master interfaces.
- OVS ports.
@@ -123,6 +125,7 @@ def set_ifaces_admin_state(ifaces_desired_state, con_profiles=()):
new_vlan_ifaces_to_activate = set()
new_ovs_interface_to_activate = set()
new_ovs_port_to_activate = set()
+ new_master_not_enslaved_ifaces = set()
master_ifaces_to_edit = set()
ifaces_to_edit = set()
remove_devs_actions = {}
@@ -132,7 +135,13 @@ def set_ifaces_admin_state(ifaces_desired_state, con_profiles=()):
nmdev = device.get_device_by_name(ifname)
if not nmdev:
if ifname in new_ifaces and iface_desired_state['state'] == 'up':
- if iface_desired_state['type'] == ovs.INTERNAL_INTERFACE_TYPE:
+ if _is_master_iface(
+ iface_desired_state
+ ) and not _is_slave_iface(iface_desired_state):
+ new_master_not_enslaved_ifaces.add(ifname)
+ elif (
+ iface_desired_state['type'] == ovs.INTERNAL_INTERFACE_TYPE
+ ):
new_ovs_interface_to_activate.add(ifname)
elif iface_desired_state['type'] == ovs.PORT_TYPE:
new_ovs_port_to_activate.add(ifname)
@@ -142,8 +151,7 @@ def set_ifaces_admin_state(ifaces_desired_state, con_profiles=()):
new_ifaces_to_activate.add(ifname)
else:
if iface_desired_state['state'] == 'up':
- master_iface_types = ovs.BRIDGE_TYPE, bond.BOND_TYPE, LB.TYPE
- if iface_desired_state['type'] in master_iface_types:
+ if _is_master_iface(iface_desired_state):
master_ifaces_to_edit.add(
(nmdev, con_profiles_by_devname[ifname].profile)
)
@@ -176,6 +184,9 @@ def set_ifaces_admin_state(ifaces_desired_state, con_profiles=()):
for dev, _ in itertools.chain(master_ifaces_to_edit, ifaces_to_edit):
remove_devs_actions.pop(dev, None)
+ for ifname in new_master_not_enslaved_ifaces:
+ device.activate(dev=None, connection_id=ifname)
+
for ifname in new_ifaces_to_activate:
device.activate(dev=None, connection_id=ifname)
@@ -213,6 +224,14 @@ def _get_new_ifaces(con_profiles):
return ifaces_without_device
+def _is_master_iface(iface_state):
+ return iface_state[Interface.TYPE] in MASTER_IFACE_TYPES
+
+
+def _is_slave_iface(iface_state):
+ return iface_state.get(MASTER_METADATA)
+
+
def _get_affected_devices(iface_state):
nmdev = device.get_device_by_name(iface_state['name'])
devs = []
--
2.23.0