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:
parent
21d090d6fa
commit
c01eb732c4
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue