From c542f82396ce6cf1399a2d7cfc3d9660fe2cf6c3 Mon Sep 17 00:00:00 2001 From: Rick Harris Date: Tue, 24 Jul 2012 17:05:52 +0000 Subject: 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 --- nova/virt/xenapi/vm_utils.py | 46 ++++++++++++++++++-------------------------- 1 file 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): -- cgit