summaryrefslogtreecommitdiff
path: root/nova/conductor/manager.py
diff options
context:
space:
mode:
Diffstat (limited to 'nova/conductor/manager.py')
-rw-r--r--nova/conductor/manager.py79
1 files changed, 62 insertions, 17 deletions
diff --git a/nova/conductor/manager.py b/nova/conductor/manager.py
index dc2b844496..1c644cf299 100644
--- a/nova/conductor/manager.py
+++ b/nova/conductor/manager.py
@@ -1307,8 +1307,37 @@ class ComputeTaskManager(base.Base):
updates = {'vm_state': vm_states.ERROR, 'task_state': None}
for instance in instances_by_uuid.values():
+
+ inst_mapping = None
+ try:
+ # We don't need the cell0-targeted context here because the
+ # instance mapping is in the API DB.
+ inst_mapping = \
+ objects.InstanceMapping.get_by_instance_uuid(
+ context, instance.uuid)
+ except exception.InstanceMappingNotFound:
+ # The API created the instance mapping record so it should
+ # definitely be here. Log an error but continue to create the
+ # instance in the cell0 database.
+ LOG.error('While burying instance in cell0, no instance '
+ 'mapping was found.', instance=instance)
+
+ # Perform a final sanity check that the instance is not mapped
+ # to some other cell already because of maybe some crazy
+ # clustered message queue weirdness.
+ if inst_mapping and inst_mapping.cell_mapping is not None:
+ LOG.error('When attempting to bury instance in cell0, the '
+ 'instance is already mapped to cell %s. Ignoring '
+ 'bury in cell0 attempt.',
+ inst_mapping.cell_mapping.identity,
+ instance=instance)
+ continue
+
with obj_target_cell(instance, cell0) as cctxt:
instance.create()
+ if inst_mapping:
+ inst_mapping.cell_mapping = cell0
+ inst_mapping.save()
# Record an instance action with a failed event.
self._create_instance_action_for_cell0(
@@ -1328,16 +1357,6 @@ class ComputeTaskManager(base.Base):
self._set_vm_state_and_notify(
cctxt, instance.uuid, 'build_instances', updates,
exc, request_spec)
- try:
- # We don't need the cell0-targeted context here because the
- # instance mapping is in the API DB.
- inst_mapping = \
- objects.InstanceMapping.get_by_instance_uuid(
- context, instance.uuid)
- inst_mapping.cell_mapping = cell0
- inst_mapping.save()
- except exception.InstanceMappingNotFound:
- pass
for build_request in build_requests:
try:
@@ -1506,13 +1525,8 @@ class ComputeTaskManager(base.Base):
instance.tags = instance_tags if instance_tags \
else objects.TagList()
- # Update mapping for instance. Normally this check is guarded by
- # a try/except but if we're here we know that a newer nova-api
- # handled the build process and would have created the mapping
- inst_mapping = objects.InstanceMapping.get_by_instance_uuid(
- context, instance.uuid)
- inst_mapping.cell_mapping = cell
- inst_mapping.save()
+ # Update mapping for instance.
+ self._map_instance_to_cell(context, instance, cell)
if not self._delete_build_request(
context, build_request, instance, cell, instance_bdms,
@@ -1540,6 +1554,37 @@ class ComputeTaskManager(base.Base):
host=host.service_host, node=host.nodename,
limits=host.limits, host_list=host_list)
+ @staticmethod
+ def _map_instance_to_cell(context, instance, cell):
+ """Update the instance mapping to point at the given cell.
+
+ During initial scheduling once a host and cell is selected in which
+ to build the instance this method is used to update the instance
+ mapping to point at that cell.
+
+ :param context: nova auth RequestContext
+ :param instance: Instance object being built
+ :param cell: CellMapping representing the cell in which the instance
+ was created and is being built.
+ :returns: InstanceMapping object that was updated.
+ """
+ inst_mapping = objects.InstanceMapping.get_by_instance_uuid(
+ context, instance.uuid)
+ # Perform a final sanity check that the instance is not mapped
+ # to some other cell already because of maybe some crazy
+ # clustered message queue weirdness.
+ if inst_mapping.cell_mapping is not None:
+ LOG.error('During scheduling instance is already mapped to '
+ 'another cell: %s. This should not happen and is an '
+ 'indication of bigger problems. If you see this you '
+ 'should report it to the nova team. Overwriting '
+ 'the mapping to point at cell %s.',
+ inst_mapping.cell_mapping.identity, cell.identity,
+ instance=instance)
+ inst_mapping.cell_mapping = cell
+ inst_mapping.save()
+ return inst_mapping
+
def _cleanup_build_artifacts(self, context, exc, instances, build_requests,
request_specs, block_device_mappings, tags,
cell_mapping_cache):