Merge "Libvirt: Support ovs fp plug in vhostuser vif"
This commit is contained in:
@@ -1376,9 +1376,10 @@ def create_ovs_vif_port(bridge, dev, iface_id, mac, instance_id):
|
||||
_set_device_mtu(dev)
|
||||
|
||||
|
||||
def delete_ovs_vif_port(bridge, dev):
|
||||
def delete_ovs_vif_port(bridge, dev, delete_dev=True):
|
||||
_ovs_vsctl(['--', '--if-exists', 'del-port', bridge, dev])
|
||||
delete_net_dev(dev)
|
||||
if delete_dev:
|
||||
delete_net_dev(dev)
|
||||
|
||||
|
||||
def ovs_set_vhostuser_port_type(dev):
|
||||
|
||||
@@ -301,6 +301,33 @@ class LibvirtVifTestCase(test.NoDBTestCase):
|
||||
ovs_interfaceid='aaa-bbb-ccc'
|
||||
)
|
||||
|
||||
vif_vhostuser_ovs_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,
|
||||
details = {network_model.VIF_DETAILS_VHOSTUSER_MODE: 'server',
|
||||
network_model.VIF_DETAILS_VHOSTUSER_SOCKET:
|
||||
'/tmp/usv-xxx-yyy-zzz',
|
||||
network_model.VIF_DETAILS_VHOSTUSER_FP_PLUG: True,
|
||||
network_model.VIF_DETAILS_VHOSTUSER_OVS_PLUG: True},
|
||||
devname='tap-xxx-yyy-zzz',
|
||||
ovs_interfaceid='aaa-bbb-ccc'
|
||||
)
|
||||
|
||||
vif_vhostuser_ovs_fp_hybrid = 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 = {'ovs_hybrid_plug': True,
|
||||
network_model.VIF_DETAILS_VHOSTUSER_MODE: 'server',
|
||||
network_model.VIF_DETAILS_VHOSTUSER_SOCKET:
|
||||
'/tmp/usv-xxx-yyy-zzz',
|
||||
network_model.VIF_DETAILS_VHOSTUSER_OVS_PLUG: True,
|
||||
network_model.VIF_DETAILS_VHOSTUSER_FP_PLUG: True},
|
||||
devname='tap-xxx-yyy-zzz',
|
||||
ovs_interfaceid='aaa-bbb-ccc'
|
||||
)
|
||||
|
||||
vif_vhostuser_no_path = network_model.VIF(id='vif-xxx-yyy-zzz',
|
||||
address='ca:fe:de:ad:be:ef',
|
||||
network=network_bridge,
|
||||
@@ -1268,3 +1295,111 @@ class LibvirtVifTestCase(test.NoDBTestCase):
|
||||
d = vif.LibvirtGenericVIFDriver()
|
||||
d.unplug_vhostuser(None, self.vif_vhostuser_ovs)
|
||||
delete_port.assert_has_calls(calls['delete_ovs_vif_port'])
|
||||
|
||||
def test_vhostuser_ovs_fp_plug(self):
|
||||
calls = {
|
||||
'create_fp_dev': [mock.call('tap-xxx-yyy-zzz',
|
||||
'/tmp/usv-xxx-yyy-zzz',
|
||||
'client')],
|
||||
'create_ovs_vif_port': [mock.call(
|
||||
'br0', 'tap-xxx-yyy-zzz',
|
||||
'aaa-bbb-ccc', 'ca:fe:de:ad:be:ef',
|
||||
'f0000000-0000-0000-0000-000000000001')]
|
||||
}
|
||||
with test.nested(
|
||||
mock.patch.object(linux_net, 'create_fp_dev'),
|
||||
mock.patch.object(linux_net, 'create_ovs_vif_port'),
|
||||
) as (create_fp_dev, create_ovs_vif_port):
|
||||
d = vif.LibvirtGenericVIFDriver()
|
||||
d.plug_vhostuser(self.instance, self.vif_vhostuser_ovs_fp)
|
||||
create_fp_dev.assert_has_calls(calls['create_fp_dev'])
|
||||
create_ovs_vif_port.assert_has_calls(calls['create_ovs_vif_port'])
|
||||
|
||||
def test_vhostuser_ovs_fp_unplug(self):
|
||||
calls = {
|
||||
'delete_ovs_vif_port': [mock.call('br0', 'tap-xxx-yyy-zzz',
|
||||
False)],
|
||||
'delete_fp_dev': [mock.call('tap-xxx-yyy-zzz')],
|
||||
}
|
||||
with test.nested(
|
||||
mock.patch.object(linux_net, 'delete_ovs_vif_port'),
|
||||
mock.patch.object(linux_net, 'delete_fp_dev')
|
||||
) as (delete_ovs_port, delete_fp_dev):
|
||||
d = vif.LibvirtGenericVIFDriver()
|
||||
d.unplug_vhostuser(None, self.vif_vhostuser_ovs_fp)
|
||||
delete_ovs_port.assert_has_calls(calls['delete_ovs_vif_port'])
|
||||
delete_fp_dev.assert_has_calls(calls['delete_fp_dev'])
|
||||
|
||||
def test_vhostuser_ovs_fp_hybrid_plug(self):
|
||||
calls = {
|
||||
'create_fp_dev': [mock.call('tap-xxx-yyy-zzz',
|
||||
'/tmp/usv-xxx-yyy-zzz',
|
||||
'client')],
|
||||
'device_exists': [mock.call('tap-xxx-yyy-zzz'),
|
||||
mock.call('qbrvif-xxx-yyy'),
|
||||
mock.call('qvovif-xxx-yyy')],
|
||||
'_create_veth_pair': [mock.call('qvbvif-xxx-yyy',
|
||||
'qvovif-xxx-yyy')],
|
||||
'execute': [mock.call('brctl', 'addbr', 'qbrvif-xxx-yyy',
|
||||
run_as_root=True),
|
||||
mock.call('brctl', 'setfd', 'qbrvif-xxx-yyy', 0,
|
||||
run_as_root=True),
|
||||
mock.call('brctl', 'stp', 'qbrvif-xxx-yyy', 'off',
|
||||
run_as_root=True),
|
||||
mock.call('tee', ('/sys/class/net/qbrvif-xxx-yyy'
|
||||
'/bridge/multicast_snooping'),
|
||||
process_input='0', run_as_root=True,
|
||||
check_exit_code=[0, 1]),
|
||||
mock.call('ip', 'link', 'set', 'qbrvif-xxx-yyy', 'up',
|
||||
run_as_root=True),
|
||||
mock.call('brctl', 'addif', 'qbrvif-xxx-yyy',
|
||||
'qvbvif-xxx-yyy', run_as_root=True),
|
||||
mock.call('brctl', 'addif', 'qbrvif-xxx-yyy',
|
||||
'tap-xxx-yyy-zzz', run_as_root=True)],
|
||||
'create_ovs_vif_port': [mock.call(
|
||||
'br0', 'qvovif-xxx-yyy',
|
||||
'aaa-bbb-ccc', 'ca:fe:de:ad:be:ef',
|
||||
'f0000000-0000-0000-0000-000000000001')]
|
||||
}
|
||||
with test.nested(
|
||||
mock.patch.object(linux_net, 'create_fp_dev'),
|
||||
mock.patch.object(linux_net, 'device_exists',
|
||||
return_value=False),
|
||||
mock.patch.object(utils, 'execute'),
|
||||
mock.patch.object(linux_net, '_create_veth_pair'),
|
||||
mock.patch.object(linux_net, 'create_ovs_vif_port')
|
||||
) as (create_fp_dev, device_exists, execute, _create_veth_pair,
|
||||
create_ovs_vif_port):
|
||||
d = vif.LibvirtGenericVIFDriver()
|
||||
d.plug_vhostuser(self.instance, self.vif_vhostuser_ovs_fp_hybrid)
|
||||
create_fp_dev.assert_has_calls(calls['create_fp_dev'])
|
||||
device_exists.assert_has_calls(calls['device_exists'])
|
||||
_create_veth_pair.assert_has_calls(calls['_create_veth_pair'])
|
||||
execute.assert_has_calls(calls['execute'])
|
||||
create_ovs_vif_port.assert_has_calls(calls['create_ovs_vif_port'])
|
||||
|
||||
def test_vhostuser_ovs_fp_hybrid_unplug(self):
|
||||
calls = {
|
||||
'device_exists': [mock.call('qbrvif-xxx-yyy')],
|
||||
'execute': [mock.call('brctl', 'delif', 'qbrvif-xxx-yyy',
|
||||
'qvbvif-xxx-yyy', run_as_root=True),
|
||||
mock.call('ip', 'link', 'set',
|
||||
'qbrvif-xxx-yyy', 'down', run_as_root=True),
|
||||
mock.call('brctl', 'delbr',
|
||||
'qbrvif-xxx-yyy', run_as_root=True)],
|
||||
'delete_ovs_vif_port': [mock.call('br0', 'qvovif-xxx-yyy')],
|
||||
'delete_fp_dev': [mock.call('tap-xxx-yyy-zzz')]
|
||||
}
|
||||
with test.nested(
|
||||
mock.patch.object(linux_net, 'device_exists',
|
||||
return_value=True),
|
||||
mock.patch.object(utils, 'execute'),
|
||||
mock.patch.object(linux_net, 'delete_ovs_vif_port'),
|
||||
mock.patch.object(linux_net, 'delete_fp_dev')
|
||||
) as (device_exists, execute, delete_ovs_vif_port, delete_fp_dev):
|
||||
d = vif.LibvirtGenericVIFDriver()
|
||||
d.unplug_vhostuser(None, self.vif_vhostuser_ovs_fp_hybrid)
|
||||
device_exists.assert_has_calls(calls['device_exists'])
|
||||
execute.assert_has_calls(calls['execute'])
|
||||
delete_ovs_vif_port.assert_has_calls(calls['delete_ovs_vif_port'])
|
||||
delete_fp_dev.assert_has_calls(calls['delete_fp_dev'])
|
||||
|
||||
@@ -636,11 +636,27 @@ class LibvirtGenericVIFDriver(object):
|
||||
if linux_net.device_exists(dev):
|
||||
return
|
||||
|
||||
ovs_plug = vif['details'].get(
|
||||
network_model.VIF_DETAILS_VHOSTUSER_OVS_PLUG,
|
||||
False)
|
||||
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)
|
||||
|
||||
if ovs_plug:
|
||||
if vif.is_hybrid_plug_enabled():
|
||||
self.plug_ovs_hybrid(instance, vif)
|
||||
utils.execute('brctl', 'addif',
|
||||
self.get_br_name(vif['id']),
|
||||
dev, run_as_root=True)
|
||||
else:
|
||||
iface_id = self.get_ovs_interfaceid(vif)
|
||||
linux_net.create_ovs_vif_port(self.get_bridge_name(vif),
|
||||
dev, iface_id,
|
||||
vif['address'],
|
||||
instance.uuid)
|
||||
except processutils.ProcessExecutionError:
|
||||
LOG.exception(_LE("Failed while plugging vif"), instance=instance)
|
||||
|
||||
@@ -874,7 +890,17 @@ class LibvirtGenericVIFDriver(object):
|
||||
def unplug_vhostuser_fp(self, instance, vif):
|
||||
"""Delete a fp netdevice interface with a vhostuser socket"""
|
||||
dev = self.get_vif_devname(vif)
|
||||
ovs_plug = vif['details'].get(
|
||||
network_model.VIF_DETAILS_VHOSTUSER_OVS_PLUG,
|
||||
False)
|
||||
|
||||
try:
|
||||
if ovs_plug:
|
||||
if vif.is_hybrid_plug_enabled():
|
||||
self.unplug_ovs_hybrid(instance, vif)
|
||||
else:
|
||||
linux_net.delete_ovs_vif_port(self.get_bridge_name(vif),
|
||||
dev, False)
|
||||
linux_net.delete_fp_dev(dev)
|
||||
except processutils.ProcessExecutionError:
|
||||
LOG.exception(_LE("Failed while unplugging vif"),
|
||||
|
||||
Reference in New Issue
Block a user