Skip to content

Commit c70d974

Browse files
Zuulopenstack-gerrit
authored andcommitted
Merge "Set instance host and drop migration under lock" into stable/victoria
2 parents 81ad810 + 3ecc098 commit c70d974

File tree

4 files changed

+35
-33
lines changed

4 files changed

+35
-33
lines changed

nova/compute/manager.py

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3472,19 +3472,11 @@ def rebuild_instance(self, context, instance, orig_image_ref, image_ref,
34723472
self._notify_instance_rebuild_error(context, instance, e, bdms)
34733473
raise
34743474
else:
3475-
instance.apply_migration_context()
3476-
# NOTE (ndipanov): This save will now update the host and node
3477-
# attributes making sure that next RT pass is consistent since
3478-
# it will be based on the instance and not the migration DB
3479-
# entry.
3480-
instance.host = self.host
3481-
instance.node = scheduled_node
3482-
instance.save()
3483-
instance.drop_migration_context()
3484-
3485-
# NOTE (ndipanov): Mark the migration as done only after we
3486-
# mark the instance as belonging to this host.
3487-
self._set_migration_status(migration, 'done')
3475+
# NOTE(gibi): Let the resource tracker set the instance
3476+
# host and drop the migration context as we need to hold the
3477+
# COMPUTE_RESOURCE_SEMAPHORE to avoid the race with
3478+
# _update_available_resources. See bug 1896463.
3479+
self.rt.finish_evacuation(instance, scheduled_node, migration)
34883480

34893481
def _do_rebuild_instance_with_claim(
34903482
self, context, instance, orig_image_ref, image_meta,

nova/compute/resource_tracker.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1970,3 +1970,21 @@ def free_pci_device_claims_for_instance(self, context, instance):
19701970
"""
19711971
self.pci_tracker.free_instance_claims(context, instance)
19721972
self.pci_tracker.save(context)
1973+
1974+
@utils.synchronized(COMPUTE_RESOURCE_SEMAPHORE, fair=True)
1975+
def finish_evacuation(self, instance, node, migration):
1976+
instance.apply_migration_context()
1977+
# NOTE (ndipanov): This save will now update the host and node
1978+
# attributes making sure that next RT pass is consistent since
1979+
# it will be based on the instance and not the migration DB
1980+
# entry.
1981+
instance.host = self.host
1982+
instance.node = node
1983+
instance.save()
1984+
instance.drop_migration_context()
1985+
1986+
# NOTE (ndipanov): Mark the migration as done only after we
1987+
# mark the instance as belonging to this host.
1988+
if migration:
1989+
migration.status = 'done'
1990+
migration.save()

nova/tests/functional/regressions/test_bug_1896463.py

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -219,13 +219,4 @@ def slow_get_mig(*args, **kwargs):
219219
server, {'OS-EXT-SRV-ATTR:host': 'host2', 'status': 'ACTIVE'})
220220

221221
self._assert_pci_device_allocated(server['id'], self.compute1_id)
222-
223-
# This is bug #1896463 as the PCI allocation was deleted by the racing
224-
# _update_available_resource periodic task.
225-
self._assert_pci_device_allocated(
226-
server['id'], self.compute2_id, num=0)
227-
228-
# FIXME(gibi): When this bug is fixed (or if you remove the sleeps
229-
# above to avoid the race condition) then we expect that the PCI
230-
# allocation exists on the destination host too.
231-
# self._assert_pci_device_allocated(server['id'], self.compute2_id)
222+
self._assert_pci_device_allocated(server['id'], self.compute2_id)

nova/tests/unit/compute/test_compute_mgr.py

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5340,19 +5340,21 @@ def test_rebuild_node_not_updated_if_not_recreate(self):
53405340
node = uuidutils.generate_uuid() # ironic node uuid
53415341
instance = fake_instance.fake_instance_obj(self.context, node=node)
53425342
instance.migration_context = None
5343+
migration = objects.Migration(status='accepted')
53435344
with test.nested(
53445345
mock.patch.object(self.compute, '_get_compute_info'),
53455346
mock.patch.object(self.compute, '_do_rebuild_instance_with_claim'),
53465347
mock.patch.object(objects.Instance, 'save'),
5347-
mock.patch.object(self.compute, '_set_migration_status'),
5348-
) as (mock_get, mock_rebuild, mock_save, mock_set):
5348+
mock.patch.object(migration, 'save'),
5349+
) as (mock_get, mock_rebuild, mock_save, mock_migration_save):
53495350
self.compute.rebuild_instance(
53505351
self.context, instance, None, None,
53515352
None, None, None, None, False,
5352-
False, False, None, None, {}, None, [])
5353+
False, False, migration, None, {}, None, [])
53535354
self.assertFalse(mock_get.called)
53545355
self.assertEqual(node, instance.node)
5355-
mock_set.assert_called_once_with(None, 'done')
5356+
self.assertEqual('done', migration.status)
5357+
mock_migration_save.assert_called_once_with()
53565358

53575359
def test_rebuild_node_updated_if_recreate(self):
53585360
dead_node = uuidutils.generate_uuid()
@@ -5365,16 +5367,15 @@ def test_rebuild_node_updated_if_recreate(self):
53655367
with test.nested(
53665368
mock.patch.object(self.compute, '_get_compute_info'),
53675369
mock.patch.object(self.compute, '_do_rebuild_instance'),
5368-
mock.patch.object(objects.Instance, 'save'),
5369-
mock.patch.object(self.compute, '_set_migration_status'),
5370-
) as (mock_get, mock_rebuild, mock_save, mock_set):
5370+
) as (mock_get, mock_rebuild):
53715371
mock_get.return_value.hypervisor_hostname = 'new-node'
53725372
self.compute.rebuild_instance(
53735373
self.context, instance, None, None, None, None, None,
5374-
None, True, False, False, None, None, {}, None, [])
5374+
None, True, False, False, mock.sentinel.migration, None, {},
5375+
None, [])
53755376
mock_get.assert_called_once_with(mock.ANY, self.compute.host)
5376-
self.assertEqual('new-node', instance.node)
5377-
mock_set.assert_called_once_with(None, 'done')
5377+
mock_rt.finish_evacuation.assert_called_once_with(
5378+
instance, 'new-node', mock.sentinel.migration)
53785379
# Make sure the rebuild_claim was called with the proper image_meta
53795380
# from the instance.
53805381
mock_rt.rebuild_claim.assert_called_once()

0 commit comments

Comments
 (0)