adds support for vhost user reconnect.

- vhost-user reconnect is a new feature added
  in dpdk 16.07 and qemu 2.7.
- vhost-user reconnect allows VMs using vhost-user
  interfaces to reconnect to the vhost-user backend if
  the backend terminates either as a result of a graceful
  shutdown or a crash with out requiring the vm to reboot.
- vhost-user reconnect requires qemu to be the vhost-user server
  and ovs to be the client.
- dpdk prior to 16.07 only supports qemu client/ dpdk server mode.
- This change extends the ovs mech driver to select the correct qemu
  vhost user socket mode based on the available interface types
  reported by the agent.

Change-Id: Iec89eaa597311e086c5f6e8d67308d446b07ac33
Closes-Bug: #1604924
Depends-on: Ia5da5b3ef28d1b23b217adc5196199df47b54ed9
This commit is contained in:
Sean Mooney 2016-07-18 04:19:04 +00:00
parent eb5871535c
commit ca60a91cbd
4 changed files with 101 additions and 8 deletions

View File

@ -127,6 +127,7 @@ EXTENSION_DRIVER_TYPE = 'ovs'
OVS_DATAPATH_SYSTEM = 'system'
OVS_DATAPATH_NETDEV = 'netdev'
OVS_DPDK_VHOST_USER = 'dpdkvhostuser'
OVS_DPDK_VHOST_USER_CLIENT = 'dpdkvhostuserclient'
# default ovs vhost-user socket location
VHOST_USER_SOCKET_DIR = '/var/run/openvswitch'

View File

@ -81,12 +81,22 @@ class OpenvswitchMechanismDriver(mech_agent.SimpleAgentMechanismDriverBase):
def get_vif_type(self, agent, context):
caps = agent['configurations'].get('ovs_capabilities', {})
if (a_const.OVS_DPDK_VHOST_USER in caps.get('iface_types', []) and
if (any(x in caps.get('iface_types', []) for x
in [a_const.OVS_DPDK_VHOST_USER,
a_const.OVS_DPDK_VHOST_USER_CLIENT]) and
agent['configurations'].get('datapath_type') ==
a_const.OVS_DATAPATH_NETDEV):
return portbindings.VIF_TYPE_VHOST_USER
return self.vif_type
def get_vhost_mode(self, iface_types):
# NOTE(sean-k-mooney): this function converts the ovs vhost user
# driver mode into the qemu vhost user mode. If OVS is the server,
# qemu is the client and vice-versa.
if (a_const.OVS_DPDK_VHOST_USER_CLIENT in iface_types):
return portbindings.VHOST_USER_MODE_SERVER
return portbindings.VHOST_USER_MODE_CLIENT
def get_vif_details(self, agent, context):
vif_details = self._pre_get_vif_details(agent, context)
self._set_bridge_name(context.current, vif_details)
@ -107,7 +117,8 @@ class OpenvswitchMechanismDriver(mech_agent.SimpleAgentMechanismDriverBase):
def _pre_get_vif_details(self, agent, context):
a_config = agent['configurations']
if a_config.get('datapath_type') != a_const.OVS_DATAPATH_NETDEV:
vif_type = self.get_vif_type(agent, context)
if vif_type != portbindings.VIF_TYPE_VHOST_USER:
details = dict(self.vif_details)
hybrid = portbindings.OVS_HYBRID_PLUG
if hybrid in a_config:
@ -115,13 +126,14 @@ class OpenvswitchMechanismDriver(mech_agent.SimpleAgentMechanismDriverBase):
# in the constructor if the agent specifically requests it
details[hybrid] = a_config[hybrid]
return details
caps = a_config.get('ovs_capabilities', {})
if a_const.OVS_DPDK_VHOST_USER in caps.get('iface_types', []):
else:
sock_path = self.agent_vhu_sockpath(agent, context.current['id'])
caps = a_config.get('ovs_capabilities', {})
mode = self.get_vhost_mode(caps.get('iface_types', []))
return {
portbindings.CAP_PORT_FILTER: False,
portbindings.VHOST_USER_MODE:
portbindings.VHOST_USER_MODE_CLIENT,
portbindings.OVS_HYBRID_PLUG: False,
portbindings.VHOST_USER_MODE: mode,
portbindings.VHOST_USER_OVS_PLUG: True,
portbindings.VHOST_USER_SOCKET: sock_path
}

View File

@ -177,3 +177,62 @@ class OpenvswitchMechanismFirewallUndefinedTestCase(
cfg.CONF.set_override('firewall_driver', '', 'SECURITYGROUP')
self.driver = mech_openvswitch.OpenvswitchMechanismDriver()
self.driver.initialize()
class OpenvswitchMechanismDPDKTestCase(OpenvswitchMechanismBaseTestCase):
GOOD_MAPPINGS = {'fake_physical_network': 'fake_bridge'}
GOOD_TUNNEL_TYPES = ['gre', 'vxlan']
VHOST_CONFIGS = {'bridge_mappings': GOOD_MAPPINGS,
'tunnel_types': GOOD_TUNNEL_TYPES,
'datapath_type': a_const.OVS_DATAPATH_NETDEV,
'ovs_capabilities': {
'iface_types': [a_const.OVS_DPDK_VHOST_USER]}}
VHOST_SERVER_CONFIGS = {'bridge_mappings': GOOD_MAPPINGS,
'tunnel_types': GOOD_TUNNEL_TYPES,
'datapath_type': a_const.OVS_DATAPATH_NETDEV,
'ovs_capabilities': {
'iface_types': [a_const.OVS_DPDK_VHOST_USER_CLIENT]}}
SYSTEM_CONFIGS = {'bridge_mappings': GOOD_MAPPINGS,
'tunnel_types': GOOD_TUNNEL_TYPES,
'datapath_type': a_const.OVS_DATAPATH_SYSTEM,
'ovs_capabilities': {'iface_types': []}}
AGENT = {'alive': True,
'configurations': VHOST_CONFIGS,
'host': 'host'}
AGENT_SERVER = {'alive': True,
'configurations': VHOST_SERVER_CONFIGS,
'host': 'host'}
AGENT_SYSTEM = {'alive': True,
'configurations': SYSTEM_CONFIGS,
'host': 'host'}
def test_get_vhost_mode(self):
ifaces = []
result = self.driver.get_vhost_mode(ifaces)
self.assertEqual(portbindings.VHOST_USER_MODE_CLIENT, result)
ifaces = [a_const.OVS_DPDK_VHOST_USER]
result = self.driver.get_vhost_mode(ifaces)
self.assertEqual(portbindings.VHOST_USER_MODE_CLIENT, result)
ifaces = [a_const.OVS_DPDK_VHOST_USER_CLIENT]
result = self.driver.get_vhost_mode(ifaces)
self.assertEqual(portbindings.VHOST_USER_MODE_SERVER, result)
def test_get_vif_type(self):
result = self.driver.get_vif_type(self.AGENT, None)
self.assertEqual(portbindings.VIF_TYPE_VHOST_USER, result)
result = self.driver.get_vif_type(self.AGENT_SERVER, None)
self.assertEqual(portbindings.VIF_TYPE_VHOST_USER, result)
result = self.driver.get_vif_type(self.AGENT_SYSTEM, None)
self.assertEqual(portbindings.VIF_TYPE_OVS, result)

View File

@ -0,0 +1,21 @@
---
features:
- vhost-user reconnect is a mechanism which allows
a vhost-user frontend to reconnect to a vhost-user
backend in the event the backend terminates.
This enable a VM utilising a vhost-user interface
to reconnect automatically to the backend e.g.
a vSwitch without requiring the VM to reboot.
In this release, support was added to the neutron
Open vSwitch agent and ml2 driver for vhost-user
reconnect.
other:
- vhost-user reconnect allows VMs using vhost-user
interfaces to reconnect to the vhost-user backend if
the backend terminates either as a result of a graceful
shutdown or a crash without requiring the VM to reboot.
- vhost-user reconnect requires dpdk 16.07 and qemu 2.7
and ovs 2.6 to function. if an older qemu is used,
reconnect will not be available but vhost-user will
still function.