From 7ae3280c34acb92e0f509566354553dc96df3de7 Mon Sep 17 00:00:00 2001 From: Mark Goddard Date: Fri, 30 Aug 2019 16:58:34 +0100 Subject: [PATCH] Create _mech_context before delete to avoid race When a network is deleted, precommit handlers are notified prior to the deletion of the network from the database. One handler exists in the ML2 plugin - _network_delete_precommit_handler. This handler queries the database for the current state of the network and uses it to create a NetworkContext which it saves under context._mech_context. When the postcommit handler _network_delete_after_delete_handler is triggered later, it passess the saved context._mech_context to mechanism drivers. A problem can occur with provider networks since the segments service also registers a precommit handler - _delete_segments_for_network. Both precommit handlers use the default priority, so the order in which they are called is random, and determined by dict ordering. If the segment precommit handler executes first, it will delete the segments associated with the network. When the ML2 plugin precommit handler runs it then sees no segments for the network and sets the provider attributes of the network in the NetworkContext to None. A mechanism driver that is passed a NetworkContext without provider attributes in its delete_network_postcommit method will not have the information to perform the necessary actions. In the case of the networking-generic-switch mechanism driver where this was observed, this resulted in the driver ignoring the event, because the network did not look like a VLAN. This change uses a priority of zero for ML2 network delete precommit handler, to ensure they query the network and store the NetworkContext before the segments service has a chance to delete segments. A similar change has been made for subnets, both to keep the pattern consistent and avoid any similar issues. Change-Id: I6482223ed2a479de4f5ef4cef056c311c0281408 Closes-Bug: #1841967 Depends-On: https://review.opendev.org/680001 (cherry picked from commit fea2d9091f71a2ec88318121ed9a22180e1ae96f) --- neutron/plugins/ml2/plugin.py | 11 +++++++++-- .../notes/fix-net-delete-race-f2fa5bac3ab35a5b.yaml | 9 +++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) create mode 100644 releasenotes/notes/fix-net-delete-race-f2fa5bac3ab35a5b.yaml diff --git a/neutron/plugins/ml2/plugin.py b/neutron/plugins/ml2/plugin.py index 44f466e596f..d0a4bf82e63 100644 --- a/neutron/plugins/ml2/plugin.py +++ b/neutron/plugins/ml2/plugin.py @@ -1157,7 +1157,11 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2, # called inside of a transaction. return super(Ml2Plugin, self).delete_network(context, id) - @registry.receives(resources.NETWORK, [events.PRECOMMIT_DELETE]) + # NOTE(mgoddard): Use a priority of zero to ensure this handler runs before + # other precommit handlers. This is necessary to ensure we avoid another + # handler deleting a subresource of the network, e.g. segments. + @registry.receives(resources.NETWORK, [events.PRECOMMIT_DELETE], + priority=0) def _network_delete_precommit_handler(self, rtype, event, trigger, context, network_id, **kwargs): network = self.get_network(context, network_id) @@ -1268,7 +1272,10 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2, # called inside of a transaction. return super(Ml2Plugin, self).delete_subnet(context, id) - @registry.receives(resources.SUBNET, [events.PRECOMMIT_DELETE]) + # NOTE(mgoddard): Use a priority of zero to ensure this handler runs before + # other precommit handlers. This is necessary to ensure we avoid another + # handler deleting a subresource of the subnet. + @registry.receives(resources.SUBNET, [events.PRECOMMIT_DELETE], priority=0) def _subnet_delete_precommit_handler(self, rtype, event, trigger, context, subnet_id, **kwargs): subnet_obj = self._get_subnet_object(context, subnet_id) diff --git a/releasenotes/notes/fix-net-delete-race-f2fa5bac3ab35a5b.yaml b/releasenotes/notes/fix-net-delete-race-f2fa5bac3ab35a5b.yaml new file mode 100644 index 00000000000..654025082dc --- /dev/null +++ b/releasenotes/notes/fix-net-delete-race-f2fa5bac3ab35a5b.yaml @@ -0,0 +1,9 @@ +--- +fixes: + - | + Fixes an issue where deletion of a provider network could result in ML2 + mechanism drivers not being passed information about the network's provider + fields. The consequences of this depend on the mechanism driver in use, but + could result in the event being ignored, leading to an incorrectly + configured network. See `bug 1841967 + `__ for details.