Skip to content

Commit

Permalink
Reproduce bug 1981813 in func env
Browse files Browse the repository at this point in the history
There stable/yoga only change in test_pci_sriov_servers.py due to
unittest.mock switch[1] only happened in zed.

[1] https://review.opendev.org/q/topic:unittest.mock+status:merged+project:openstack/nova

Related-Bug: #1981813
Change-Id: I9367b7ed475917bdb05eb3f209ce1a4e646534e2
(cherry picked from commit f8c91eb)
(cherry picked from commit 4954f99)
  • Loading branch information
gibizer committed Jan 25, 2023
1 parent d3f3dd8 commit 0c87681
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 3 deletions.
9 changes: 6 additions & 3 deletions nova/tests/fixtures/libvirt.py
Original file line number Diff line number Diff line change
Expand Up @@ -2185,9 +2185,12 @@ def setUp(self):

# libvirt driver needs to call out to the filesystem to get the
# parent_ifname for the SRIOV VFs.
self.useFixture(fixtures.MockPatch(
'nova.pci.utils.get_ifname_by_pci_address',
return_value='fake_pf_interface_name'))
self.mock_get_ifname_by_pci_address = self.useFixture(
fixtures.MockPatch(
"nova.pci.utils.get_ifname_by_pci_address",
return_value="fake_pf_interface_name",
)
).mock

self.useFixture(fixtures.MockPatch(
'nova.pci.utils.get_mac_by_pci_address',
Expand Down
74 changes: 74 additions & 0 deletions nova/tests/functional/libvirt/test_pci_sriov_servers.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@

import nova
from nova import context
from nova import exception
from nova.network import constants
from nova import objects
from nova.objects import fields
Expand Down Expand Up @@ -944,6 +945,79 @@ def test_create_server_after_change_in_nonsriov_pf_to_sriov_pf(self):
],
)

def test_change_bound_port_vnic_type_kills_compute_at_restart(self):
"""Create a server with a direct port and change the vnic_type of the
bound port to macvtap. Then restart the compute service.
As the vnic_type is changed on the port but the vif_type is hwveb
instead of macvtap the vif plug logic will try to look up the netdev
of the parent VF. Howvere that VF consumed by the instance so the
netdev does not exists. This causes that the compute service will fail
with an exception during startup
"""
pci_info = fakelibvirt.HostPCIDevicesInfo(num_pfs=1, num_vfs=2)
self.start_compute(pci_info=pci_info)

# create a direct port
port = self.neutron.network_4_port_1
self.neutron.create_port({'port': port})

# create a server using the VF via neutron
server = self._create_server(networks=[{'port': port['id']}])

# update the vnic_type of the port in neutron
port = copy.deepcopy(port)
port['binding:vnic_type'] = 'macvtap'
self.neutron.update_port(port['id'], {"port": port})

compute = self.computes['compute1']

# Force an update on the instance info cache to ensure nova gets the
# information about the updated port
with context.target_cell(
context.get_admin_context(),
self.host_mappings['compute1'].cell_mapping
) as cctxt:
compute.manager._heal_instance_info_cache(cctxt)

def fake_get_ifname_by_pci_address(pci_addr: str, pf_interface=False):
# we want to fail the netdev lookup only if the pci_address is
# already consumed by our instance. So we look into the instance
# definition to see if the device is attached to the instance as VF
conn = compute.manager.driver._host.get_connection()
dom = conn.lookupByUUIDString(server['id'])
dev = dom._def['devices']['nics'][0]
lookup_addr = pci_addr.replace(':', '_').replace('.', '_')
if (
dev['type'] == 'hostdev' and
dev['source'] == 'pci_' + lookup_addr
):
# nova tried to look up the netdev of an already consumed VF.
# So we have to fail
raise exception.PciDeviceNotFoundById(id=pci_addr)

# We need to simulate the actual failure manually as in our functional
# environment all the PCI lookup is mocked. In reality nova tries to
# look up the netdev of the pci device on the host used by the port as
# the parent of the macvtap. However, as the originally direct port is
# bound to the instance, the VF pci device is already consumed by the
# instance and therefore there is no netdev for the VF.
with mock.patch(
'nova.pci.utils.get_ifname_by_pci_address',
side_effect=fake_get_ifname_by_pci_address,
):
# This is bug 1981813 as the compute service fails to start with an
# exception.
# Nova cannot prevent the vnic_type change on a bound port. Neutron
# should prevent that instead. But the nova-compute should still
# be able to start up and only log an ERROR for this instance in
# inconsistent state.
self.assertRaises(
exception.PciDeviceNotFoundById,
self.restart_compute_service,
'compute1',
)


class SRIOVAttachDetachTest(_PCIServersTestBase):
# no need for aliases as these test will request SRIOV via neutron
Expand Down

0 comments on commit 0c87681

Please sign in to comment.