Skip to content

Commit 7da9444

Browse files
author
Balazs Gibizer
committed
Skip querying resource request in revert_resize if no qos port
During revert_resize we can skip collecting port resource requests from neutron if there is no port with allocation key in the binding profile in the network info caches of the instance. Note that we cannot do the same optimization in the MigrationTask as we would like to use migration to heal missing port allocations. See more in bug #1819923. Change-Id: I72d0e28f3b9319e521243d7d0dc5dfa4feaf56f5 blueprint: support-move-ops-with-qos-ports
1 parent 47bfc46 commit 7da9444

File tree

4 files changed

+51
-10
lines changed

4 files changed

+51
-10
lines changed

nova/compute/api.py

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3459,16 +3459,24 @@ def revert_resize(self, context, instance):
34593459
reqspec.flavor = instance.old_flavor
34603460
reqspec.save()
34613461

3462-
# TODO(gibi): do not directly overwrite the
3463-
# RequestSpec.requested_resources as others like cyborg might added
3464-
# to things there already
3465-
# NOTE(gibi): We need to collect the requested resource again as it is
3466-
# intentionally not persisted in nova. Note that this needs to be
3467-
# done here as the nova API code directly calls revert on the
3468-
# dest compute service skipping the conductor.
3469-
port_res_req = self.network_api.get_requested_resource_for_instance(
3470-
context, instance.uuid)
3471-
reqspec.requested_resources = port_res_req
3462+
# NOTE(gibi): This is a performance optimization. If the network info
3463+
# cache does not have ports with allocations in the binding profile
3464+
# then we can skip reading port resource request from neutron below.
3465+
# If a port has resource request then that would have already caused
3466+
# that the finish_resize call put allocation in the binding profile
3467+
# during the resize.
3468+
if instance.get_network_info().has_port_with_allocation():
3469+
# TODO(gibi): do not directly overwrite the
3470+
# RequestSpec.requested_resources as others like cyborg might added
3471+
# to things there already
3472+
# NOTE(gibi): We need to collect the requested resource again as it
3473+
# is intentionally not persisted in nova. Note that this needs to
3474+
# be done here as the nova API code directly calls revert on the
3475+
# dest compute service skipping the conductor.
3476+
port_res_req = (
3477+
self.network_api.get_requested_resource_for_instance(
3478+
context, instance.uuid))
3479+
reqspec.requested_resources = port_res_req
34723480

34733481
instance.task_state = task_states.RESIZE_REVERTING
34743482
instance.save(expected_task_state=[None])

nova/network/model.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -487,6 +487,9 @@ def hydrate(cls, vif):
487487
vif['network'] = Network.hydrate(vif['network'])
488488
return vif
489489

490+
def has_allocation(self):
491+
return self['profile'] and bool(self['profile'].get('allocation'))
492+
490493

491494
def get_netmask(ip, subnet):
492495
"""Returns the netmask appropriate for injection into a guest."""
@@ -540,6 +543,9 @@ def get_plug_time_events(self, migration):
540543
return [('network-vif-plugged', vif['id'])
541544
for vif in self if not vif.has_bind_time_event(migration)]
542545

546+
def has_port_with_allocation(self):
547+
return any(vif.has_allocation() for vif in self)
548+
543549

544550
class NetworkInfoAsyncWrapper(NetworkInfo):
545551
"""Wrapper around NetworkInfo that allows retrieving NetworkInfo

nova/tests/unit/compute/test_compute_api.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
from nova.db import api as db
4343
from nova import exception
4444
from nova.image import api as image_api
45+
from nova.network import model
4546
from nova.network.neutronv2 import api as neutron_api
4647
from nova.network.neutronv2 import constants
4748
from nova import objects
@@ -1663,6 +1664,8 @@ def _test_revert_resize(
16631664
mock_check, mock_get_host_az, mock_get_requested_resources):
16641665
params = dict(vm_state=vm_states.RESIZED)
16651666
fake_inst = self._create_instance_obj(params=params)
1667+
fake_inst.info_cache.network_info = model.NetworkInfo([
1668+
model.VIF(id=uuids.port1, profile={'allocation': uuids.rp})])
16661669
fake_inst.old_flavor = fake_inst.flavor
16671670
fake_mig = objects.Migration._from_db_object(
16681671
self.context, objects.Migration(),
@@ -1722,6 +1725,7 @@ def test_revert_resize_concurrent_fail(
17221725
mock_get_host_az, mock_get_requested_resources):
17231726
params = dict(vm_state=vm_states.RESIZED)
17241727
fake_inst = self._create_instance_obj(params=params)
1728+
fake_inst.info_cache.network_info = model.NetworkInfo([])
17251729
fake_inst.old_flavor = fake_inst.flavor
17261730
fake_mig = objects.Migration._from_db_object(
17271731
self.context, objects.Migration(),
@@ -1746,6 +1750,7 @@ def test_revert_resize_concurrent_fail(
17461750
mock_get_migration.assert_called_once_with(
17471751
self.context, fake_inst['uuid'], 'finished')
17481752
mock_inst_save.assert_called_once_with(expected_task_state=[None])
1753+
mock_get_requested_resources.assert_not_called()
17491754

17501755
@mock.patch('nova.compute.utils.is_volume_backed_instance',
17511756
return_value=False)

nova/tests/unit/network/test_network_info.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -887,6 +887,28 @@ def test_get_events(self):
887887
[('network-vif-plugged', uuids.normal_vif)],
888888
network_info.get_plug_time_events(diff_host))
889889

890+
def test_has_port_with_allocation(self):
891+
network_info = model.NetworkInfo([])
892+
self.assertFalse(network_info.has_port_with_allocation())
893+
894+
network_info.append(
895+
model.VIF(id=uuids.port_without_profile))
896+
self.assertFalse(network_info.has_port_with_allocation())
897+
898+
network_info.append(
899+
model.VIF(id=uuids.port_no_allocation, profile={'foo': 'bar'}))
900+
self.assertFalse(network_info.has_port_with_allocation())
901+
902+
network_info.append(
903+
model.VIF(
904+
id=uuids.port_empty_alloc, profile={'allocation': None}))
905+
self.assertFalse(network_info.has_port_with_allocation())
906+
907+
network_info.append(
908+
model.VIF(
909+
id=uuids.port_with_alloc, profile={'allocation': uuids.rp}))
910+
self.assertTrue(network_info.has_port_with_allocation())
911+
890912

891913
class TestNetworkMetadata(test.NoDBTestCase):
892914
def setUp(self):

0 commit comments

Comments
 (0)