These are meant to replace the ad-hoc helpers qemuHotplugDiskSourceAtttach...
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(a)redhat.com>
---
src/qemu/qemu_block.c | 117 ++++++++++++++++++++++++++++++++++++++++
src/qemu/qemu_block.h | 29 ++++++++++
src/qemu/qemu_command.c | 67 +++++++++++++++++++++++
src/qemu/qemu_command.h | 11 ++++
4 files changed, 224 insertions(+)
diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c
index 560488c852..4130a30e45 100644
--- a/src/qemu/qemu_block.c
+++ b/src/qemu/qemu_block.c
@@ -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 it's
+ * 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 it's
+ * 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 it's 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 it's 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
diff --git a/src/qemu/qemu_block.h b/src/qemu/qemu_block.h
index a49c73670b..934a1f125d 100644
--- a/src/qemu/qemu_block.h
+++ b/src/qemu/qemu_block.h
@@ -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,
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index b767a1e15f..2a1d22eebf 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -11184,3 +11184,70 @@ 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;
+ qemuBlockStorageSourceChainDataPtr ret = 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_STEAL_PTR(ret, data);
+ return ret;
+}
+
+
+/**
+ * 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;
+ qemuBlockStorageSourceChainDataPtr ret = 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_STEAL_PTR(ret, data);
+ return ret;
+}
diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h
index c885d61578..8695832c16 100644
--- a/src/qemu/qemu_command.h
+++ b/src/qemu/qemu_command.h
@@ -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,
--
2.21.0