From 95342f389cc965f936388c25d5c73760b9b9cef9 Mon Sep 17 00:00:00 2001 From: Boden R Date: Fri, 16 Oct 2015 13:04:57 -0600 Subject: [PATCH] psec profile distributed locking Change the current NSX v3 plugin implementation to use distributed locking when initializing the port security spoofguard profile. stable/liberty backport candidate Change-Id: I26419f757399aba21c131cefff9745ffd377ec98 --- vmware_nsx/plugins/nsx_v3/plugin.py | 22 ++++++++++++--------- vmware_nsx/tests/unit/nsx_v3/test_plugin.py | 6 ++++++ 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/vmware_nsx/plugins/nsx_v3/plugin.py b/vmware_nsx/plugins/nsx_v3/plugin.py index 4f30b68927..cbd0ef88ff 100644 --- a/vmware_nsx/plugins/nsx_v3/plugin.py +++ b/vmware_nsx/plugins/nsx_v3/plugin.py @@ -59,6 +59,7 @@ from oslo_utils import importutils from oslo_utils import uuidutils from vmware_nsx.common import config # noqa from vmware_nsx.common import exceptions as nsx_exc +from vmware_nsx.common import locking from vmware_nsx.common import nsx_constants from vmware_nsx.common import utils from vmware_nsx.db import db as nsx_db @@ -194,19 +195,22 @@ class NsxV3Plugin(addr_pair_db.AllowedAddressPairsMixin, @utils.retry_upon_exception_nsxv3(Exception) def _init_port_security_profile(self): - # NOTE(boden): potential race cond with distributed plugins - # whereupon a different plugin could create the profile - # after we don't find an existing one and create another profile = self._get_port_security_profile() if profile: return profile - self._switching_profiles.create_spoofguard_profile( - NSX_V3_PSEC_PROFILE_NAME, 'Neutron Port Security Profile', - whitelist_ports=True, whitelist_switches=False, - tags=utils.build_v3_tags_payload({ - 'id': NSX_V3_PSEC_PROFILE_NAME, - 'tenant_id': 'neutron-nsx-plugin'})) + with locking.LockManager.get_lock('nsxv3_psec_profile_init'): + # NOTE(boden): double-checked locking pattern + profile = self._get_port_security_profile() + if profile: + return profile + + self._switching_profiles.create_spoofguard_profile( + NSX_V3_PSEC_PROFILE_NAME, 'Neutron Port Security Profile', + whitelist_ports=True, whitelist_switches=False, + tags=utils.build_v3_tags_payload({ + 'id': NSX_V3_PSEC_PROFILE_NAME, + 'tenant_id': 'neutron-nsx-plugin'})) return self._get_port_security_profile() diff --git a/vmware_nsx/tests/unit/nsx_v3/test_plugin.py b/vmware_nsx/tests/unit/nsx_v3/test_plugin.py index 4d9fd747b0..3fbb62f4bd 100644 --- a/vmware_nsx/tests/unit/nsx_v3/test_plugin.py +++ b/vmware_nsx/tests/unit/nsx_v3/test_plugin.py @@ -12,6 +12,7 @@ # implied. # See the License for the specific language governing permissions and # limitations under the License. +import mock import six from neutron.api.v2 import attributes @@ -78,6 +79,11 @@ class NsxV3PluginTestCaseMixin(test_plugin.NeutronDbPluginV2TestCase, if getattr(self.plugin, '_port_client', None): self.plugin._port_client._client._session = self.mock_api + mocked_locking = mock.patch.object( + nsx_plugin, 'locking', new=mock.Mock()) + mocked_locking.start() + self._patchers.append(mocked_locking) + self.maxDiff = None def tearDown(self):