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