diff --git a/neutron/agent/common/placement_report.py b/neutron/agent/common/placement_report.py index cd37d19d1cd..6e447256c97 100644 --- a/neutron/agent/common/placement_report.py +++ b/neutron/agent/common/placement_report.py @@ -151,12 +151,14 @@ class PlacementState(object): self._driver_uuid_namespace, hypervisor['name'], device) + agent_rp_uuid = place_utils.agent_resource_provider_uuid( + self._driver_uuid_namespace, hypervisor['name']) rps.append( DeferredCall( self._client.ensure_resource_provider, {'name': rp_name, 'uuid': rp_uuid, - 'parent_provider_uuid': hypervisor['uuid']})) + 'parent_provider_uuid': agent_rp_uuid})) return rps def deferred_create_resource_providers(self): diff --git a/neutron/services/placement_report/plugin.py b/neutron/services/placement_report/plugin.py index 49e4987f7d2..cd1ad712b37 100644 --- a/neutron/services/placement_report/plugin.py +++ b/neutron/services/placement_report/plugin.py @@ -161,11 +161,19 @@ class PlacementReportPlugin(service_base.ServicePluginBase): try: LOG.debug('placement client: {}'.format(deferred)) deferred.execute() - except Exception: + except Exception as e: errors = True - LOG.exception( - 'placement client call failed: %s', - str(deferred)) + placement_error_str = \ + 're-parenting a provider is not currently allowed' + if (placement_error_str in str(e)): + msg = ( + 'placement client call failed' + ' (this may be due to bug' + ' https://launchpad.net/bugs/1921150): %s' + ) + else: + msg = 'placement client call failed: %s' + LOG.exception(msg, str(deferred)) resources_synced = not errors agent_db.resources_synced = resources_synced diff --git a/neutron/tests/unit/agent/common/test_placement_report.py b/neutron/tests/unit/agent/common/test_placement_report.py index 4432f144cdb..082e3724cc6 100644 --- a/neutron/tests/unit/agent/common/test_placement_report.py +++ b/neutron/tests/unit/agent/common/test_placement_report.py @@ -47,14 +47,10 @@ class PlacementStateTestCase(base.BaseTestCase): self.client_mock = mock.Mock() self.driver_uuid_namespace = uuid.UUID( '00000000-0000-0000-0000-000000000001') - # uuid below generated by the following command: - # uuid -v5 '00000000-0000-0000-0000-000000000001' 'fakehost' self.hypervisor1_rp_uuid = uuid.UUID( - 'c0b4abe5-516f-54b8-b965-ff94060dcbcc') - # uuid below generated by the following command: - # uuid -v5 '00000000-0000-0000-0000-000000000001' 'fakehost2' + '00000000-0000-0000-0000-000000000002') self.hypervisor2_rp_uuid = uuid.UUID( - '544155b7-1295-5f10-b5f0-eadc50abc6d4') + '00000000-0000-0000-0000-000000000003') self.kwargs = { 'rp_bandwidths': {}, 'rp_inventory_defaults': {}, diff --git a/releasenotes/notes/bug-1921150-c02692e548a3750e.yaml b/releasenotes/notes/bug-1921150-c02692e548a3750e.yaml new file mode 100644 index 00000000000..22e16f0cece --- /dev/null +++ b/releasenotes/notes/bug-1921150-c02692e548a3750e.yaml @@ -0,0 +1,17 @@ +--- +issues: + - | + When using the minimim-bandwidth QoS feature due to bug + https://launchpad.net/bugs/1921150 physical NIC resource providers + were for some time created with the wrong parent (i.e. the + hypervisor RP). This is now partially fixed and new resource + providers are created now with the expected parent (i.e. the agent + RP). However Placement does not allow re-parenting an already + existing resource provider, therefore the following Placement + DB update may be needed after the fix for bug 1921150 is applied: + neutron/tools/bug-1921150-re-parent-device-rps.sql + Until all resource providers have the proper parent, neutron-server + will retry the re-parenting update, which will be rejected every time, + therefore expect polluted logs and some wasted load on Placement. + However please note that the bandwidth-aware scheduling is supposed + to work even with the wrongly parented resource providers. diff --git a/tools/bug-1921150-re-parent-device-rps.sql b/tools/bug-1921150-re-parent-device-rps.sql new file mode 100644 index 00000000000..c87a0c2845c --- /dev/null +++ b/tools/bug-1921150-re-parent-device-rps.sql @@ -0,0 +1,52 @@ +/* + Licensed under the Apache License, Version 2.0 (the "License"); you may + not use this file except in compliance with the License. You may obtain + a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + License for the specific language governing permissions and limitations + under the License. +*/ + +/* +Fix wrongly parented physical NIC resource providers due to bug +https://bugs.launchpad.net/neutron/+bug/1921150 + +Compatible with MySQL. +*/ + +USE placement; + +SELECT 'Affected device RPs:' as ''; + +SELECT * +FROM resource_providers +WHERE + (name LIKE '%:NIC Switch agent:%' OR + name LIKE '%:Open vSwitch agent:%') AND + parent_provider_id=root_provider_id; + + +/* +To find the proper parent we have to use the naming scheme of the RPs which +is :: +The name of the proper parent for deviceRP is name of the deviceRP minus +everything after the second ':'. +*/ + +UPDATE resource_providers as rp +INNER JOIN resource_providers as parent_rp +ON + parent_rp.name=SUBSTRING(rp.name, 1, LOCATE(':', rp.name, LOCATE(':', rp.name) + 1) -1) +SET + rp.parent_provider_id = parent_rp.id +WHERE + (rp.name LIKE '%:NIC Switch agent:%' OR + rp.name LIKE '%:Open vSwitch agent:%') AND + rp.parent_provider_id=rp.root_provider_id; + +SELECT CONCAT('Fixed ', ROW_COUNT(), ' RPs') as '';