From e9cf2fd6cca8a3d5c06bcb073cb310cd61208b41 Mon Sep 17 00:00:00 2001 From: Terry Wilson Date: Fri, 15 Dec 2023 21:00:43 +0000 Subject: [PATCH] Handle creation of Port_Binding with chassis set When there is a backlog of notifications to be sent, it is possible that ovsdb-server will merge insert and update notifications. Due to this, we need to handle the situation where we see a Port_Binding created with the chassis set. Closes-Bug: #2017748 Change-Id: Idfae87cf6c60e9e18ede91ea20857cea5322738c (cherry picked from commit a641e8aec09c1e33a15a34b19d92675ed2c85682) --- neutron/agent/ovn/extensions/qos_hwol.py | 4 ++-- neutron/agent/ovn/metadata/agent.py | 21 +++++++++++++++++---- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/neutron/agent/ovn/extensions/qos_hwol.py b/neutron/agent/ovn/extensions/qos_hwol.py index a813418d04c..5652f0f6d42 100644 --- a/neutron/agent/ovn/extensions/qos_hwol.py +++ b/neutron/agent/ovn/extensions/qos_hwol.py @@ -158,13 +158,13 @@ class PortBindingChassisCreatedEvent(_PortBindingChassisEvent): LOG_MSG = 'Port ID %s, datapath %s, OVS port name: %s (event: %s)' def __init__(self, ovn_agent): - events = (self.ROW_UPDATE,) + events = (self.ROW_CREATE, self.ROW_UPDATE,) super().__init__(ovn_agent, events) def match_fn(self, event, row, old): try: return (row.chassis[0].name == self.ovn_agent.chassis and - not old.chassis) + (event == self.ROW_CREATE or not old.chassis)) except (IndexError, AttributeError): return False diff --git a/neutron/agent/ovn/metadata/agent.py b/neutron/agent/ovn/metadata/agent.py index bb65b33894f..1745239701b 100644 --- a/neutron/agent/ovn/metadata/agent.py +++ b/neutron/agent/ovn/metadata/agent.py @@ -109,6 +109,16 @@ class PortBindingEvent(row_event.RowEvent): self.agent.resync() +class PortBindingCreateWithChassis(PortBindingEvent): + EVENT = PortBindingEvent.ROW_CREATE + + def match_fn(self, event, row, old): + self._log_msg = "Port %s in datapath %s bound to our chassis on insert" + if not (super().match_fn(event, row, old) and row.chassis): + return False + return row.chassis[0].name == self.agent.chassis + + class PortBindingUpdatedEvent(PortBindingEvent): EVENT = PortBindingEvent.ROW_UPDATE @@ -316,6 +326,7 @@ class MetadataAgent(object): tables = ('Encap', 'Port_Binding', 'Datapath_Binding', 'SB_Global', 'Chassis') events = (PortBindingUpdatedEvent(self), + PortBindingCreateWithChassis(self), PortBindingDeletedEvent(self), SbGlobalUpdateEvent(self), ) @@ -345,7 +356,8 @@ class MetadataAgent(object): self._proxy.run() # Do the initial sync. - self.sync() + # Provisioning handled by PortBindingCreateWithChassis + self.sync(provision=False) # Register the agent with its corresponding Chassis self.register_metadata_agent() @@ -396,7 +408,7 @@ class MetadataAgent(object): return set(p.datapath for p in self._vif_ports(ports)) @_sync_lock - def sync(self): + def sync(self, provision=True): """Agent sync. This function will make sure that all networks with ports in our @@ -423,8 +435,9 @@ class MetadataAgent(object): # resync all network namespaces based on the associated datapaths, # even those that are already running. This is to make sure # everything within each namespace is up to date. - for datapath in net_datapaths: - self.provision_datapath(datapath) + if provision: + for datapath in net_datapaths: + self.provision_datapath(datapath) @staticmethod def _get_veth_name(datapath):