[libvirt] [PATCH 10/10] qemu: Error out when domain starting if the cdbfilter setting conflicts
Osier Yang
jyang at redhat.com
Tue Dec 4 17:13:04 UTC 2012
On 2012年12月04日 21:17, Osier Yang wrote:
> 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 | 50 ++++++++++++++++++++++++++++++++++++++++-----
> 4 files changed, 60 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 c2b01b9..41e4143 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 5cb068e..fac7d57 100644
> --- a/src/qemu/qemu_process.c
> +++ b/src/qemu/qemu_process.c
> @@ -3704,12 +3704,50 @@ 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))) {
> + virDomainObjUnlock(domobj);
> + 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);
> + goto cleanup;
> + }
> + virDomainObjUnlock(domobj);
> + }
> + }
> +
> + /* 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)
With the following patch squashed in (to avoid the deadlock,
it's not that comfortable to have nest lock/unlock, but I don't
have better idea temporally).
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index fac7d57..5284c74 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -3714,17 +3714,21 @@ int qemuProcessStart(virConnectPtr conn,
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])))
+
entry->domains[i]))) {
+ virDomainObjLock(vm);
goto cleanup;
+ }
if (!(diskdef = virDomainDiskFindByPath(domobj->def,
disk->src))) {
virDomainObjUnlock(domobj);
+ virDomainObjLock(vm);
goto cleanup;
}
@@ -3737,10 +3741,12 @@ int qemuProcessStart(virConnectPtr conn,
"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 */
More information about the libvir-list
mailing list