|
|
a41c76 |
From 7dae651c45df86ce74b304535baf62013d7f527d Mon Sep 17 00:00:00 2001
|
|
|
a41c76 |
Message-Id: <7dae651c45df86ce74b304535baf62013d7f527d@dist-git>
|
|
|
a41c76 |
From: Peter Krempa <pkrempa@redhat.com>
|
|
|
a41c76 |
Date: Tue, 23 Jun 2020 12:23:38 +0200
|
|
|
a41c76 |
Subject: [PATCH] qemu: backup: Move fetching of checkpoint list for
|
|
|
a41c76 |
incremental backup
|
|
|
a41c76 |
MIME-Version: 1.0
|
|
|
a41c76 |
Content-Type: text/plain; charset=UTF-8
|
|
|
a41c76 |
Content-Transfer-Encoding: 8bit
|
|
|
a41c76 |
|
|
|
a41c76 |
Fetch the checkpoint list for every disk specifically based on the new
|
|
|
a41c76 |
per-disk 'incremental' field.
|
|
|
a41c76 |
|
|
|
a41c76 |
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
|
|
|
a41c76 |
Reviewed-by: Eric Blake <eblake@redhat.com>
|
|
|
a41c76 |
(cherry picked from commit 15c5ed8ba64e26090174d296486eacfa240af53e)
|
|
|
a41c76 |
https://bugzilla.redhat.com/show_bug.cgi?id=1804593
|
|
|
a41c76 |
Message-Id: <485f9933893a9890f018889a76fc48654de2c58a.1592906423.git.pkrempa@redhat.com>
|
|
|
a41c76 |
Reviewed-by: Ján Tomko <jtomko@redhat.com>
|
|
|
a41c76 |
---
|
|
|
a41c76 |
src/qemu/qemu_backup.c | 109 ++++++++++++++++++++---------------------
|
|
|
a41c76 |
1 file changed, 53 insertions(+), 56 deletions(-)
|
|
|
a41c76 |
|
|
|
a41c76 |
diff --git a/src/qemu/qemu_backup.c b/src/qemu/qemu_backup.c
|
|
|
a41c76 |
index adbf696de6..13e2a7412b 100644
|
|
|
a41c76 |
--- a/src/qemu/qemu_backup.c
|
|
|
a41c76 |
+++ b/src/qemu/qemu_backup.c
|
|
|
a41c76 |
@@ -173,6 +173,50 @@ qemuBackupDiskDataCleanup(virDomainObjPtr vm,
|
|
|
a41c76 |
}
|
|
|
a41c76 |
|
|
|
a41c76 |
|
|
|
a41c76 |
+/**
|
|
|
a41c76 |
+ * qemuBackupBeginCollectIncrementalCheckpoints:
|
|
|
a41c76 |
+ * @vm: domain object
|
|
|
a41c76 |
+ * @incrFrom: name of checkpoint representing starting point of incremental backup
|
|
|
a41c76 |
+ *
|
|
|
a41c76 |
+ * Returns a NULL terminated list of pointers to checkpoint definitions in
|
|
|
a41c76 |
+ * chronological order starting from the 'current' checkpoint until reaching
|
|
|
a41c76 |
+ * @incrFrom.
|
|
|
a41c76 |
+ */
|
|
|
a41c76 |
+static virDomainMomentDefPtr *
|
|
|
a41c76 |
+qemuBackupBeginCollectIncrementalCheckpoints(virDomainObjPtr vm,
|
|
|
a41c76 |
+ const char *incrFrom)
|
|
|
a41c76 |
+{
|
|
|
a41c76 |
+ virDomainMomentObjPtr n = virDomainCheckpointGetCurrent(vm->checkpoints);
|
|
|
a41c76 |
+ g_autofree virDomainMomentDefPtr *incr = NULL;
|
|
|
a41c76 |
+ size_t nincr = 0;
|
|
|
a41c76 |
+
|
|
|
a41c76 |
+ while (n) {
|
|
|
a41c76 |
+ virDomainMomentDefPtr def = n->def;
|
|
|
a41c76 |
+
|
|
|
a41c76 |
+ if (VIR_APPEND_ELEMENT_COPY(incr, nincr, def) < 0)
|
|
|
a41c76 |
+ return NULL;
|
|
|
a41c76 |
+
|
|
|
a41c76 |
+ if (STREQ(def->name, incrFrom)) {
|
|
|
a41c76 |
+ def = NULL;
|
|
|
a41c76 |
+ if (VIR_APPEND_ELEMENT_COPY(incr, nincr, def) < 0)
|
|
|
a41c76 |
+ return NULL;
|
|
|
a41c76 |
+
|
|
|
a41c76 |
+ return g_steal_pointer(&incr;;
|
|
|
a41c76 |
+ }
|
|
|
a41c76 |
+
|
|
|
a41c76 |
+ if (!n->def->parent_name)
|
|
|
a41c76 |
+ break;
|
|
|
a41c76 |
+
|
|
|
a41c76 |
+ n = virDomainCheckpointFindByName(vm->checkpoints, n->def->parent_name);
|
|
|
a41c76 |
+ }
|
|
|
a41c76 |
+
|
|
|
a41c76 |
+ virReportError(VIR_ERR_OPERATION_INVALID,
|
|
|
a41c76 |
+ _("could not locate checkpoint '%s' for incremental backup"),
|
|
|
a41c76 |
+ incrFrom);
|
|
|
a41c76 |
+ return NULL;
|
|
|
a41c76 |
+}
|
|
|
a41c76 |
+
|
|
|
a41c76 |
+
|
|
|
a41c76 |
static int
|
|
|
a41c76 |
qemuBackupGetBitmapMergeRange(virStorageSourcePtr from,
|
|
|
a41c76 |
const char *bitmapname,
|
|
|
a41c76 |
@@ -334,11 +378,11 @@ qemuBackupDiskPrepareDataOne(virDomainObjPtr vm,
|
|
|
a41c76 |
struct qemuBackupDiskData *dd,
|
|
|
a41c76 |
virJSONValuePtr actions,
|
|
|
a41c76 |
bool pull,
|
|
|
a41c76 |
- virDomainMomentDefPtr *incremental,
|
|
|
a41c76 |
virHashTablePtr blockNamedNodeData,
|
|
|
a41c76 |
virQEMUDriverConfigPtr cfg)
|
|
|
a41c76 |
{
|
|
|
a41c76 |
qemuDomainObjPrivatePtr priv = vm->privateData;
|
|
|
a41c76 |
+ g_autofree virDomainMomentDefPtr *incremental = NULL;
|
|
|
a41c76 |
|
|
|
a41c76 |
/* set data structure */
|
|
|
a41c76 |
dd->backupdisk = backupdisk;
|
|
|
a41c76 |
@@ -360,7 +404,8 @@ qemuBackupDiskPrepareDataOne(virDomainObjPtr vm,
|
|
|
a41c76 |
* pull mode:
|
|
|
a41c76 |
* both: original disk
|
|
|
a41c76 |
*/
|
|
|
a41c76 |
- if (pull || (incremental && dd->store->format >= VIR_STORAGE_FILE_BACKING)) {
|
|
|
a41c76 |
+ if (pull || (dd->backupdisk->incremental &&
|
|
|
a41c76 |
+ dd->store->format >= VIR_STORAGE_FILE_BACKING)) {
|
|
|
a41c76 |
dd->backingStore = dd->domdisk->src;
|
|
|
a41c76 |
} else {
|
|
|
a41c76 |
dd->backingStore = dd->terminator = virStorageSourceNew();
|
|
|
a41c76 |
@@ -372,7 +417,10 @@ qemuBackupDiskPrepareDataOne(virDomainObjPtr vm,
|
|
|
a41c76 |
if (qemuDomainPrepareStorageSourceBlockdev(NULL, dd->store, priv, cfg) < 0)
|
|
|
a41c76 |
return -1;
|
|
|
a41c76 |
|
|
|
a41c76 |
- if (incremental) {
|
|
|
a41c76 |
+ if (dd->backupdisk->incremental) {
|
|
|
a41c76 |
+ if (!(incremental = qemuBackupBeginCollectIncrementalCheckpoints(vm, dd->backupdisk->incremental)))
|
|
|
a41c76 |
+ return -1;
|
|
|
a41c76 |
+
|
|
|
a41c76 |
if (dd->backupdisk->exportbitmap)
|
|
|
a41c76 |
dd->incrementalBitmap = g_strdup(dd->backupdisk->exportbitmap);
|
|
|
a41c76 |
else
|
|
|
a41c76 |
@@ -441,7 +489,6 @@ qemuBackupDiskPrepareDataOnePull(virJSONValuePtr actions,
|
|
|
a41c76 |
static ssize_t
|
|
|
a41c76 |
qemuBackupDiskPrepareData(virDomainObjPtr vm,
|
|
|
a41c76 |
virDomainBackupDefPtr def,
|
|
|
a41c76 |
- virDomainMomentDefPtr *incremental,
|
|
|
a41c76 |
virHashTablePtr blockNamedNodeData,
|
|
|
a41c76 |
virJSONValuePtr actions,
|
|
|
a41c76 |
virQEMUDriverConfigPtr cfg,
|
|
|
a41c76 |
@@ -464,8 +511,7 @@ qemuBackupDiskPrepareData(virDomainObjPtr vm,
|
|
|
a41c76 |
ndisks++;
|
|
|
a41c76 |
|
|
|
a41c76 |
if (qemuBackupDiskPrepareDataOne(vm, backupdisk, dd, actions, pull,
|
|
|
a41c76 |
- incremental, blockNamedNodeData,
|
|
|
a41c76 |
- cfg) < 0)
|
|
|
a41c76 |
+ blockNamedNodeData, cfg) < 0)
|
|
|
a41c76 |
goto error;
|
|
|
a41c76 |
|
|
|
a41c76 |
if (pull) {
|
|
|
a41c76 |
@@ -622,50 +668,6 @@ qemuBackupBeginPullExportDisks(virDomainObjPtr vm,
|
|
|
a41c76 |
}
|
|
|
a41c76 |
|
|
|
a41c76 |
|
|
|
a41c76 |
-/**
|
|
|
a41c76 |
- * qemuBackupBeginCollectIncrementalCheckpoints:
|
|
|
a41c76 |
- * @vm: domain object
|
|
|
a41c76 |
- * @incrFrom: name of checkpoint representing starting point of incremental backup
|
|
|
a41c76 |
- *
|
|
|
a41c76 |
- * Returns a NULL terminated list of pointers to checkpoint definitions in
|
|
|
a41c76 |
- * chronological order starting from the 'current' checkpoint until reaching
|
|
|
a41c76 |
- * @incrFrom.
|
|
|
a41c76 |
- */
|
|
|
a41c76 |
-static virDomainMomentDefPtr *
|
|
|
a41c76 |
-qemuBackupBeginCollectIncrementalCheckpoints(virDomainObjPtr vm,
|
|
|
a41c76 |
- const char *incrFrom)
|
|
|
a41c76 |
-{
|
|
|
a41c76 |
- virDomainMomentObjPtr n = virDomainCheckpointGetCurrent(vm->checkpoints);
|
|
|
a41c76 |
- g_autofree virDomainMomentDefPtr *incr = NULL;
|
|
|
a41c76 |
- size_t nincr = 0;
|
|
|
a41c76 |
-
|
|
|
a41c76 |
- while (n) {
|
|
|
a41c76 |
- virDomainMomentDefPtr def = n->def;
|
|
|
a41c76 |
-
|
|
|
a41c76 |
- if (VIR_APPEND_ELEMENT_COPY(incr, nincr, def) < 0)
|
|
|
a41c76 |
- return NULL;
|
|
|
a41c76 |
-
|
|
|
a41c76 |
- if (STREQ(def->name, incrFrom)) {
|
|
|
a41c76 |
- def = NULL;
|
|
|
a41c76 |
- if (VIR_APPEND_ELEMENT_COPY(incr, nincr, def) < 0)
|
|
|
a41c76 |
- return NULL;
|
|
|
a41c76 |
-
|
|
|
a41c76 |
- return g_steal_pointer(&incr;;
|
|
|
a41c76 |
- }
|
|
|
a41c76 |
-
|
|
|
a41c76 |
- if (!n->def->parent_name)
|
|
|
a41c76 |
- break;
|
|
|
a41c76 |
-
|
|
|
a41c76 |
- n = virDomainCheckpointFindByName(vm->checkpoints, n->def->parent_name);
|
|
|
a41c76 |
- }
|
|
|
a41c76 |
-
|
|
|
a41c76 |
- virReportError(VIR_ERR_OPERATION_INVALID,
|
|
|
a41c76 |
- _("could not locate checkpoint '%s' for incremental backup"),
|
|
|
a41c76 |
- incrFrom);
|
|
|
a41c76 |
- return NULL;
|
|
|
a41c76 |
-}
|
|
|
a41c76 |
-
|
|
|
a41c76 |
-
|
|
|
a41c76 |
void
|
|
|
a41c76 |
qemuBackupJobTerminate(virDomainObjPtr vm,
|
|
|
a41c76 |
qemuDomainJobStatus jobstatus)
|
|
|
a41c76 |
@@ -799,7 +801,6 @@ qemuBackupBegin(virDomainObjPtr vm,
|
|
|
a41c76 |
bool pull = false;
|
|
|
a41c76 |
virDomainMomentObjPtr chk = NULL;
|
|
|
a41c76 |
g_autoptr(virDomainCheckpointDef) chkdef = NULL;
|
|
|
a41c76 |
- g_autofree virDomainMomentDefPtr *incremental = NULL;
|
|
|
a41c76 |
g_autoptr(virJSONValue) actions = NULL;
|
|
|
a41c76 |
struct qemuBackupDiskData *dd = NULL;
|
|
|
a41c76 |
ssize_t ndd = 0;
|
|
|
a41c76 |
@@ -867,10 +868,6 @@ qemuBackupBegin(virDomainObjPtr vm,
|
|
|
a41c76 |
if (virDomainBackupAlignDisks(def, vm->def, suffix) < 0)
|
|
|
a41c76 |
goto endjob;
|
|
|
a41c76 |
|
|
|
a41c76 |
- if (def->incremental &&
|
|
|
a41c76 |
- !(incremental = qemuBackupBeginCollectIncrementalCheckpoints(vm, def->incremental)))
|
|
|
a41c76 |
- goto endjob;
|
|
|
a41c76 |
-
|
|
|
a41c76 |
actions = virJSONValueNewArray();
|
|
|
a41c76 |
|
|
|
a41c76 |
/* The 'chk' checkpoint must be rolled back if the transaction command
|
|
|
a41c76 |
@@ -884,7 +881,7 @@ qemuBackupBegin(virDomainObjPtr vm,
|
|
|
a41c76 |
if (!(blockNamedNodeData = qemuBlockGetNamedNodeData(vm, QEMU_ASYNC_JOB_BACKUP)))
|
|
|
a41c76 |
goto endjob;
|
|
|
a41c76 |
|
|
|
a41c76 |
- if ((ndd = qemuBackupDiskPrepareData(vm, def, incremental, blockNamedNodeData,
|
|
|
a41c76 |
+ if ((ndd = qemuBackupDiskPrepareData(vm, def, blockNamedNodeData,
|
|
|
a41c76 |
actions, cfg, &dd)) <= 0) {
|
|
|
a41c76 |
if (ndd == 0) {
|
|
|
a41c76 |
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
|
|
a41c76 |
--
|
|
|
a41c76 |
2.27.0
|
|
|
a41c76 |
|