Add VIFHostDevice support to libvirt driver

This patch adds VIFHostDevice support to the libvirt driver.

* The os-vif VIFHostDevice object describes a PCI passthrough network
  device when dev_type is "ethernet". For an in-depth description, consult:
  https://libvirt.org/formatdomain.html#elementsNICSHostdev

* VIFHostDevice does not specify 802.1Qbh or VLAN options, therefore
  it can be viewed as a simplified "VEB".

* VIFHostDevice with an OVS Representor port profile can be used
  to plug/unplug accelerated OVS ports in future patches.

* TODO: when dev_type is "generic", the object describes a generic
  PCI passthrough device as described in:
  https://libvirt.org/formatdomain.html#elementsHostDevSubsys
  Currently this mode is unimplemented and requires possible changes to
  the XML configuration classes or fundamental os-vif code.

Change-Id: Id7d3964ee632089e7dd2c3fd446a349b1bb9832e
Signed-off-by: Jan Gutter <jan.gutter@netronome.com>
This commit is contained in:
Jan Gutter 2017-07-23 20:04:21 +02:00
parent a553373a14
commit b4c1a2059d
2 changed files with 78 additions and 0 deletions

View File

@ -20,6 +20,7 @@ import mock
import os_vif
from os_vif import exception as osv_exception
from os_vif import objects as osv_objects
from os_vif.objects import fields as osv_fields
from oslo_concurrency import processutils
from oslo_config import cfg
import six
@ -398,6 +399,24 @@ class LibvirtVifTestCase(test.NoDBTestCase):
port_profile=self.os_vif_ovs_prof,
network=self.os_vif_network)
self.os_vif_hostdevice_ethernet = osv_objects.vif.VIFHostDevice(
id="dc065497-3c8d-4f44-8fb4-e1d33c16a536",
address="22:52:25:62:e2:aa",
plugin="linux_bridge",
vif_name="nicdc065497-3c",
dev_type=osv_fields.VIFHostDeviceDevType.ETHERNET,
dev_address='0000:0a:00.1',
network=self.os_vif_network)
self.os_vif_hostdevice_generic = osv_objects.vif.VIFHostDevice(
id="dc065497-3c8d-4f44-8fb4-e1d33c16a536",
address="22:52:25:62:e2:aa",
plugin="linux_bridge",
vif_name="nicdc065497-3c",
dev_type=osv_fields.VIFHostDeviceDevType.GENERIC,
dev_address='0000:0a:00.1',
network=self.os_vif_network)
self.os_vif_inst_info = osv_objects.instance_info.InstanceInfo(
uuid="d5b1090c-9e00-4fa4-9504-4b1494857970",
name="instance-000004da",
@ -1556,3 +1575,45 @@ class LibvirtVifTestCase(test.NoDBTestCase):
<filterref
filter="nova-instance-instance-00000001-22522562e2aa"/>
</interface>""", cfg.to_xml())
@mock.patch("nova.network.os_vif_util.nova_to_osvif_instance")
@mock.patch("nova.network.os_vif_util.nova_to_osvif_vif")
def test_config_os_vif_hostdevice_ethernet(self, mock_convert_vif,
mock_convert_inst):
mock_convert_vif.return_value = self.os_vif_hostdevice_ethernet
mock_convert_inst.return_value = self.os_vif_inst_info
hostimpl = host.Host("qemu:///system")
flavor = objects.Flavor(name='m1.small')
image_meta = objects.ImageMeta.from_dict({})
d = vif.LibvirtGenericVIFDriver()
cfg = d.get_config(self.instance, self.vif_bridge,
image_meta, flavor,
CONF.libvirt.virt_type,
hostimpl)
self._assertXmlEqual("""
<interface type="hostdev" managed="yes">
<mac address="22:52:25:62:e2:aa"/>
<source>
<address type="pci" domain="0x0000"
bus="0x0a" slot="0x00" function="0x1"/>
</source>
</interface>""", cfg.to_xml())
@mock.patch("nova.network.os_vif_util.nova_to_osvif_instance")
@mock.patch("nova.network.os_vif_util.nova_to_osvif_vif")
def test_config_os_vif_hostdevice_generic(self, mock_convert_vif,
mock_convert_inst):
mock_convert_vif.return_value = self.os_vif_hostdevice_generic
mock_convert_inst.return_value = self.os_vif_inst_info
hostimpl = host.Host("qemu:///system")
flavor = objects.Flavor(name='m1.small')
image_meta = objects.ImageMeta.from_dict({})
d = vif.LibvirtGenericVIFDriver()
self.assertRaises(exception.InternalError,
d.get_config, self.instance, self.vif_bridge,
image_meta, flavor, CONF.libvirt.virt_type,
hostimpl)

View File

@ -23,6 +23,7 @@ import os
import os_vif
from os_vif import exception as osv_exception
from os_vif.objects import fields as osv_fields
from oslo_concurrency import processutils
from oslo_log import log as logging
@ -468,6 +469,22 @@ class LibvirtGenericVIFDriver(object):
conf.driver_name = None
conf.vhost_queues = None
def _set_config_VIFHostDevice(self, instance, vif, conf, host=None):
if vif.dev_type == osv_fields.VIFHostDeviceDevType.ETHERNET:
# This sets the required fields for an <interface type='hostdev'>
# section in a libvirt domain (by using a subset of hw_veb's
# options).
designer.set_vif_host_backend_hw_veb(
conf, 'hostdev', vif.dev_address, None)
else:
# TODO(jangutter): dev_type == VIFHostDeviceDevType.GENERIC
# is currently unsupported under os-vif. The corresponding conf
# class would be: LibvirtConfigGuestHostdevPCI
# but os-vif only returns a LibvirtConfigGuestInterface object
raise exception.InternalError(
_("Unsupported os-vif VIFHostDevice dev_type %(type)s") %
{'type': vif.dev_type})
def _set_config_VIFPortProfileOpenVSwitch(self, profile, conf):
conf.vporttype = "openvswitch"
conf.add_vport_param("interfaceid",