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);
 
