Skip to content

Commit cef7d6c

Browse files
Zuulopenstack-gerrit
authored andcommitted
Merge "Don't unset Instance.old_flavor, new_flavor until necessary"
2 parents 6113997 + 44376d2 commit cef7d6c

File tree

3 files changed

+64
-62
lines changed

3 files changed

+64
-62
lines changed

nova/compute/manager.py

Lines changed: 52 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -4307,14 +4307,17 @@ def do_confirm_resize(context, instance, migration):
43074307
instance=instance)
43084308
finally:
43094309
# Whether an error occurred or not, at this point the
4310-
# instance is on the dest host so to avoid leaking
4311-
# allocations in placement, delete them here.
4310+
# instance is on the dest host. Avoid leaking allocations
4311+
# in placement by deleting them here...
43124312
self._delete_allocation_after_move(
43134313
context, instance, migration)
4314-
# Also as the instance is not any more on this host, update
4315-
# the scheduler about the move
4314+
# ...inform the scheduler about the move...
43164315
self._delete_scheduler_instance_info(
43174316
context, instance.uuid)
4317+
# ...and unset the cached flavor information (this is done
4318+
# last since the resource tracker relies on it for its
4319+
# periodic tasks)
4320+
self._delete_stashed_flavor_info(instance)
43184321

43194322
do_confirm_resize(context, instance, migration)
43204323

@@ -4353,13 +4356,6 @@ def _confirm_resize(self, context, instance, migration=None):
43534356
self.host, action=fields.NotificationAction.RESIZE_CONFIRM,
43544357
phase=fields.NotificationPhase.START)
43554358

4356-
# NOTE(danms): delete stashed migration information
4357-
old_instance_type = instance.old_flavor
4358-
instance.old_flavor = None
4359-
instance.new_flavor = None
4360-
instance.system_metadata.pop('old_vm_state', None)
4361-
instance.save()
4362-
43634359
# NOTE(tr3buchet): tear down networks on source host
43644360
self.network_api.setup_networks_on_host(context, instance,
43654361
migration.source_compute, teardown=True)
@@ -4383,8 +4379,9 @@ def _confirm_resize(self, context, instance, migration=None):
43834379
# instance.migration_context so make sure to not call
43844380
# instance.drop_migration_context() until after drop_move_claim
43854381
# is called.
4386-
self.rt.drop_move_claim(context, instance, migration.source_node,
4387-
old_instance_type, prefix='old_')
4382+
self.rt.drop_move_claim(
4383+
context, instance, migration.source_node, instance.old_flavor,
4384+
prefix='old_')
43884385
instance.drop_migration_context()
43894386

43904387
# NOTE(mriedem): The old_vm_state could be STOPPED but the user
@@ -4435,6 +4432,13 @@ def _delete_allocation_after_move(self, context, instance, migration):
44354432
'migration_uuid': migration.uuid})
44364433
raise
44374434

4435+
def _delete_stashed_flavor_info(self, instance):
4436+
"""Remove information about the flavor change after a resize."""
4437+
instance.old_flavor = None
4438+
instance.new_flavor = None
4439+
instance.system_metadata.pop('old_vm_state', None)
4440+
instance.save()
4441+
44384442
@wrap_exception()
44394443
@wrap_instance_event(prefix='compute')
44404444
@errors_out_migration
@@ -4687,6 +4691,13 @@ def _revert_snapshot_based_resize_at_dest(
46874691
self.rt.drop_move_claim(ctxt, instance, instance.node,
46884692
instance_type=instance.new_flavor)
46894693

4694+
def _revert_instance_flavor_host_node(self, instance, migration):
4695+
"""Revert host, node and flavor fields after a resize-revert."""
4696+
self._set_instance_info(instance, instance.old_flavor)
4697+
instance.host = migration.source_compute
4698+
instance.node = migration.source_node
4699+
instance.save(expected_task_state=[task_states.RESIZE_REVERTING])
4700+
46904701
@wrap_exception()
46914702
@reverts_task_state
46924703
@wrap_instance_event(prefix='compute')
@@ -4715,7 +4726,11 @@ def do_revert():
47154726
with self._error_out_instance_on_exception(ctxt, instance):
47164727
self._finish_revert_snapshot_based_resize_at_source(
47174728
ctxt, instance, migration)
4718-
do_revert()
4729+
4730+
try:
4731+
do_revert()
4732+
finally:
4733+
self._delete_stashed_flavor_info(instance)
47194734

47204735
# Broadcast to all schedulers that the instance is on this host.
47214736
# This is best effort so if anything fails just log it.
@@ -4737,16 +4752,14 @@ def _finish_revert_snapshot_based_resize_at_source(
47374752
task_state is "resize_reverting".
47384753
:param migration: Migration object whose status is "reverting".
47394754
"""
4740-
# Delete stashed old_vm_state information. We will use this to
4741-
# determine if the guest should be powered on when we spawn it.
4742-
old_vm_state = instance.system_metadata.pop(
4755+
# Get stashed old_vm_state information to determine if guest should
4756+
# be powered on after spawn; we default to ACTIVE for backwards
4757+
# compatibility if old_vm_state is not set
4758+
old_vm_state = instance.system_metadata.get(
47434759
'old_vm_state', vm_states.ACTIVE)
47444760

4745-
# Update instance host/node and flavor-related fields. After this
4746-
# if anything fails the instance will get rebuilt/rebooted on this
4747-
# host.
4748-
self._finish_revert_resize_update_instance_flavor_host_node(
4749-
instance, migration)
4761+
# Revert the flavor and host/node fields to their previous values
4762+
self._revert_instance_flavor_host_node(instance, migration)
47504763

47514764
# Move the allocations against the source compute node resource
47524765
# provider, held by the migration, to the instance which will drop
@@ -4936,27 +4949,6 @@ def _finish_revert_resize_network_migrate_finish(
49364949
LOG.error('Timeout waiting for Neutron events: %s', events,
49374950
instance=instance)
49384951

4939-
def _finish_revert_resize_update_instance_flavor_host_node(self, instance,
4940-
migration):
4941-
"""Updates host/node and flavor-related fields on the instance.
4942-
4943-
This is used when finish the revert resize operation on the source
4944-
host and updates the instance flavor-related fields back to the old
4945-
flavor and then nulls out the old/new_flavor fields.
4946-
4947-
The instance host/node fields are also set back to the source compute
4948-
host/node.
4949-
4950-
:param instance: Instance object
4951-
:param migration: Migration object
4952-
"""
4953-
self._set_instance_info(instance, instance.old_flavor)
4954-
instance.old_flavor = None
4955-
instance.new_flavor = None
4956-
instance.host = migration.source_compute
4957-
instance.node = migration.source_node
4958-
instance.save(expected_task_state=[task_states.RESIZE_REVERTING])
4959-
49604952
@wrap_exception()
49614953
@reverts_task_state
49624954
@wrap_instance_event(prefix='compute')
@@ -4970,6 +4962,16 @@ def finish_revert_resize(
49704962
revert the resized attributes in the database.
49714963

49724964
"""
4965+
try:
4966+
self._finish_revert_resize(
4967+
context, instance, migration, request_spec)
4968+
finally:
4969+
self._delete_stashed_flavor_info(instance)
4970+
4971+
def _finish_revert_resize(
4972+
self, context, instance, migration, request_spec=None,
4973+
):
4974+
"""Inner version of finish_revert_resize."""
49734975
with self._error_out_instance_on_exception(context, instance):
49744976
bdms = objects.BlockDeviceMappingList.get_by_instance_uuid(
49754977
context, instance.uuid)
@@ -4979,14 +4981,14 @@ def finish_revert_resize(
49794981
self.host, action=fields.NotificationAction.RESIZE_REVERT,
49804982
phase=fields.NotificationPhase.START, bdms=bdms)
49814983

4982-
# NOTE(mriedem): delete stashed old_vm_state information; we
4983-
# default to ACTIVE for backwards compatibility if old_vm_state
4984-
# is not set
4985-
old_vm_state = instance.system_metadata.pop('old_vm_state',
4986-
vm_states.ACTIVE)
4984+
# Get stashed old_vm_state information to determine if guest should
4985+
# be powered on after spawn; we default to ACTIVE for backwards
4986+
# compatibility if old_vm_state is not set
4987+
old_vm_state = instance.system_metadata.get(
4988+
'old_vm_state', vm_states.ACTIVE)
49874989

4988-
self._finish_revert_resize_update_instance_flavor_host_node(
4989-
instance, migration)
4990+
# Revert the flavor and host/node fields to their previous values
4991+
self._revert_instance_flavor_host_node(instance, migration)
49904992

49914993
try:
49924994
source_allocations = self._revert_allocation(

nova/tests/functional/libvirt/test_numa_servers.py

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -696,8 +696,7 @@ def fake_confirm_migration(*args, **kwargs):
696696
self.ctxt, dst_host,
697697
).numa_topology,
698698
)
699-
# FIXME(stephenfin): There should still be two pinned cores here
700-
self.assertEqual(0, len(src_numa_topology.cells[0].pinned_cpus))
699+
self.assertEqual(2, len(src_numa_topology.cells[0].pinned_cpus))
701700
self.assertEqual(2, len(dst_numa_topology.cells[0].pinned_cpus))
702701

703702
# before continuing with the actualy confirm process
@@ -738,14 +737,10 @@ def fake_confirm_migration(*args, **kwargs):
738737

739738
# Now confirm the resize
740739

741-
# FIXME(stephenfin): This should be successful, but it's failing with a
742-
# HTTP 500 due to bug #1879878
743740
post = {'confirmResize': None}
744-
exc = self.assertRaises(
745-
client.OpenStackApiException,
746-
self.api.post_server_action, server['id'], post)
747-
self.assertEqual(500, exc.response.status_code)
748-
self.assertIn('CPUUnpinningInvalid', str(exc))
741+
self.api.post_server_action(server['id'], post)
742+
743+
server = self._wait_for_state_change(server, 'ACTIVE')
749744

750745

751746
class NUMAServerTestWithCountingQuotaFromPlacement(NUMAServersTest):

nova/tests/unit/compute/test_compute_mgr.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8797,9 +8797,14 @@ def fake_drop_move_claim(*args, **kwargs):
87978797
self.migration)
87988798
mock_delete.assert_called_once_with(self.context, self.instance,
87998799
self.migration)
8800-
mock_save.assert_called_with(expected_task_state=
8801-
[None, task_states.DELETING,
8802-
task_states.SOFT_DELETING])
8800+
mock_save.assert_has_calls([
8801+
mock.call(
8802+
expected_task_state=[
8803+
None, task_states.DELETING, task_states.SOFT_DELETING,
8804+
],
8805+
),
8806+
mock.call(),
8807+
])
88038808
mock_delete_scheduler_info.assert_called_once_with(
88048809
self.context, self.instance.uuid)
88058810

0 commit comments

Comments
 (0)