summaryrefslogtreecommitdiff
path: root/nova/virt
diff options
context:
space:
mode:
authorAndrew Laski <andrew.laski@rackspace.com>2014-06-13 17:15:00 -0400
committerAndrew Laski <andrew.laski@rackspace.com>2014-07-16 15:15:04 +0000
commitbe58dd8432a8d12484f5553d79a02e720e2c0435 (patch)
treed5170234dbb42626421e5f97bfc55088f7956459 /nova/virt
parentc2d62d2a4332ff7f13d4840864ee7df778c377ef (diff)
downloadnova-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.py3
-rw-r--r--nova/virt/xenapi/volume_utils.py11
-rw-r--r--nova/virt/xenapi/volumeops.py17
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)