Skip to content

Commit

Permalink
Add support for vhost-vfio xml gen
Browse files Browse the repository at this point in the history
- This change introduces xml generation
  support for vhost-vifo interfaces.
- This change support setting the mac
  of vhost-vfio ports
- This change support setting the ring
  layout of vhost-vfio ports. The default
  layout is virtio.

Change-Id: I1f00db50445f4b77cbd0c643cc87562e41ce9840
  • Loading branch information
Sean Mooney committed Jan 9, 2018
1 parent c8c1b02 commit 13de00c
Show file tree
Hide file tree
Showing 4 changed files with 163 additions and 0 deletions.
78 changes: 78 additions & 0 deletions nova/tests/unit/virt/libvirt/test_config.py
Expand Up @@ -26,6 +26,84 @@ def assertXmlEqual(self, expectedXmlstr, actualXmlstr):
self.assertThat(actualXmlstr, matchers.XMLMatches(expectedXmlstr))


class LibvirtConfigQemuCommandlineTest(LibvirtConfigBaseTest):

def test_no_args(self):
obj = config.LibvirtConfigQemuCommandline()
xml = obj.to_xml()

self.assertXmlEqual(
'<qemu:commandline '
'xmlns:qemu="http://libvirt.org/schemas/domain/qemu/1.0"/>', xml)

def test_with_args(self):
obj = config.LibvirtConfigQemuCommandline()
obj.args = ['my-first-arg', 'a-second-arg']
xml = obj.to_xml()

self.assertXmlEqual(
"""<qemu:commandline xmlns:qemu="http://libvirt.org/schemas/domain/qemu/1.0">
<qemu:arg value="my-first-arg"/>
<qemu:arg value="a-second-arg"/>
</qemu:commandline>""", xml)


class LibvirtConfigVhostVFIOTest(LibvirtConfigBaseTest):

def test_default(self):
obj = config.LibvirtConfigVhostVFIO()
xml = obj.to_xml()

self.assertXmlEqual(
"""<qemu:commandline xmlns:qemu="http://libvirt.org/schemas/domain/qemu/1.0">
<qemu:arg value="-chardev"/>
<qemu:arg value="vfio,id=chardev-,sysfsdev=/sys/bus/mdev/"/>
<qemu:arg value="-netdev"/>
<qemu:arg value="vhost-vfio,id=netdev-,"""
"""chardev=chardev-,ringlayout=virtio"/>
<qemu:arg value="-device"/>
<qemu:arg value="virtio-net-pci,netdev=netdev-,mac="/>
</qemu:commandline>""", xml)

def test_all_params_set(self):
obj = config.LibvirtConfigVhostVFIO()
obj.uuid = 'fake-uuid'
obj.ring_layout = 'fake-layout'
obj.path = '/some/fake/path'
obj.address = 'fake-mac'
xml = obj.to_xml()

self.assertXmlEqual(
"""<qemu:commandline xmlns:qemu="http://libvirt.org/schemas/domain/qemu/1.0">
<qemu:arg value="-chardev"/>
<qemu:arg value="vfio,id=chardev-fake-uui,"""
"""sysfsdev=/some/fake/path"/>
<qemu:arg value="-netdev"/>
<qemu:arg value="vhost-vfio,id=netdev-fake-uuid,"""
"""chardev=chardev-fake-uui,ringlayout=fake-layout"/>
<qemu:arg value="-device"/>
<qemu:arg value="virtio-net-pci,"""
"""netdev=netdev-fake-uuid,mac=fake-mac"/>
</qemu:commandline>""", xml)

def test_path_from_uuid(self):
obj = config.LibvirtConfigVhostVFIO()
obj.uuid = 'fake-uuid'
xml = obj.to_xml()

self.assertXmlEqual(
"""<qemu:commandline xmlns:qemu="http://libvirt.org/schemas/domain/qemu/1.0">
<qemu:arg value="-chardev"/>
<qemu:arg value="vfio,id=chardev-fake-uui,"""
"""sysfsdev=/sys/bus/mdev/fake-uuid"/>
<qemu:arg value="-netdev"/>
<qemu:arg value="vhost-vfio,id=netdev-fake-uuid,"""
"""chardev=chardev-fake-uui,ringlayout=virtio"/>
<qemu:arg value="-device"/>
<qemu:arg value="virtio-net-pci,netdev=netdev-fake-uuid,mac="/>
</qemu:commandline>""", xml)


class LibvirtConfigTest(LibvirtConfigBaseTest):

def test_config_plain(self):
Expand Down
22 changes: 22 additions & 0 deletions nova/tests/unit/virt/libvirt/test_vif.py
Expand Up @@ -1721,6 +1721,28 @@ def test_config_os_vif_ovs_hybrid(self, mock_convert_vif,
filter="nova-instance-instance-00000001-22522562e2aa"/>
</interface>""", cfg.to_xml())

def test_config_vfio(self):
driver = vif.LibvirtGenericVIFDriver()
vif_details = {"mdev_path": "/fake/mdev/path",
"id": 123, "ring_layout": "fake-layout",
"address": "fake-mac"}
conf = driver.get_config_vhostVFIO(None, vif_details, None,
None, None, None)
self.assertEqual(vif_details["mdev_path"], conf.path)
self.assertEqual(vif_details["ring_layout"], conf.ring_layout)
self.assertEqual(vif_details["id"], conf.uuid)
self.assertEqual(vif_details["address"], conf.address)

def test_config_vfio_no_path_or_layout(self):
driver = vif.LibvirtGenericVIFDriver()
vif_details = {"id": 123, "address": "fake-mac"}
conf = driver.get_config_vhostVFIO(None, vif_details, None,
None, None, None)
self.assertEqual("/sys/bus/mdev/devices/123", conf.path)
self.assertEqual("virtio", conf.ring_layout)
self.assertEqual(vif_details["id"], conf.uuid)
self.assertEqual(vif_details["address"], conf.address)

@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,
Expand Down
53 changes: 53 additions & 0 deletions nova/virt/libvirt/config.py
Expand Up @@ -37,6 +37,8 @@

# Namespace to use for Nova specific metadata items in XML
NOVA_NS = "http://openstack.org/xmlns/libvirt/nova/1.0"
# Namespace to use for qemu specific items in XML
QEMU_NS = "http://libvirt.org/schemas/domain/qemu/1.0"


class LibvirtConfigObject(object):
Expand Down Expand Up @@ -80,6 +82,57 @@ def to_xml(self, pretty_print=True):
return xml_str


class LibvirtConfigQemuCommandline(LibvirtConfigObject):

def __init__(self, **kwargs):
super(LibvirtConfigQemuCommandline, self).__init__(
root_name="commandline", ns_prefix="qemu",
ns_uri=QEMU_NS, **kwargs)
self.args = []

def format_dom(self):
etree.register_namespace('qemu', QEMU_NS)
root = super(LibvirtConfigQemuCommandline, self).format_dom()
for arg in self.args:
elm = etree.SubElement(root, "{%s}arg" % QEMU_NS)
elm.set("value", str(arg))

return root


class LibvirtConfigVhostVFIO(LibvirtConfigQemuCommandline):

def __init__(self, **kwargs):
super(LibvirtConfigVhostVFIO, self).__init__(
**kwargs)
self.uuid = ""
self.path = ""
self.ring_layout = "virtio"
self.address = ""

def format_dom(self):
chardev = ("chardev-%s" % self.uuid)[:16]
netdev = ("netdev-%s" % self.uuid)[:16]
path = (self.path if self.path
else "/sys/bus/mdev/%s" % self.uuid)
layout = self.ring_layout
self.args = ["-chardev",
"vfio,id=%(chardev)s,sysfsdev=%(path)s" % {
"chardev": chardev,
"path": path},
"-netdev",
"vhost-vfio,id=%(netdev)s,chardev=%(chardev)s," % {
"chardev": chardev,
"netdev": netdev,
} +
"ringlayout=%(layout)s" % {"layout": layout},
"-device",
"virtio-net-pci,netdev=%(netdev)s,mac=%(mac)s" % {
"netdev": netdev, "mac": self.address}
]
return super(LibvirtConfigVhostVFIO, self).format_dom()


class LibvirtConfigCaps(LibvirtConfigObject):

def __init__(self, **kwargs):
Expand Down
10 changes: 10 additions & 0 deletions nova/virt/libvirt/vif.py
Expand Up @@ -431,6 +431,16 @@ def get_config_vhostuser(self, instance, vif, image_meta,

return conf

def get_config_vhostVFIO(self, instance, vif, image_meta,
inst_type, virt_type, host):
conf = vconfig.LibvirtConfigVhostVFIO()
conf.uuid = vif['id']
conf.path = vif.get('mdev_path',
"/sys/bus/mdev/devices/%s" % vif['id'])
conf.ring_layout = vif.get('ring_layout', 'virtio')
conf.address = vif['address']
return conf

def get_config_ib_hostdev(self, instance, vif, image_meta,
inst_type, virt_type, host):
return self.get_base_hostdev_pci_config(vif)
Expand Down

0 comments on commit 13de00c

Please sign in to comment.