Set OVS inactivity_probe to vsctl_timeout when adding manager

If the vsctl_timeout > OVS's inactivity probe interval and a
transaction execution time exceeds the probe interval, OVS will
disconnect and the transaction will return TRY_AGAIN and most
likely repeat failing until the vsctl_timeout is reached. This
change ensures that the "failsafe" creation of the manager also
sets the inactivity probe to the vsctl_timeout value.

Currently the patch doesn't override the probe_interval on an
existing Manager since it is possible that connection is used by
outside applications and it theoretically should be handled at
deployment.

Related-Bug: #1627106
Change-Id: I76fa0a0cf04a166edf062086fceb2fd90960ad6b
This commit is contained in:
Terry Wilson 2017-03-03 11:46:16 -06:00
parent da507c616d
commit 1698bee770
4 changed files with 28 additions and 5 deletions

View File

@ -55,6 +55,8 @@ OVS_DEFAULT_CAPS = {
'iface_types': [],
}
_SENTINEL = object()
def _ofport_result_pending(result):
"""Return True if ovs-vsctl indicates the result is still pending."""
@ -107,8 +109,21 @@ class BaseOVS(object):
self.vsctl_timeout = cfg.CONF.ovs_vsctl_timeout
self.ovsdb = ovsdb.API.get(self)
def add_manager(self, connection_uri):
self.ovsdb.add_manager(connection_uri).execute()
def add_manager(self, connection_uri, timeout=_SENTINEL):
"""Have ovsdb-server listen for manager connections
:param connection_uri: Manager target string
:param timeout: The Manager probe_interval timeout value
(defaults to ovs_vsctl_timeout)
"""
if timeout is _SENTINEL:
timeout = cfg.CONF.ovs_vsctl_timeout
with self.ovsdb.transaction() as txn:
txn.add(self.ovsdb.add_manager(connection_uri))
if timeout:
txn.add(
self.ovsdb.db_set('Manager', connection_uri,
('inactivity_probe', timeout * 1000)))
def get_manager(self):
return self.ovsdb.get_manager().execute()

View File

@ -28,10 +28,15 @@ def _connection_to_manager_uri(conn_uri):
return 'p%s:%s' % (proto, addr)
def enable_connection_uri(conn_uri):
def enable_connection_uri(conn_uri, set_timeout=False):
class OvsdbVsctlContext(object):
vsctl_timeout = cfg.CONF.ovs_vsctl_timeout
manager_uri = _connection_to_manager_uri(conn_uri)
api = ovsdb.API.get(OvsdbVsctlContext, 'vsctl')
api.add_manager(manager_uri).execute(check_error=False, log_errors=True)
with api.transaction() as txn:
txn.add(api.add_manager(manager_uri))
if set_timeout:
timeout = cfg.CONF.ovs_vsctl_timeout * 1000
txn.add(api.db_set('Manager', manager_uri,
('inactivity_probe', timeout)))

View File

@ -126,7 +126,7 @@ def get_schema_helper(connection, schema_name, retry=True):
if not retry:
ctx.reraise = True
# We may have failed due to set-manager not being called
helpers.enable_connection_uri(connection)
helpers.enable_connection_uri(connection, set_timeout=True)
# There is a small window for a race, so retry up to a second
@tenacity.retry(wait=tenacity.wait_exponential(multiplier=0.01),

View File

@ -510,6 +510,9 @@ class OVSLibTestCase(base.BaseOVSLinuxTestCase):
self.addCleanup(self.ovs.remove_manager, conn_uri)
self.ovs.add_manager(conn_uri)
self.assertIn(conn_uri, self.ovs.get_manager())
self.assertEqual(self.ovs.db_get_val('Manager', conn_uri,
'inactivity_probe'),
self.ovs.vsctl_timeout * 1000)
self.ovs.remove_manager(conn_uri)
self.assertNotIn(conn_uri, self.ovs.get_manager())