ae23c9
From 736bcac80123ee6415953277449359722ae93d37 Mon Sep 17 00:00:00 2001
ae23c9
From: Kevin Wolf <kwolf@redhat.com>
ae23c9
Date: Wed, 10 Oct 2018 13:50:54 +0100
ae23c9
Subject: [PATCH 4/5] commit: Add top-node/base-node options
ae23c9
ae23c9
RH-Author: Kevin Wolf <kwolf@redhat.com>
ae23c9
Message-id: <20181010135055.3874-2-kwolf@redhat.com>
ae23c9
Patchwork-id: 82569
ae23c9
O-Subject: [RHEL-8 qemu-kvm PATCH 1/2] commit: Add top-node/base-node options
ae23c9
Bugzilla: 1637970
ae23c9
RH-Acked-by: John Snow <jsnow@redhat.com>
ae23c9
RH-Acked-by: Fam Zheng <famz@redhat.com>
ae23c9
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
ae23c9
ae23c9
The block-commit QMP command required specifying the top and base nodes
ae23c9
of the commit jobs using the file name of that node. While this works
ae23c9
in simple cases (local files with absolute paths), the file names
ae23c9
generated for more complicated setups can be hard to predict.
ae23c9
ae23c9
The block-commit command has more problems than just this, so we want to
ae23c9
replace it altogether in the long run, but libvirt needs a reliable way
ae23c9
to address nodes now. So we don't want to wait for a new, cleaner
ae23c9
command, but just add the minimal thing needed right now.
ae23c9
ae23c9
This adds two new options top-node and base-node to the command, which
ae23c9
allow specifying node names instead. They are mutually exclusive with
ae23c9
the old options.
ae23c9
ae23c9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
ae23c9
(cherry picked from commit 3c605f4074ebeb97970eb660fb56a9cb06525923)
ae23c9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
ae23c9
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
ae23c9
---
ae23c9
 blockdev.c           | 32 ++++++++++++++++++++++++++++++--
ae23c9
 qapi/block-core.json | 24 ++++++++++++++++++------
ae23c9
 2 files changed, 48 insertions(+), 8 deletions(-)
ae23c9
ae23c9
diff --git a/blockdev.c b/blockdev.c
ae23c9
index b8e4b0d..70af034 100644
ae23c9
--- a/blockdev.c
ae23c9
+++ b/blockdev.c
ae23c9
@@ -3325,7 +3325,9 @@ out:
ae23c9
 }
ae23c9
 
ae23c9
 void qmp_block_commit(bool has_job_id, const char *job_id, const char *device,
ae23c9
+                      bool has_base_node, const char *base_node,
ae23c9
                       bool has_base, const char *base,
ae23c9
+                      bool has_top_node, const char *top_node,
ae23c9
                       bool has_top, const char *top,
ae23c9
                       bool has_backing_file, const char *backing_file,
ae23c9
                       bool has_speed, int64_t speed,
ae23c9
@@ -3386,7 +3388,20 @@ void qmp_block_commit(bool has_job_id, const char *job_id, const char *device,
ae23c9
     /* default top_bs is the active layer */
ae23c9
     top_bs = bs;
ae23c9
 
ae23c9
-    if (has_top && top) {
ae23c9
+    if (has_top_node && has_top) {
ae23c9
+        error_setg(errp, "'top-node' and 'top' are mutually exclusive");
ae23c9
+        goto out;
ae23c9
+    } else if (has_top_node) {
ae23c9
+        top_bs = bdrv_lookup_bs(NULL, top_node, errp);
ae23c9
+        if (top_bs == NULL) {
ae23c9
+            goto out;
ae23c9
+        }
ae23c9
+        if (!bdrv_chain_contains(bs, top_bs)) {
ae23c9
+            error_setg(errp, "'%s' is not in this backing file chain",
ae23c9
+                       top_node);
ae23c9
+            goto out;
ae23c9
+        }
ae23c9
+    } else if (has_top && top) {
ae23c9
         if (strcmp(bs->filename, top) != 0) {
ae23c9
             top_bs = bdrv_find_backing_image(bs, top);
ae23c9
         }
ae23c9
@@ -3399,7 +3414,20 @@ void qmp_block_commit(bool has_job_id, const char *job_id, const char *device,
ae23c9
 
ae23c9
     assert(bdrv_get_aio_context(top_bs) == aio_context);
ae23c9
 
ae23c9
-    if (has_base && base) {
ae23c9
+    if (has_base_node && has_base) {
ae23c9
+        error_setg(errp, "'base-node' and 'base' are mutually exclusive");
ae23c9
+        goto out;
ae23c9
+    } else if (has_base_node) {
ae23c9
+        base_bs = bdrv_lookup_bs(NULL, base_node, errp);
ae23c9
+        if (base_bs == NULL) {
ae23c9
+            goto out;
ae23c9
+        }
ae23c9
+        if (!bdrv_chain_contains(top_bs, base_bs)) {
ae23c9
+            error_setg(errp, "'%s' is not in this backing file chain",
ae23c9
+                       base_node);
ae23c9
+            goto out;
ae23c9
+        }
ae23c9
+    } else if (has_base && base) {
ae23c9
         base_bs = bdrv_find_backing_image(top_bs, base);
ae23c9
     } else {
ae23c9
         base_bs = bdrv_find_base(top_bs);
ae23c9
diff --git a/qapi/block-core.json b/qapi/block-core.json
ae23c9
index 602c028..5fb7983 100644
ae23c9
--- a/qapi/block-core.json
ae23c9
+++ b/qapi/block-core.json
ae23c9
@@ -1434,12 +1434,23 @@
ae23c9
 #
ae23c9
 # @device:  the device name or node-name of a root node
ae23c9
 #
ae23c9
-# @base:   The file name of the backing image to write data into.
ae23c9
-#                    If not specified, this is the deepest backing image.
ae23c9
+# @base-node: The node name of the backing image to write data into.
ae23c9
+#             If not specified, this is the deepest backing image.
ae23c9
+#             (since: 3.1)
ae23c9
 #
ae23c9
-# @top:    The file name of the backing image within the image chain,
ae23c9
-#                    which contains the topmost data to be committed down. If
ae23c9
-#                    not specified, this is the active layer.
ae23c9
+# @base: Same as @base-node, except that it is a file name rather than a node
ae23c9
+#        name. This must be the exact filename string that was used to open the
ae23c9
+#        node; other strings, even if addressing the same file, are not
ae23c9
+#        accepted (deprecated, use @base-node instead)
ae23c9
+#
ae23c9
+# @top-node: The node name of the backing image within the image chain
ae23c9
+#            which contains the topmost data to be committed down. If
ae23c9
+#            not specified, this is the active layer. (since: 3.1)
ae23c9
+#
ae23c9
+# @top: Same as @top-node, except that it is a file name rather than a node
ae23c9
+#       name. This must be the exact filename string that was used to open the
ae23c9
+#       node; other strings, even if addressing the same file, are not
ae23c9
+#       accepted (deprecated, use @base-node instead)
ae23c9
 #
ae23c9
 # @backing-file:  The backing file string to write into the overlay
ae23c9
 #                           image of 'top'.  If 'top' is the active layer,
ae23c9
@@ -1508,7 +1519,8 @@
ae23c9
 #
ae23c9
 ##
ae23c9
 { 'command': 'block-commit',
ae23c9
-  'data': { '*job-id': 'str', 'device': 'str', '*base': 'str', '*top': 'str',
ae23c9
+  'data': { '*job-id': 'str', 'device': 'str', '*base-node': 'str',
ae23c9
+            '*base': 'str', '*top-node': 'str', '*top': 'str',
ae23c9
             '*backing-file': 'str', '*speed': 'int',
ae23c9
             '*filter-node-name': 'str',
ae23c9
             '*auto-finalize': 'bool', '*auto-dismiss': 'bool' } }
ae23c9
-- 
ae23c9
1.8.3.1
ae23c9