Skip to content

Commit

Permalink
Fixing call to hasManagedSaveImage
Browse files Browse the repository at this point in the history
Fixes bug #1044090

hasManagedSaveImage is not implmented in the LXC libvirt driver, resulting
in the following error when a vm is deleted "Error from libvirt during saved
instance removal. Code=3 Error=this function is not supported by the
connection driver: virDomainHasManagedSaveImage"

This commit replaces the use of hasManagedSaveImage, managedSaveRemove and
undefine with undefineFlags which does the work of all 3 calls and is
implemented in versions of libvirt > 0.9.4. We also revert back to calling
undefine if undefineFlags raises an error.

Change-Id: Ib8d451aeff7767f835c3c1aab99ee4ab5e299852
  • Loading branch information
derekhiggins committed Sep 5, 2012
1 parent 06dec8e commit aeacea1
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 16 deletions.
7 changes: 7 additions & 0 deletions nova/tests/fakelibvirt.py
Expand Up @@ -69,6 +69,7 @@ def _reset():
VIR_DOMAIN_CRASHED = 6

VIR_DOMAIN_XML_SECURE = 1
VIR_DOMAIN_UNDEFINE_MANAGED_SAVE = 1

VIR_CPU_COMPARE_ERROR = -1
VIR_CPU_COMPARE_INCOMPATIBLE = 0
Expand Down Expand Up @@ -276,6 +277,12 @@ def isActive(self):
def undefine(self):
self._connection._undefine(self)

def undefineFlags(self, flags):
self.undefine()
if flags & VIR_DOMAIN_UNDEFINE_MANAGED_SAVE:
if self.hasManagedSaveImage(0):
self.managedSaveRemove()

def destroy(self):
self._state = VIR_DOMAIN_SHUTOFF
self._connection._mark_not_running(self)
Expand Down
29 changes: 25 additions & 4 deletions nova/tests/test_libvirt.py
Expand Up @@ -2160,12 +2160,33 @@ def fake_lookup_by_name(instance_name):
instance = db.instance_create(self.context, self.test_instance)
conn.destroy(instance, {})

def test_destroy_saved(self):
"""Ensure destroy calls managedSaveRemove for saved instance"""
def test_destroy(self):
"""Ensure destroy calls virDomain.undefineFlags"""
mock = self.mox.CreateMock(libvirt.virDomain)
mock.destroy()
mock.undefineFlags(1).AndReturn(1)

self.mox.ReplayAll()

def fake_lookup_by_name(instance_name):
return mock

def fake_get_info(instance_name):
return {'state': power_state.SHUTDOWN}

conn = libvirt_driver.LibvirtDriver(False)
self.stubs.Set(conn, '_lookup_by_name', fake_lookup_by_name)
self.stubs.Set(conn, 'get_info', fake_get_info)
instance = {"name": "instancename", "id": "instanceid",
"uuid": "875a8070-d0b9-4949-8b31-104d125c9a64"}
conn.destroy(instance, [])

def test_destroy_noflag(self):
"""Ensure destroy calls virDomain.undefine
if mock.undefineFlags raises an error"""
mock = self.mox.CreateMock(libvirt.virDomain)
mock.destroy()
mock.hasManagedSaveImage(0).AndReturn(1)
mock.managedSaveRemove(0)
mock.undefineFlags(1).AndRaise(libvirt.libvirtError('Err'))
mock.undefine()

self.mox.ReplayAll()
Expand Down
19 changes: 7 additions & 12 deletions nova/virt/libvirt/driver.py
Expand Up @@ -483,18 +483,13 @@ def _cleanup(self, instance, network_info, block_device_info):
virt_dom = None
if virt_dom:
try:
# NOTE(derekh): we can switch to undefineFlags and
# VIR_DOMAIN_UNDEFINE_MANAGED_SAVE once we require 0.9.4
if virt_dom.hasManagedSaveImage(0):
virt_dom.managedSaveRemove(0)
except libvirt.libvirtError as e:
errcode = e.get_error_code()
LOG.error(_("Error from libvirt during saved instance "
"removal. Code=%(errcode)s Error=%(e)s") %
locals(), instance=instance)
try:
# NOTE(justinsb): We remove the domain definition.
virt_dom.undefine()
try:
virt_dom.undefineFlags(
libvirt.VIR_DOMAIN_UNDEFINE_MANAGED_SAVE)
except libvirt.libvirtError as e:
LOG.debug(_("Error from libvirt during undefineFlags."
" Retrying with undefine"), instance=instance)
virt_dom.undefine()
except libvirt.libvirtError as e:
errcode = e.get_error_code()
LOG.error(_("Error from libvirt during undefine. "
Expand Down

0 comments on commit aeacea1

Please sign in to comment.