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:
Przemyslaw Czesnowicz 2015-01-12 16:21:43 +00:00
parent a4f9c1b9f4
commit 9e2605bee8
7 changed files with 109 additions and 0 deletions

View File

@ -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.")

View File

@ -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'

View File

@ -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):

View File

@ -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)

View File

@ -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))

View File

@ -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

View File

@ -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']