]> xenbits.xensource.com Git - libvirt.git/commitdiff
backup: Add new qemu monitor bitmap
authorEric Blake <eblake@redhat.com>
Thu, 6 Jun 2019 02:25:05 +0000 (21:25 -0500)
committerEric Blake <eblake@redhat.com>
Wed, 12 Jun 2019 02:47:10 +0000 (21:47 -0500)
The upcoming virDomainBackup() API needs to take advantage of various
qcow2 bitmap manipulations as the basis to virDomainCheckpoints and
incremental backups.  Add four functions to expose
block-dirty-bitmap-{add,enable,disable,merge} (this is the
recently-added QEMU_CAPS_BITMAP_MERGE capability).

Signed-off-by: Eric Blake <eblake@redhat.com>
Acked-by: Peter Krempa <pkrempa@redhat.com>
src/qemu/qemu_monitor.c
src/qemu/qemu_monitor.h
src/qemu/qemu_monitor_json.c
src/qemu/qemu_monitor_json.h
tests/qemumonitorjsontest.c

index 187513a986bb93173c3e9c3838708c5ecd9ea63b..a371f7d425e58d23e13f82d15c88f847f501f79c 100644 (file)
@@ -4488,3 +4488,54 @@ qemuMonitorGetCurrentMachineInfo(qemuMonitorPtr mon,
 
     return qemuMonitorJSONGetCurrentMachineInfo(mon, info);
 }
+
+
+int
+qemuMonitorAddBitmap(qemuMonitorPtr mon,
+                     const char *node,
+                     const char *bitmap,
+                     bool persistent)
+{
+    VIR_DEBUG("node=%s bitmap=%s persistent=%d", node, bitmap, persistent);
+
+    QEMU_CHECK_MONITOR(mon);
+
+    return qemuMonitorJSONAddBitmap(mon, node, bitmap, persistent);
+}
+
+int
+qemuMonitorEnableBitmap(qemuMonitorPtr mon,
+                        const char *node,
+                        const char *bitmap)
+{
+    VIR_DEBUG("node=%s bitmap=%s", node, bitmap);
+
+    QEMU_CHECK_MONITOR(mon);
+
+    return qemuMonitorJSONEnableBitmap(mon, node, bitmap);
+}
+
+int
+qemuMonitorMergeBitmaps(qemuMonitorPtr mon,
+                        const char *node,
+                        const char *dst,
+                        virJSONValuePtr *src)
+{
+    VIR_DEBUG("node=%s dst=%s", node, dst);
+
+    QEMU_CHECK_MONITOR(mon);
+
+    return qemuMonitorJSONMergeBitmaps(mon, node, dst, src);
+}
+
+int
+qemuMonitorDeleteBitmap(qemuMonitorPtr mon,
+                        const char *node,
+                        const char *bitmap)
+{
+    VIR_DEBUG("node=%s bitmap=%s", node, bitmap);
+
+    QEMU_CHECK_MONITOR(mon);
+
+    return qemuMonitorJSONDeleteBitmap(mon, node, bitmap);
+}
index fa84ff821e36d3f50067781953fa9594ad0bd45d..30474c325d6ca19de2d34db5a421ffd326724ac9 100644 (file)
@@ -646,6 +646,25 @@ int qemuMonitorSetBalloon(qemuMonitorPtr mon,
                           unsigned long long newmem);
 int qemuMonitorSetCPU(qemuMonitorPtr mon, int cpu, bool online);
 
+int qemuMonitorAddBitmap(qemuMonitorPtr mon,
+                         const char *node,
+                         const char *bitmap,
+                         bool persistent)
+    ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3);
+int qemuMonitorEnableBitmap(qemuMonitorPtr mon,
+                            const char *node,
+                            const char *bitmap)
+    ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3);
+int qemuMonitorMergeBitmaps(qemuMonitorPtr mon,
+                            const char *node,
+                            const char *dst,
+                            virJSONValuePtr *src)
+    ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(4);
+int qemuMonitorDeleteBitmap(qemuMonitorPtr mon,
+                            const char *node,
+                            const char *bitmap)
+    ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3);
+
 
 /* XXX should we pass the virDomainDiskDefPtr instead
  * and hide dev_name details inside monitor. Reconsider
index 93113d4e8aec375bc190849d16884580d0813cb9..41eef0c38cd3e0d53870d0cdaea777e9ba7a16ca 100644 (file)
@@ -8510,3 +8510,122 @@ qemuMonitorJSONGetCurrentMachineInfo(qemuMonitorPtr mon,
     virJSONValueFree(reply);
     return ret;
 }
+
+
+int
+qemuMonitorJSONAddBitmap(qemuMonitorPtr mon,
+                         const char *node,
+                         const char *bitmap,
+                         bool persistent)
+{
+    int ret = -1;
+    virJSONValuePtr cmd;
+    virJSONValuePtr reply = NULL;
+
+    if (!(cmd = qemuMonitorJSONMakeCommand("block-dirty-bitmap-add",
+                                           "s:node", node,
+                                           "s:name", bitmap,
+                                           "b:persistent", persistent,
+                                           NULL)))
+        return -1;
+
+    if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0)
+        goto cleanup;
+
+    if (qemuMonitorJSONCheckError(cmd, reply) < 0)
+        goto cleanup;
+
+    ret = 0;
+ cleanup:
+    virJSONValueFree(cmd);
+    virJSONValueFree(reply);
+    return ret;
+}
+
+int
+qemuMonitorJSONEnableBitmap(qemuMonitorPtr mon,
+                            const char *node,
+                            const char *bitmap)
+{
+    int ret = -1;
+    virJSONValuePtr cmd;
+    virJSONValuePtr reply = NULL;
+
+    if (!(cmd = qemuMonitorJSONMakeCommand("block-dirty-bitmap-enable",
+                                           "s:node", node,
+                                           "s:name", bitmap,
+                                           NULL)))
+        return -1;
+
+    if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0)
+        goto cleanup;
+
+    if (qemuMonitorJSONCheckError(cmd, reply) < 0)
+        goto cleanup;
+
+    ret = 0;
+ cleanup:
+    virJSONValueFree(cmd);
+    virJSONValueFree(reply);
+    return ret;
+}
+
+int
+qemuMonitorJSONMergeBitmaps(qemuMonitorPtr mon,
+                            const char *node,
+                            const char *dst,
+                            virJSONValuePtr *src)
+{
+    int ret = -1;
+    virJSONValuePtr cmd;
+    virJSONValuePtr reply = NULL;
+
+    if (!(cmd = qemuMonitorJSONMakeCommand("block-dirty-bitmap-merge",
+                                           "s:node", node,
+                                           "s:target", dst,
+                                           "a:bitmaps", src,
+                                           NULL)))
+        goto cleanup;
+
+    if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0)
+        goto cleanup;
+
+    if (qemuMonitorJSONCheckError(cmd, reply) < 0)
+        goto cleanup;
+
+    ret = 0;
+ cleanup:
+    virJSONValueFree(*src);
+    *src = NULL;
+    virJSONValueFree(cmd);
+    virJSONValueFree(reply);
+    return ret;
+}
+
+int
+qemuMonitorJSONDeleteBitmap(qemuMonitorPtr mon,
+                            const char *node,
+                            const char *bitmap)
+{
+    int ret = -1;
+    virJSONValuePtr cmd;
+    virJSONValuePtr reply = NULL;
+
+    if (!(cmd = qemuMonitorJSONMakeCommand("block-dirty-bitmap-remove",
+                                           "s:node", node,
+                                           "s:name", bitmap,
+                                           NULL)))
+        return -1;
+
+    if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0)
+        goto cleanup;
+
+    if (qemuMonitorJSONCheckError(cmd, reply) < 0)
+        goto cleanup;
+
+    ret = 0;
+ cleanup:
+    virJSONValueFree(cmd);
+    virJSONValueFree(reply);
+    return ret;
+}
index e41bdc8c4f852eb8ae70fe3a6c6268ac7ea6bfba..8f92e6de35f7e80bbeca5ab3f7cd7ec006cb6dbc 100644 (file)
@@ -580,5 +580,22 @@ int
 qemuMonitorJSONGetCurrentMachineInfo(qemuMonitorPtr mon,
                                      qemuMonitorCurrentMachineInfoPtr info)
     ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
+int qemuMonitorJSONAddBitmap(qemuMonitorPtr mon,
+                             const char *node,
+                             const char *bitmap,
+                             bool persistent);
+
+int qemuMonitorJSONEnableBitmap(qemuMonitorPtr mon,
+                                const char *node,
+                                const char *bitmap);
+
+int qemuMonitorJSONMergeBitmaps(qemuMonitorPtr mon,
+                                const char *node,
+                                const char *dst,
+                                virJSONValuePtr *src);
+
+int qemuMonitorJSONDeleteBitmap(qemuMonitorPtr mon,
+                                const char *node,
+                                const char *bitmap);
 
 #endif /* LIBVIRT_QEMU_MONITOR_JSON_H */
index d29ce855cf18cbcfa9146d8c0378a87484bcc7fe..c585479e622f915451ad76261322e77c0ad6b6d5 100644 (file)
@@ -1337,6 +1337,9 @@ GEN_TEST_FUNC(qemuMonitorJSONBlockdevTrayOpen, "foodev", true)
 GEN_TEST_FUNC(qemuMonitorJSONBlockdevTrayClose, "foodev")
 GEN_TEST_FUNC(qemuMonitorJSONBlockdevMediumRemove, "foodev")
 GEN_TEST_FUNC(qemuMonitorJSONBlockdevMediumInsert, "foodev", "newnode")
+GEN_TEST_FUNC(qemuMonitorJSONAddBitmap, "node", "bitmap", true)
+GEN_TEST_FUNC(qemuMonitorJSONEnableBitmap, "node", "bitmap")
+GEN_TEST_FUNC(qemuMonitorJSONDeleteBitmap, "node", "bitmap")
 
 static int
 testQemuMonitorJSONqemuMonitorJSONNBDServerStart(const void *opaque)
@@ -1376,6 +1379,40 @@ testQemuMonitorJSONqemuMonitorJSONNBDServerStart(const void *opaque)
     return 0;
 }
 
+static int
+testQemuMonitorJSONqemuMonitorJSONMergeBitmaps(const void *opaque)
+{
+    const testGenericData *data = opaque;
+    virDomainXMLOptionPtr xmlopt = data->xmlopt;
+    VIR_AUTOPTR(qemuMonitorTest) test = NULL;
+    VIR_AUTOPTR(virJSONValue) arr = NULL;
+
+    if (!(test = qemuMonitorTestNewSchema(xmlopt, data->schema)))
+        return -1;
+
+    if (!(arr = virJSONValueNewArray()))
+        return -1;
+
+    if (virJSONValueArrayAppendString(arr, "b1") < 0 ||
+        virJSONValueArrayAppendString(arr, "b2") < 0)
+        return -1;
+
+    if (qemuMonitorTestAddItem(test, "block-dirty-bitmap-merge",
+                               "{\"return\":{}}") < 0)
+        return -1;
+
+    if (qemuMonitorJSONMergeBitmaps(qemuMonitorTestGetMonitor(test),
+                                    "node", "dst", &arr) < 0)
+        return -1;
+
+    if (arr) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "arr should have been cleared");
+        return -1;
+    }
+
+    return 0;
+}
+
 static bool
 testQemuMonitorJSONqemuMonitorJSONQueryCPUsEqual(struct qemuMonitorQueryCpusEntry *a,
                                                  struct qemuMonitorQueryCpusEntry *b)
@@ -3019,6 +3056,9 @@ mymain(void)
     DO_TEST_GEN(qemuMonitorJSONBlockdevTrayClose);
     DO_TEST_GEN(qemuMonitorJSONBlockdevMediumRemove);
     DO_TEST_GEN(qemuMonitorJSONBlockdevMediumInsert);
+    DO_TEST_GEN(qemuMonitorJSONAddBitmap);
+    DO_TEST_GEN(qemuMonitorJSONEnableBitmap);
+    DO_TEST_GEN(qemuMonitorJSONDeleteBitmap);
     DO_TEST(qemuMonitorJSONGetBalloonInfo);
     DO_TEST(qemuMonitorJSONGetBlockInfo);
     DO_TEST(qemuMonitorJSONGetAllBlockStatsInfo);
@@ -3035,6 +3075,7 @@ mymain(void)
     DO_TEST(qemuMonitorJSONSendKeyHoldtime);
     DO_TEST(qemuMonitorSupportsActiveCommit);
     DO_TEST(qemuMonitorJSONNBDServerStart);
+    DO_TEST(qemuMonitorJSONMergeBitmaps);
 
     DO_TEST_CPU_DATA("host");
     DO_TEST_CPU_DATA("full");