[PATCH v4 03/11] qemu: snapshot: Introduce helpers for creating overlays on <transient/> disks

Ján Tomko jtomko at redhat.com
Fri Sep 25 17:23:24 UTC 2020


On a Thursday in 2020, Peter Krempa wrote:
>To implement <transient/> disks we'll need to install an overlay on top
>of the original disk image which will be discarded after the VM is
>turned off. This was initially implemented by qemu but libvirt never
>picked up this option. With blockdev the qemu feature became unsupported
>so we need to do this via the snapshot code anyways.
>
>The helpers introduced in this patch prepare a fake snapshot disk
>definition for a disk which is configured as <transient/> and use it to
>create a snapshot (without actually modifying metada or persistent def).
>
>Signed-off-by: Peter Krempa <pkrempa at redhat.com>
>---
> src/qemu/qemu_snapshot.c | 91 +++++++++++++++++++++++++++++++++++++++-
> src/qemu/qemu_snapshot.h |  5 +++
> 2 files changed, 95 insertions(+), 1 deletion(-)
>
>diff --git a/src/qemu/qemu_snapshot.c b/src/qemu/qemu_snapshot.c
>index ca051071aa..d10e7b6b3a 100644
>--- a/src/qemu/qemu_snapshot.c
>+++ b/src/qemu/qemu_snapshot.c
>@@ -986,6 +986,7 @@ qemuSnapshotDiskPrepareOne(virDomainObjPtr vm,
>                            qemuSnapshotDiskDataPtr dd,
>                            virHashTablePtr blockNamedNodeData,
>                            bool reuse,
>+                           bool updateConfig,
>                            qemuDomainAsyncJob asyncJob,
>                            virJSONValuePtr actions)
> {
>@@ -1008,7 +1009,8 @@ qemuSnapshotDiskPrepareOne(virDomainObjPtr vm,
>         return -1;
>
>     /* modify disk in persistent definition only when the source is the same */
>-    if (vm->newDef &&
>+    if (updateConfig &&
>+        vm->newDef &&
>         (persistdisk = virDomainDiskByTarget(vm->newDef, dd->disk->dst)) &&
>         virStorageSourceIsSameLocation(dd->disk->src, persistdisk->src)) {
>
>@@ -1116,6 +1118,54 @@ qemuSnapshotDiskPrepareActiveExternal(virDomainObjPtr vm,
>                                        snapctxt->dd + snapctxt->ndd++,
>                                        blockNamedNodeData,
>                                        reuse,
>+                                       true,
>+                                       asyncJob,
>+                                       snapctxt->actions) < 0)
>+            return NULL;
>+    }
>+
>+    return g_steal_pointer(&snapctxt);
>+}
>+
>+
>+static qemuSnapshotDiskContextPtr
>+qemuSnapshotDiskPrepareDisksTransient(virDomainObjPtr vm,
>+                                      virQEMUDriverConfigPtr cfg,
>+                                      virHashTablePtr blockNamedNodeData,
>+                                      qemuDomainAsyncJob asyncJob)
>+{
>+    g_autoptr(qemuSnapshotDiskContext) snapctxt = NULL;
>+    size_t i;
>+
>+    snapctxt = qemuSnapshotDiskContextNew(vm->def->ndisks, vm, asyncJob);
>+
>+    for (i = 0; i < vm->def->ndisks; i++) {
>+        virDomainDiskDefPtr domdisk = vm->def->disks[i];
>+        g_autoptr(virDomainSnapshotDiskDef) snapdisk = g_new0(virDomainSnapshotDiskDef, 1);
>+
>+        if (!domdisk->transient)
>+            continue;
>+
>+        /* validation code makes sure that we do this only for local disks
>+         * with a file source */
>+        snapdisk->name = g_strdup(domdisk->dst);
>+        snapdisk->snapshot = VIR_DOMAIN_SNAPSHOT_LOCATION_EXTERNAL;
>+        snapdisk->src = virStorageSourceNew();
>+        snapdisk->src->type = VIR_STORAGE_TYPE_FILE;
>+        snapdisk->src->format = VIR_STORAGE_FILE_QCOW2;
>+        snapdisk->src->path = g_strdup_printf("%s.TRANSIENT", domdisk->src->path);

I'd prefer:
a) an empty line between these assignments and the if()
b) a lowercase name, but I guess standing out is important here as the
file is not meant to stay.

>+        if (virFileExists(snapdisk->src->path)) {
>+            virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
>+                           _("Overlay file '%s' for transient disk '%s' already exists"),
>+                           snapdisk->src->path, domdisk->dst);
>+            return NULL;
>+        }
>+
>+        if (qemuSnapshotDiskPrepareOne(vm, cfg, domdisk, snapdisk,
>+                                       snapctxt->dd + snapctxt->ndd++,
>+                                       blockNamedNodeData,
>+                                       false,
>+                                       false,
>                                        asyncJob,
>                                        snapctxt->actions) < 0)
>             return NULL;
>@@ -1253,6 +1303,45 @@ qemuSnapshotCreateActiveExternalDisks(virDomainObjPtr vm,
> }
>
>
>+/**
>+ * qemuSnapshotCreateDisksTransient:
>+ * @vm: domain object
>+ * @asyncJob: qemu async job type
>+ *
>+ * Creates overlays on top of disks which are configured as <transient/>. Note
>+ * that the validation code ensures that <transient> disks have appropriate
>+ * configuration.
>+ */
>+int
>+qemuSnapshotCreateDisksTransient(virDomainObjPtr vm,
>+                                 qemuDomainAsyncJob asyncJob)
>+{
>+    qemuDomainObjPrivatePtr priv = vm->privateData;
>+    virQEMUDriverPtr driver = priv->driver;
>+    g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
>+    g_autoptr(qemuSnapshotDiskContext) snapctxt = NULL;
>+    g_autoptr(virHashTable) blockNamedNodeData = NULL;
>+
>+    if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BLOCKDEV)) {
>+        if (!(blockNamedNodeData = qemuBlockGetNamedNodeData(vm, asyncJob)))
>+            return -1;
>+
>+        if (!(snapctxt = qemuSnapshotDiskPrepareDisksTransient(vm, cfg,
>+                                                               blockNamedNodeData,
>+                                                               asyncJob)))
>+            return -1;
>+
>+        if (qemuSnapshotDiskCreate(snapctxt, cfg) < 0)
>+            return -1;
>+    }
>+
>+    /* the overlays are established, so they can be deleted on a shutdown */

*on shutdown
sounds better to me

>+    priv->inhibitDiskTransientDelete = false;
>+
>+    return 0;
>+}
>+
>+
> static int
> qemuSnapshotCreateActiveExternal(virQEMUDriverPtr driver,
>                                  virDomainObjPtr vm,

With the empty line added:
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/20200925/475d4a39/attachment-0001.sig>


More information about the libvir-list mailing list