From 2c8208138a7e881268de62b0b3d80b63b1f3c969 Mon Sep 17 00:00:00 2001 From: Rodolfo Alonso Hernandez Date: Tue, 7 Jun 2022 09:26:04 +0000 Subject: [PATCH] [OVS][QoS] Unset the min-bw QoS from the phys bridge interface The minimum bandwidth OVS QoS policy is set in the physical bridge interface, not the port that receives the Neutron QoS policy. If no other port has a minimum bandwidth rule, the OVS QoS policy can be unset from this port and deleted. This patch fixes the port that must be updated. Closes-Bug: #1977819 Change-Id: I0ebcc85f5ffa9dc29ffedee0c7df1828c85e1576 (cherry picked from commit 9f5e211796dbc0df0bad1ae29fbb82eb7317fb82) --- neutron/agent/common/ovs_lib.py | 11 +++++--- .../functional/agent/common/test_ovs_lib.py | 27 +++++++++++++++---- 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/neutron/agent/common/ovs_lib.py b/neutron/agent/common/ovs_lib.py index b5d520c31e8..e2f26c00664 100644 --- a/neutron/agent/common/ovs_lib.py +++ b/neutron/agent/common/ovs_lib.py @@ -1013,9 +1013,14 @@ class OVSBridge(BaseOVS): self._min_bw_qos_id, qos_constants.RULE_TYPE_MINIMUM_BANDWIDTH, qos_id=qos_id, queues=qos_queues) - self.ovsdb.db_clear('Port', port_id, 'qos').execute( - check_error=False) - if not qos_queues: + else: + # Find the physical bridge interface with the QoS assigned and + # unset it. + for port in self.ovsdb.db_find( + 'Port', ('qos', '=', qos_id), + columns=['_uuid', 'qos']).execute(check_error=True): + self.ovsdb.db_clear('Port', port['_uuid'], + 'qos').execute(check_error=True) self._delete_qos(qos_id) self._delete_queue( queue['_uuid'], qos_constants.RULE_TYPE_MINIMUM_BANDWIDTH) diff --git a/neutron/tests/functional/agent/common/test_ovs_lib.py b/neutron/tests/functional/agent/common/test_ovs_lib.py index 758f9a6ff0f..326de08ecc6 100644 --- a/neutron/tests/functional/agent/common/test_ovs_lib.py +++ b/neutron/tests/functional/agent/common/test_ovs_lib.py @@ -125,14 +125,15 @@ class BaseOVSTestCase(base.BaseSudoTestCase): return None return qoses - def _create_bridge(self): - self.ovs.ovsdb.add_br(self.br_name).execute() - self.elements_to_clean['bridges'].append(self.br_name) + def _create_bridge(self, br_name=None): + br_name = br_name or self.br_name + self.ovs.ovsdb.add_br(br_name).execute() + self.elements_to_clean['bridges'].append(br_name) - def _create_port(self, port_name): + def _create_port(self, port_name, br_name=None): row_event = WaitForPortCreateEvent(port_name) self.ovs.ovsdb.idl.notify_handler.watch_event(row_event) - self.ovs.ovsdb.add_port(self.br_name, port_name).execute( + self.ovs.ovsdb.add_port(br_name or self.br_name, port_name).execute( check_error=True) self.assertTrue(row_event.wait()) @@ -505,6 +506,15 @@ class BaseOVSTestCase(base.BaseSudoTestCase): rule_type_id=self.ovs._min_bw_qos_id) self._check_value({'_uuid': qos_id}, self._list_qos, qos_id, keys_to_check=['_uuid']) + + # Assign the QoS policy to the physical bridge interface. This QoS + # must be unset once the minimum bandwidth queue is removed. + br_phy = ('br-phy-' + uuidutils.generate_uuid())[:6] + ext_port = ('phy-' + uuidutils.generate_uuid())[:9] + self._create_bridge(br_name=br_phy) + self._create_port(ext_port, br_name=br_phy) + self.ovs._set_port_qos(ext_port, qos_id=qos_id) + qos = self._list_qos(qos_id) self.assertEqual(queue_id_1, qos['queues'][1].uuid) self.assertEqual(queue_id_2, qos['queues'][2].uuid) @@ -515,9 +525,16 @@ class BaseOVSTestCase(base.BaseSudoTestCase): qos = self._list_qos(qos_id) self.assertEqual(1, len(qos['queues'])) self.assertEqual(queue_id_1, qos['queues'][1].uuid) + ports_with_qos = self.ovs.ovsdb.db_find( + 'Port', ('qos', '=', qos_id)).execute(check_error=True) + self.assertEqual(1, len(ports_with_qos)) + self.assertEqual(ext_port, ports_with_qos[0]['name']) self.ovs.delete_minimum_bandwidth_queue(neutron_port_id_1) self.assertIsNone(self._list_qos(qos_id)) + ports_with_qos = self.ovs.ovsdb.db_find( + 'Port', ('qos', '=', qos_id)).execute(check_error=True) + self.assertEqual(0, len(ports_with_qos)) def test_delete_minimum_bandwidth_queue_no_qos_found(self): queue_id, neutron_port_id = self._create_queue(queue_num=1)