Merge "Consider hostdev devices when building metadata" into stable/queens

This commit is contained in:
Zuul 2018-07-30 17:55:02 +00:00 committed by Gerrit Code Review
commit 922b32a5de
2 changed files with 63 additions and 3 deletions

View File

@ -1697,6 +1697,12 @@ class LibvirtConnTestCase(test.NoDBTestCase,
<alias name='net0'/>
<address type='ccw' cssid='0xfe' ssid='0x0' devno='0x0001'/>
</interface>
<hostdev mode="subsystem" type="pci" managed="yes">
<source>
<address bus="0x06" domain="0x0000" function="0x1"
slot="0x00"/>
</source>
</hostdev>
</devices>
</domain>"""
@ -1750,24 +1756,32 @@ class LibvirtConnTestCase(test.NoDBTestCase,
vif.instance_uuid = '32dfcb37-5af1-552b-357c-be8c3aa38310'
vif.uuid = '12ec4b21-ef22-6c21-534b-ba3e3ab3a311'
vif.tag = 'mytag1'
vif1 = obj_vif.VirtualInterface(context=self.context)
vif1.address = '51:5a:2c:a4:5e:1b'
vif1.network_id = 123
vif1.instance_uuid = '32dfcb37-5af1-552b-357c-be8c3aa38310'
vif1.uuid = 'abec4b21-ef22-6c21-534b-ba3e3ab3a312'
vif2 = obj_vif.VirtualInterface(context=self.context)
vif2.address = 'fa:16:3e:d1:28:e4'
vif2.network_id = 123
vif2.instance_uuid = '32dfcb37-5af1-552b-357c-be8c3aa38310'
vif2.uuid = '645686e4-7086-4eab-8c2f-c41f017a1b16'
vif2.tag = 'mytag2'
vif3 = obj_vif.VirtualInterface(context=self.context)
vif3.address = '52:54:00:14:6f:50'
vif3.network_id = 123
vif3.instance_uuid = '32dfcb37-5af1-552b-357c-be8c3aa38310'
vif3.uuid = '99cc3604-782d-4a32-a27c-bc33ac56ce86'
vif3.tag = 'mytag3'
vifs = [vif, vif1, vif2, vif3]
vif4 = obj_vif.VirtualInterface(context=self.context)
vif4.address = 'da:d1:f2:91:95:c1'
vif4.tag = 'pf_tag'
vifs = [vif, vif1, vif2, vif3, vif4]
network_info = _fake_network_info(self, 4)
network_info[0]['vnic_type'] = network_model.VNIC_TYPE_DIRECT_PHYSICAL
@ -1784,11 +1798,13 @@ class LibvirtConnTestCase(test.NoDBTestCase,
mock.patch('nova.virt.libvirt.host.Host.get_guest',
return_value=guest),
mock.patch.object(nova.virt.libvirt.guest.Guest, 'get_xml_desc',
return_value=xml)):
return_value=xml),
mock.patch.object(pci_utils, 'get_mac_by_pci_address',
return_value='da:d1:f2:91:95:c1')):
metadata_obj = drvr._build_device_metadata(self.context,
instance_ref)
metadata = metadata_obj.devices
self.assertEqual(10, len(metadata))
self.assertEqual(11, len(metadata))
self.assertIsInstance(metadata[0],
objects.DiskMetadata)
self.assertIsInstance(metadata[0].bus,
@ -1846,6 +1862,11 @@ class LibvirtConnTestCase(test.NoDBTestCase,
self.assertIsInstance(metadata[9],
objects.NetworkInterfaceMetadata)
self.assertEqual(['mytag3'], metadata[9].tags)
self.assertIsInstance(metadata[10],
objects.NetworkInterfaceMetadata)
self.assertEqual(['pf_tag'], metadata[10].tags)
self.assertEqual('da:d1:f2:91:95:c1', metadata[10].mac)
self.assertEqual('0000:06:00.1', metadata[10].bus.address)
@mock.patch.object(host.Host, 'get_connection')
@mock.patch.object(nova.virt.libvirt.guest.Guest, 'get_xml_desc')

View File

@ -8675,6 +8675,42 @@ class LibvirtDriver(driver.ComputeDriver):
device.bus = bus
return device
def _build_hostdev_metadata(self, dev, vifs_to_expose, vlans_by_mac):
"""Builds a metadata object for a hostdev. This can only be a PF, so we
don't need trusted_by_mac like in _build_interface_metadata because
only VFs can be trusted.
:param dev: The LibvirtConfigGuestHostdevPCI to build metadata for.
:param vifs_to_expose: The list of tagged and/or vlan'ed
VirtualInterface objects.
:param vlans_by_mac: A dictionary of mac address -> vlan associations.
:return: A NetworkInterfaceMetadata object, or None.
"""
# Strip out the leading '0x'
pci_address = pci_utils.get_pci_address(
*[x[2:] for x in (dev.domain, dev.bus, dev.slot, dev.function)])
try:
mac = pci_utils.get_mac_by_pci_address(pci_address,
pf_interface=True)
except exception.PciDeviceNotFoundById:
LOG.debug('Not exposing metadata for not found PCI device %s',
pci_address)
return None
vif = vifs_to_expose.get(mac)
if not vif:
LOG.debug('No VIF found with MAC %s, not building metadata', mac)
return None
device = objects.NetworkInterfaceMetadata(mac=mac)
device.bus = objects.PCIDeviceBus(address=pci_address)
if 'tag' in vif and vif.tag:
device.tags = [vif.tag]
vlan = vlans_by_mac.get(mac)
if vlan:
device.vlan = int(vlan)
return device
def _build_device_metadata(self, context, instance):
"""Builds a metadata object for instance devices, that maps the user
provided tag to the hypervisor assigned device address.
@ -8710,6 +8746,9 @@ class LibvirtDriver(driver.ComputeDriver):
vlans_by_mac)
if isinstance(dev, vconfig.LibvirtConfigGuestDisk):
device = self._build_disk_metadata(dev, tagged_bdms)
if isinstance(dev, vconfig.LibvirtConfigGuestHostdevPCI):
device = self._build_hostdev_metadata(dev, vifs_to_expose,
vlans_by_mac)
if device:
devices.append(device)
if devices: