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". --- This assumes the lock manager will prevents one using same disk mixed with non-shared and shared modes. I.E. The following scenario won't be happen: * dom1, with disk /dev/sdb's cdbfilter="no" shared * dom2, with disk /dev/sdb's cdbfilter="yes" and non-shared Without the lock manager, dom2's staring will override the disk's unpriv_sgio to 0. --- src/qemu/qemu_process.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++ src/qemu/qemu_process.h | 2 + 2 files changed, 53 insertions(+), 0 deletions(-) diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 4117251..ace0404 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -3385,6 +3385,54 @@ qemuProcessReconnectAll(virConnectPtr conn, virQEMUDriverPtr driver) virHashForEach(driver->domains.objs, qemuProcessReconnectHelper, &data); } +/* Check if a shared disk's setting conflicts with the conf + * used by other domain(s). Currently only checks the cdbfilter + * setting. + * + * Returns 0 if no conflicts, otherwise returns -1. + */ +int +qemuCheckSharedDisk(virHashTablePtr sharedDisks, + virDomainDiskDefPtr disk) +{ + int val; + size_t *ref = NULL; + char *key = NULL; + int ret = 0; + + if (!(key = qemuGetSharedDiskKey(disk->src))) + return -1; + + /* It can't be conflict if no other domain is + * is sharing it. + */ + if (!(ref = virHashLookup(sharedDisks, key))) + goto cleanup; + + if (ref == (void *)0x1) + goto cleanup; + + if (virGetDeviceUnprivSGIO(disk->src, &val) < 0) { + ret = -1; + goto cleanup; + } + + if ((val == 0 && + disk->cdbfilter == VIR_DOMAIN_DISK_CDB_FILTER_YES) || + (val == 1 && + disk->cdbfilter == VIR_DOMAIN_DISK_CDB_FILTER_NO)) + goto cleanup; + + virReportError(VIR_ERR_INTERNAL_ERROR, + _("cdbfilter of shared disk '%s' conflicts with other " + "active domains"), disk->src); + ret = -1; + +cleanup: + VIR_FREE(key); + return ret; +} + int qemuProcessStart(virConnectPtr conn, virQEMUDriverPtr driver, virDomainObjPtr vm, @@ -3733,6 +3781,9 @@ int qemuProcessStart(virConnectPtr conn, if (disk->type == VIR_DOMAIN_DISK_TYPE_BLOCK && disk->shared) { if (qemuAddSharedDisk(driver->sharedDisks, disk->src) < 0) goto cleanup; + + if (qemuCheckSharedDisk(driver->sharedDisks, disk) < 0) + goto cleanup; } /* Set sysfs unpriv_sgio if cdbfilter is specified */ diff --git a/src/qemu/qemu_process.h b/src/qemu/qemu_process.h index c12df32..3aad08f 100644 --- a/src/qemu/qemu_process.h +++ b/src/qemu/qemu_process.h @@ -98,5 +98,7 @@ bool qemuProcessAutoDestroyActive(virQEMUDriverPtr driver, virDomainObjPtr vm); virBitmapPtr qemuPrepareCpumap(virQEMUDriverPtr driver, virBitmapPtr nodemask); +int qemuCheckSharedDisk(virHashTablePtr sharedDisks, + virDomainDiskDefPtr disk); #endif /* __QEMU_PROCESS_H__ */ -- 1.7.7.6 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list