render / rpms / libvirt

Forked from rpms/libvirt 9 months ago
Clone
d0f569
From b2529d5ff3a18a2b0022da75431cea5bf037819e Mon Sep 17 00:00:00 2001
d0f569
Message-Id: <b2529d5ff3a18a2b0022da75431cea5bf037819e@dist-git>
d0f569
From: Peter Krempa <pkrempa@redhat.com>
d0f569
Date: Wed, 28 Jul 2021 17:37:21 +0200
d0f569
Subject: [PATCH] RHEL: Enable usage of x-blockdev-reopen
d0f569
MIME-Version: 1.0
d0f569
Content-Type: text/plain; charset=UTF-8
d0f569
Content-Transfer-Encoding: 8bit
d0f569
d0f569
RHEL-only
d0f569
d0f569
Introduce a new capability QEMU_CAPS_BLOCKDEV_REOPEN_COM_REDHAT_AV_8_2_0_API
d0f569
based on the presence of '__com.redhat_rhel-av-8_2_0-api' feature for
d0f569
'x-blockdev-reopen' which states that reopen works for what libvirt
d0f569
is going to use it and wire up code to call the x- prefixed command.
d0f569
d0f569
This implementation will become dormant once qemu starts supporting
d0f569
upstream-stable blockdev-reopen.
d0f569
d0f569
https://bugzilla.redhat.com/show_bug.cgi?id=1799013
d0f569
d0f569
Starting with libvirt-7.6, upstream has adapted to the new format of
d0f569
arguments so this patch was modified to support blockdev-reopen which
d0f569
takes an array of nodes to reopen.
d0f569
d0f569
https://bugzilla.redhat.com/show_bug.cgi?id=1929765
d0f569
Message-Id: <3fcde2fc6add36d5276ae224caf18adc8bca7d48.1627486352.git.pkrempa@redhat.com>
d0f569
Reviewed-by: Ján Tomko <jtomko@redhat.com>
d0f569
---
d0f569
 src/qemu/qemu_block.c        | 24 +++++++++++++++---------
d0f569
 src/qemu/qemu_block.h        |  3 ++-
d0f569
 src/qemu/qemu_capabilities.c | 13 +++++++++++++
d0f569
 src/qemu/qemu_capabilities.h |  3 +++
d0f569
 src/qemu/qemu_monitor.c      |  5 +++--
d0f569
 src/qemu/qemu_monitor.h      |  3 ++-
d0f569
 src/qemu/qemu_monitor_json.c | 12 +++++++++---
d0f569
 src/qemu/qemu_monitor_json.h |  3 ++-
d0f569
 tests/qemumonitorjsontest.c  |  2 +-
d0f569
 9 files changed, 50 insertions(+), 18 deletions(-)
d0f569
d0f569
diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c
d0f569
index e5ff653a60..aa566d0097 100644
d0f569
--- a/src/qemu/qemu_block.c
d0f569
+++ b/src/qemu/qemu_block.c
d0f569
@@ -3331,7 +3331,8 @@ qemuBlockBitmapsHandleCommitFinish(virStorageSource *topsrc,
d0f569
 
d0f569
 int
d0f569
 qemuBlockReopenFormatMon(qemuMonitor *mon,
d0f569
-                         virStorageSource *src)
d0f569
+                         virStorageSource *src,
d0f569
+                         bool downstream)
d0f569
 {
d0f569
     g_autoptr(virJSONValue) reopenprops = NULL;
d0f569
     g_autoptr(virJSONValue) srcprops = NULL;
d0f569
@@ -3340,15 +3341,19 @@ qemuBlockReopenFormatMon(qemuMonitor *mon,
d0f569
     if (!(srcprops = qemuBlockStorageSourceGetBlockdevProps(src, src->backingStore)))
d0f569
         return -1;
d0f569
 
d0f569
-    if (virJSONValueArrayAppend(reopenoptions, &srcprops) < 0)
d0f569
-        return -1;
d0f569
+    if (downstream) {
d0f569
+        reopenprops = g_steal_pointer(&srcprops);
d0f569
+    } else {
d0f569
+        if (virJSONValueArrayAppend(reopenoptions, &srcprops) < 0)
d0f569
+            return -1;
d0f569
 
d0f569
-    if (virJSONValueObjectAdd(&reopenprops,
d0f569
-                              "a:options", &reopenoptions,
d0f569
-                              NULL) < 0)
d0f569
-        return -1;
d0f569
+        if (virJSONValueObjectAdd(&reopenprops,
d0f569
+                                  "a:options", &reopenoptions,
d0f569
+                                  NULL) < 0)
d0f569
+            return -1;
d0f569
+    }
d0f569
 
d0f569
-    if (qemuMonitorBlockdevReopen(mon, &reopenprops) < 0)
d0f569
+    if (qemuMonitorBlockdevReopen(mon, &reopenprops, downstream) < 0)
d0f569
         return -1;
d0f569
 
d0f569
     return 0;
d0f569
@@ -3372,6 +3377,7 @@ qemuBlockReopenFormat(virDomainObj *vm,
d0f569
 {
d0f569
     qemuDomainObjPrivate *priv = vm->privateData;
d0f569
     virQEMUDriver *driver = priv->driver;
d0f569
+    bool downstream = virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BLOCKDEV_REOPEN_COM_REDHAT_AV_8_2_0_API);
d0f569
     int rc;
d0f569
 
d0f569
     /* If we are lacking the object here, qemu might have opened an image with
d0f569
@@ -3385,7 +3391,7 @@ qemuBlockReopenFormat(virDomainObj *vm,
d0f569
     if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
d0f569
         return -1;
d0f569
 
d0f569
-    rc = qemuBlockReopenFormatMon(priv->mon, src);
d0f569
+    rc = qemuBlockReopenFormatMon(priv->mon, src, downstream);
d0f569
 
d0f569
     qemuDomainObjExitMonitor(driver, vm);
d0f569
     if (rc < 0)
d0f569
diff --git a/src/qemu/qemu_block.h b/src/qemu/qemu_block.h
d0f569
index 184a549d5c..130cfcdefd 100644
d0f569
--- a/src/qemu/qemu_block.h
d0f569
+++ b/src/qemu/qemu_block.h
d0f569
@@ -267,7 +267,8 @@ qemuBlockBitmapsHandleCommitFinish(virStorageSource *topsrc,
d0f569
 /* only for use in qemumonitorjsontest */
d0f569
 int
d0f569
 qemuBlockReopenFormatMon(qemuMonitor *mon,
d0f569
-                         virStorageSource *src);
d0f569
+                         virStorageSource *src,
d0f569
+                         bool downstream);
d0f569
 
d0f569
 int
d0f569
 qemuBlockReopenReadWrite(virDomainObj *vm,
d0f569
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
d0f569
index 5f1eb5014c..8ae80ef8d7 100644
d0f569
--- a/src/qemu/qemu_capabilities.c
d0f569
+++ b/src/qemu/qemu_capabilities.c
d0f569
@@ -654,6 +654,9 @@ VIR_ENUM_IMPL(virQEMUCaps,
d0f569
               "rbd-encryption", /* QEMU_CAPS_RBD_ENCRYPTION */
d0f569
               "sev-guest-kernel-hashes", /* QEMU_CAPS_SEV_GUEST_KERNEL_HASHES */
d0f569
               "sev-inject-launch-secret", /* QEMU_CAPS_SEV_INJECT_LAUNCH_SECRET */
d0f569
+
d0f569
+              /* 420 */
d0f569
+              "blockdev-reopen.__com.redhat_rhel-av-8_2_0-api", /* QEMU_CAPS_BLOCKDEV_REOPEN_COM_REDHAT_AV_8_2_0_API */
d0f569
     );
d0f569
 
d0f569
 
d0f569
@@ -1540,6 +1543,7 @@ static struct virQEMUCapsDevicePropsFlags virQEMUCapsDevicePropsVhostUserFS[] =
d0f569
 /* see documentation for virQEMUQAPISchemaPathGet for the query format */
d0f569
 static struct virQEMUCapsStringFlags virQEMUCapsQMPSchemaQueries[] = {
d0f569
     { "block-commit/arg-type/*top",  QEMU_CAPS_ACTIVE_COMMIT },
d0f569
+    { "x-blockdev-reopen/$__com.redhat_rhel-av-8_2_0-api", QEMU_CAPS_BLOCKDEV_REOPEN_COM_REDHAT_AV_8_2_0_API },
d0f569
     { "blockdev-add/arg-type/options/+gluster/debug-level", QEMU_CAPS_GLUSTER_DEBUG_LEVEL},
d0f569
     { "blockdev-add/arg-type/+gluster/debug", QEMU_CAPS_GLUSTER_DEBUG_LEVEL},
d0f569
     { "blockdev-add/arg-type/+vxhs", QEMU_CAPS_VXHS},
d0f569
@@ -5235,6 +5239,15 @@ virQEMUCapsInitProcessCaps(virQEMUCaps *qemuCaps)
d0f569
         qemuCaps->arch == VIR_ARCH_MIPS)
d0f569
         virQEMUCapsSet(qemuCaps, QEMU_CAPS_SCSI_NCR53C90);
d0f569
 
d0f569
+    /* RHEL-only:
d0f569
+     * - if upstream blockdev-reopen is enabled, clear the downstream flag
d0f569
+     * - if the downstream flag is present but not the upstream, assert the upstream flag too
d0f569
+     */
d0f569
+    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_BLOCKDEV_REOPEN))
d0f569
+        virQEMUCapsClear(qemuCaps, QEMU_CAPS_BLOCKDEV_REOPEN_COM_REDHAT_AV_8_2_0_API);
d0f569
+    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_BLOCKDEV_REOPEN_COM_REDHAT_AV_8_2_0_API))
d0f569
+        virQEMUCapsSet(qemuCaps, QEMU_CAPS_BLOCKDEV_REOPEN);
d0f569
+
d0f569
     virQEMUCapsInitProcessCapsInterlock(qemuCaps);
d0f569
 }
d0f569
 
d0f569
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
d0f569
index e3a3ab4445..cde6c18b4c 100644
d0f569
--- a/src/qemu/qemu_capabilities.h
d0f569
+++ b/src/qemu/qemu_capabilities.h
d0f569
@@ -634,6 +634,9 @@ typedef enum { /* virQEMUCapsFlags grouping marker for syntax-check */
d0f569
     QEMU_CAPS_SEV_GUEST_KERNEL_HASHES, /* sev-guest.kernel-hashes= */
d0f569
     QEMU_CAPS_SEV_INJECT_LAUNCH_SECRET, /* 'sev-inject-launch-secret' qmp command present */
d0f569
 
d0f569
+    /* 420 */
d0f569
+    QEMU_CAPS_BLOCKDEV_REOPEN_COM_REDHAT_AV_8_2_0_API, /* downstream support for blockdev reopen in rhel-av-8.2.0 */
d0f569
+
d0f569
     QEMU_CAPS_LAST /* this must always be the last item */
d0f569
 } virQEMUCapsFlags;
d0f569
 
d0f569
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
d0f569
index babf9e62fb..23638d3fe8 100644
d0f569
--- a/src/qemu/qemu_monitor.c
d0f569
+++ b/src/qemu/qemu_monitor.c
d0f569
@@ -4247,14 +4247,15 @@ qemuMonitorBlockdevAdd(qemuMonitor *mon,
d0f569
 
d0f569
 int
d0f569
 qemuMonitorBlockdevReopen(qemuMonitor *mon,
d0f569
-                          virJSONValue **props)
d0f569
+                          virJSONValue **props,
d0f569
+                          bool downstream)
d0f569
 {
d0f569
     VIR_DEBUG("props=%p (node-name=%s)", *props,
d0f569
               NULLSTR(virJSONValueObjectGetString(*props, "node-name")));
d0f569
 
d0f569
     QEMU_CHECK_MONITOR(mon);
d0f569
 
d0f569
-    return qemuMonitorJSONBlockdevReopen(mon, props);
d0f569
+    return qemuMonitorJSONBlockdevReopen(mon, props, downstream);
d0f569
 }
d0f569
 
d0f569
 
d0f569
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
d0f569
index 9b2e4e1421..d2037914be 100644
d0f569
--- a/src/qemu/qemu_monitor.h
d0f569
+++ b/src/qemu/qemu_monitor.h
d0f569
@@ -1426,7 +1426,8 @@ int qemuMonitorBlockdevAdd(qemuMonitor *mon,
d0f569
                            virJSONValue **props);
d0f569
 
d0f569
 int qemuMonitorBlockdevReopen(qemuMonitor *mon,
d0f569
-                              virJSONValue **props);
d0f569
+                              virJSONValue **props,
d0f569
+                              bool downstream);
d0f569
 
d0f569
 int qemuMonitorBlockdevDel(qemuMonitor *mon,
d0f569
                            const char *nodename);
d0f569
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
d0f569
index b0b513683b..34a46b9b41 100644
d0f569
--- a/src/qemu/qemu_monitor_json.c
d0f569
+++ b/src/qemu/qemu_monitor_json.c
d0f569
@@ -8051,13 +8051,19 @@ qemuMonitorJSONBlockdevAdd(qemuMonitor *mon,
d0f569
 
d0f569
 int
d0f569
 qemuMonitorJSONBlockdevReopen(qemuMonitor *mon,
d0f569
-                              virJSONValue **props)
d0f569
+                              virJSONValue **props,
d0f569
+                              bool downstream)
d0f569
 {
d0f569
     g_autoptr(virJSONValue) cmd = NULL;
d0f569
     g_autoptr(virJSONValue) reply = NULL;
d0f569
 
d0f569
-    if (!(cmd = qemuMonitorJSONMakeCommandInternal("blockdev-reopen", props)))
d0f569
-        return -1;
d0f569
+    if (downstream) {
d0f569
+        if (!(cmd = qemuMonitorJSONMakeCommandInternal("x-blockdev-reopen", props)))
d0f569
+            return -1;
d0f569
+    } else {
d0f569
+        if (!(cmd = qemuMonitorJSONMakeCommandInternal("blockdev-reopen", props)))
d0f569
+            return -1;
d0f569
+    }
d0f569
 
d0f569
     if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0)
d0f569
         return -1;
d0f569
diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h
d0f569
index 64d9ebdaa3..15ce03d7af 100644
d0f569
--- a/src/qemu/qemu_monitor_json.h
d0f569
+++ b/src/qemu/qemu_monitor_json.h
d0f569
@@ -748,7 +748,8 @@ qemuMonitorJSONBlockdevAdd(qemuMonitor *mon,
d0f569
 
d0f569
 int
d0f569
 qemuMonitorJSONBlockdevReopen(qemuMonitor *mon,
d0f569
-                              virJSONValue **props)
d0f569
+                              virJSONValue **props,
d0f569
+                              bool downstream)
d0f569
     ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
d0f569
 
d0f569
 int
d0f569
diff --git a/tests/qemumonitorjsontest.c b/tests/qemumonitorjsontest.c
d0f569
index 48e2a457ab..8624a547b5 100644
d0f569
--- a/tests/qemumonitorjsontest.c
d0f569
+++ b/tests/qemumonitorjsontest.c
d0f569
@@ -2780,7 +2780,7 @@ testQemuMonitorJSONBlockdevReopen(const void *opaque)
d0f569
     if (qemuMonitorTestAddItem(test, "blockdev-reopen", "{\"return\":{}}") < 0)
d0f569
         return -1;
d0f569
 
d0f569
-    if (qemuBlockReopenFormatMon(qemuMonitorTestGetMonitor(test), src) < 0)
d0f569
+    if (qemuBlockReopenFormatMon(qemuMonitorTestGetMonitor(test), src, false) < 0)
d0f569
         return -1;
d0f569
 
d0f569
     return 0;
d0f569
-- 
d0f569
2.34.1
d0f569