[libvirt] [PATCH 10/10] qemu: Error out when domain starting if the cdbfilter setting conflicts

Osier Yang jyang at redhat.com
Wed Nov 28 12:45:20 UTC 2012


This prevents the domain starting if the shared disk's setting
conflicts with other active domain(s), E.g. A domain with
"cdbfilter" set as "yes", however, another active domain is using
it set as "no".

* src/conf/domain_conf.h: (Declare helper virDomainDiskFindByPath)
* src/conf/domain_conf.c: (Implement virDomainDiskFindByPath)
* src/libvirt_private.syms (export virDomainDiskFindByPath)
* src/qemu/qemu_process.c: (Error out if the shared disk's cdbfilter
                            conflicts with others)
---
 src/conf/domain_conf.c   |   13 +++++++++++++
 src/conf/domain_conf.h   |    2 ++
 src/libvirt_private.syms |    1 +
 src/qemu/qemu_process.c  |   43 +++++++++++++++++++++++++++++++++++++------
 4 files changed, 53 insertions(+), 6 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 880cb6e..811143c 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -3055,6 +3055,19 @@ virDomainDiskFindControllerModel(virDomainDefPtr def,
     return model;
 }
 
+virDomainDiskDefPtr
+virDomainDiskFindByPath(virDomainDefPtr def,
+                        const char *path)
+{
+    int i;
+
+    for (i = 0; i < def->ndisks; i++)
+        if (STREQ(def->disks[i]->src, path))
+            return def->disks[i];
+
+    return NULL;
+}
+
 int
 virDomainDiskDefAssignAddress(virCapsPtr caps, virDomainDiskDefPtr def)
 {
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 47a16c8..5838a7b 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1886,6 +1886,8 @@ void virDomainDiskHostDefFree(virDomainDiskHostDefPtr def);
 int virDomainDiskFindControllerModel(virDomainDefPtr def,
                                      virDomainDiskDefPtr disk,
                                      int controllerType);
+virDomainDiskDefPtr virDomainDiskFindByPath(virDomainDefPtr def,
+                                            const char *path);
 void virDomainControllerDefFree(virDomainControllerDefPtr def);
 void virDomainFSDefFree(virDomainFSDefPtr def);
 void virDomainActualNetDefFree(virDomainActualNetDefPtr def);
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index c756130..37187db 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -343,6 +343,7 @@ virDomainDiskDefFree;
 virDomainDiskDeviceTypeToString;
 virDomainDiskErrorPolicyTypeFromString;
 virDomainDiskErrorPolicyTypeToString;
+virDomainDiskFindByPath;
 virDomainDiskFindControllerModel;
 virDomainDiskGeometryTransTypeFromString;
 virDomainDiskGeometryTransTypeToString;
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 7ac83b5..691ceea 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -3704,12 +3704,43 @@ int qemuProcessStart(virConnectPtr conn,
         if (disk->rawio == 1)
             virCommandAllowCap(cmd, CAP_SYS_RAWIO);
 
-        /* Add to qemud_driver->sharedDisks list if the disk is shared */
-        if (disk->shared &&
-            (qemuSharedDiskListAdd(driver->sharedDisks,
-                                   disk->src,
-                                   vm->def->name) < 0)) {
-            goto cleanup;
+        if (disk->shared) {
+            /* Error out if the cdbfilter setting is different with what
+             * other domain(s) uses.
+             */
+            qemuSharedDiskPtr entry = NULL;
+
+            if ((entry = qemuSharedDiskListFind(driver->sharedDisks,
+                                               disk->src,
+                                               NULL,
+                                               NULL))) {
+                for (i = 0; i < entry->ndomains; i++) {
+                    virDomainObjPtr domobj = NULL;
+                    virDomainDiskDefPtr diskdef = NULL;
+
+                    if (!(domobj = virDomainFindByName(&driver->domains,
+                                                       entry->domains[i])))
+                        goto cleanup;
+
+                    if (!(diskdef = virDomainDiskFindByPath(domobj->def,
+                                                            disk->src)))
+                        goto cleanup;
+
+                    if (diskdef->cdbfilter != disk->cdbfilter) {
+                        virReportError(VIR_ERR_INTERNAL_ERROR,
+                                       _("cdbfilter of shared disk '%s' "
+                                         "conflicts with other active "
+                                         "domains"), disk->src);
+                        goto cleanup;
+                    }
+                }
+            }
+
+            /* Add to qemud_driver->sharedDisks list if the disk is shared */
+            if (qemuSharedDiskListAdd(driver->sharedDisks,
+                                      disk->src,
+                                      vm->def->name) < 0)
+                goto cleanup;
         }
 
         if (!disk->cdbfilter)
-- 
1.7.7.6




More information about the libvir-list mailing list