Skip to content

Commit e6c6178

Browse files
committed
Drop source node allocations if finish_resize fails
By the time finish_resize runs on the dest host, the instance host/node values are already pointing at the dest (they are set by resize_instance on the source compute before casting to finish_resize on the dest). If finish_resize fails, the instance is essentially stuck on the dest host so rather than revert the allocations (which will drop the new flavor allocations against the dest host where the instance now lives) we should just drop the old flavor allocations on the source node resource provider, which is what this change does. The functional regression recreate test is updated to show this working. Change-Id: I52c8d038118c858004e17e71b2fba9e9e2714815 Closes-Bug: #1825537 (cherry picked from commit ea297d6)
1 parent eaa1fc6 commit e6c6178

File tree

3 files changed

+28
-17
lines changed

3 files changed

+28
-17
lines changed

nova/compute/manager.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4776,7 +4776,22 @@ def finish_resize(self, context, disk_info, image, instance,
47764776
migration)
47774777
except Exception:
47784778
with excutils.save_and_reraise_exception():
4779-
self._revert_allocation(context, instance, migration)
4779+
# At this point, resize_instance (which runs on the source) has
4780+
# already updated the instance host/node values to point to
4781+
# this (the dest) compute, so we need to leave the allocations
4782+
# against the dest node resource provider intact and drop the
4783+
# allocations against the source node resource provider. If the
4784+
# user tries to recover the server by hard rebooting it, it
4785+
# will happen on this host so that's where the allocations
4786+
# should go. Note that this is the same method called from
4787+
# confirm_resize to cleanup the source node allocations held
4788+
# by the migration record.
4789+
LOG.info('Deleting allocations for old flavor on source node '
4790+
'%s after finish_resize failure. You may be able to '
4791+
'recover the instance by hard rebooting it.',
4792+
migration.source_compute, instance=instance)
4793+
self._delete_allocation_after_move(
4794+
context, instance, migration)
47804795

47814796
def _finish_resize_helper(self, context, disk_info, image, instance,
47824797
migration):

nova/tests/functional/regressions/test_bug_1825537.py

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -67,16 +67,9 @@ def test_finish_resize_fails_allocation_cleanup(self):
6767
# allocations should still exist with the new flavor.
6868
source_rp_uuid = self._get_provider_uuid_by_host('host1')
6969
dest_rp_uuid = self._get_provider_uuid_by_host('host2')
70-
# FIXME(mriedem): This is bug 1825537 where the allocations are
71-
# reverted when finish_resize fails so the dest node resource provider
72-
# does not have any allocations and the instance allocations are for
73-
# the old flavor on the source node resource provider even though the
74-
# instance is not running on the source host nor pointed at the source
75-
# host in the DB.
76-
# self.assertFlavorMatchesAllocation(
77-
# self.flavor2, server['id'], dest_rp_uuid)
78-
dest_rp_usages = self._get_provider_usages(dest_rp_uuid)
79-
no_usage = {'VCPU': 0, 'MEMORY_MB': 0, 'DISK_GB': 0}
80-
self.assertEqual(no_usage, dest_rp_usages)
8170
self.assertFlavorMatchesAllocation(
82-
self.flavor1, server['id'], source_rp_uuid)
71+
self.flavor2, server['id'], dest_rp_uuid)
72+
# And the source node provider should not have any usage.
73+
source_rp_usages = self._get_provider_usages(source_rp_uuid)
74+
no_usage = {'VCPU': 0, 'MEMORY_MB': 0, 'DISK_GB': 0}
75+
self.assertEqual(no_usage, source_rp_usages)

nova/tests/functional/test_servers.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3723,10 +3723,13 @@ def fake_resize_method(*args, **kwargs):
37233723

37243724
# Ensure the allocation records still exist on the host.
37253725
source_rp_uuid = self._get_provider_uuid_by_host(hostname)
3726-
# FIXME(mriedem): This is wrong for the _finish_resize case.
3727-
# The new_flavor should have been subtracted from the doubled
3728-
# allocation which just leaves us with the original flavor.
3729-
self.assertFlavorMatchesUsage(source_rp_uuid, self.flavor1)
3726+
if failing_method == '_finish_resize':
3727+
# finish_resize will drop the old flavor allocations.
3728+
self.assertFlavorMatchesUsage(source_rp_uuid, self.flavor2)
3729+
else:
3730+
# The new_flavor should have been subtracted from the doubled
3731+
# allocation which just leaves us with the original flavor.
3732+
self.assertFlavorMatchesUsage(source_rp_uuid, self.flavor1)
37303733

37313734
def test_resize_to_same_host_prep_resize_fails(self):
37323735
self._test_resize_to_same_host_instance_fails(

0 commit comments

Comments
 (0)