Avoid unnecessary port update during live migration

The ComputeManager.pre_live_migration method, which runs on the
destination host during live migration, calls setup_networks_on_host
with the destination host which causes the "migrating_to" attribute
to get set to the destination host in the port binding profile. This
is to initiate setting up floating IP information on the destination
host for DVR.

The ComputeManager.post_live_migration_at_destination method calls the
same method from the destination host, so at this point the "migrating_to"
attribute is already set to the destination host in the port binding
profile from pre_live_migration and we make unnecessary port update calls
to Neutron for each port attached to the instance.

This change simply checks to see if the "migrating_to" attribute is
already set to the given host and if so, skips the port update call.

Change-Id: I8b2ffd94c5ff0881d0df4efdde9be938888c16d7
Closes-Bug: #1758453
This commit is contained in:
Matt Riedemann 2018-03-25 16:56:19 -04:00
parent 32b7f48c00
commit 8d68f23230
2 changed files with 29 additions and 8 deletions

View File

@ -319,14 +319,18 @@ class API(base_api.NetworkAPI):
host_id = p.get(BINDING_HOST_ID)
if host_id != host:
port_profile = _get_binding_profile(p)
port_profile[MIGRATING_ATTR] = host
self._update_port_with_migration_profile(
instance, p['id'], port_profile, admin_client)
LOG.debug("Port %(port_id)s updated with migration "
"profile %(profile_data)s successfully",
{'port_id': p['id'],
'profile_data': port_profile},
instance=instance)
# If the "migrating_to" attribute already points at the given
# host, then skip the port update call since we're not changing
# anything.
if host != port_profile.get(MIGRATING_ATTR):
port_profile[MIGRATING_ATTR] = host
self._update_port_with_migration_profile(
instance, p['id'], port_profile, admin_client)
LOG.debug("Port %(port_id)s updated with migration "
"profile %(profile_data)s successfully",
{'port_id': p['id'],
'profile_data': port_profile},
instance=instance)
def setup_networks_on_host(self, context, instance, host=None,
teardown=False):

View File

@ -4284,6 +4284,23 @@ class TestNeutronv2WithMock(test.TestCase):
self.api._setup_migration_port_profile.assert_not_called()
self.api._clear_migration_port_profile.assert_not_called()
def test__setup_migration_port_profile_no_update(self):
"""Tests the case that the port binding profile already has the
"migrating_to" attribute set to the provided host so the port update
call is skipped.
"""
ports = [{
neutronapi.BINDING_HOST_ID: 'source-host',
neutronapi.BINDING_PROFILE: {
neutronapi.MIGRATING_ATTR: 'dest-host'
}
}] * 2
with mock.patch.object(self.api, '_update_port_with_migration_profile',
new_callable=mock.NonCallableMock):
self.api._setup_migration_port_profile(
self.context, mock.sentinel.instance, 'dest-host',
mock.sentinel.admin_client, ports)
@mock.patch.object(neutronapi, 'get_client', return_value=mock.Mock())
def test_update_port_profile_for_migration_teardown_true_with_profile(
self, get_client_mock):