Merge "Add option to configure live migration activation strategy for OVN"

This commit is contained in:
Zuul 2025-01-17 23:26:50 +00:00 committed by Gerrit Code Review
commit 93032d8ab0
4 changed files with 76 additions and 24 deletions

View File

@ -230,6 +230,15 @@ ovn_opts = [
'connected to the router through any other routers, '
'similar to the default ML2/OVS behavior. Defaults to '
'"False".')),
cfg.StrOpt('live_migration_activation_strategy',
default="rarp",
choices=["rarp", ""],
help=_('Activation strategy to use for live migration. '
'The default `rarp` strategy expects the hypervisor to '
'send a Reverse ARP request through the migrated port '
'after migration is complete. '
'An empty value means a migrated port is immediately '
'activated on the destination host.')),
]
nb_global_opts = [
@ -334,6 +343,10 @@ def is_ovn_distributed_floating_ip():
return cfg.CONF.ovn.enable_distributed_floating_ip
def get_ovn_lm_activation_strategy():
return cfg.CONF.ovn.live_migration_activation_strategy
def get_ovn_vhost_sock_dir():
return cfg.CONF.ovn.vhost_sock_dir

View File

@ -485,34 +485,13 @@ class OVNClient:
ovn_const.VIF_DETAILS_PF_MAC_ADDRESS)),
ovn_const.LSP_OPTIONS_VIF_PLUG_REPRESENTOR_VF_NUM_KEY: str(
bp_info.bp_param.get(ovn_const.VIF_DETAILS_VF_NUM))})
chassis = utils.determine_bind_host(self._sb_idl, port)
if chassis:
# If OVN supports multi-chassis port bindings, use it for live
# migration to asynchronously configure destination port while
# VM is migrating
if utils.is_additional_chassis_supported(self._sb_idl):
mdst = port.get(
portbindings.PROFILE, {}).get(
ovn_const.MIGRATING_ATTR)
if mdst:
# Let OVN know that the port should be configured on
# destination too
chassis += ',%s' % mdst
# Block traffic on destination host until libvirt sends
# a RARP packet from it to inform network about the new
# location of the port
# TODO(ihrachys) Remove this once OVN properly supports
# activation of DPDK ports (bug 2092407)
if (port[portbindings.VIF_TYPE] !=
portbindings.VIF_TYPE_VHOST_USER):
options['activation-strategy'] = 'rarp'
if port_type != ovn_const.LSP_TYPE_VIRTUAL:
# Virtual ports can not be bound by using the requested-chassis
# mechanism, ovn-controller will create the Port_Binding entry
# when it sees an ARP coming from the VIP
if port_type != ovn_const.LSP_TYPE_VIRTUAL:
options[ovn_const.LSP_OPTIONS_REQUESTED_CHASSIS_KEY] = \
chassis
options = self._configure_requested_chassis_options(
options, port)
if self.is_mcast_flood_broken and port_type not in (
'vtep', ovn_const.LSP_TYPE_LOCALPORT, 'router'):
@ -526,6 +505,33 @@ class OVNClient:
bp_info.vnic_type, bp_info.capabilities, mtu
)
def _configure_requested_chassis_options(self, options, port):
options = copy.deepcopy(options)
chassis = utils.determine_bind_host(self._sb_idl, port)
if chassis:
# If OVN supports multi-chassis port bindings, use it for live
# migration to asynchronously configure destination port while
# VM is migrating
if utils.is_additional_chassis_supported(self._sb_idl):
mdst = port.get(
portbindings.PROFILE, {}).get(ovn_const.MIGRATING_ATTR)
if mdst:
# Let OVN know that the port should be configured on
# destination too
chassis += ',%s' % mdst
# Block traffic on destination host until libvirt sends
# a RARP packet from it to inform network about the new
# location of the port
# TODO(ihrachys) Remove this once OVN properly supports
# activation of DPDK ports (bug 2092407)
if (port[portbindings.VIF_TYPE] !=
portbindings.VIF_TYPE_VHOST_USER):
strategy = ovn_conf.get_ovn_lm_activation_strategy()
if strategy:
options['activation-strategy'] = strategy
options[ovn_const.LSP_OPTIONS_REQUESTED_CHASSIS_KEY] = chassis
return options
def update_port_dhcp_options(self, port_info, txn):
dhcpv4_options = []
dhcpv6_options = []

View File

@ -2102,6 +2102,30 @@ class TestOVNMechanismDriver(TestOVNMechanismDriverBase):
self.assertEqual('fake-src,fake-dest',
options.options['requested-chassis'])
def test__get_port_options_no_activation_strategy(self):
cfg.CONF.set_override('live_migration_activation_strategy',
'', group='ovn')
port = {
'id': 'virt-port',
'mac_address': '00:00:00:00:00:00',
'device_owner': 'device_owner',
'network_id': 'foo',
'fixed_ips': [],
portbindings.HOST_ID: 'fake-src',
portbindings.PROFILE: {
ovn_const.MIGRATING_ATTR: 'fake-dest',
},
portbindings.VIF_TYPE: portbindings.VIF_TYPE_VHOST_USER,
}
with mock.patch.object(
self.mech_driver._ovn_client._sb_idl, 'is_col_present',
return_value=True):
options = self.mech_driver._ovn_client._get_port_options(port)
self.assertNotIn('activation-strategy', options.options)
self.assertEqual('fake-src,fake-dest',
options.options['requested-chassis'])
def test__get_port_options_not_migrating_additional_chassis_present(self):
port = {
'id': 'virt-port',

View File

@ -0,0 +1,9 @@
---
features:
- |
For OVN, you can now select which port binding activation strategy to use
for migrated ports, by setting the new configuration option
``[ovn]ovn_live_migration_activation_strategy``. If set to an empty string,
no activation strategy will be used, and the destination port binding will
be immediately activated after creation without waiting for migration to
complete.