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:
Peter Krempa 2019-04-04 16:50:49 +02:00
parent 2523999717
commit 042c95bd19
4 changed files with 220 additions and 0 deletions

View File

@ -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:
* @driver: qemu driver object

View File

@ -125,6 +125,35 @@ qemuBlockStorageSourceDetachOneBlockdev(virQEMUDriverPtr driver,
qemuDomainAsyncJob asyncJob,
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
qemuBlockSnapshotAddLegacy(virJSONValuePtr actions,
virDomainDiskDefPtr disk,

View File

@ -11184,3 +11184,66 @@ qemuBuildStorageSourceAttachPrepareCommon(virStorageSourcePtr src,
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);
}

View File

@ -107,6 +107,17 @@ qemuBuildStorageSourceAttachPrepareCommon(virStorageSourcePtr src,
qemuBlockStorageSourceAttachDataPtr data,
virQEMUCapsPtr qemuCaps);
qemuBlockStorageSourceChainDataPtr
qemuBuildStorageSourceChainAttachPrepareDrive(virDomainDiskDefPtr disk,
virQEMUCapsPtr qemuCaps);
qemuBlockStorageSourceChainDataPtr
qemuBuildStorageSourceChainAttachPrepareBlockdev(virStorageSourcePtr top,
virQEMUCapsPtr qemuCaps);
char
*qemuBuildDiskDeviceStr(const virDomainDef *def,
virDomainDiskDefPtr disk,