Fix detach SR-IOV when using LibvirtConfigGuestHostdevPCI

This patch fixes an issue which was introduced by this
change If3edc1965c01a077eb61984a442e0d778d870d75.
Usually the vif config is of type LibvirtConfigGuestInterface,
but some vif use LibvirtConfigGuestHostdevPCI config
(e.g.  the ib_hostdev). The difference is that
LibvirtConfigGuestInterface keeps the pci address in source_dev
while LibvirtConfigGuestHostdevPCI has domain, bus, slot and
function, instead of relying on the vif config type we can take the
pci address for the neutron port.

Closes-Bug: #1560860

Change-Id: I62a7ff16f1c9c5da923451520fbeeabb5cc0c5c6
(cherry picked from commit f15d9a9693)
This commit is contained in:
Moshe Levi 2016-03-23 10:59:04 +02:00 committed by Matt Riedemann
parent 8cfb483c83
commit a9d55427b6
2 changed files with 27 additions and 24 deletions

View File

@ -10357,15 +10357,11 @@ class LibvirtConnTestCase(test.NoDBTestCase):
@mock.patch.object(host.Host,
'has_min_version', return_value=True)
@mock.patch.object(FakeVirtDomain, 'detachDeviceFlags')
@mock.patch.object(utils, 'get_image_from_system_metadata',
return_value=None)
def test_detach_sriov_ports(self,
mock_get_image_metadata,
mock_detachDeviceFlags,
mock_has_min_version):
def _test_detach_sriov_ports(self,
mock_has_min_version, vif_type):
instance = objects.Instance(**self.test_instance)
expeted_pci_slot = "0000:00:00.0"
network_info = _fake_network_info(self, 1)
network_info[0]['vnic_type'] = network_model.VNIC_TYPE_DIRECT
# some more adjustments for the fake network_info so that
@ -10374,27 +10370,37 @@ class LibvirtConnTestCase(test.NoDBTestCase):
# and most importantly the pci_slot which is translated to
# cfg.source_dev, then to PciDevice.address and sent to
# _detach_pci_devices
network_info[0]['profile'] = dict(pci_slot="0000:00:00.0")
network_info[0]['type'] = "hw_veb"
network_info[0]['profile'] = dict(pci_slot=expeted_pci_slot)
network_info[0]['type'] = vif_type
network_info[0]['details'] = dict(vlan="2145")
instance.info_cache = objects.InstanceInfoCache(
network_info=network_info)
# fill the pci_devices of the instance so that
# pci_manager.get_instance_pci_devs will not return an empty list
# which will eventually fail the assertion for detachDeviceFlags
expected_pci_device_obj = (
objects.PciDevice(address=expeted_pci_slot, request_id=None))
instance.pci_devices = objects.PciDeviceList()
instance.pci_devices.objects = [
objects.PciDevice(address='0000:00:00.0', request_id=None)
]
instance.pci_devices.objects = [expected_pci_device_obj]
domain = FakeVirtDomain()
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
guest = libvirt_guest.Guest(domain)
drvr._detach_sriov_ports(self.context, instance, guest)
mock_get_image_metadata.assert_called_once_with(
instance.system_metadata)
self.assertTrue(mock_detachDeviceFlags.called)
with mock.patch.object(drvr, '_detach_pci_devices') as mock_detach_pci:
drvr._detach_sriov_ports(self.context, instance, guest)
mock_detach_pci.assert_called_once_with(
guest, [expected_pci_device_obj])
def test_detach_sriov_ports_interface_interface_hostdev(self):
# Note: test detach_sriov_ports method for vif with config
# LibvirtConfigGuestInterface
self._test_detach_sriov_ports(vif_type="hw_veb")
def test_detach_sriov_ports_interface_pci_hostdev(self):
# Note: test detach_sriov_ports method for vif with config
# LibvirtConfigGuestHostdevPCI
self._test_detach_sriov_ports(vif_type="ib_hostdev")
@mock.patch.object(host.Host, 'has_min_version', return_value=True)
@mock.patch.object(FakeVirtDomain, 'detachDeviceFlags')

View File

@ -3413,16 +3413,13 @@ class LibvirtDriver(driver.ComputeDriver):
raise exception.PciDeviceDetachFailed(reason=reason,
dev=network_info)
image_meta = objects.ImageMeta.from_instance(instance)
# In case of SR-IOV vif types we create pci request per SR-IOV port
# Therefore we can trust that pci_slot value in the vif is correct.
sriov_pci_addresses = [
self.vif_driver.get_config(instance,
vif,
image_meta,
instance.flavor,
CONF.libvirt.virt_type,
self._host).source_dev
vif['profile']['pci_slot']
for vif in network_info
if vif['vnic_type'] in network_model.VNIC_TYPES_SRIOV
if vif['vnic_type'] in network_model.VNIC_TYPES_SRIOV and
vif['profile'].get('pci_slot') is not None
]
# use detach_pci_devices to avoid failure in case of