Skip to content

Commit 26fbc9e

Browse files
committed
Call Neutron immediately upon _post_live_migration() start
Previously, we first called to Cinder to cleanp source volume connections, then to Neutron to activate destination port bindings. This means that, if Cinder or the storage backend were slow, the live migrated instance would be without network connectivity during that entire process. This patch immediately activates the port bindings on the destination (and thus gives the instance network connectivity). We just need to get the old network_info first, in order to use it in notifications and to stash it for the later call to driver.post_live_migration_at_source(). This is a smaller and safer change than the parallelization attempt in the subsequent patch, so it's done in its own patch because it might be backportable, and would help with network downtime during live migration. To avoid any potential data leaks, we want to be certain to cleanup volumes on the source. To that end we wrap the code that is being moved before the source volume cleanup code in a try/finally block in order to prevent any uncaught exception from blocking the cleanup. Change-Id: I700943723a32e732e3e3be825f3fd44a9f923a0b
1 parent 45e2349 commit 26fbc9e

File tree

1 file changed

+42
-33
lines changed

1 file changed

+42
-33
lines changed

nova/compute/manager.py

Lines changed: 42 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -9337,41 +9337,50 @@ def _post_live_migration(self, ctxt, instance, dest,
93379337
LOG.info('_post_live_migration() is started..',
93389338
instance=instance)
93399339

9340-
# Cleanup source host post live-migration
9341-
block_device_info = self._get_instance_block_device_info(
9342-
ctxt, instance, bdms=source_bdms)
9343-
self.driver.post_live_migration(ctxt, instance, block_device_info,
9344-
migrate_data)
9345-
9346-
# Disconnect volumes from this (the source) host.
9347-
self._post_live_migration_remove_source_vol_connections(
9348-
ctxt, instance, source_bdms)
9349-
9350-
# NOTE(artom) At this point in time we have not bound the ports to the
9351-
# destination host yet (this happens in migrate_instance_start()
9352-
# below). Therefore, the "old" source network info that's still in the
9353-
# instance info cache is safe to use here, since it'll be used below
9354-
# during driver.post_live_migration_at_source() to unplug the VIFs on
9355-
# the source.
9356-
network_info = instance.get_network_info()
9340+
# NOTE(artom) The ordering and exception handling are important here.
9341+
# We want to immediately activate the port bindings on the destination
9342+
# host to minimize network downtime. This happens in
9343+
# migrate_instance_start(). It's also crucial that we call
9344+
# _post_live_migration_remove_source_vol_connections() to clean up
9345+
# source volume connections and prevent potential data leaks. We
9346+
# therefore activate the port bindings in a try block, and, regardless
9347+
# of any expcetions during that process, clean up volume connections in
9348+
# a finally block.
9349+
try:
9350+
# NOTE(artom) At this point in time we have not bound the ports to
9351+
# the destination host yet (this happens in
9352+
# migrate_instance_start() below). Therefore, the "old" source
9353+
# network info that's still in the instance info cache is safe to
9354+
# use here, since it'll be used below during
9355+
# driver.post_live_migration_at_source() to unplug the VIFs on the
9356+
# source.
9357+
network_info = instance.get_network_info()
93579358

9358-
self._notify_about_instance_usage(ctxt, instance,
9359-
"live_migration._post.start",
9360-
network_info=network_info)
9361-
compute_utils.notify_about_instance_action(
9362-
ctxt, instance, self.host,
9363-
action=fields.NotificationAction.LIVE_MIGRATION_POST,
9364-
phase=fields.NotificationPhase.START)
9359+
self._notify_about_instance_usage(ctxt, instance,
9360+
"live_migration._post.start",
9361+
network_info=network_info)
9362+
compute_utils.notify_about_instance_action(
9363+
ctxt, instance, self.host,
9364+
action=fields.NotificationAction.LIVE_MIGRATION_POST,
9365+
phase=fields.NotificationPhase.START)
93659366

9366-
migration = objects.Migration(
9367-
source_compute=self.host, dest_compute=dest,
9368-
)
9369-
# For neutron, migrate_instance_start will activate the destination
9370-
# host port bindings, if there are any created by conductor before live
9371-
# migration started.
9372-
self.network_api.migrate_instance_start(ctxt,
9373-
instance,
9374-
migration)
9367+
migration = objects.Migration(
9368+
source_compute=self.host, dest_compute=dest,
9369+
)
9370+
# For neutron, migrate_instance_start will activate the destination
9371+
# host port bindings, if there are any created by conductor before
9372+
# live migration started.
9373+
self.network_api.migrate_instance_start(ctxt, instance, migration)
9374+
finally:
9375+
# Cleanup source host post live-migration
9376+
block_device_info = self._get_instance_block_device_info(
9377+
ctxt, instance, bdms=source_bdms)
9378+
self.driver.post_live_migration(ctxt, instance, block_device_info,
9379+
migrate_data)
9380+
9381+
# Disconnect volumes from this (the source) host.
9382+
self._post_live_migration_remove_source_vol_connections(
9383+
ctxt, instance, source_bdms)
93759384

93769385
destroy_vifs = False
93779386
try:

0 commit comments

Comments
 (0)