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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list