1
0
mirror of https://gitlab.com/libvirt/libvirt.git synced 2025-03-07 17:28:15 +00:00

qemu: Check if the shared disk's cdbfilter conflicts with others

This prevents domain starting and disk attaching if the shared disk's
setting conflicts with other active domain(s), E.g. A domain with
"sgio" set as "filtered", however, another active domain is using
it set as "unfiltered".
This commit is contained in:
Osier Yang 2013-01-02 22:37:11 +08:00
parent 278f87c4b5
commit 1279e421b2
3 changed files with 61 additions and 0 deletions

View File

@ -5814,6 +5814,11 @@ qemuDomainAttachDeviceDiskLive(virConnectPtr conn,
goto end; goto end;
} }
if (disk->type == VIR_DOMAIN_DISK_TYPE_BLOCK &&
disk->shared &&
(qemuCheckSharedDisk(driver->sharedDisks, disk) < 0))
goto end;
if (qemuDomainDetermineDiskChain(driver, disk, false) < 0) if (qemuDomainDetermineDiskChain(driver, disk, false) < 0)
goto end; goto end;

View File

@ -3437,6 +3437,56 @@ qemuSetUnprivSGIO(virDomainDiskDefPtr disk)
return 0; return 0;
} }
/* Check if a shared disk's setting conflicts with the conf
* used by other domain(s). Currently only checks the sgio
* setting. Note that this should only be called for disk with
* block source.
*
* 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, NULL, &val) < 0) {
ret = -1;
goto cleanup;
}
if ((val == 0 &&
(disk->sgio == VIR_DOMAIN_DISK_SGIO_FILTERED ||
disk->sgio == VIR_DOMAIN_DISK_SGIO_DEFAULT)) ||
(val == 1 &&
disk->sgio == VIR_DOMAIN_DISK_SGIO_UNFILTERED))
goto cleanup;
virReportError(VIR_ERR_OPERATION_INVALID,
_("sgio of shared disk '%s' conflicts with other "
"active domains"), disk->src);
ret = -1;
cleanup:
VIR_FREE(key);
return ret;
}
int qemuProcessStart(virConnectPtr conn, int qemuProcessStart(virConnectPtr conn,
virQEMUDriverPtr driver, virQEMUDriverPtr driver,
virDomainObjPtr vm, virDomainObjPtr vm,
@ -3785,6 +3835,9 @@ int qemuProcessStart(virConnectPtr conn,
if (disk->type == VIR_DOMAIN_DISK_TYPE_BLOCK && disk->shared) { if (disk->type == VIR_DOMAIN_DISK_TYPE_BLOCK && disk->shared) {
if (qemuAddSharedDisk(driver->sharedDisks, disk->src) < 0) if (qemuAddSharedDisk(driver->sharedDisks, disk->src) < 0)
goto cleanup; goto cleanup;
if (qemuCheckSharedDisk(driver->sharedDisks, disk) < 0)
goto cleanup;
} }
if (qemuSetUnprivSGIO(disk) < 0) if (qemuSetUnprivSGIO(disk) < 0)

View File

@ -100,4 +100,7 @@ virBitmapPtr qemuPrepareCpumap(virQEMUDriverPtr driver,
virBitmapPtr nodemask); virBitmapPtr nodemask);
int qemuSetUnprivSGIO(virDomainDiskDefPtr disk); int qemuSetUnprivSGIO(virDomainDiskDefPtr disk);
int qemuCheckSharedDisk(virHashTablePtr sharedDisks,
virDomainDiskDefPtr disk);
#endif /* __QEMU_PROCESS_H__ */ #endif /* __QEMU_PROCESS_H__ */