changeset: 487:900bee6f2cc8 user: "Hugh O. Brock " date: Tue May 01 16:22:22 2007 -0400 summary: 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. diff -r fddee0787dde -r 900bee6f2cc8 src/virtManager/domain.py --- a/src/virtManager/domain.py Wed Apr 25 17:51:42 2007 -0400 +++ b/src/virtManager/domain.py Tue May 01 16:22:22 2007 -0400 @@ -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) - - # XXX remove from defined XML. Eek ! + 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) + + 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)