This prevent the domain starting if the shared disk's setting conflicts
with other active domain(s), E.g. A domain with unpriv_sgio set as
"yes", however, another active domain is using it set as "no".
---
src/conf/domain_conf.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
src/conf/domain_conf.h | 3 +++
src/libvirt_private.syms | 1 +
src/qemu/qemu_process.c | 14 +++++++++++++-
4 files changed, 62 insertions(+), 1 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 02df96e..fb7bb1f 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -15763,3 +15763,48 @@ virDomainDiskIsUsed(const virDomainObjList doms,
return false;
}
+
+static int
+virDomainSharedDiskCompare(const void *payload,
+ const void *name ATTRIBUTE_UNUSED,
+ const void *opaque)
+{
+ virDomainObjPtr obj = (virDomainObjPtr)payload;
+ const virDomainDiskDefPtr disk = (virDomainDiskDefPtr)opaque;
+ int i;
+
+ virDomainObjLock(obj);
+
+ /* Ingores the inactive ones */
+ if (!virDomainObjIsActive(obj))
+ return 0;
+
+ for (i = 0; i < obj->def->ndisks; i++) {
+ if (STRNEQ(obj->def->disks[i]->src, disk->src))
+ continue;
+
+ if (obj->def->disks[i]->unpriv_sgio != disk->unpriv_sgio) {
+ virDomainObjUnlock(obj);
+ return 1;
+ }
+ }
+
+ virDomainObjUnlock(obj);
+ return 0;
+}
+
+/* Validate if the shared disk conf is conflicted with other domains,
+ * currently only validates the unpriv_sgio setting
+ */
+bool
+virDomainSharedDiskValidate(const virDomainObjList doms,
+ const virDomainDiskDefPtr disk)
+{
+ virDomainObjPtr obj;
+
+ obj = virHashSearch(doms.objs, virDomainSharedDiskCompare, disk);
+ if (obj)
+ return false;
+
+ return true;
+}
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 3105e05..35f46d2 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1878,6 +1878,9 @@ bool virDomainDiskIsUsed(const virDomainObjList doms,
char *name,
char *diskSrc,
bool active);
+bool
+virDomainSharedDiskValidate(const virDomainObjList doms,
+ const virDomainDiskDefPtr disk);
bool virDomainObjTaint(virDomainObjPtr obj,
enum virDomainTaintFlags taint);
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index b9019b7..b14eb40 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -489,6 +489,7 @@ virDomainSaveStatus;
virDomainSaveXML;
virDomainSeclabelTypeFromString;
virDomainSeclabelTypeToString;
+virDomainSharedDiskValidate;
virDomainShutdownReasonTypeFromString;
virDomainShutdownReasonTypeToString;
virDomainShutoffReasonTypeFromString;
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index eeaaea0..b5676e0 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -3711,6 +3711,18 @@ int qemuProcessStart(virConnectPtr conn,
if (!disk->unpriv_sgio)
continue;
+ /* Error out if the disk is shared, but the unpriv_sgio conflicts
+ * with other active domain(s).
+ */
+ if (disk->shared &&
+ !virDomainSharedDiskValidate(driver->domains,
+ disk)) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("Setting of shared disk '%s' conflicts with
"
+ "other active domains"), disk->src);
+ goto cleanup;
+ }
+
if (virGetDeviceUnprivSGIO(disk->src, &old_unpriv_sgio) < 0)
goto cleanup;
@@ -3719,7 +3731,7 @@ int qemuProcessStart(virConnectPtr conn,
if (virSetDeviceUnprivSGIO(disk->src,
(disk->unpriv_sgio ==
VIR_DOMAIN_DISK_UNPRIV_SGIO_YES)
- ? 1 : 0) < 0)
+ ? 1 : 0) < 0)
goto cleanup;
}
--
1.7.7.6