Merge "Libvirt: Support fp plug in vhostuser vif"
This commit is contained in:
@@ -89,3 +89,6 @@ sysctl: CommandFilter, sysctl, root
|
||||
|
||||
# nova/network/linux_net.py: 'conntrack'
|
||||
conntrack: CommandFilter, conntrack, root
|
||||
|
||||
# nova/network/linux_net.py: 'fp-vdev'
|
||||
fp-vdev: CommandFilter, fp-vdev, root
|
||||
|
||||
@@ -1413,6 +1413,20 @@ def create_tap_dev(dev, mac_address=None):
|
||||
check_exit_code=[0, 2, 254])
|
||||
|
||||
|
||||
def create_fp_dev(dev, sockpath, sockmode):
|
||||
if not device_exists(dev):
|
||||
utils.execute('fp-vdev', 'add', dev, '--sockpath', sockpath,
|
||||
'--sockmode', sockmode, run_as_root=True)
|
||||
_set_device_mtu(dev)
|
||||
utils.execute('ip', 'link', 'set', dev, 'up', run_as_root=True,
|
||||
check_exit_code=[0, 2, 254])
|
||||
|
||||
|
||||
def delete_fp_dev(dev):
|
||||
if device_exists(dev):
|
||||
utils.execute('fp-vdev', 'del', dev, run_as_root=True)
|
||||
|
||||
|
||||
def delete_net_dev(dev):
|
||||
"""Delete a network device only if it exists."""
|
||||
if device_exists(dev):
|
||||
|
||||
@@ -76,6 +76,9 @@ VIF_DETAILS_VHOSTUSER_SOCKET = 'vhostuser_socket'
|
||||
# Specifies whether vhost-user socket should be plugged
|
||||
# into ovs bridge. Valid values are True and False
|
||||
VIF_DETAILS_VHOSTUSER_OVS_PLUG = 'vhostuser_ovs_plug'
|
||||
# Specifies whether vhost-user socket should be used to
|
||||
# create a fp netdevice interface.
|
||||
VIF_DETAILS_VHOSTUSER_FP_PLUG = 'vhostuser_fp_plug'
|
||||
|
||||
# Constants for dictionary keys in the 'vif_details' field that are
|
||||
# valid for VIF_TYPE_TAP.
|
||||
|
||||
@@ -280,6 +280,16 @@ class LibvirtVifTestCase(test.NoDBTestCase):
|
||||
'/tmp/vif-xxx-yyy-zzz'}
|
||||
)
|
||||
|
||||
vif_vhostuser_fp = network_model.VIF(id='vif-xxx-yyy-zzz',
|
||||
address='ca:fe:de:ad:be:ef',
|
||||
network=network_bridge,
|
||||
type=network_model.VIF_TYPE_VHOSTUSER,
|
||||
devname='tap-xxx-yyy-zzz',
|
||||
details = {network_model.VIF_DETAILS_VHOSTUSER_SOCKET:
|
||||
'/tmp/usv-xxx-yyy-zzz',
|
||||
network_model.VIF_DETAILS_VHOSTUSER_FP_PLUG: True},
|
||||
)
|
||||
|
||||
vif_vhostuser_ovs = network_model.VIF(id='vif-xxx-yyy-zzz',
|
||||
address='ca:fe:de:ad:be:ef',
|
||||
network=network_bridge,
|
||||
@@ -1217,6 +1227,19 @@ class LibvirtVifTestCase(test.NoDBTestCase):
|
||||
self._assertMacEquals(node, self.vif_vhostuser_ovs)
|
||||
self._assertModel(xml, network_model.VIF_MODEL_VIRTIO)
|
||||
|
||||
@mock.patch.object(linux_net, 'create_fp_dev')
|
||||
def test_vhostuser_fp_plug(self, mock_create_fp_dev):
|
||||
d = vif.LibvirtGenericVIFDriver()
|
||||
d.plug_vhostuser(self.instance, self.vif_vhostuser_fp)
|
||||
mock_create_fp_dev.assert_has_calls(
|
||||
[mock.call('tap-xxx-yyy-zzz', '/tmp/usv-xxx-yyy-zzz', 'client')])
|
||||
|
||||
@mock.patch.object(linux_net, 'delete_fp_dev')
|
||||
def test_vhostuser_fp_unplug(self, mock_delete_fp_dev):
|
||||
d = vif.LibvirtGenericVIFDriver()
|
||||
d.unplug_vhostuser(None, self.vif_vhostuser_fp)
|
||||
mock_delete_fp_dev.assert_has_calls([mock.call('tap-xxx-yyy-zzz')])
|
||||
|
||||
def test_vhostuser_ovs_plug(self):
|
||||
|
||||
calls = {
|
||||
|
||||
@@ -386,10 +386,7 @@ class LibvirtGenericVIFDriver(object):
|
||||
|
||||
return conf
|
||||
|
||||
def get_config_vhostuser(self, instance, vif, image_meta,
|
||||
inst_type, virt_type, host):
|
||||
conf = self.get_base_config(instance, vif, image_meta,
|
||||
inst_type, virt_type)
|
||||
def _get_vhostuser_settings(self, vif):
|
||||
vif_details = vif['details']
|
||||
mode = vif_details.get(network_model.VIF_DETAILS_VHOSTUSER_MODE,
|
||||
'server')
|
||||
@@ -397,6 +394,13 @@ class LibvirtGenericVIFDriver(object):
|
||||
if sock_path is None:
|
||||
raise exception.VifDetailsMissingVhostuserSockPath(
|
||||
vif_id=vif['id'])
|
||||
return mode, sock_path
|
||||
|
||||
def get_config_vhostuser(self, instance, vif, image_meta,
|
||||
inst_type, virt_type, host):
|
||||
conf = self.get_base_config(instance, vif, image_meta,
|
||||
inst_type, virt_type)
|
||||
mode, sock_path = self._get_vhostuser_settings(vif)
|
||||
designer.set_vif_host_backend_vhostuser_config(conf, mode, sock_path)
|
||||
# (vladikr) Not setting up driver and queues for vhostuser
|
||||
# as queues are not supported in Libvirt until version 1.2.17
|
||||
@@ -626,18 +630,41 @@ class LibvirtGenericVIFDriver(object):
|
||||
linux_net.create_tap_dev(dev, mac)
|
||||
linux_net._set_device_mtu(dev)
|
||||
|
||||
def plug_vhostuser_fp(self, instance, vif):
|
||||
"""Create a fp netdevice interface with a vhostuser socket"""
|
||||
dev = self.get_vif_devname(vif)
|
||||
if linux_net.device_exists(dev):
|
||||
return
|
||||
|
||||
sockmode_qemu, sockpath = self._get_vhostuser_settings(vif)
|
||||
sockmode_port = 'client' if sockmode_qemu == 'server' else 'server'
|
||||
|
||||
try:
|
||||
linux_net.create_fp_dev(dev, sockpath, sockmode_port)
|
||||
except processutils.ProcessExecutionError:
|
||||
LOG.exception(_LE("Failed while plugging vif"), instance=instance)
|
||||
|
||||
def plug_vhostuser_ovs(self, instance, vif):
|
||||
"""Plug a VIF_TYPE_VHOSTUSER into an ovs bridge"""
|
||||
iface_id = self.get_ovs_interfaceid(vif)
|
||||
port_name = os.path.basename(
|
||||
vif['details'][network_model.VIF_DETAILS_VHOSTUSER_SOCKET])
|
||||
linux_net.create_ovs_vif_port(self.get_bridge_name(vif),
|
||||
port_name, iface_id, vif['address'],
|
||||
instance.uuid)
|
||||
linux_net.ovs_set_vhostuser_port_type(port_name)
|
||||
|
||||
def plug_vhostuser(self, instance, vif):
|
||||
fp_plug = vif['details'].get(
|
||||
network_model.VIF_DETAILS_VHOSTUSER_FP_PLUG,
|
||||
False)
|
||||
ovs_plug = vif['details'].get(
|
||||
network_model.VIF_DETAILS_VHOSTUSER_OVS_PLUG,
|
||||
False)
|
||||
if ovs_plug:
|
||||
iface_id = self.get_ovs_interfaceid(vif)
|
||||
port_name = os.path.basename(
|
||||
vif['details'][network_model.VIF_DETAILS_VHOSTUSER_SOCKET])
|
||||
linux_net.create_ovs_vif_port(self.get_bridge_name(vif),
|
||||
port_name, iface_id, vif['address'],
|
||||
instance.uuid)
|
||||
linux_net.ovs_set_vhostuser_port_type(port_name)
|
||||
if fp_plug:
|
||||
self.plug_vhostuser_fp(instance, vif)
|
||||
elif ovs_plug:
|
||||
self.plug_vhostuser_ovs(instance, vif)
|
||||
|
||||
def plug_vrouter(self, instance, vif):
|
||||
"""Plug into Contrail's network port
|
||||
@@ -844,15 +871,33 @@ class LibvirtGenericVIFDriver(object):
|
||||
LOG.exception(_LE("Failed while unplugging vif"),
|
||||
instance=instance)
|
||||
|
||||
def unplug_vhostuser_fp(self, instance, vif):
|
||||
"""Delete a fp netdevice interface with a vhostuser socket"""
|
||||
dev = self.get_vif_devname(vif)
|
||||
try:
|
||||
linux_net.delete_fp_dev(dev)
|
||||
except processutils.ProcessExecutionError:
|
||||
LOG.exception(_LE("Failed while unplugging vif"),
|
||||
instance=instance)
|
||||
|
||||
def unplug_vhostuser_ovs(self, instance, vif):
|
||||
"""Unplug a VIF_TYPE_VHOSTUSER into an ovs bridge"""
|
||||
port_name = os.path.basename(
|
||||
vif['details'][network_model.VIF_DETAILS_VHOSTUSER_SOCKET])
|
||||
linux_net.delete_ovs_vif_port(self.get_bridge_name(vif),
|
||||
port_name)
|
||||
|
||||
def unplug_vhostuser(self, instance, vif):
|
||||
fp_plug = vif['details'].get(
|
||||
network_model.VIF_DETAILS_VHOSTUSER_FP_PLUG,
|
||||
False)
|
||||
ovs_plug = vif['details'].get(
|
||||
network_model.VIF_DETAILS_VHOSTUSER_OVS_PLUG,
|
||||
False)
|
||||
if ovs_plug:
|
||||
port_name = os.path.basename(
|
||||
vif['details'][network_model.VIF_DETAILS_VHOSTUSER_SOCKET])
|
||||
linux_net.delete_ovs_vif_port(self.get_bridge_name(vif),
|
||||
port_name)
|
||||
if fp_plug:
|
||||
self.unplug_vhostuser_fp(instance, vif)
|
||||
elif ovs_plug:
|
||||
self.unplug_vhostuser_ovs(instance, vif)
|
||||
|
||||
def unplug_vrouter(self, instance, vif):
|
||||
"""Unplug Contrail's network port
|
||||
|
||||
Reference in New Issue
Block a user