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:
parent
eb5871535c
commit
ca60a91cbd
@ -127,6 +127,7 @@ EXTENSION_DRIVER_TYPE = 'ovs'
|
|||||||
OVS_DATAPATH_SYSTEM = 'system'
|
OVS_DATAPATH_SYSTEM = 'system'
|
||||||
OVS_DATAPATH_NETDEV = 'netdev'
|
OVS_DATAPATH_NETDEV = 'netdev'
|
||||||
OVS_DPDK_VHOST_USER = 'dpdkvhostuser'
|
OVS_DPDK_VHOST_USER = 'dpdkvhostuser'
|
||||||
|
OVS_DPDK_VHOST_USER_CLIENT = 'dpdkvhostuserclient'
|
||||||
|
|
||||||
# default ovs vhost-user socket location
|
# default ovs vhost-user socket location
|
||||||
VHOST_USER_SOCKET_DIR = '/var/run/openvswitch'
|
VHOST_USER_SOCKET_DIR = '/var/run/openvswitch'
|
||||||
|
@ -81,12 +81,22 @@ class OpenvswitchMechanismDriver(mech_agent.SimpleAgentMechanismDriverBase):
|
|||||||
|
|
||||||
def get_vif_type(self, agent, context):
|
def get_vif_type(self, agent, context):
|
||||||
caps = agent['configurations'].get('ovs_capabilities', {})
|
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
|
||||||
agent['configurations'].get('datapath_type') ==
|
in [a_const.OVS_DPDK_VHOST_USER,
|
||||||
a_const.OVS_DATAPATH_NETDEV):
|
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 portbindings.VIF_TYPE_VHOST_USER
|
||||||
return self.vif_type
|
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):
|
def get_vif_details(self, agent, context):
|
||||||
vif_details = self._pre_get_vif_details(agent, context)
|
vif_details = self._pre_get_vif_details(agent, context)
|
||||||
self._set_bridge_name(context.current, vif_details)
|
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):
|
def _pre_get_vif_details(self, agent, context):
|
||||||
a_config = agent['configurations']
|
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)
|
details = dict(self.vif_details)
|
||||||
hybrid = portbindings.OVS_HYBRID_PLUG
|
hybrid = portbindings.OVS_HYBRID_PLUG
|
||||||
if hybrid in a_config:
|
if hybrid in a_config:
|
||||||
@ -115,13 +126,14 @@ class OpenvswitchMechanismDriver(mech_agent.SimpleAgentMechanismDriverBase):
|
|||||||
# in the constructor if the agent specifically requests it
|
# in the constructor if the agent specifically requests it
|
||||||
details[hybrid] = a_config[hybrid]
|
details[hybrid] = a_config[hybrid]
|
||||||
return details
|
return details
|
||||||
caps = a_config.get('ovs_capabilities', {})
|
else:
|
||||||
if a_const.OVS_DPDK_VHOST_USER in caps.get('iface_types', []):
|
|
||||||
sock_path = self.agent_vhu_sockpath(agent, context.current['id'])
|
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 {
|
return {
|
||||||
portbindings.CAP_PORT_FILTER: False,
|
portbindings.CAP_PORT_FILTER: False,
|
||||||
portbindings.VHOST_USER_MODE:
|
portbindings.OVS_HYBRID_PLUG: False,
|
||||||
portbindings.VHOST_USER_MODE_CLIENT,
|
portbindings.VHOST_USER_MODE: mode,
|
||||||
portbindings.VHOST_USER_OVS_PLUG: True,
|
portbindings.VHOST_USER_OVS_PLUG: True,
|
||||||
portbindings.VHOST_USER_SOCKET: sock_path
|
portbindings.VHOST_USER_SOCKET: sock_path
|
||||||
}
|
}
|
||||||
|
@ -177,3 +177,62 @@ class OpenvswitchMechanismFirewallUndefinedTestCase(
|
|||||||
cfg.CONF.set_override('firewall_driver', '', 'SECURITYGROUP')
|
cfg.CONF.set_override('firewall_driver', '', 'SECURITYGROUP')
|
||||||
self.driver = mech_openvswitch.OpenvswitchMechanismDriver()
|
self.driver = mech_openvswitch.OpenvswitchMechanismDriver()
|
||||||
self.driver.initialize()
|
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)
|
||||||
|
@ -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.
|
||||||
|
|
Loading…
Reference in New Issue
Block a user