Merge "[DVR] Add lock during creation of FIP agent gateway port" into stable/rocky

This commit is contained in:
Zuul 2019-08-15 22:53:16 +00:00 committed by Gerrit Code Review
commit ed3b41a0cd
1 changed files with 44 additions and 32 deletions

View File

@ -30,6 +30,7 @@ from neutron_lib.exceptions import l3 as l3_exc
from neutron_lib.plugins import constants as plugin_constants from neutron_lib.plugins import constants as plugin_constants
from neutron_lib.plugins import directory from neutron_lib.plugins import directory
from neutron_lib.plugins import utils as plugin_utils from neutron_lib.plugins import utils as plugin_utils
from oslo_concurrency import lockutils
from oslo_config import cfg from oslo_config import cfg
from oslo_log import helpers as log_helper from oslo_log import helpers as log_helper
from oslo_log import log as logging from oslo_log import log as logging
@ -982,13 +983,9 @@ class _DVRAgentInterfaceMixin(object):
def create_fip_agent_gw_port_if_not_exists( def create_fip_agent_gw_port_if_not_exists(
self, context, network_id, host): self, context, network_id, host):
"""Function to return the FIP Agent GW port. # TODO(slaweq): add proper constraint on database level to avoid
# creation of duplicated Floating IP gateway ports for same network and
This function will create a FIP Agent GW port # same L3 agent. When this will be done, we can get rid of this lock.
if required. If the port already exists, it
will return the existing port and will not
create a new one.
"""
try: try:
l3_agent_db = self._get_agent_by_type_and_host( l3_agent_db = self._get_agent_by_type_and_host(
context, const.AGENT_TYPE_L3, host) context, const.AGENT_TYPE_L3, host)
@ -1001,31 +998,46 @@ class _DVRAgentInterfaceMixin(object):
l3_agent_mode = self._get_agent_mode(l3_agent_db) l3_agent_mode = self._get_agent_mode(l3_agent_db)
if l3_agent_mode == const.L3_AGENT_MODE_DVR_NO_EXTERNAL: if l3_agent_mode == const.L3_AGENT_MODE_DVR_NO_EXTERNAL:
return return
if l3_agent_db: if not l3_agent_db:
LOG.debug("Agent ID exists: %s", l3_agent_db['id']) return
f_port = self._get_agent_gw_ports_exist_for_network( lock_name = 'fip-gw-lock-' + network_id + '-' + host
context, network_id, host, l3_agent_db['id']) with lockutils.lock(lock_name, external=True):
if not f_port: return self._create_fip_agent_gw_port_if_not_exists(
LOG.info('Agent Gateway port does not exist,' context, network_id, host, l3_agent_db)
' so create one: %s', f_port)
port_data = {'tenant_id': '', def _create_fip_agent_gw_port_if_not_exists(self, context, network_id,
'network_id': network_id, host, l3_agent_db):
'device_id': l3_agent_db['id'], """Function to return the FIP Agent GW port.
'device_owner': const.DEVICE_OWNER_AGENT_GW,
portbindings.HOST_ID: host, This function will create a FIP Agent GW port
'admin_state_up': True, if required. If the port already exists, it
'name': ''} will return the existing port and will not
agent_port = plugin_utils.create_port( create a new one.
self._core_plugin, context, {'port': port_data}) """
if agent_port: LOG.debug("Agent ID exists: %s", l3_agent_db['id'])
self._populate_mtu_and_subnets_for_ports(context, f_port = self._get_agent_gw_ports_exist_for_network(
[agent_port]) context, network_id, host, l3_agent_db['id'])
return agent_port if not f_port:
msg = _("Unable to create the Agent Gateway Port") LOG.info('Agent Gateway port does not exist,'
raise n_exc.BadRequest(resource='router', msg=msg) ' so create one: %s', f_port)
else: port_data = {'tenant_id': '',
self._populate_mtu_and_subnets_for_ports(context, [f_port]) 'network_id': network_id,
return f_port 'device_id': l3_agent_db['id'],
'device_owner': const.DEVICE_OWNER_AGENT_GW,
portbindings.HOST_ID: host,
'admin_state_up': True,
'name': ''}
agent_port = plugin_utils.create_port(
self._core_plugin, context, {'port': port_data})
if agent_port:
self._populate_mtu_and_subnets_for_ports(context,
[agent_port])
return agent_port
msg = _("Unable to create the Agent Gateway Port")
raise n_exc.BadRequest(resource='router', msg=msg)
else:
self._populate_mtu_and_subnets_for_ports(context, [f_port])
return f_port
def _generate_arp_table_and_notify_agent( def _generate_arp_table_and_notify_agent(
self, context, fixed_ip, mac_address, notifier): self, context, fixed_ip, mac_address, notifier):