Update RequestSpec.pci_request for resize
Nova uses the RequestSpec.pci_request in the PciPassthroughFilter to decide if the PCI devicesm, requested via the pci_alias in the flavor extra_spec, are available on a potential target host. During resize the new flavor might contain different pci_alias request than the old flavor of the instance. In this case Nova should use the pci_alias from the new flavor to scheduler the destination host of the resize. However this logic was missing and Nova used the old pci_request value based on the old flavor. This patch adds the missing logic. Closes-Bug: #1983753 Closes-Bug: #1941005 Change-Id: I73c9ae27e9c42ee211a53bed3d849650b65f08be
This commit is contained in:
parent
6d602c6b73
commit
a93092e0d5
@ -4227,6 +4227,19 @@ class API:
|
||||
if not same_flavor:
|
||||
request_spec.numa_topology = hardware.numa_get_constraints(
|
||||
new_flavor, instance.image_meta)
|
||||
# if the flavor is changed then we need to recalculate the
|
||||
# pci_requests as well because the new flavor might request
|
||||
# different pci_aliases
|
||||
new_pci_requests = pci_request.get_pci_requests_from_flavor(
|
||||
new_flavor)
|
||||
new_pci_requests.instance_uuid = instance.uuid
|
||||
# The neutron based InstancePCIRequest cannot change during resize,
|
||||
# so we just need to copy them from the old request
|
||||
for request in request_spec.pci_requests.requests or []:
|
||||
if request.source == objects.InstancePCIRequest.NEUTRON_PORT:
|
||||
new_pci_requests.requests.append(request)
|
||||
request_spec.pci_requests = new_pci_requests
|
||||
|
||||
# TODO(huaqiang): Remove in Wallaby
|
||||
# check nova-compute nodes have been updated to Victoria to resize
|
||||
# instance to a new mixed instance from a dedicated or shared
|
||||
|
@ -1389,13 +1389,16 @@ class PCIServersTest(_PCIServersTestBase):
|
||||
|
||||
# Resize it to a flavor without PCI devices. We expect this to work, as
|
||||
# test_compute1 is available.
|
||||
# FIXME(artom) This is bug 1941005.
|
||||
flavor_id = self._create_flavor()
|
||||
ex = self.assertRaises(client.OpenStackApiException,
|
||||
self._resize_server, server, flavor_id)
|
||||
self.assertEqual(500, ex.response.status_code)
|
||||
self.assertIn('NoValidHost', str(ex))
|
||||
# self._confirm_resize(server)
|
||||
with mock.patch(
|
||||
'nova.virt.libvirt.driver.LibvirtDriver'
|
||||
'.migrate_disk_and_power_off',
|
||||
return_value='{}',
|
||||
):
|
||||
self._resize_server(server, flavor_id)
|
||||
self._confirm_resize(server)
|
||||
self.assertPCIDeviceCounts('test_compute0', total=1, free=1)
|
||||
self.assertPCIDeviceCounts('test_compute1', total=0, free=0)
|
||||
|
||||
def _confirm_resize(self, server, host='host1'):
|
||||
# NOTE(sbauza): Unfortunately, _cleanup_resize() in libvirt checks the
|
||||
|
@ -16,7 +16,6 @@ import fixtures
|
||||
from oslo_serialization import jsonutils
|
||||
|
||||
from nova.tests.fixtures import libvirt as fakelibvirt
|
||||
from nova.tests.functional.api import client
|
||||
from nova.tests.functional.libvirt import test_pci_sriov_servers
|
||||
|
||||
|
||||
@ -119,19 +118,10 @@ class TestPciResize(test_pci_sriov_servers._PCIServersTestBase):
|
||||
"compute2", total=num_pci_on_dest, free=num_pci_on_dest - 1)
|
||||
|
||||
def test_resize_from_two_devs_to_one_dev_dest_has_two_devs(self):
|
||||
# this works
|
||||
self._test_resize_from_two_devs_to_one_dev(num_pci_on_dest=2)
|
||||
|
||||
def test_resize_from_two_devs_to_one_dev_dest_has_one_dev(self):
|
||||
# This is bug 1983753 as nova uses the old InstancePciRequest during
|
||||
# the scheduling and therefore tries to find a compute with two PCI
|
||||
# devs even though the flavor only requests one.
|
||||
ex = self.assertRaises(
|
||||
client.OpenStackApiException,
|
||||
self._test_resize_from_two_devs_to_one_dev,
|
||||
num_pci_on_dest=1
|
||||
)
|
||||
self.assertIn('nova.exception.NoValidHost', str(ex))
|
||||
self._test_resize_from_two_devs_to_one_dev(num_pci_on_dest=1)
|
||||
|
||||
def test_resize_from_vf_to_pf(self):
|
||||
# The fake libvirt will emulate on the host:
|
||||
@ -181,13 +171,7 @@ class TestPciResize(test_pci_sriov_servers._PCIServersTestBase):
|
||||
# dev. This should fit to compute2 having exactly one PF dev.
|
||||
extra_spec = {"pci_passthrough:alias": "a-pf:1"}
|
||||
flavor_id = self._create_flavor(extra_spec=extra_spec)
|
||||
# This is bug 1983753 as nova uses the old InstancePciRequest during
|
||||
# the scheduling and therefore tries to find a compute with a VF dev
|
||||
# even though the flavor only requests a PF dev.
|
||||
ex = self.assertRaises(
|
||||
client.OpenStackApiException,
|
||||
self._resize_server,
|
||||
server,
|
||||
flavor_id=flavor_id,
|
||||
)
|
||||
self.assertIn('nova.exception.NoValidHost', str(ex))
|
||||
self._resize_server(server, flavor_id=flavor_id)
|
||||
self._confirm_resize(server)
|
||||
self.assertPCIDeviceCounts("compute1", total=1, free=1)
|
||||
self.assertPCIDeviceCounts("compute2", total=1, free=0)
|
||||
|
@ -2089,7 +2089,8 @@ class _ComputeAPIUnitTestMixIn(object):
|
||||
filter_properties = {'ignore_hosts': [fake_inst['host']]}
|
||||
|
||||
if request_spec:
|
||||
fake_spec = objects.RequestSpec()
|
||||
fake_spec = objects.RequestSpec(
|
||||
pci_requests=objects.InstancePCIRequests(requests=[]))
|
||||
if requested_destination:
|
||||
cell1 = objects.CellMapping(uuid=uuids.cell1, name='cell1')
|
||||
fake_spec.requested_destination = objects.Destination(
|
||||
|
Loading…
Reference in New Issue
Block a user