From 54928267e8807167fb96c8fe414a482833a39465 Mon Sep 17 00:00:00 2001 From: Wangpan Date: Tue, 18 Dec 2012 10:06:15 +0800 Subject: Fix race condition of resize confirmation Currently, the db update of migration status is after the db update of instance's vm_state in _finish_resize, so a race condition occurs when an instance's vm_state is updated but the migration status doesn't, and at this moment a resize confirmation is performed, then an exception 'MigrationNotFoundByStatus' is raised. Fixes: bug #1066140 Change-Id: I1dac98cc99d3491c92faaad2b9dcc40d7c0524b5 --- nova/compute/manager.py | 6 +++--- nova/tests/compute/test_compute.py | 9 +++++++++ 2 files changed, 12 insertions(+), 3 deletions(-) (limited to 'nova') diff --git a/nova/compute/manager.py b/nova/compute/manager.py index 6efc83fb9..0ad115236 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -2002,6 +2002,9 @@ class ComputeManager(manager.SchedulerDependentManager): image, resize_instance, block_device_info) + migration = self.conductor_api.migration_update(context, + migration, 'finished') + instance = self._instance_update(context, instance['uuid'], vm_state=vm_states.RESIZED, @@ -2010,9 +2013,6 @@ class ComputeManager(manager.SchedulerDependentManager): expected_task_state=task_states. RESIZE_FINISH) - migration = self.conductor_api.migration_update(context, - migration, 'finished') - self._notify_about_instance_usage( context, instance, "finish_resize.end", network_info=network_info) diff --git a/nova/tests/compute/test_compute.py b/nova/tests/compute/test_compute.py index 079a25d27..3c69f7642 100644 --- a/nova/tests/compute/test_compute.py +++ b/nova/tests/compute/test_compute.py @@ -1722,7 +1722,16 @@ class ComputeTestCase(BaseTestCase): def fake(*args, **kwargs): pass + def fake_migration_update(context, id, values): + # Ensure instance status updates is after the migration finish + migration_ref = db.migration_get(context, id) + instance_uuid = migration_ref['instance_uuid'] + instance = db.instance_get_by_uuid(context, instance_uuid) + self.assertFalse(instance['vm_state'] == vm_states.RESIZED) + self.assertEqual(instance['task_state'], task_states.RESIZE_FINISH) + self.stubs.Set(self.compute.driver, 'finish_migration', fake) + self.stubs.Set(db, 'migration_update', fake_migration_update) reservations = self._ensure_quota_reservations_committed() -- cgit