Index: src/domain_conf.c =================================================================== RCS file: /data/cvs/libvirt/src/domain_conf.c,v retrieving revision 1.36 diff -u -p -r1.36 domain_conf.c --- src/domain_conf.c 4 Nov 2008 23:22:06 -0000 1.36 +++ src/domain_conf.c 13 Nov 2008 09:25:03 -0000 @@ -3432,5 +3432,68 @@ const char *virDomainDefDefaultEmulator( return emulator; } +int virDiskAlreadyAttached(virConnectPtr conn, + const char *diskxmlStr, + const char *xmlStr) +{ + xmlDocPtr xml; + xmlNodePtr node; + virDomainDiskDefPtr def = NULL; + xmlXPathContextPtr ctxt = NULL; + xmlXPathObjectPtr obj = NULL; + char xpath[PATH_MAX]; + int ret = 0; + + if (!(xml = xmlReadDoc(BAD_CAST diskxmlStr, "device.xml", NULL, + XML_PARSE_NOENT | XML_PARSE_NONET | + XML_PARSE_NOERROR | XML_PARSE_NOWARNING))) { + virDomainReportError(conn, VIR_ERR_XML_ERROR, NULL); + goto error; + } + + node = xmlDocGetRootElement(xml); + if (node == NULL) { + virDomainReportError(conn, VIR_ERR_XML_ERROR, + "%s", _("missing root element")); + goto error; + } + + if (VIR_ALLOC(def) < 0) { + virDomainReportError(conn, VIR_ERR_NO_MEMORY, NULL); + return ret; + } + def = virDomainDiskDefParseXML(conn, node); + + xmlFreeDoc(xml); + if (!(xml = xmlReadDoc(BAD_CAST xmlStr, "device.xml", NULL, + XML_PARSE_NOENT | XML_PARSE_NONET | + XML_PARSE_NOERROR | XML_PARSE_NOWARNING))) { + virDomainReportError(conn, VIR_ERR_XML_ERROR, NULL); + goto error; + } + ctxt = xmlXPathNewContext(xml); + if (!ctxt) + goto error; + + if (def->type == VIR_DOMAIN_DISK_TYPE_FILE) + sprintf(xpath, "string(/domain/devices/disk/source[@file='%s']/@file)", def->src); + else + sprintf(xpath, "string(/domain/devices/disk/source[@dev='%s']/@dev)", def->src); + obj = xmlXPathEval(BAD_CAST xpath, ctxt); + if (STREQ(obj->stringval, def->src)) { + virDomainReportError(conn, VIR_ERR_INVALID_ARG, _("Disk %s which own guest has already used"), def->src); + goto error; + } + + ret = 1; + + error: + xmlFreeDoc(xml); + xmlXPathFreeContext(ctxt); + xmlXPathFreeObject(obj); + VIR_FREE(def); + return ret; +} + #endif /* ! PROXY */ Index: src/domain_conf.h =================================================================== RCS file: /data/cvs/libvirt/src/domain_conf.h,v retrieving revision 1.16 diff -u -p -r1.16 domain_conf.h --- src/domain_conf.h 4 Nov 2008 23:22:06 -0000 1.16 +++ src/domain_conf.h 13 Nov 2008 09:25:03 -0000 @@ -578,6 +578,9 @@ int virDiskNameToBusDeviceIndex(virDomai const char *virDomainDefDefaultEmulator(virConnectPtr conn, virDomainDefPtr def, virCapsPtr caps); +int virDiskAlreadyAttached(virConnectPtr conn, + const char *diskxmlStr, + const char *xmlStr); VIR_ENUM_DECL(virDomainVirt) Index: src/libvirt.c =================================================================== RCS file: /data/cvs/libvirt/src/libvirt.c,v retrieving revision 1.170 diff -u -p -r1.170 libvirt.c --- src/libvirt.c 6 Nov 2008 16:36:07 -0000 1.170 +++ src/libvirt.c 13 Nov 2008 09:25:04 -0000 @@ -3244,6 +3244,9 @@ virDomainAttachDevice(virDomainPtr domai } conn = domain->conn; + if(!virDiskAlreadyAttached(conn, xml, virDomainGetXMLDesc(domain, 0))) + return (-1); + if (conn->driver->domainAttachDevice) return conn->driver->domainAttachDevice (domain, xml);