Allow removal of devices from inactive domains. Requires rewriting the XML and redefining the domain. To work on xen 3.0.3 userland, also requires libvirt patch to xm_internal.c.

This commit is contained in:
Hugh O. Brock 2007-05-01 16:22:22 -04:00
parent 21d090d6fa
commit c01eb732c4
1 changed files with 60 additions and 4 deletions

View File

@ -545,13 +545,69 @@ class vmmDomain(gobject.GObject):
self.get_connection().define_domain(newxml)
def remove_device(self, xml):
logging.debug("Removing device " + xml)
def remove_device(self, dev_xml):
logging.debug("Removing device " + dev_xml)
if self.is_active():
self.vm.detachDevice(xml)
self.vm.detachDevice(dev_xml)
else:
# XXX remove from defined XML. Eek !
xml = self.get_xml()
doc = None
try:
doc = libxml2.parseDoc(xml)
except:
return
ctx = doc.xpathNewContext()
try:
dev_doc = libxml2.parseDoc(dev_xml)
except:
raise RuntimeError("Device XML would not parse")
dev_ctx = dev_doc.xpathNewContext()
ret = None
try:
dev = dev_ctx.xpathEval("//*")
dev_type = dev[0].name
if dev_type=="interface":
address = dev_ctx.xpathEval("/interface/mac/@address")
if len(address) > 0 and address[0].content != None:
logging.debug("The mac address appears to be %s" % address[0].content)
ret = ctx.xpathEval("/domain/devices/interface[mac/@address='%s']" % address[0].content)
if len(ret) >0:
ret[0].unlinkNode()
ret[0].freeNode()
newxml=doc.serialize()
logging.debug("Redefine with " + newxml)
self.get_connection().define_domain(newxml)
elif dev_type=="disk":
disk_type_node = dev_ctx.xpathEval("/disk/@type")
disk_type = None
if len(disk_type_node) > 0 and disk_type_node[0].content != None:
disk_type = disk_type_node[0].content
logging.debug("Looking for disk type %s" % disk_type)
if disk_type == "block":
path = dev_ctx.xpathEval("/disk/source/@dev")
if len(path) > 0 and path[0].content != None:
logging.debug("Looking for path %s" % path[0].content)
ret = ctx.xpathEval("/domain/devices/disk[source/@dev='%s']" % path[0].content)
elif disk_type == "file":
path = dev_ctx.xpathEval("/disk/source/@file")
if len(path) > 0 and path[0].content != None:
ret = ctx.xpathEval("/domain/devices/disk[source/@file='%s']" % path[0].content)
if len(ret) > 0:
ret[0].unlinkNode()
ret[0].freeNode()
newxml=doc.serialize()
logging.debug("Redefine with " + newxml)
self.get_connection().define_domain(newxml)
# XXX remove from defined XML. Eek !
finally:
if ctx != None:
ctx.xpathFreeContext()
if doc != None:
doc.freeDoc()
if dev_doc != None:
dev_doc.freeDoc()
def set_vcpu_count(self, vcpus):
vcpus = int(vcpus)