mirror of
https://github.com/libvirt/libvirt.git
synced 2025-02-25 18:55:26 -06:00
qemu: hotplug: Prepare for blockdev-add/blockdev-del with backing chains
Initialize data for the whole backing chain when plugging in or removing disks when a machine supports -blockdev. Similarly to startup we need to prepare the structures for the whole backing chain and take care of the copy-on-read feature. Signed-off-by: Peter Krempa <pkrempa@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com>
This commit is contained in:
parent
adf85f4791
commit
6d5468adc4
@ -380,6 +380,10 @@ qemuHotplugRemoveManagedPR(virQEMUDriverPtr driver,
|
|||||||
struct _qemuHotplugDiskSourceData {
|
struct _qemuHotplugDiskSourceData {
|
||||||
qemuBlockStorageSourceAttachDataPtr *backends;
|
qemuBlockStorageSourceAttachDataPtr *backends;
|
||||||
size_t nbackends;
|
size_t nbackends;
|
||||||
|
|
||||||
|
/* disk copy-on-read object */
|
||||||
|
virJSONValuePtr corProps;
|
||||||
|
char *corAlias;
|
||||||
};
|
};
|
||||||
typedef struct _qemuHotplugDiskSourceData qemuHotplugDiskSourceData;
|
typedef struct _qemuHotplugDiskSourceData qemuHotplugDiskSourceData;
|
||||||
typedef qemuHotplugDiskSourceData *qemuHotplugDiskSourceDataPtr;
|
typedef qemuHotplugDiskSourceData *qemuHotplugDiskSourceDataPtr;
|
||||||
@ -393,6 +397,9 @@ qemuHotplugDiskSourceDataFree(qemuHotplugDiskSourceDataPtr data)
|
|||||||
if (!data)
|
if (!data)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
virJSONValueFree(data->corProps);
|
||||||
|
VIR_FREE(data->corAlias);
|
||||||
|
|
||||||
for (i = 0; i < data->nbackends; i++)
|
for (i = 0; i < data->nbackends; i++)
|
||||||
qemuBlockStorageSourceAttachDataFree(data->backends[i]);
|
qemuBlockStorageSourceAttachDataFree(data->backends[i]);
|
||||||
|
|
||||||
@ -461,25 +468,40 @@ qemuHotplugRemoveStorageSourcePrepareData(virStorageSourcePtr src,
|
|||||||
|
|
||||||
static qemuHotplugDiskSourceDataPtr
|
static qemuHotplugDiskSourceDataPtr
|
||||||
qemuHotplugDiskSourceRemovePrepare(virDomainDiskDefPtr disk,
|
qemuHotplugDiskSourceRemovePrepare(virDomainDiskDefPtr disk,
|
||||||
virQEMUCapsPtr qemuCaps ATTRIBUTE_UNUSED)
|
virQEMUCapsPtr qemuCaps)
|
||||||
{
|
{
|
||||||
|
qemuDomainDiskPrivatePtr diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk);
|
||||||
qemuBlockStorageSourceAttachDataPtr backend = NULL;
|
qemuBlockStorageSourceAttachDataPtr backend = NULL;
|
||||||
qemuHotplugDiskSourceDataPtr data = NULL;
|
qemuHotplugDiskSourceDataPtr data = NULL;
|
||||||
qemuHotplugDiskSourceDataPtr ret = NULL;
|
qemuHotplugDiskSourceDataPtr ret = NULL;
|
||||||
char *drivealias = NULL;
|
char *drivealias = NULL;
|
||||||
|
virStorageSourcePtr n;
|
||||||
|
|
||||||
if (VIR_ALLOC(data) < 0)
|
if (VIR_ALLOC(data) < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (!(drivealias = qemuAliasDiskDriveFromDisk(disk)))
|
if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_BLOCKDEV)) {
|
||||||
goto cleanup;
|
if (VIR_STRDUP(data->corAlias, diskPriv->nodeCopyOnRead) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
if (!(backend = qemuHotplugRemoveStorageSourcePrepareData(disk->src,
|
for (n = disk->src; virStorageSourceIsBacking(n); n = n->backingStore) {
|
||||||
drivealias)))
|
if (!(backend = qemuHotplugRemoveStorageSourcePrepareData(n, NULL)))
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
if (VIR_APPEND_ELEMENT(data->backends, data->nbackends, backend) < 0)
|
if (VIR_APPEND_ELEMENT(data->backends, data->nbackends, backend) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!(drivealias = qemuAliasDiskDriveFromDisk(disk)))
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if (!(backend = qemuHotplugRemoveStorageSourcePrepareData(disk->src,
|
||||||
|
drivealias)))
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if (VIR_APPEND_ELEMENT(data->backends, data->nbackends, backend) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
VIR_STEAL_PTR(ret, data);
|
VIR_STEAL_PTR(ret, data);
|
||||||
|
|
||||||
@ -502,21 +524,39 @@ static qemuHotplugDiskSourceDataPtr
|
|||||||
qemuHotplugDiskSourceAttachPrepare(virDomainDiskDefPtr disk,
|
qemuHotplugDiskSourceAttachPrepare(virDomainDiskDefPtr disk,
|
||||||
virQEMUCapsPtr qemuCaps)
|
virQEMUCapsPtr qemuCaps)
|
||||||
{
|
{
|
||||||
qemuBlockStorageSourceAttachDataPtr backend;
|
qemuBlockStorageSourceAttachDataPtr backend = NULL;
|
||||||
qemuHotplugDiskSourceDataPtr data;
|
qemuHotplugDiskSourceDataPtr data;
|
||||||
qemuHotplugDiskSourceDataPtr ret = NULL;
|
qemuHotplugDiskSourceDataPtr ret = NULL;
|
||||||
|
virStorageSourcePtr n;
|
||||||
|
|
||||||
if (VIR_ALLOC(data) < 0)
|
if (VIR_ALLOC(data) < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (!(backend = qemuBuildStorageSourceAttachPrepareDrive(disk, qemuCaps)))
|
if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_BLOCKDEV)) {
|
||||||
goto cleanup;
|
if (disk->copy_on_read == VIR_TRISTATE_SWITCH_ON &&
|
||||||
|
!(data->corProps = qemuBlockStorageGetCopyOnReadProps(disk)))
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
if (qemuBuildStorageSourceAttachPrepareCommon(disk->src, backend, qemuCaps) < 0)
|
for (n = disk->src; virStorageSourceIsBacking(n); n = n->backingStore) {
|
||||||
goto cleanup;
|
if (!(backend = qemuBlockStorageSourceAttachPrepareBlockdev(n)))
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
if (VIR_APPEND_ELEMENT(data->backends, data->nbackends, backend) < 0)
|
if (qemuBuildStorageSourceAttachPrepareCommon(n, backend, qemuCaps) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
|
if (VIR_APPEND_ELEMENT(data->backends, data->nbackends, backend) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!(backend = qemuBuildStorageSourceAttachPrepareDrive(disk, qemuCaps)))
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if (qemuBuildStorageSourceAttachPrepareCommon(disk->src, backend, qemuCaps) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if (VIR_APPEND_ELEMENT(data->backends, data->nbackends, backend) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
VIR_STEAL_PTR(ret, data);
|
VIR_STEAL_PTR(ret, data);
|
||||||
|
|
||||||
@ -546,6 +586,10 @@ qemuHotplugDiskSourceAttach(qemuMonitorPtr mon,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (data->corProps &&
|
||||||
|
qemuMonitorAddObject(mon, &data->corProps, &data->corAlias) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -566,6 +610,9 @@ qemuHotplugDiskSourceRemove(qemuMonitorPtr mon,
|
|||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
|
if (data->corAlias)
|
||||||
|
ignore_value(qemuMonitorDelObject(mon, data->corAlias));
|
||||||
|
|
||||||
for (i = 0; i < data->nbackends; i++)
|
for (i = 0; i < data->nbackends; i++)
|
||||||
qemuBlockStorageSourceAttachRollback(mon, data->backends[i]);
|
qemuBlockStorageSourceAttachRollback(mon, data->backends[i]);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user