diff options
author | Andrew Laski <andrew.laski@rackspace.com> | 2014-06-13 17:15:00 -0400 |
---|---|---|
committer | Andrew Laski <andrew.laski@rackspace.com> | 2014-07-16 15:15:04 +0000 |
commit | be58dd8432a8d12484f5553d79a02e720e2c0435 (patch) | |
tree | d5170234dbb42626421e5f97bfc55088f7956459 /nova/virt | |
parent | c2d62d2a4332ff7f13d4840864ee7df778c377ef (diff) | |
download | nova-be58dd8432a8d12484f5553d79a02e720e2c0435.tar.gz |
Xen: Cleanup orphan volume connections on boot failure
If the boot process fails after the VDI creation but before a VBD is
created then the current cleanup methods will not work as they all rely
on lookups via VBD.
Change-Id: Id0d93ee60f75bf319baf7859b220ca325175128a
Closes-bug: #1329941
Diffstat (limited to 'nova/virt')
-rw-r--r-- | nova/virt/xenapi/vmops.py | 3 | ||||
-rw-r--r-- | nova/virt/xenapi/volume_utils.py | 11 | ||||
-rw-r--r-- | nova/virt/xenapi/volumeops.py | 17 |
3 files changed, 31 insertions, 0 deletions
diff --git a/nova/virt/xenapi/vmops.py b/nova/virt/xenapi/vmops.py index c7db7ea992..f8b913b6b5 100644 --- a/nova/virt/xenapi/vmops.py +++ b/nova/virt/xenapi/vmops.py @@ -341,6 +341,9 @@ class VMOps(object): vdi_refs = [vdi['ref'] for vdi in vdis.values() if not vdi.get('osvol')] vm_utils.safe_destroy_vdis(self._session, vdi_refs) + vol_vdi_refs = [vdi['ref'] for vdi in vdis.values() + if vdi.get('osvol')] + self._volumeops.safe_cleanup_from_vdis(vol_vdi_refs) undo_mgr.undo_with(undo_create_disks) return vdis diff --git a/nova/virt/xenapi/volume_utils.py b/nova/virt/xenapi/volume_utils.py index d1a01d58f2..f1537914be 100644 --- a/nova/virt/xenapi/volume_utils.py +++ b/nova/virt/xenapi/volume_utils.py @@ -301,6 +301,17 @@ def find_sr_from_vbd(session, vbd_ref): return sr_ref +def find_sr_from_vdi(session, vdi_ref): + """Find the SR reference from the VDI reference.""" + try: + sr_ref = session.call_xenapi("VDI.get_SR", vdi_ref) + except session.XenAPI.Failure as exc: + LOG.exception(exc) + raise exception.StorageError( + reason=_('Unable to find SR from VDI %s') % vdi_ref) + return sr_ref + + def find_vbd_by_number(session, vm_ref, dev_number): """Get the VBD reference from the device number.""" vbd_refs = session.VM.get_VBDs(vm_ref) diff --git a/nova/virt/xenapi/volumeops.py b/nova/virt/xenapi/volumeops.py index 5eb28165af..f6b4bde804 100644 --- a/nova/virt/xenapi/volumeops.py +++ b/nova/virt/xenapi/volumeops.py @@ -204,3 +204,20 @@ class VolumeOps(object): raise return bad_devices + + def safe_cleanup_from_vdis(self, vdi_refs): + # A helper method to detach volumes that are not associated with an + # instance + + for vdi_ref in vdi_refs: + try: + sr_ref = volume_utils.find_sr_from_vdi(self._session, vdi_ref) + except exception.StorageError as exc: + LOG.debug(exc.format_message()) + continue + try: + # Forget (i.e. disconnect) SR only if not in use + volume_utils.purge_sr(self._session, sr_ref) + except Exception: + LOG.debug('Ignoring error while purging sr: %s' % sr_ref, + exc_info=True) |