Merge "NSX|V: prevent deadlock with subnet creation and deletion"
This commit is contained in:
commit
2082495477
@ -494,11 +494,7 @@ class RouterDistributedDriver(router_driver.RouterBaseDriver):
|
|||||||
with locking.LockManager.get_lock(network_id):
|
with locking.LockManager.get_lock(network_id):
|
||||||
dhcp_id = self.edge_manager.create_dhcp_edge_service(
|
dhcp_id = self.edge_manager.create_dhcp_edge_service(
|
||||||
context, network_id, subnet)
|
context, network_id, subnet)
|
||||||
|
self.plugin._update_dhcp_adddress(context, network_id)
|
||||||
address_groups = self.plugin._create_network_dhcp_address_group(
|
|
||||||
context, network_id)
|
|
||||||
self.edge_manager.update_dhcp_edge_service(
|
|
||||||
context, network_id, address_groups=address_groups)
|
|
||||||
if dhcp_id:
|
if dhcp_id:
|
||||||
edge_id, az_name = self.plugin._get_edge_id_and_az_by_rtr_id(
|
edge_id, az_name = self.plugin._get_edge_id_and_az_by_rtr_id(
|
||||||
context, dhcp_id)
|
context, dhcp_id)
|
||||||
|
@ -1893,6 +1893,13 @@ class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin,
|
|||||||
return self._update_port(context, id, port, original_port,
|
return self._update_port(context, id, port, original_port,
|
||||||
is_compute_port, device_id)
|
is_compute_port, device_id)
|
||||||
|
|
||||||
|
def _update_dhcp_adddress(self, context, network_id):
|
||||||
|
with locking.LockManager.get_lock('dhcp-update-%s' % network_id):
|
||||||
|
address_groups = self._create_network_dhcp_address_group(
|
||||||
|
context, network_id)
|
||||||
|
self._update_dhcp_edge_service(context, network_id,
|
||||||
|
address_groups)
|
||||||
|
|
||||||
def _update_port(self, context, id, port, original_port, is_compute_port,
|
def _update_port(self, context, id, port, original_port, is_compute_port,
|
||||||
device_id):
|
device_id):
|
||||||
attrs = port[port_def.RESOURCE_NAME]
|
attrs = port[port_def.RESOURCE_NAME]
|
||||||
@ -2039,11 +2046,8 @@ class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin,
|
|||||||
self._create_dhcp_static_binding(context, ret_port)
|
self._create_dhcp_static_binding(context, ret_port)
|
||||||
elif owner == constants.DEVICE_OWNER_DHCP:
|
elif owner == constants.DEVICE_OWNER_DHCP:
|
||||||
# Update the ip of the dhcp port
|
# Update the ip of the dhcp port
|
||||||
with locking.LockManager.get_lock(ret_port['network_id']):
|
self._update_dhcp_adddress(context,
|
||||||
address_groups = self._create_network_dhcp_address_group(
|
ret_port['network_id'])
|
||||||
context, ret_port['network_id'])
|
|
||||||
self._update_dhcp_edge_service(
|
|
||||||
context, ret_port['network_id'], address_groups)
|
|
||||||
elif (owner == constants.DEVICE_OWNER_ROUTER_GW or
|
elif (owner == constants.DEVICE_OWNER_ROUTER_GW or
|
||||||
owner == constants.DEVICE_OWNER_ROUTER_INTF):
|
owner == constants.DEVICE_OWNER_ROUTER_INTF):
|
||||||
# This is a router port - update the edge appliance
|
# This is a router port - update the edge appliance
|
||||||
@ -2278,34 +2282,33 @@ class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin,
|
|||||||
# and send update dhcp interface rest call before deleting subnet's
|
# and send update dhcp interface rest call before deleting subnet's
|
||||||
# corresponding dhcp interface rest call and lead to overlap response
|
# corresponding dhcp interface rest call and lead to overlap response
|
||||||
# from backend.
|
# from backend.
|
||||||
with locking.LockManager.get_lock('nsx-edge-pool'):
|
network_id = subnet['network_id']
|
||||||
with db_api.context_manager.writer.using(context):
|
with locking.LockManager.get_lock(network_id):
|
||||||
super(NsxVPluginV2, self).delete_subnet(context, id)
|
with locking.LockManager.get_lock('nsx-edge-pool'):
|
||||||
|
with db_api.context_manager.writer.using(context):
|
||||||
|
super(NsxVPluginV2, self).delete_subnet(context, id)
|
||||||
|
|
||||||
if subnet['enable_dhcp']:
|
if subnet['enable_dhcp']:
|
||||||
# There is only DHCP port available
|
# There is only DHCP port available
|
||||||
if len(ports) == 1:
|
if len(ports) == 1:
|
||||||
port = ports.pop()
|
port = ports.pop()
|
||||||
|
# This is done out of the transaction as it invokes
|
||||||
|
# update_port which interfaces with the NSX
|
||||||
self.ipam.delete_port(context, port['id'])
|
self.ipam.delete_port(context, port['id'])
|
||||||
|
|
||||||
if subnet['enable_dhcp']:
|
# Delete the DHCP edge service
|
||||||
# Delete the DHCP edge service
|
filters = {'network_id': [network_id]}
|
||||||
network_id = subnet['network_id']
|
remaining_subnets = self.get_subnets(context,
|
||||||
filters = {'network_id': [network_id]}
|
filters=filters)
|
||||||
remaining_subnets = self.get_subnets(context,
|
if len(remaining_subnets) == 0:
|
||||||
filters=filters)
|
self._cleanup_dhcp_edge_before_deletion(
|
||||||
if len(remaining_subnets) == 0:
|
|
||||||
self._cleanup_dhcp_edge_before_deletion(
|
|
||||||
context, network_id)
|
|
||||||
LOG.debug("Delete the DHCP service for network %s",
|
|
||||||
network_id)
|
|
||||||
self._delete_dhcp_edge_service(context, network_id)
|
|
||||||
else:
|
|
||||||
# Update address group and delete the DHCP port only
|
|
||||||
with locking.LockManager.get_lock(network_id):
|
|
||||||
addr_groups = self._create_network_dhcp_address_group(
|
|
||||||
context, network_id)
|
context, network_id)
|
||||||
self._update_dhcp_edge_service(context, network_id,
|
LOG.debug("Delete the DHCP service for network %s",
|
||||||
addr_groups)
|
network_id)
|
||||||
|
self._delete_dhcp_edge_service(context, network_id)
|
||||||
|
else:
|
||||||
|
# Update address group and delete the DHCP port only
|
||||||
|
self._update_dhcp_adddress(context, network_id)
|
||||||
|
|
||||||
def _is_overlapping_reserved_subnets(self, subnet):
|
def _is_overlapping_reserved_subnets(self, subnet):
|
||||||
"""Return True if the subnet overlaps with reserved subnets.
|
"""Return True if the subnet overlaps with reserved subnets.
|
||||||
@ -2428,7 +2431,8 @@ class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin,
|
|||||||
self._update_dhcp_service_with_subnet(context, s)
|
self._update_dhcp_service_with_subnet(context, s)
|
||||||
except Exception:
|
except Exception:
|
||||||
with excutils.save_and_reraise_exception():
|
with excutils.save_and_reraise_exception():
|
||||||
self.delete_subnet(context, s['id'])
|
super(NsxVPluginV2, self).delete_subnet(context,
|
||||||
|
s['id'])
|
||||||
return s
|
return s
|
||||||
|
|
||||||
def _process_subnet_ext_attr_create(self, session, subnet_db,
|
def _process_subnet_ext_attr_create(self, session, subnet_db,
|
||||||
@ -2630,11 +2634,7 @@ class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin,
|
|||||||
network_id)
|
network_id)
|
||||||
self._delete_dhcp_edge_service(context, network_id)
|
self._delete_dhcp_edge_service(context, network_id)
|
||||||
return
|
return
|
||||||
with locking.LockManager.get_lock(network_id):
|
self._update_dhcp_adddress(context, network_id)
|
||||||
address_groups = self._create_network_dhcp_address_group(
|
|
||||||
context, network_id)
|
|
||||||
self._update_dhcp_edge_service(context, network_id,
|
|
||||||
address_groups)
|
|
||||||
|
|
||||||
def _get_conflict_network_ids_by_overlapping(self, context, subnets):
|
def _get_conflict_network_ids_by_overlapping(self, context, subnets):
|
||||||
with locking.LockManager.get_lock('nsx-networking'):
|
with locking.LockManager.get_lock('nsx-networking'):
|
||||||
@ -2732,10 +2732,7 @@ class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin,
|
|||||||
self.edge_manager.create_dhcp_edge_service(context, network_id,
|
self.edge_manager.create_dhcp_edge_service(context, network_id,
|
||||||
subnet)
|
subnet)
|
||||||
# Create all dhcp ports within the network
|
# Create all dhcp ports within the network
|
||||||
address_groups = self._create_network_dhcp_address_group(
|
self._update_dhcp_adddress(context, network_id)
|
||||||
context, network_id)
|
|
||||||
self.edge_manager.update_dhcp_edge_service(
|
|
||||||
context, network_id, address_groups=address_groups)
|
|
||||||
|
|
||||||
except Exception:
|
except Exception:
|
||||||
with excutils.save_and_reraise_exception():
|
with excutils.save_and_reraise_exception():
|
||||||
|
@ -1541,11 +1541,7 @@ class EdgeManager(object):
|
|||||||
LOG.error('Database conflict could not be recovered '
|
LOG.error('Database conflict could not be recovered '
|
||||||
'for VDR %(vdr)s DHCP edge %(dhcp)s',
|
'for VDR %(vdr)s DHCP edge %(dhcp)s',
|
||||||
{'vdr': vdr_router_id, 'dhcp': dhcp_edge_id})
|
{'vdr': vdr_router_id, 'dhcp': dhcp_edge_id})
|
||||||
with locking.LockManager.get_lock(network_id):
|
self.plugin._update_dhcp_adddress(context, network_id)
|
||||||
address_groups = self.plugin._create_network_dhcp_address_group(
|
|
||||||
context, network_id)
|
|
||||||
self.update_dhcp_edge_service(
|
|
||||||
context, network_id, address_groups=address_groups)
|
|
||||||
|
|
||||||
self.set_sysctl_rp_filter_for_vdr_dhcp(
|
self.set_sysctl_rp_filter_for_vdr_dhcp(
|
||||||
context, dhcp_edge_id, network_id)
|
context, dhcp_edge_id, network_id)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user