From dbadf7b2ed4a9a6dad0a049c9ca02c451c99c8c0 Mon Sep 17 00:00:00 2001 From: Kevin Benton Date: Mon, 6 Feb 2017 01:36:31 -0800 Subject: [PATCH] Skip segment checks during network delete operations These checks aren't necessary when triggered as part of a network delete operation since any remaining subnets and ports will be removed from the network. Additionally, they can race with the auto cleanup methods for ports and subnets if segment deletion is moved to BEFORE_DELETE where it should be. Change-Id: I996f5b22f5179f5540760cc05c9f091bb3f3069b --- neutron/plugins/ml2/db.py | 6 +++++- neutron/services/segments/db.py | 7 ++++--- neutron/services/segments/plugin.py | 6 +++++- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/neutron/plugins/ml2/db.py b/neutron/plugins/ml2/db.py index 5de9838911c..bbd19e391ab 100644 --- a/neutron/plugins/ml2/db.py +++ b/neutron/plugins/ml2/db.py @@ -285,8 +285,12 @@ def is_dhcp_active_on_any_subnet(context, subnet_ids): def _prevent_segment_delete_with_port_bound(resource, event, trigger, - context, segment): + context, segment, + for_net_delete=False): """Raise exception if there are any ports bound with segment_id.""" + if for_net_delete: + # don't check for network deletes + return segment_id = segment['id'] query = context.session.query(models_v2.Port) query = query.join( diff --git a/neutron/services/segments/db.py b/neutron/services/segments/db.py index 8cc4ee595f7..82eb254b0a7 100644 --- a/neutron/services/segments/db.py +++ b/neutron/services/segments/db.py @@ -169,13 +169,13 @@ class SegmentDbMixin(common_db_mixin.CommonDbMixin): return list({mapping.segment_id for mapping in segment_host_mapping}) @log_helpers.log_method_call - def delete_segment(self, context, uuid): + def delete_segment(self, context, uuid, for_net_delete=False): """Delete an existing segment.""" segment = self.get_segment(context, uuid) # Do some preliminary operations before deleting the segment registry.notify(resources.SEGMENT, events.BEFORE_DELETE, self.delete_segment, context=context, - segment=segment) + segment=segment, for_net_delete=for_net_delete) # Delete segment in DB with context.session.begin(subtransactions=True): @@ -309,7 +309,8 @@ def _delete_segments_for_network(resource, event, trigger, segments = segments_plugin.get_segments( admin_ctx, filters={'network_id': [network_id]}) for segment in segments: - segments_plugin.delete_segment(admin_ctx, segment['id']) + segments_plugin.delete_segment(admin_ctx, segment['id'], + for_net_delete=True) def subscribe(): diff --git a/neutron/services/segments/plugin.py b/neutron/services/segments/plugin.py index d9146cc236d..09e9b50a57e 100644 --- a/neutron/services/segments/plugin.py +++ b/neutron/services/segments/plugin.py @@ -80,8 +80,12 @@ class Plugin(db.SegmentDbMixin, segment.SegmentPluginBase): return cls._instance def _prevent_segment_delete_with_subnet_associated( - self, resource, event, trigger, context, segment): + self, resource, event, trigger, context, segment, + for_net_delete=False): """Raise exception if there are any subnets associated with segment.""" + if for_net_delete: + # don't check if this is a part of a network delete operation + return segment_id = segment['id'] query = context.session.query(models_v2.Subnet.id) query = query.filter(models_v2.Subnet.segment_id == segment_id)