diff options
author | ZHU ZHU <zhuzhubj@cn.ibm.com> | 2014-09-03 03:59:13 -0500 |
---|---|---|
committer | ZHU ZHU <zhuzhubj@cn.ibm.com> | 2014-09-29 22:46:33 -0500 |
commit | e1f8664c9fa83f77f5bb763ffcc3157905ed954c (patch) | |
tree | ac30322ebaac002fc1c830afdf0acb4c9d4912a4 | |
parent | e7469a8c1bb9e8bd1c8fb593170b6ada7a241112 (diff) | |
download | nova-e1f8664c9fa83f77f5bb763ffcc3157905ed954c.tar.gz |
VMWare: Fix VM leak when deletion of VM during resizing
During the VM resizing, before VM arrive RESIZED state, driver
migrate_disk_and_power_off will initially rename orginal vm
'uuid' to be 'uuid-orig' and clone a new vm with 'uuid' name.
When deletion VM is triggered at this time window, it wouldn't
be able to delete the VM uuid-orig in VCenter and so cause VM leak.
As VM task state will be set to 'deleting' and it can not be used to
determine the resize migrating/migrated state, this fix will
attempt to delete orig VM within destroy phase.
Change-Id: I7598afbf0dc3c527471af34224003d28e64daaff
Closes-Bug: #1359138
-rw-r--r-- | nova/tests/virt/vmwareapi/test_driver_api.py | 11 | ||||
-rw-r--r-- | nova/virt/vmwareapi/vmops.py | 11 |
2 files changed, 20 insertions, 2 deletions
diff --git a/nova/tests/virt/vmwareapi/test_driver_api.py b/nova/tests/virt/vmwareapi/test_driver_api.py index fb3e2450a5..7d99a98818 100644 --- a/nova/tests/virt/vmwareapi/test_driver_api.py +++ b/nova/tests/virt/vmwareapi/test_driver_api.py @@ -1482,8 +1482,15 @@ class VMwareAPIVMTestCase(test.NoDBTestCase): self.conn.destroy(self.context, self.instance, self.network_info, None, True) - mock_get.assert_called_once_with(self.conn._vmops._session, - self.instance['uuid']) + mock_get.assert_called_with(self.conn._vmops._session, + self.instance['uuid']) + expected_args = [((self.conn._vmops._session, + self.instance['uuid'] + '-orig'),), + ((self.conn._vmops._session, + self.instance['uuid']),)] + # one for VM named uuid-orig, one for VM named uuid + self.assertEqual(expected_args, mock_get.call_args_list) + self.assertEqual(2, mock_get.call_count) self.assertFalse(mock_call.called) def _rescue(self, config_drive=False): diff --git a/nova/virt/vmwareapi/vmops.py b/nova/virt/vmwareapi/vmops.py index 67ed6c32ad..fe520b1893 100644 --- a/nova/virt/vmwareapi/vmops.py +++ b/nova/virt/vmwareapi/vmops.py @@ -839,6 +839,17 @@ class VMwareVMOps(object): self._destroy_instance(instance, destroy_disks=destroy_disks, instance_name=rescue_name) + # When VM deletion is triggered in middle of VM resize before VM + # arrive RESIZED state, uuid-orig VM need to deleted to avoid + # VM leak. Within method _destroy_instance it will check vmref + # exist or not before attempt deletion. + resize_orig_vmname = instance['uuid'] + self._migrate_suffix + vm_orig_ref = vm_util.get_vm_ref_from_name(self._session, + resize_orig_vmname) + if vm_orig_ref: + self._destroy_instance(instance, + destroy_disks=destroy_disks, + instance_name=resize_orig_vmname) self._destroy_instance(instance, destroy_disks=destroy_disks) LOG.debug("Instance destroyed", instance=instance) |