diff options
| author | Rick Harris <rconradharris@gmail.com> | 2012-07-24 17:05:52 +0000 |
|---|---|---|
| committer | Rick Harris <rconradharris@gmail.com> | 2012-07-24 17:14:57 +0000 |
| commit | c542f82396ce6cf1399a2d7cfc3d9660fe2cf6c3 (patch) | |
| tree | 548074a8472ff7d2f5f3cd96983438c408ecf9e9 | |
| parent | 013ab2fdfc2c8a0c74ecf3c2287fb6a36d8b6728 (diff) | |
| download | nova-c542f82396ce6cf1399a2d7cfc3d9660fe2cf6c3.tar.gz nova-c542f82396ce6cf1399a2d7cfc3d9660fe2cf6c3.tar.xz nova-c542f82396ce6cf1399a2d7cfc3d9660fe2cf6c3.zip | |
Xen: Ensure snapshot is torn down on error.
This patch solves the problem of snapshots being left around if an
exception is generated in _wait_for_vhd_coalesce.
The solution is to separate snapshot from coalesce and then to ensure
any exceptions generated after a snapshot trigger a cleanup.
Change-Id: I4c03243bc41f76d80d32934dd9506d1861951184
| -rw-r--r-- | nova/virt/xenapi/vm_utils.py | 46 |
1 files changed, 19 insertions, 27 deletions
diff --git a/nova/virt/xenapi/vm_utils.py b/nova/virt/xenapi/vm_utils.py index a49c2ec9c..9d340861d 100644 --- a/nova/virt/xenapi/vm_utils.py +++ b/nova/virt/xenapi/vm_utils.py @@ -471,28 +471,32 @@ def get_vdi_for_vm_safely(session, vm_ref): def snapshot_attached_here(session, instance, vm_ref, label): LOG.debug(_("Starting snapshot for VM"), instance=instance) - try: - template_vm_ref, vdi_uuids = _create_snapshot( - session, instance, vm_ref, label) - except session.XenAPI.Failure, exc: - LOG.error(_("Unable to Snapshot instance: %(exc)s"), locals(), - instance=instance) - raise + # Memorize the original_parent_uuid so we can poll for coalesce + vm_vdi_ref, vm_vdi_rec = get_vdi_for_vm_safely(session, vm_ref) + original_parent_uuid = _get_vhd_parent_uuid(session, vm_vdi_ref) + + template_vm_ref, template_vdi_uuid = _create_snapshot( + session, instance, vm_ref, label) try: + sr_ref = vm_vdi_rec["SR"] + + # NOTE(sirp): This rescan is necessary to ensure the VM's `sm_config` + # matches the underlying VHDs. + _scan_sr(session, sr_ref) + + parent_uuid, base_uuid = _wait_for_vhd_coalesce( + session, instance, sr_ref, vm_vdi_ref, original_parent_uuid) + + vdi_uuids = [vdi_rec['uuid'] for vdi_rec in + _walk_vdi_chain(session, template_vdi_uuid)] + yield vdi_uuids finally: _destroy_snapshot(session, instance, template_vm_ref) def _create_snapshot(session, instance, vm_ref, label): - """Creates Snapshot (Template) VM, Snapshot VBD, Snapshot VDI, - Snapshot VHD - """ - vm_vdi_ref, vm_vdi_rec = get_vdi_for_vm_safely(session, vm_ref) - - original_parent_uuid = _get_vhd_parent_uuid(session, vm_vdi_ref) - template_vm_ref = session.call_xenapi('VM.snapshot', vm_ref, label) template_vdi_rec = get_vdi_for_vm_safely(session, template_vm_ref)[1] template_vdi_uuid = template_vdi_rec["uuid"] @@ -500,19 +504,7 @@ def _create_snapshot(session, instance, vm_ref, label): LOG.debug(_("Created snapshot %(template_vdi_uuid)s with label" " '%(label)s'"), locals(), instance=instance) - sr_ref = vm_vdi_rec["SR"] - - # NOTE(sirp): This rescan is necessary to ensure the VM's `sm_config` - # matches the underlying VHDs. - _scan_sr(session, sr_ref) - - parent_uuid, base_uuid = _wait_for_vhd_coalesce( - session, instance, sr_ref, vm_vdi_ref, original_parent_uuid) - - vdi_uuids = [vdi_rec['uuid'] for vdi_rec in - _walk_vdi_chain(session, template_vdi_uuid)] - - return template_vm_ref, vdi_uuids + return template_vm_ref, template_vdi_uuid def _destroy_snapshot(session, instance, vm_ref): |
