[libvirt] [PATCH 03/10] qemu: Introduce new set of helpers for attaching and detaching storage chains

Ján Tomko jtomko at redhat.com
Tue Jun 25 17:52:09 UTC 2019


On Mon, Jun 24, 2019 at 05:38:48PM +0200, Peter Krempa wrote:
>These are meant to replace the ad-hoc helpers qemuHotplugDiskSourceAtttach...

s/ttt/tt/

>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

functions? a function?

>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 at 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

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 it's

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 it's backing chain and supporting objects.

its

>+ * 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

its

>+ * 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;

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;
>+    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;

VIR_RETURN_PTR(data);

Reviewed-by: Ján Tomko <jtomko at redhat.com>

Jano
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://listman.redhat.com/archives/libvir-list/attachments/20190625/f823b1e3/attachment-0001.sig>


More information about the libvir-list mailing list