From 95d80a2757e23b6e8cdb44576f3913eedb400810 Mon Sep 17 00:00:00 2001 From: Hemanth Nakkina Date: Wed, 16 Jun 2021 15:00:44 +0530 Subject: [PATCH] [OVN] neutron-ovn-metadat-agent add retry logic for sb_idl Add retry logic to retrieve OvsdbSb IDL object. Add port fork event in MetadataProxyHandler to wait for the OvsdbSb IDL object. Closes-Bug: #1928031 Change-Id: Idce1ec4e160c5a7f8532b57f577b9518a06b0dd0 --- neutron/agent/ovn/metadata/ovsdb.py | 9 +++++++++ neutron/agent/ovn/metadata/server.py | 18 ++++++++++++++++++ .../unit/agent/ovn/metadata/test_server.py | 1 + 3 files changed, 28 insertions(+) diff --git a/neutron/agent/ovn/metadata/ovsdb.py b/neutron/agent/ovn/metadata/ovsdb.py index 661e2525bbf..8eae982f05e 100644 --- a/neutron/agent/ovn/metadata/ovsdb.py +++ b/neutron/agent/ovn/metadata/ovsdb.py @@ -12,6 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +from oslo_log import log from ovs.db import idl from ovsdbapp.backend.ovs_idl import connection from ovsdbapp.backend.ovs_idl import idlutils @@ -23,6 +24,9 @@ from neutron.plugins.ml2.drivers.ovn.mech_driver.ovsdb import impl_idl_ovn from neutron.plugins.ml2.drivers.ovn.mech_driver.ovsdb import ovsdb_monitor +LOG = log.getLogger(__name__) + + class MetadataAgentOvnSbIdl(ovsdb_monitor.OvnIdl): SCHEMA = 'OVN_Southbound' @@ -51,7 +55,12 @@ class MetadataAgentOvnSbIdl(ovsdb_monitor.OvnIdl): def _get_ovsdb_helper(self, connection_string): return idlutils.get_schema_helper(connection_string, self.SCHEMA) + @tenacity.retry( + wait=tenacity.wait_exponential( + max=config.get_ovn_ovsdb_retry_max_interval()), + reraise=True) def start(self): + LOG.info('Getting OvsdbSbOvnIdl for MetadataAgent with retry') conn = connection.Connection( self, timeout=config.get_ovn_ovsdb_timeout()) return impl_idl_ovn.OvsdbSbOvnIdl(conn) diff --git a/neutron/agent/ovn/metadata/server.py b/neutron/agent/ovn/metadata/server.py index 58cec315d0b..21818f483f6 100644 --- a/neutron/agent/ovn/metadata/server.py +++ b/neutron/agent/ovn/metadata/server.py @@ -14,6 +14,7 @@ import hashlib import hmac +import threading import urllib from neutron._i18n import _ @@ -46,8 +47,21 @@ class MetadataProxyHandler(object): def __init__(self, conf, chassis): self.conf = conf self.chassis = chassis + self._sb_idl = None + self._post_fork_event = threading.Event() self.subscribe() + @property + def sb_idl(self): + if not self._sb_idl: + self._post_fork_event.wait() + + return self._sb_idl + + @sb_idl.setter + def sb_idl(self, val): + self._sb_idl = val + def subscribe(self): registry.subscribe(self.post_fork_initialize, resources.PROCESS, @@ -56,10 +70,14 @@ class MetadataProxyHandler(object): def post_fork_initialize(self, resource, event, trigger, payload=None): # We need to open a connection to OVN SouthBound database for # each worker so that we can process the metadata requests. + self._post_fork_event.clear() self.sb_idl = ovsdb.MetadataAgentOvnSbIdl( tables=('Port_Binding', 'Datapath_Binding', 'Chassis'), chassis=self.chassis).start() + # Now IDL connections can be safely used. + self._post_fork_event.set() + @webob.dec.wsgify(RequestClass=webob.Request) def __call__(self, req): try: diff --git a/neutron/tests/unit/agent/ovn/metadata/test_server.py b/neutron/tests/unit/agent/ovn/metadata/test_server.py index 26fdf1c0692..43dce60769e 100644 --- a/neutron/tests/unit/agent/ovn/metadata/test_server.py +++ b/neutron/tests/unit/agent/ovn/metadata/test_server.py @@ -57,6 +57,7 @@ class TestMetadataProxyHandler(base.BaseTestCase): self.log = self.log_p.start() self.handler = agent.MetadataProxyHandler(self.fake_conf, 'chassis1') self.handler.sb_idl = mock.Mock() + self.handler._post_fork_event.set() def test_call(self): req = mock.Mock()