Fix instance evacuation with PCI devices

update_port_binding_for_instance() now checks that a valid migration
object exists as a parameter before any mapping between old/new PCI
devices can occur.  A migration should be present in the case of a
cold migration, resize, or evacuation.

An evacuation (being a special case of a rebuild) however, will not
pass a migration to update_port_binding_for_instance, as it
is called directly from setup_instance_network().  This calling function
does not currently take a migration parameter, even though one will
certainly exist for an evacuation.

This commit adds an optional migration parameter to
setup_instance_network_on_host() and passes any migration object to
the port update routine.

Closes-Bug: #1703629
Related-Bug: #1677621
Related-Bug: #1630698

Change-Id: I4e394c8d275995eac4b049a7b1329ea90f2394be
(cherry picked from commit b930336854)
(cherry picked from commit b9c1a58dd0)
This commit is contained in:
Steven Webster 2017-06-12 17:10:03 -04:00 committed by Matt Riedemann
parent 4246d5779e
commit 8b3b8e5657
5 changed files with 16 additions and 8 deletions

View File

@ -2780,7 +2780,8 @@ class ComputeManager(manager.Manager):
self._do_rebuild_instance_with_claim(
claim_ctxt, context, instance, orig_image_ref,
image_ref, injected_files, new_pass, orig_sys_metadata,
bdms, recreate, on_shared_storage, preserve_ephemeral)
bdms, recreate, on_shared_storage, preserve_ephemeral,
migration)
except exception.ComputeResourcesUnavailable as e:
LOG.debug("Could not rebuild instance on this host, not "
"enough resources available.", instance=instance)
@ -2836,7 +2837,8 @@ class ComputeManager(manager.Manager):
def _do_rebuild_instance(self, context, instance, orig_image_ref,
image_ref, injected_files, new_pass,
orig_sys_metadata, bdms, recreate,
on_shared_storage, preserve_ephemeral):
on_shared_storage, preserve_ephemeral,
migration):
orig_vm_state = instance.vm_state
if recreate:
@ -2901,7 +2903,7 @@ class ComputeManager(manager.Manager):
# TODO(cfriesen): this network_api call and the one above
# are so similar, we should really try to unify them.
self.network_api.setup_instance_network_on_host(
context, instance, self.host)
context, instance, self.host, migration)
network_info = compute_utils.get_nw_info_for_instance(instance)
if bdms is None:

View File

@ -525,7 +525,8 @@ class API(base_api.NetworkAPI):
self.network_rpcapi.migrate_instance_finish(context, **args)
def setup_instance_network_on_host(self, context, instance, host):
def setup_instance_network_on_host(self, context, instance, host,
migration=None):
"""Setup network for specified instance on host."""
self.migrate_instance_finish(context, instance,
{'source_compute': None,

View File

@ -338,12 +338,15 @@ class NetworkAPI(base.Base):
"""Finish migrating the network of an instance."""
raise NotImplementedError()
def setup_instance_network_on_host(self, context, instance, host):
def setup_instance_network_on_host(self, context, instance, host,
migration=None):
"""Setup network for specified instance on host.
:param context: The request context.
:param instance: nova.objects.instance.Instance object.
:param host: The host which network should be setup for instance.
:param migration: The migration object if the instance is being
tracked with a migration.
"""
raise NotImplementedError()

View File

@ -2377,9 +2377,11 @@ class API(base_api.NetworkAPI):
"""Create a private DNS domain with optional nova project."""
raise NotImplementedError()
def setup_instance_network_on_host(self, context, instance, host):
def setup_instance_network_on_host(self, context, instance, host,
migration=None):
"""Setup network for specified instance on host."""
self._update_port_binding_for_instance(context, instance, host)
self._update_port_binding_for_instance(context, instance, host,
migration)
def cleanup_instance_network_on_host(self, context, instance, host):
"""Cleanup network for specified instance on host."""

View File

@ -11706,7 +11706,7 @@ class EvacuateHostTestCase(BaseTestCase):
mock_setup_networks_on_host.assert_called_once_with(
ctxt, self.inst, self.inst.host)
mock_setup_instance_network_on_host.assert_called_once_with(
ctxt, self.inst, self.inst.host)
ctxt, self.inst, self.inst.host, migration)
_test_rebuild()