[PATCH] qemu: backup: Fix handling of backing store for backup target images

Peter Krempa posted 1 patch 4 years ago
Test syntax-check failed
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/libvirt tags/patchew/1384a52886f7a6f5d8121c77d90a3735f10cf3e8.1586177822.git.pkrempa@redhat.com
src/qemu/qemu_backup.c | 26 ++++++++++++++++++++++----
1 file changed, 22 insertions(+), 4 deletions(-)
[PATCH] qemu: backup: Fix handling of backing store for backup target images
Posted by Peter Krempa 4 years ago
We always tried to install backing store for the image even if it didn't
make sesne, e.g. for a full backup into a raw image. Additionally we
didn't record the backing file into the qcow2 metadata so the image
itself contained the diff of data but reading from it would be
incomplete as it depends on the backing image.

This patch fixes both issues by carefully installing the correct backing
file when appropriate and also recording it into the metadata when
creating the image.

https://bugzilla.redhat.com/show_bug.cgi?id=1813310

Signed-off-by: Peter Krempa <pkrempa@redhat.com>
---
 src/qemu/qemu_backup.c | 26 ++++++++++++++++++++++----
 1 file changed, 22 insertions(+), 4 deletions(-)

diff --git a/src/qemu/qemu_backup.c b/src/qemu/qemu_backup.c
index 9a056fa407..5d18720f53 100644
--- a/src/qemu/qemu_backup.c
+++ b/src/qemu/qemu_backup.c
@@ -105,6 +105,8 @@ struct qemuBackupDiskData {
     virDomainDiskDefPtr domdisk;
     qemuBlockJobDataPtr blockjob;
     virStorageSourcePtr store;
+    virStorageSourcePtr terminator;
+    virStorageSourcePtr backingStore;
     char *incrementalBitmap;
     qemuBlockStorageSourceChainDataPtr crdata;
     bool labelled;
@@ -146,6 +148,7 @@ qemuBackupDiskDataCleanupOne(virDomainObjPtr vm,
         qemuBlockJobStartupFinalize(vm, dd->blockjob);

     qemuBlockStorageSourceChainDataFree(dd->crdata);
+    virObjectUnref(dd->terminator);
 }


@@ -295,6 +298,7 @@ qemuBackupDiskPrepareDataOne(virDomainObjPtr vm,
                              virDomainBackupDiskDefPtr backupdisk,
                              struct qemuBackupDiskData *dd,
                              virJSONValuePtr actions,
+                             bool pull,
                              virDomainMomentDefPtr *incremental,
                              virHashTablePtr blockNamedNodeData,
                              virQEMUDriverConfigPtr cfg)
@@ -314,6 +318,19 @@ qemuBackupDiskPrepareDataOne(virDomainObjPtr vm,
     if (!dd->store->format)
         dd->store->format = VIR_STORAGE_FILE_QCOW2;

+    /* calculate backing store to use:
+     * push mode:
+     *   full backups: no backing store
+     *   incremental: original disk if format supports backing store
+     * pull mode:
+     *   both: original disk
+     */
+    if (pull || (incremental && dd->store->format >= VIR_STORAGE_FILE_BACKING)) {
+        dd->backingStore = dd->domdisk->src;
+    } else {
+        dd->backingStore = dd->terminator = virStorageSourceNew();
+    }
+
     if (qemuDomainStorageFileInit(priv->driver, vm, dd->store, dd->domdisk->src) < 0)
         return -1;

@@ -337,7 +354,7 @@ qemuBackupDiskPrepareDataOne(virDomainObjPtr vm,

     /* use original disk as backing to prevent opening the backing chain */
     if (!(dd->crdata = qemuBuildStorageSourceChainAttachPrepareBlockdevTop(dd->store,
-                                                                           dd->domdisk->src,
+                                                                           dd->backingStore,
                                                                            priv->qemuCaps)))
         return -1;

@@ -398,6 +415,7 @@ qemuBackupDiskPrepareData(virDomainObjPtr vm,
     struct qemuBackupDiskData *disks = NULL;
     ssize_t ndisks = 0;
     size_t i;
+    bool pull = def->type == VIR_DOMAIN_BACKUP_TYPE_PULL;

     disks = g_new0(struct qemuBackupDiskData, def->ndisks);

@@ -410,12 +428,12 @@ qemuBackupDiskPrepareData(virDomainObjPtr vm,

         ndisks++;

-        if (qemuBackupDiskPrepareDataOne(vm, backupdisk, dd, actions,
+        if (qemuBackupDiskPrepareDataOne(vm, backupdisk, dd, actions, pull,
                                          incremental, blockNamedNodeData,
                                          cfg) < 0)
             goto error;

-        if (def->type == VIR_DOMAIN_BACKUP_TYPE_PULL) {
+        if (pull) {
             if (qemuBackupDiskPrepareDataOnePull(actions, dd) < 0)
                 goto error;
         } else {
@@ -480,7 +498,7 @@ qemuBackupDiskPrepareOneStorage(virDomainObjPtr vm,
                                                    dd->store, dd->domdisk->src) < 0)
             return -1;

-        if (qemuBlockStorageSourceCreate(vm, dd->store, NULL, NULL,
+        if (qemuBlockStorageSourceCreate(vm, dd->store, dd->backingStore, NULL,
                                          dd->crdata->srcdata[0],
                                          QEMU_ASYNC_JOB_BACKUP) < 0)
             return -1;
-- 
2.25.1

Re: [PATCH] qemu: backup: Fix handling of backing store for backup target images
Posted by Ján Tomko 4 years ago
On a Monday in 2020, Peter Krempa wrote:
>We always tried to install backing store for the image even if it didn't
>make sesne, e.g. for a full backup into a raw image. Additionally we

sense

>didn't record the backing file into the qcow2 metadata so the image
>itself contained the diff of data but reading from it would be
>incomplete as it depends on the backing image.
>
>This patch fixes both issues by carefully installing the correct backing
>file when appropriate and also recording it into the metadata when
>creating the image.
>
>https://bugzilla.redhat.com/show_bug.cgi?id=1813310
>
>Signed-off-by: Peter Krempa <pkrempa@redhat.com>
>---
> src/qemu/qemu_backup.c | 26 ++++++++++++++++++++++----
> 1 file changed, 22 insertions(+), 4 deletions(-)
>

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

Jano