render / rpms / libvirt

Forked from rpms/libvirt 9 months ago
Clone
b971b8
From 14b1e4fc93ba1a87854aa1afaf519cc3accff4c6 Mon Sep 17 00:00:00 2001
b971b8
Message-Id: <14b1e4fc93ba1a87854aa1afaf519cc3accff4c6@dist-git>
b971b8
From: Peter Krempa <pkrempa@redhat.com>
b971b8
Date: Tue, 23 Jun 2020 12:23:34 +0200
b971b8
Subject: [PATCH] qemu: backup: Fix handling of backing store for backup target
b971b8
 images
b971b8
MIME-Version: 1.0
b971b8
Content-Type: text/plain; charset=UTF-8
b971b8
Content-Transfer-Encoding: 8bit
b971b8
b971b8
We always tried to install backing store for the image even if it didn't
b971b8
make sense, e.g. for a full backup into a raw image. Additionally we
b971b8
didn't record the backing file into the qcow2 metadata so the image
b971b8
itself contained the diff of data but reading from it would be
b971b8
incomplete as it depends on the backing image.
b971b8
b971b8
This patch fixes both issues by carefully installing the correct backing
b971b8
file when appropriate and also recording it into the metadata when
b971b8
creating the image.
b971b8
b971b8
https://bugzilla.redhat.com/show_bug.cgi?id=1813310
b971b8
b971b8
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
b971b8
Reviewed-by: Ján Tomko <jtomko@redhat.com>
b971b8
(cherry picked from commit 4aea6f42fe32175ce0cb9015913db536097130e4)
b971b8
https://bugzilla.redhat.com/show_bug.cgi?id=1804593
b971b8
Message-Id: <8c4ebc06863aac1f75532b6633772944a6b0bd2a.1592906423.git.pkrempa@redhat.com>
b971b8
Reviewed-by: Ján Tomko <jtomko@redhat.com>
b971b8
---
b971b8
 src/qemu/qemu_backup.c | 26 ++++++++++++++++++++++----
b971b8
 1 file changed, 22 insertions(+), 4 deletions(-)
b971b8
b971b8
diff --git a/src/qemu/qemu_backup.c b/src/qemu/qemu_backup.c
b971b8
index 9a056fa407..5d18720f53 100644
b971b8
--- a/src/qemu/qemu_backup.c
b971b8
+++ b/src/qemu/qemu_backup.c
b971b8
@@ -105,6 +105,8 @@ struct qemuBackupDiskData {
b971b8
     virDomainDiskDefPtr domdisk;
b971b8
     qemuBlockJobDataPtr blockjob;
b971b8
     virStorageSourcePtr store;
b971b8
+    virStorageSourcePtr terminator;
b971b8
+    virStorageSourcePtr backingStore;
b971b8
     char *incrementalBitmap;
b971b8
     qemuBlockStorageSourceChainDataPtr crdata;
b971b8
     bool labelled;
b971b8
@@ -146,6 +148,7 @@ qemuBackupDiskDataCleanupOne(virDomainObjPtr vm,
b971b8
         qemuBlockJobStartupFinalize(vm, dd->blockjob);
b971b8
 
b971b8
     qemuBlockStorageSourceChainDataFree(dd->crdata);
b971b8
+    virObjectUnref(dd->terminator);
b971b8
 }
b971b8
 
b971b8
 
b971b8
@@ -295,6 +298,7 @@ qemuBackupDiskPrepareDataOne(virDomainObjPtr vm,
b971b8
                              virDomainBackupDiskDefPtr backupdisk,
b971b8
                              struct qemuBackupDiskData *dd,
b971b8
                              virJSONValuePtr actions,
b971b8
+                             bool pull,
b971b8
                              virDomainMomentDefPtr *incremental,
b971b8
                              virHashTablePtr blockNamedNodeData,
b971b8
                              virQEMUDriverConfigPtr cfg)
b971b8
@@ -314,6 +318,19 @@ qemuBackupDiskPrepareDataOne(virDomainObjPtr vm,
b971b8
     if (!dd->store->format)
b971b8
         dd->store->format = VIR_STORAGE_FILE_QCOW2;
b971b8
 
b971b8
+    /* calculate backing store to use:
b971b8
+     * push mode:
b971b8
+     *   full backups: no backing store
b971b8
+     *   incremental: original disk if format supports backing store
b971b8
+     * pull mode:
b971b8
+     *   both: original disk
b971b8
+     */
b971b8
+    if (pull || (incremental && dd->store->format >= VIR_STORAGE_FILE_BACKING)) {
b971b8
+        dd->backingStore = dd->domdisk->src;
b971b8
+    } else {
b971b8
+        dd->backingStore = dd->terminator = virStorageSourceNew();
b971b8
+    }
b971b8
+
b971b8
     if (qemuDomainStorageFileInit(priv->driver, vm, dd->store, dd->domdisk->src) < 0)
b971b8
         return -1;
b971b8
 
b971b8
@@ -337,7 +354,7 @@ qemuBackupDiskPrepareDataOne(virDomainObjPtr vm,
b971b8
 
b971b8
     /* use original disk as backing to prevent opening the backing chain */
b971b8
     if (!(dd->crdata = qemuBuildStorageSourceChainAttachPrepareBlockdevTop(dd->store,
b971b8
-                                                                           dd->domdisk->src,
b971b8
+                                                                           dd->backingStore,
b971b8
                                                                            priv->qemuCaps)))
b971b8
         return -1;
b971b8
 
b971b8
@@ -398,6 +415,7 @@ qemuBackupDiskPrepareData(virDomainObjPtr vm,
b971b8
     struct qemuBackupDiskData *disks = NULL;
b971b8
     ssize_t ndisks = 0;
b971b8
     size_t i;
b971b8
+    bool pull = def->type == VIR_DOMAIN_BACKUP_TYPE_PULL;
b971b8
 
b971b8
     disks = g_new0(struct qemuBackupDiskData, def->ndisks);
b971b8
 
b971b8
@@ -410,12 +428,12 @@ qemuBackupDiskPrepareData(virDomainObjPtr vm,
b971b8
 
b971b8
         ndisks++;
b971b8
 
b971b8
-        if (qemuBackupDiskPrepareDataOne(vm, backupdisk, dd, actions,
b971b8
+        if (qemuBackupDiskPrepareDataOne(vm, backupdisk, dd, actions, pull,
b971b8
                                          incremental, blockNamedNodeData,
b971b8
                                          cfg) < 0)
b971b8
             goto error;
b971b8
 
b971b8
-        if (def->type == VIR_DOMAIN_BACKUP_TYPE_PULL) {
b971b8
+        if (pull) {
b971b8
             if (qemuBackupDiskPrepareDataOnePull(actions, dd) < 0)
b971b8
                 goto error;
b971b8
         } else {
b971b8
@@ -480,7 +498,7 @@ qemuBackupDiskPrepareOneStorage(virDomainObjPtr vm,
b971b8
                                                    dd->store, dd->domdisk->src) < 0)
b971b8
             return -1;
b971b8
 
b971b8
-        if (qemuBlockStorageSourceCreate(vm, dd->store, NULL, NULL,
b971b8
+        if (qemuBlockStorageSourceCreate(vm, dd->store, dd->backingStore, NULL,
b971b8
                                          dd->crdata->srcdata[0],
b971b8
                                          QEMU_ASYNC_JOB_BACKUP) < 0)
b971b8
             return -1;
b971b8
-- 
b971b8
2.27.0
b971b8