Libvirt: Support for generic vhostuser vif.
This commit implements support for generic vhostuser vif. Change-Id: I827aa45698ff53418725a112acdc42dfacbc1c61 Blueprint: libvirt-vif-vhost-user Co-Authored-By: Luke Gorrie <luke@snabb.co>
This commit is contained in:
parent
a4f9c1b9f4
commit
9e2605bee8
|
@ -732,6 +732,11 @@ class NetworkMissingPhysicalNetwork(NovaException):
|
|||
msg_fmt = _("Physical network is missing for network %(network_uuid)s")
|
||||
|
||||
|
||||
class VifDetailsMissingVhostuserSockPath(Invalid):
|
||||
msg_fmt = _("vhostuser_sock_path not present in vif_details"
|
||||
" for vif %(vif_id)s")
|
||||
|
||||
|
||||
class DatastoreNotFound(NotFound):
|
||||
msg_fmt = _("Could not find the datastore reference(s) which the VM uses.")
|
||||
|
||||
|
|
|
@ -39,6 +39,7 @@ VIF_TYPE_802_QBH = '802.1qbh'
|
|||
VIF_TYPE_HW_VEB = 'hw_veb'
|
||||
VIF_TYPE_MLNX_DIRECT = 'mlnx_direct'
|
||||
VIF_TYPE_MIDONET = 'midonet'
|
||||
VIF_TYPE_VHOSTUSER = 'vhostuser'
|
||||
VIF_TYPE_OTHER = 'other'
|
||||
|
||||
# Constants for dictionary keys in the 'vif_details' field in the VIF
|
||||
|
@ -53,6 +54,13 @@ VIF_DETAILS_PHYSICAL_NETWORK = 'physical_network'
|
|||
VIF_DETAILS_PROFILEID = 'profileid'
|
||||
VIF_DETAILS_VLAN = 'vlan'
|
||||
|
||||
# Constants for vhost-user related fields in 'vif_details'.
|
||||
# Sets mode on vhost-user socket, valid values are 'client'
|
||||
# and 'server'
|
||||
VIF_DETAILS_VHOSTUSER_MODE = 'vhostuser_mode'
|
||||
# Location of the directory to store vhost-user sockets
|
||||
VIF_DETAILS_VHOSTUSER_DIR = 'vhostuser_sock_dir'
|
||||
|
||||
# Define supported virtual NIC types. VNIC_TYPE_DIRECT and VNIC_TYPE_MACVTAP
|
||||
# are used for SR-IOV ports
|
||||
VNIC_TYPE_NORMAL = 'normal'
|
||||
|
|
|
@ -1297,6 +1297,22 @@ class LibvirtConfigGuestInterfaceTest(LibvirtConfigBaseTest):
|
|||
</vlan>
|
||||
</interface>""")
|
||||
|
||||
def test_config_vhostuser(self):
|
||||
obj = config.LibvirtConfigGuestInterface()
|
||||
obj.net_type = "vhostuser"
|
||||
obj.vhostuser_type = "unix"
|
||||
obj.vhostuser_mode = "server"
|
||||
obj.mac_addr = "DE:AD:BE:EF:CA:FE"
|
||||
obj.vhostuser_path = "/vhost-user/test.sock"
|
||||
obj.model = "virtio"
|
||||
xml = obj.to_xml()
|
||||
self.assertXmlEqual(xml, """
|
||||
<interface type="vhostuser">
|
||||
<mac address="DE:AD:BE:EF:CA:FE"/>
|
||||
<model type="virtio"/>
|
||||
<source type="unix" mode="server" path="/vhost-user/test.sock"/>
|
||||
</interface>""")
|
||||
|
||||
|
||||
class LibvirtConfigGuestFeatureTest(LibvirtConfigBaseTest):
|
||||
|
||||
|
|
|
@ -261,6 +261,20 @@ class LibvirtVifTestCase(test.NoDBTestCase):
|
|||
type=network_model.VIF_TYPE_IOVISOR,
|
||||
devname='tap-xxx-yyy-zzz',
|
||||
ovs_interfaceid=None)
|
||||
vif_vhostuser = network_model.VIF(id='vif-xxx-yyy-zzz',
|
||||
address='ca:fe:de:ad:be:ef',
|
||||
network=network_bridge,
|
||||
type=network_model.VIF_TYPE_VHOSTUSER,
|
||||
details = {network_model.VIF_DETAILS_VHOSTUSER_MODE: 'client',
|
||||
network_model.VIF_DETAILS_VHOSTUSER_DIR: '/tmp'}
|
||||
)
|
||||
|
||||
vif_vhostuser_no_path = network_model.VIF(id='vif-xxx-yyy-zzz',
|
||||
address='ca:fe:de:ad:be:ef',
|
||||
network=network_bridge,
|
||||
type=network_model.VIF_TYPE_VHOSTUSER,
|
||||
details = {network_model.VIF_DETAILS_VHOSTUSER_MODE: 'client'}
|
||||
)
|
||||
|
||||
instance = {
|
||||
'name': 'instance-name',
|
||||
|
@ -1022,3 +1036,27 @@ class LibvirtVifTestCase(test.NoDBTestCase):
|
|||
self.assertTrue(type_id_found)
|
||||
self.assertTrue(typeversion_id_found)
|
||||
self.assertTrue(instance_id_found)
|
||||
|
||||
def test_vhostuser_driver(self):
|
||||
d = vif.LibvirtGenericVIFDriver()
|
||||
xml = self._get_instance_xml(d, self.vif_vhostuser)
|
||||
node = self._get_node(xml)
|
||||
self.assertEqual(node.get("type"),
|
||||
network_model.VIF_TYPE_VHOSTUSER)
|
||||
|
||||
self._assertTypeEquals(node, network_model.VIF_TYPE_VHOSTUSER,
|
||||
"source", "mode", "client")
|
||||
self._assertTypeEquals(node, network_model.VIF_TYPE_VHOSTUSER,
|
||||
"source", "path", "/tmp/vif-xxx-yyy-zzz")
|
||||
self._assertTypeEquals(node, network_model.VIF_TYPE_VHOSTUSER,
|
||||
"source", "type", "unix")
|
||||
self._assertMacEquals(node, self.vif_vhostuser)
|
||||
self._assertModel(xml, network_model.VIF_MODEL_VIRTIO)
|
||||
|
||||
def test_vhostuser_driver_no_path(self):
|
||||
d = vif.LibvirtGenericVIFDriver()
|
||||
|
||||
self.assertRaises(exception.VifDetailsMissingVhostuserSockPath,
|
||||
self._get_instance_xml,
|
||||
d,
|
||||
self.vif_vhostuser_no_path)
|
||||
|
|
|
@ -1127,6 +1127,9 @@ class LibvirtConfigGuestInterface(LibvirtConfigGuestDevice):
|
|||
self.filtername = None
|
||||
self.filterparams = []
|
||||
self.driver_name = None
|
||||
self.vhostuser_mode = None
|
||||
self.vhostuser_path = None
|
||||
self.vhostuser_type = None
|
||||
self.vif_inbound_peak = None
|
||||
self.vif_inbound_burst = None
|
||||
self.vif_inbound_average = None
|
||||
|
@ -1165,6 +1168,10 @@ class LibvirtConfigGuestInterface(LibvirtConfigGuestDevice):
|
|||
addr_elem.set("function", "0x%s" % (func))
|
||||
source_elem.append(addr_elem)
|
||||
dev.append(source_elem)
|
||||
elif self.net_type == "vhostuser":
|
||||
dev.append(etree.Element("source", type=self.vhostuser_type,
|
||||
mode=self.vhostuser_mode,
|
||||
path=self.vhostuser_path))
|
||||
else:
|
||||
dev.append(etree.Element("source", bridge=self.source_dev))
|
||||
|
||||
|
|
|
@ -142,6 +142,16 @@ def set_vif_host_backend_direct_config(conf, devname):
|
|||
conf.model = "virtio"
|
||||
|
||||
|
||||
def set_vif_host_backend_vhostuser_config(conf, mode, path):
|
||||
"""Populate a LibvirtConfigGuestInterface instance
|
||||
with host backend details for vhostuser socket.
|
||||
"""
|
||||
conf.net_type = "vhostuser"
|
||||
conf.vhostuser_type = "unix"
|
||||
conf.vhostuser_mode = mode
|
||||
conf.vhostuser_path = path
|
||||
|
||||
|
||||
def set_vif_bandwidth_config(conf, inst_type):
|
||||
"""Config vif inbound/outbound bandwidth limit. parameters are
|
||||
set in instance_type_extra_specs table, key is in the format
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
import copy
|
||||
|
||||
import os
|
||||
from oslo_concurrency import processutils
|
||||
from oslo_config import cfg
|
||||
|
||||
|
@ -329,6 +330,24 @@ class LibvirtGenericVIFDriver(object):
|
|||
|
||||
return conf
|
||||
|
||||
def get_config_vhostuser(self, instance, vif, image_meta,
|
||||
inst_type, virt_type):
|
||||
conf = self.get_base_config(instance, vif, image_meta,
|
||||
inst_type, virt_type)
|
||||
vif_details = vif['details']
|
||||
mode = vif_details.get(network_model.VIF_DETAILS_VHOSTUSER_MODE,
|
||||
'server')
|
||||
path = vif_details.get(network_model.VIF_DETAILS_VHOSTUSER_DIR)
|
||||
if path is None:
|
||||
raise exception.VifDetailsMissingVhostuserSockPath(
|
||||
vif_id=vif['id'])
|
||||
|
||||
designer.set_vif_host_backend_vhostuser_config(
|
||||
conf,
|
||||
mode,
|
||||
os.path.join(path, vif['id']))
|
||||
return conf
|
||||
|
||||
def get_config(self, instance, vif, image_meta,
|
||||
inst_type, virt_type):
|
||||
vif_type = vif['type']
|
||||
|
@ -510,6 +529,9 @@ class LibvirtGenericVIFDriver(object):
|
|||
except processutils.ProcessExecutionError:
|
||||
LOG.exception(_LE("Failed while plugging vif"), instance=instance)
|
||||
|
||||
def plug_vhostuser(self, instance, vif):
|
||||
pass
|
||||
|
||||
def plug(self, instance, vif):
|
||||
vif_type = vif['type']
|
||||
|
||||
|
@ -663,6 +685,9 @@ class LibvirtGenericVIFDriver(object):
|
|||
LOG.exception(_LE("Failed while unplugging vif"),
|
||||
instance=instance)
|
||||
|
||||
def unplug_vhostuser(self, instance, vif):
|
||||
pass
|
||||
|
||||
def unplug(self, instance, vif):
|
||||
vif_type = vif['type']
|
||||
|
||||
|
|
Loading…
Reference in New Issue