a41c76
From 0ca4a633af46f2e06d3ef831919ca75387f42103 Mon Sep 17 00:00:00 2001
a41c76
Message-Id: <0ca4a633af46f2e06d3ef831919ca75387f42103@dist-git>
a41c76
From: Peter Krempa <pkrempa@redhat.com>
a41c76
Date: Mon, 16 Mar 2020 22:12:34 +0100
a41c76
Subject: [PATCH] rhel: Enable usage of x-blockdev-reopen
a41c76
MIME-Version: 1.0
a41c76
Content-Type: text/plain; charset=UTF-8
a41c76
Content-Transfer-Encoding: 8bit
a41c76
a41c76
RHEL-only
a41c76
a41c76
Introduce a new capability QEMU_CAPS_BLOCKDEV_REOPEN_COM_REDHAT_AV_8_2_0_API
a41c76
based on the presence of '__com.redhat_rhel-av-8_2_0-api' feature for
a41c76
'x-blockdev-reopen' which states that reopen works for what libvirt
a41c76
is going to use it and wire up code to call the x- prefixed command.
a41c76
a41c76
This implementation will become dormant once qemu starts supporting
a41c76
upstream-stable blockdev-reopen.
a41c76
a41c76
https://bugzilla.redhat.com/show_bug.cgi?id=1799013
a41c76
Message-Id: <098dc0e73e1b561af991f2a9ecf13436dde3b33d.1584391727.git.pkrempa@redhat.com>
a41c76
Reviewed-by: Ján Tomko <jtomko@redhat.com>
a41c76
---
a41c76
 src/qemu/qemu_block.c        |  3 ++-
a41c76
 src/qemu/qemu_capabilities.c | 13 +++++++++++++
a41c76
 src/qemu/qemu_capabilities.h |  3 +++
a41c76
 src/qemu/qemu_monitor.c      |  5 +++--
a41c76
 src/qemu/qemu_monitor.h      |  3 ++-
a41c76
 src/qemu/qemu_monitor_json.c | 12 +++++++++---
a41c76
 src/qemu/qemu_monitor_json.h |  3 ++-
a41c76
 7 files changed, 34 insertions(+), 8 deletions(-)
a41c76
a41c76
diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c
a41c76
index 21c1ad9618..099ceeb802 100644
a41c76
--- a/src/qemu/qemu_block.c
a41c76
+++ b/src/qemu/qemu_block.c
a41c76
@@ -3225,6 +3225,7 @@ qemuBlockReopenFormat(virDomainObjPtr vm,
a41c76
     qemuDomainObjPrivatePtr priv = vm->privateData;
a41c76
     virQEMUDriverPtr driver = priv->driver;
a41c76
     g_autoptr(virJSONValue) reopenprops = NULL;
a41c76
+    bool downstream = virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BLOCKDEV_REOPEN_COM_REDHAT_AV_8_2_0_API);
a41c76
     int rc;
a41c76
 
a41c76
     /* If we are lacking the object here, qemu might have opened an image with
a41c76
@@ -3241,7 +3242,7 @@ qemuBlockReopenFormat(virDomainObjPtr vm,
a41c76
     if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
a41c76
         return -1;
a41c76
 
a41c76
-    rc = qemuMonitorBlockdevReopen(priv->mon, &reopenprops);
a41c76
+    rc = qemuMonitorBlockdevReopen(priv->mon, &reopenprops, downstream);
a41c76
 
a41c76
     if (qemuDomainObjExitMonitor(driver, vm) < 0 || rc < 0)
a41c76
         return -1;
a41c76
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
a41c76
index a4046b09d6..0b4ed4253c 100644
a41c76
--- a/src/qemu/qemu_capabilities.c
a41c76
+++ b/src/qemu/qemu_capabilities.c
a41c76
@@ -561,6 +561,9 @@ VIR_ENUM_IMPL(virQEMUCaps,
a41c76
               "vhost-user-fs",
a41c76
               "blockdev-snapshot.allow-write-only-overlay",
a41c76
               "blockdev-reopen",
a41c76
+
a41c76
+              /* 355 */
a41c76
+              "blockdev-reopen.__com.redhat_rhel-av-8_2_0-api"
a41c76
     );
a41c76
 
a41c76
 
a41c76
@@ -1419,6 +1422,7 @@ static struct virQEMUCapsStringFlags virQEMUCapsDevicePropsNVDIMM[] = {
a41c76
 
a41c76
 /* see documentation for virQEMUQAPISchemaPathGet for the query format */
a41c76
 static struct virQEMUCapsStringFlags virQEMUCapsQMPSchemaQueries[] = {
a41c76
+    { "x-blockdev-reopen/$__com.redhat_rhel-av-8_2_0-api", QEMU_CAPS_BLOCKDEV_REOPEN_COM_REDHAT_AV_8_2_0_API },
a41c76
     { "blockdev-add/arg-type/options/+gluster/debug-level", QEMU_CAPS_GLUSTER_DEBUG_LEVEL},
a41c76
     { "blockdev-add/arg-type/+gluster/debug", QEMU_CAPS_GLUSTER_DEBUG_LEVEL},
a41c76
     { "blockdev-add/arg-type/+vxhs", QEMU_CAPS_VXHS},
a41c76
@@ -4861,6 +4865,15 @@ virQEMUCapsInitProcessCaps(virQEMUCapsPtr qemuCaps)
a41c76
         virQEMUCapsGet(qemuCaps, QEMU_CAPS_SAVEVM_MONITOR_NODES))
a41c76
         virQEMUCapsSet(qemuCaps, QEMU_CAPS_BLOCKDEV);
a41c76
 
a41c76
+    /* RHEL-only:
a41c76
+     * - if upstream blockdev-reopen is enabled, clear the downstream flag
a41c76
+     * - if the downstream flag is present but not the upstream, assert the upstream flag too
a41c76
+     */
a41c76
+    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_BLOCKDEV_REOPEN))
a41c76
+        virQEMUCapsClear(qemuCaps, QEMU_CAPS_BLOCKDEV_REOPEN_COM_REDHAT_AV_8_2_0_API);
a41c76
+    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_BLOCKDEV_REOPEN_COM_REDHAT_AV_8_2_0_API))
a41c76
+        virQEMUCapsSet(qemuCaps, QEMU_CAPS_BLOCKDEV_REOPEN);
a41c76
+
a41c76
     virQEMUCapsInitProcessCapsInterlock(qemuCaps);
a41c76
 }
a41c76
 
a41c76
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
a41c76
index 8fdbe05638..0f7c586703 100644
a41c76
--- a/src/qemu/qemu_capabilities.h
a41c76
+++ b/src/qemu/qemu_capabilities.h
a41c76
@@ -543,6 +543,9 @@ typedef enum { /* virQEMUCapsFlags grouping marker for syntax-check */
a41c76
     QEMU_CAPS_BLOCKDEV_SNAPSHOT_ALLOW_WRITE_ONLY, /* blockdev-snapshot has the 'allow-write-only-overlay' feature */
a41c76
     QEMU_CAPS_BLOCKDEV_REOPEN, /* 'blockdev-reopen' qmp command is supported */
a41c76
 
a41c76
+    /* 355 */
a41c76
+    QEMU_CAPS_BLOCKDEV_REOPEN_COM_REDHAT_AV_8_2_0_API, /* downstream support for blockdev reopen in rhel-av-8.2.0 */
a41c76
+
a41c76
     QEMU_CAPS_LAST /* this must always be the last item */
a41c76
 } virQEMUCapsFlags;
a41c76
 
a41c76
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
a41c76
index c4202d59af..5915035589 100644
a41c76
--- a/src/qemu/qemu_monitor.c
a41c76
+++ b/src/qemu/qemu_monitor.c
a41c76
@@ -4409,14 +4409,15 @@ qemuMonitorBlockdevAdd(qemuMonitorPtr mon,
a41c76
 
a41c76
 int
a41c76
 qemuMonitorBlockdevReopen(qemuMonitorPtr mon,
a41c76
-                          virJSONValuePtr *props)
a41c76
+                          virJSONValuePtr *props,
a41c76
+                          bool downstream)
a41c76
 {
a41c76
     VIR_DEBUG("props=%p (node-name=%s)", *props,
a41c76
               NULLSTR(virJSONValueObjectGetString(*props, "node-name")));
a41c76
 
a41c76
     QEMU_CHECK_MONITOR(mon);
a41c76
 
a41c76
-    return qemuMonitorJSONBlockdevReopen(mon, props);
a41c76
+    return qemuMonitorJSONBlockdevReopen(mon, props, downstream);
a41c76
 }
a41c76
 
a41c76
 
a41c76
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
a41c76
index 481fc8e12e..ca975d084c 100644
a41c76
--- a/src/qemu/qemu_monitor.h
a41c76
+++ b/src/qemu/qemu_monitor.h
a41c76
@@ -1326,7 +1326,8 @@ int qemuMonitorBlockdevAdd(qemuMonitorPtr mon,
a41c76
                            virJSONValuePtr *props);
a41c76
 
a41c76
 int qemuMonitorBlockdevReopen(qemuMonitorPtr mon,
a41c76
-                              virJSONValuePtr *props);
a41c76
+                              virJSONValuePtr *props,
a41c76
+                              bool downstream);
a41c76
 
a41c76
 int qemuMonitorBlockdevDel(qemuMonitorPtr mon,
a41c76
                            const char *nodename);
a41c76
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
a41c76
index 0122b77259..92d7317a82 100644
a41c76
--- a/src/qemu/qemu_monitor_json.c
a41c76
+++ b/src/qemu/qemu_monitor_json.c
a41c76
@@ -8832,14 +8832,20 @@ qemuMonitorJSONBlockdevAdd(qemuMonitorPtr mon,
a41c76
 
a41c76
 int
a41c76
 qemuMonitorJSONBlockdevReopen(qemuMonitorPtr mon,
a41c76
-                              virJSONValuePtr *props)
a41c76
+                              virJSONValuePtr *props,
a41c76
+                              bool downstream)
a41c76
 {
a41c76
     g_autoptr(virJSONValue) cmd = NULL;
a41c76
     g_autoptr(virJSONValue) reply = NULL;
a41c76
     virJSONValuePtr pr = g_steal_pointer(props);
a41c76
 
a41c76
-    if (!(cmd = qemuMonitorJSONMakeCommandInternal("blockdev-reopen", pr)))
a41c76
-        return -1;
a41c76
+    if (downstream) {
a41c76
+        if (!(cmd = qemuMonitorJSONMakeCommandInternal("x-blockdev-reopen", pr)))
a41c76
+            return -1;
a41c76
+    } else {
a41c76
+        if (!(cmd = qemuMonitorJSONMakeCommandInternal("blockdev-reopen", pr)))
a41c76
+            return -1;
a41c76
+    }
a41c76
 
a41c76
     if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0)
a41c76
         return -1;
a41c76
diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h
a41c76
index 801babef97..38c61a5661 100644
a41c76
--- a/src/qemu/qemu_monitor_json.h
a41c76
+++ b/src/qemu/qemu_monitor_json.h
a41c76
@@ -601,7 +601,8 @@ int qemuMonitorJSONBlockdevAdd(qemuMonitorPtr mon,
a41c76
     ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
a41c76
 
a41c76
 int qemuMonitorJSONBlockdevReopen(qemuMonitorPtr mon,
a41c76
-                                  virJSONValuePtr *props)
a41c76
+                                  virJSONValuePtr *props,
a41c76
+                                  bool downstream)
a41c76
     ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
a41c76
 
a41c76
 int qemuMonitorJSONBlockdevDel(qemuMonitorPtr mon,
a41c76
-- 
a41c76
2.25.1
a41c76