[libvirt] [PATCH] Don't allow two or more disks to be mapped to the same image file

Hu Tao hutao at cn.fujitsu.com
Thu Mar 24 07:02:21 UTC 2011


If two or more disks are mapped to the same image file, operating
on these disks at the same time may corrupt data stored in the
image file.
---
 src/conf/domain_conf.c   |   22 ++++++++++++++++++++++
 src/conf/domain_conf.h   |    2 ++
 src/libvirt_private.syms |    1 +
 src/qemu/qemu_driver.c   |    6 ++++++
 4 files changed, 31 insertions(+), 0 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 1b02c25..93a081d 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -5455,6 +5455,14 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps,
         if (!disk)
             goto error;
 
+        if (virDomainDiskConflict(disk, def)) {
+            virDomainReportError(VIR_ERR_INTERNAL_ERROR, "%s %s %s",
+                                 _("source"),
+                                 disk->src,
+                                 _("is already mapped to another device, "
+                                   "skip this device."));
+            continue;
+        }
         def->disks[def->ndisks++] = disk;
     }
     VIR_FREE(nodes);
@@ -9088,3 +9096,17 @@ cleanup:
 
     return ret;
 }
+
+bool virDomainDiskConflict(virDomainDiskDefPtr disk, virDomainDefPtr def)
+{
+    int i;
+
+    if (!disk->src)
+        return false;
+
+    for (i = 0; i < def->ndisks; i++) {
+        if (STREQ(disk->src, def->disks[i]->src))
+            return true;
+    }
+    return false;
+}
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 9f595d6..78b2f95 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1350,6 +1350,8 @@ int virDomainDiskDefForeachPath(virDomainDiskDefPtr disk,
                                 bool ignoreOpenFailure,
                                 virDomainDiskDefPathIterator iter,
                                 void *opaque);
+bool virDomainDiskConflict(virDomainDiskDefPtr disk,
+                           virDomainDefPtr def);
 
 typedef const char* (*virLifecycleToStringFunc)(int type);
 typedef int (*virLifecycleFromStringFunc)(const char *type);
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index b4b6c63..17e2ec4 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -237,6 +237,7 @@ virDomainDeviceTypeToString;
 virDomainDiskBusTypeToString;
 virDomainDiskCacheTypeFromString;
 virDomainDiskCacheTypeToString;
+virDomainDiskConflict;
 virDomainDiskDefAssignAddress;
 virDomainDiskDefForeachPath;
 virDomainDiskDefFree;
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 6f296c9..6de08d3 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -4058,6 +4058,12 @@ static int qemudDomainAttachDevice(virDomainPtr dom,
             break;
 
         case VIR_DOMAIN_DISK_DEVICE_DISK:
+            if (virDomainDiskConflict(dev->data.disk, vm->def)) {
+                qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s %s %s",
+                                _("source"), dev->data.disk->src,
+                                _("is already mapped to another device."));
+                break;
+            }
             if (dev->data.disk->bus == VIR_DOMAIN_DISK_BUS_USB) {
                 ret = qemuDomainAttachUsbMassstorageDevice(driver, vm,
                                                            dev->data.disk, qemuCaps);
-- 
1.7.3.1




More information about the libvir-list mailing list