mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-12-11 20:32:35 +03:00
qemu: Introduce new set of helpers for attaching and detaching storage chains
These are meant to replace the ad-hoc helpers qemuHotplugDiskSourceAttach... and the open-coded version in qemu_command.c for use in command line generation. The functions for preparing for attach of chains unfortunately need to be in qemu_command.c as they use function defined by that file and inclusion hierarchy. In this patch new functions are introduced and subsequent patches then refactor individual parts to use them. Signed-off-by: Peter Krempa <pkrempa@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com>
This commit is contained in:
@@ -1622,6 +1622,123 @@ qemuBlockStorageSourceDetachPrepare(virStorageSourcePtr src,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
qemuBlockStorageSourceChainDataFree(qemuBlockStorageSourceChainDataPtr data)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
if (!data)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (i = 0; i < data->nsrcdata; i++)
|
||||||
|
qemuBlockStorageSourceAttachDataFree(data->srcdata[i]);
|
||||||
|
|
||||||
|
VIR_FREE(data->srcdata);
|
||||||
|
VIR_FREE(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* qemuBlockStorageSourceChainDetachPrepareBlockdev
|
||||||
|
* @src: storage source chain to remove
|
||||||
|
*
|
||||||
|
* Prepares qemuBlockStorageSourceChainDataPtr for detaching @src and its
|
||||||
|
* backingStore if -blockdev was used.
|
||||||
|
*/
|
||||||
|
qemuBlockStorageSourceChainDataPtr
|
||||||
|
qemuBlockStorageSourceChainDetachPrepareBlockdev(virStorageSourcePtr src)
|
||||||
|
{
|
||||||
|
VIR_AUTOPTR(qemuBlockStorageSourceAttachData) backend = NULL;
|
||||||
|
VIR_AUTOPTR(qemuBlockStorageSourceChainData) data = NULL;
|
||||||
|
virStorageSourcePtr n;
|
||||||
|
|
||||||
|
if (VIR_ALLOC(data) < 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
for (n = src; virStorageSourceIsBacking(n); n = n->backingStore) {
|
||||||
|
if (!(backend = qemuBlockStorageSourceDetachPrepare(n, NULL)))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (VIR_APPEND_ELEMENT(data->srcdata, data->nsrcdata, backend) < 0)
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
VIR_RETURN_PTR(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* qemuBlockStorageSourceChainDetachPrepareLegacy
|
||||||
|
* @src: storage source chain to remove
|
||||||
|
* @driveAlias: Alias of the 'drive' backend (always consumed)
|
||||||
|
*
|
||||||
|
* Prepares qemuBlockStorageSourceChainDataPtr for detaching @src and its
|
||||||
|
* backingStore if -drive was used.
|
||||||
|
*/
|
||||||
|
qemuBlockStorageSourceChainDataPtr
|
||||||
|
qemuBlockStorageSourceChainDetachPrepareDrive(virStorageSourcePtr src,
|
||||||
|
char *driveAlias)
|
||||||
|
{
|
||||||
|
VIR_AUTOPTR(qemuBlockStorageSourceAttachData) backend = NULL;
|
||||||
|
VIR_AUTOPTR(qemuBlockStorageSourceChainData) data = NULL;
|
||||||
|
|
||||||
|
if (VIR_ALLOC(data) < 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (!(backend = qemuBlockStorageSourceDetachPrepare(src, driveAlias)))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (VIR_APPEND_ELEMENT(data->srcdata, data->nsrcdata, backend) < 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
VIR_RETURN_PTR(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* qemuBlockStorageSourceChainAttach:
|
||||||
|
* @mon: monitor object
|
||||||
|
* @data: storage source chain data
|
||||||
|
*
|
||||||
|
* Attach a storage source including its backing chain and supporting objects.
|
||||||
|
* Caller must enter @mon prior calling this function. In case of error this
|
||||||
|
* function returns -1. @data is updated so that qemuBlockStorageSourceChainDetach
|
||||||
|
* can be used to roll-back the changes.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
qemuBlockStorageSourceChainAttach(qemuMonitorPtr mon,
|
||||||
|
qemuBlockStorageSourceChainDataPtr data)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
for (i = data->nsrcdata; i > 0; i--) {
|
||||||
|
if (qemuBlockStorageSourceAttachApply(mon, data->srcdata[i - 1]) < 0)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* qemuBlockStorageSourceChainDetach:
|
||||||
|
* @mon: monitor object
|
||||||
|
* @data: storage source chain data
|
||||||
|
*
|
||||||
|
* Detach a unused storage source including all its backing chain and related
|
||||||
|
* objects described by @data.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
qemuBlockStorageSourceChainDetach(qemuMonitorPtr mon,
|
||||||
|
qemuBlockStorageSourceChainDataPtr data)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
for (i = 0; i < data->nsrcdata; i++)
|
||||||
|
qemuBlockStorageSourceAttachRollback(mon, data->srcdata[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* qemuBlockStorageSourceDetachOneBlockdev:
|
* qemuBlockStorageSourceDetachOneBlockdev:
|
||||||
* @driver: qemu driver object
|
* @driver: qemu driver object
|
||||||
|
|||||||
@@ -125,6 +125,35 @@ qemuBlockStorageSourceDetachOneBlockdev(virQEMUDriverPtr driver,
|
|||||||
qemuDomainAsyncJob asyncJob,
|
qemuDomainAsyncJob asyncJob,
|
||||||
virStorageSourcePtr src);
|
virStorageSourcePtr src);
|
||||||
|
|
||||||
|
struct _qemuBlockStorageSourceChainData {
|
||||||
|
qemuBlockStorageSourceAttachDataPtr *srcdata;
|
||||||
|
size_t nsrcdata;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct _qemuBlockStorageSourceChainData qemuBlockStorageSourceChainData;
|
||||||
|
typedef qemuBlockStorageSourceChainData *qemuBlockStorageSourceChainDataPtr;
|
||||||
|
|
||||||
|
void
|
||||||
|
qemuBlockStorageSourceChainDataFree(qemuBlockStorageSourceChainDataPtr data);
|
||||||
|
|
||||||
|
qemuBlockStorageSourceChainDataPtr
|
||||||
|
qemuBlockStorageSourceChainDetachPrepareBlockdev(virStorageSourcePtr src);
|
||||||
|
qemuBlockStorageSourceChainDataPtr
|
||||||
|
qemuBlockStorageSourceChainDetachPrepareDrive(virStorageSourcePtr src,
|
||||||
|
char *driveAlias);
|
||||||
|
|
||||||
|
int
|
||||||
|
qemuBlockStorageSourceChainAttach(qemuMonitorPtr mon,
|
||||||
|
qemuBlockStorageSourceChainDataPtr data);
|
||||||
|
|
||||||
|
void
|
||||||
|
qemuBlockStorageSourceChainDetach(qemuMonitorPtr mon,
|
||||||
|
qemuBlockStorageSourceChainDataPtr data);
|
||||||
|
|
||||||
|
|
||||||
|
VIR_DEFINE_AUTOPTR_FUNC(qemuBlockStorageSourceChainData,
|
||||||
|
qemuBlockStorageSourceChainDataFree);
|
||||||
|
|
||||||
int
|
int
|
||||||
qemuBlockSnapshotAddLegacy(virJSONValuePtr actions,
|
qemuBlockSnapshotAddLegacy(virJSONValuePtr actions,
|
||||||
virDomainDiskDefPtr disk,
|
virDomainDiskDefPtr disk,
|
||||||
|
|||||||
@@ -11184,3 +11184,66 @@ qemuBuildStorageSourceAttachPrepareCommon(virStorageSourcePtr src,
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* qemuBuildStorageSourceChainAttachPrepareDrive:
|
||||||
|
* @disk: disk definition
|
||||||
|
* @qemuCaps: qemu capabilities object
|
||||||
|
*
|
||||||
|
* Prepares qemuBlockStorageSourceChainDataPtr for attaching @disk via -drive.
|
||||||
|
*/
|
||||||
|
qemuBlockStorageSourceChainDataPtr
|
||||||
|
qemuBuildStorageSourceChainAttachPrepareDrive(virDomainDiskDefPtr disk,
|
||||||
|
virQEMUCapsPtr qemuCaps)
|
||||||
|
{
|
||||||
|
VIR_AUTOPTR(qemuBlockStorageSourceAttachData) elem = NULL;
|
||||||
|
VIR_AUTOPTR(qemuBlockStorageSourceChainData) data = NULL;
|
||||||
|
|
||||||
|
if (VIR_ALLOC(data) < 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (!(elem = qemuBuildStorageSourceAttachPrepareDrive(disk, qemuCaps)))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (qemuBuildStorageSourceAttachPrepareCommon(disk->src, elem, qemuCaps) < 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (VIR_APPEND_ELEMENT(data->srcdata, data->nsrcdata, elem) < 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
VIR_RETURN_PTR(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* qemuBuildStorageSourceChainAttachPrepareDrive:
|
||||||
|
* @top: storage source chain
|
||||||
|
* @qemuCaps: qemu capabilities object
|
||||||
|
*
|
||||||
|
* Prepares qemuBlockStorageSourceChainDataPtr for attaching @top via -blockdev.
|
||||||
|
*/
|
||||||
|
qemuBlockStorageSourceChainDataPtr
|
||||||
|
qemuBuildStorageSourceChainAttachPrepareBlockdev(virStorageSourcePtr top,
|
||||||
|
virQEMUCapsPtr qemuCaps)
|
||||||
|
{
|
||||||
|
VIR_AUTOPTR(qemuBlockStorageSourceAttachData) elem = NULL;
|
||||||
|
VIR_AUTOPTR(qemuBlockStorageSourceChainData) data = NULL;
|
||||||
|
virStorageSourcePtr n;
|
||||||
|
|
||||||
|
if (VIR_ALLOC(data) < 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
for (n = top; virStorageSourceIsBacking(n); n = n->backingStore) {
|
||||||
|
if (!(elem = qemuBlockStorageSourceAttachPrepareBlockdev(n)))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (qemuBuildStorageSourceAttachPrepareCommon(n, elem, qemuCaps) < 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (VIR_APPEND_ELEMENT(data->srcdata, data->nsrcdata, elem) < 0)
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
VIR_RETURN_PTR(data);
|
||||||
|
}
|
||||||
|
|||||||
@@ -107,6 +107,17 @@ qemuBuildStorageSourceAttachPrepareCommon(virStorageSourcePtr src,
|
|||||||
qemuBlockStorageSourceAttachDataPtr data,
|
qemuBlockStorageSourceAttachDataPtr data,
|
||||||
virQEMUCapsPtr qemuCaps);
|
virQEMUCapsPtr qemuCaps);
|
||||||
|
|
||||||
|
|
||||||
|
qemuBlockStorageSourceChainDataPtr
|
||||||
|
qemuBuildStorageSourceChainAttachPrepareDrive(virDomainDiskDefPtr disk,
|
||||||
|
virQEMUCapsPtr qemuCaps);
|
||||||
|
|
||||||
|
|
||||||
|
qemuBlockStorageSourceChainDataPtr
|
||||||
|
qemuBuildStorageSourceChainAttachPrepareBlockdev(virStorageSourcePtr top,
|
||||||
|
virQEMUCapsPtr qemuCaps);
|
||||||
|
|
||||||
|
|
||||||
char
|
char
|
||||||
*qemuBuildDiskDeviceStr(const virDomainDef *def,
|
*qemuBuildDiskDeviceStr(const virDomainDef *def,
|
||||||
virDomainDiskDefPtr disk,
|
virDomainDiskDefPtr disk,
|
||||||
|
|||||||
Reference in New Issue
Block a user