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 | 56 +++++++++++++++++++++++++++++++++++++++++-----
4 files changed, 66 insertions(+), 6 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 50d853e..1d6bb1f 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -3062,6 +3062,19 @@ virDomainDiskFindControllerModel(virDomainDefPtr def,
return model;
}
+virDomainDiskDefPtr
+virDomainDiskFindByPath(virDomainDefPtr def,
+ const char *path)
+{
+ int i;
+
+ for (i = 0; i < def->ndisks; i++)
+ if (STREQ_NULLABLE(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 d7c9b6b..2f24a3f 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1897,6 +1897,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 78e4a5c..b220a76 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -352,6 +352,7 @@ virDomainDiskDefFree;
virDomainDiskDeviceTypeToString;
virDomainDiskErrorPolicyTypeFromString;
virDomainDiskErrorPolicyTypeToString;
+virDomainDiskFindByPath;
virDomainDiskFindControllerModel;
virDomainDiskGeometryTransTypeFromString;
virDomainDiskGeometryTransTypeToString;
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 05f8622..2938a65 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -3712,12 +3712,56 @@ 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))) {
+ virDomainObjUnlock(vm);
+ for (i = 0; i < entry->ndomains; i++) {
+ virDomainObjPtr domobj = NULL;
+ virDomainDiskDefPtr diskdef = NULL;
+
+ if (!(domobj = virDomainFindByName(&driver->domains,
+ entry->domains[i]))) {
+ virDomainObjLock(vm);
+ goto cleanup;
+ }
+
+ if (!(diskdef = virDomainDiskFindByPath(domobj->def,
+ disk->src))) {
+ virDomainObjUnlock(domobj);
+ virDomainObjLock(vm);
+ goto cleanup;
+ }
+
+ /* XXX: Can be abstracted into a function when there
+ * are more stuffs to check in future.
+ */
+ if (diskdef->cdbfilter != disk->cdbfilter) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("cdbfilter of shared disk '%s'
"
+ "conflicts with other active "
+ "domains"), disk->src);
+ virDomainObjUnlock(domobj);
+ virDomainObjLock(vm);
+ goto cleanup;
+ }
+ virDomainObjUnlock(domobj);
+ }
+ virDomainObjLock(vm);
+ }
+
+ /* 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