ovn: use requested-chassis list format for live migration
This makes OVN asynchronously set up destination port while VMs are being migrated, reducing network downtime. Also configure 'rarp' activation strategy to wait until libvirt notifies the network about new VM location with a RARP issued from the vif. Change-Id: I55811ea72b2bf0d0b244f422861dca4a7bf8f257
This commit is contained in:
parent
f8673c0516
commit
35fade3b5f
|
@ -372,9 +372,25 @@ class OVNClient(object):
|
|||
ovn_const.VIF_DETAILS_PF_MAC_ADDRESS)),
|
||||
ovn_const.LSP_OPTIONS_VIF_PLUG_REPRESENTOR_VF_NUM_KEY: str(
|
||||
binding_prof.get(ovn_const.VIF_DETAILS_VF_NUM))})
|
||||
options.update({
|
||||
ovn_const.LSP_OPTIONS_REQUESTED_CHASSIS_KEY: (
|
||||
self.determine_bind_host(port))})
|
||||
chassis = self.determine_bind_host(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 self._sb_idl.is_col_present('Port_Binding',
|
||||
'additional_chassis'):
|
||||
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
|
||||
options['activation-strategy'] = 'rarp'
|
||||
options[ovn_const.LSP_OPTIONS_REQUESTED_CHASSIS_KEY] = chassis
|
||||
|
||||
# TODO(lucasagomes): Enable the mcast_flood_reports by default,
|
||||
# according to core OVN developers it shouldn't cause any harm
|
||||
|
|
|
@ -1843,6 +1843,59 @@ class TestOVNMechanismDriver(TestOVNMechanismDriverBase):
|
|||
mock.ANY,
|
||||
filters={'id': subnet_ids})
|
||||
|
||||
def test__get_port_options_migrating_additional_chassis_missing(self):
|
||||
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',
|
||||
}
|
||||
}
|
||||
options = self.mech_driver._ovn_client._get_port_options(port)
|
||||
self.assertNotIn('activation-strategy', options.options)
|
||||
self.assertEqual('fake-src', options.options['requested-chassis'])
|
||||
|
||||
def test__get_port_options_migrating_additional_chassis_present(self):
|
||||
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',
|
||||
}
|
||||
}
|
||||
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.assertEqual('rarp', options.options['activation-strategy'])
|
||||
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',
|
||||
'mac_address': '00:00:00:00:00:00',
|
||||
'device_owner': 'device_owner',
|
||||
'network_id': 'foo',
|
||||
'fixed_ips': [],
|
||||
portbindings.HOST_ID: 'fake-src',
|
||||
}
|
||||
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',
|
||||
options.options['requested-chassis'])
|
||||
|
||||
def test_update_port(self):
|
||||
with mock.patch.object(
|
||||
self.mech_driver._ovn_client, 'is_metadata_port') as \
|
||||
|
|
Loading…
Reference in New Issue