Blame SOURCES/libvirt-qemu-new-function-to-retrieve-migration-blocker-reasons-from-QEMU.patch

a1c947
From 90d326f60706a990db3ed49ba338d911471578c0 Mon Sep 17 00:00:00 2001
a1c947
Message-Id: <90d326f60706a990db3ed49ba338d911471578c0@dist-git>
a1c947
From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= <eperezma@redhat.com>
a1c947
Date: Thu, 21 Jul 2022 19:29:10 +0200
a1c947
Subject: [PATCH] qemu: new function to retrieve migration blocker reasons from
a1c947
 QEMU
a1c947
MIME-Version: 1.0
a1c947
Content-Type: text/plain; charset=UTF-8
a1c947
Content-Transfer-Encoding: 8bit
a1c947
a1c947
Since QEMU 6.0, if migration is blocked for some reason,
a1c947
'query-migrate' will return an array of error strings describing the
a1c947
migration blockers.  This can be used to check whether there are any
a1c947
devices, or other conditions, that would cause migration to fail.
a1c947
a1c947
This patch adds a function that sends this query via a QMP command and
a1c947
returns the resulting array of reasons. qemuMigrationSrcIsAllowed()
a1c947
will be able to use the new function to ask QEMU for migration
a1c947
blockers, instead of the hardcoded guesses that libvirt currently has.
a1c947
a1c947
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
a1c947
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
a1c947
Reviewed-by: Laine Stump <laine@redhat.com>
a1c947
a1c947
(cherry picked from commit 7e52c4839fabac2d19c6f22c99142e992e3d898e)
a1c947
Resolves: https://bugzilla.redhat.com/2092833
a1c947
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
a1c947
---
a1c947
 src/qemu/qemu_monitor.c      | 12 ++++++++++
a1c947
 src/qemu/qemu_monitor.h      |  4 ++++
a1c947
 src/qemu/qemu_monitor_json.c | 46 ++++++++++++++++++++++++++++++++++++
a1c947
 src/qemu/qemu_monitor_json.h |  3 +++
a1c947
 4 files changed, 65 insertions(+)
a1c947
a1c947
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
a1c947
index fda5d2f368..865a3e69ed 100644
a1c947
--- a/src/qemu/qemu_monitor.c
a1c947
+++ b/src/qemu/qemu_monitor.c
a1c947
@@ -4541,3 +4541,15 @@ qemuMonitorMigrateRecover(qemuMonitor *mon,
a1c947
 
a1c947
     return qemuMonitorJSONMigrateRecover(mon, uri);
a1c947
 }
a1c947
+
a1c947
+
a1c947
+int
a1c947
+qemuMonitorGetMigrationBlockers(qemuMonitor *mon,
a1c947
+                                char ***blockers)
a1c947
+{
a1c947
+    VIR_DEBUG("blockers=%p", blockers);
a1c947
+
a1c947
+    QEMU_CHECK_MONITOR(mon);
a1c947
+
a1c947
+    return qemuMonitorJSONGetMigrationBlockers(mon, blockers);
a1c947
+}
a1c947
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
a1c947
index 95267ec6c7..0c3f023419 100644
a1c947
--- a/src/qemu/qemu_monitor.h
a1c947
+++ b/src/qemu/qemu_monitor.h
a1c947
@@ -1554,3 +1554,7 @@ qemuMonitorChangeMemoryRequestedSize(qemuMonitor *mon,
a1c947
 int
a1c947
 qemuMonitorMigrateRecover(qemuMonitor *mon,
a1c947
                           const char *uri);
a1c947
+
a1c947
+int
a1c947
+qemuMonitorGetMigrationBlockers(qemuMonitor *mon,
a1c947
+                                char ***blockers);
a1c947
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
a1c947
index 3aad2ab212..84f4589c42 100644
a1c947
--- a/src/qemu/qemu_monitor_json.c
a1c947
+++ b/src/qemu/qemu_monitor_json.c
a1c947
@@ -3434,6 +3434,52 @@ int qemuMonitorJSONMigrate(qemuMonitor *mon,
a1c947
     return 0;
a1c947
 }
a1c947
 
a1c947
+
a1c947
+/*
a1c947
+ * Get the exposed migration blockers.
a1c947
+ *
a1c947
+ * This function assume qemu has the capability of request them.
a1c947
+ *
a1c947
+ * It returns a NULL terminated array on blockers if there are any, or it set
a1c947
+ * it to NULL otherwise.
a1c947
+ */
a1c947
+int
a1c947
+qemuMonitorJSONGetMigrationBlockers(qemuMonitor *mon,
a1c947
+                                    char ***blockers)
a1c947
+{
a1c947
+    g_autoptr(virJSONValue) cmd = NULL;
a1c947
+    g_autoptr(virJSONValue) reply = NULL;
a1c947
+    virJSONValue *data;
a1c947
+    virJSONValue *jblockers;
a1c947
+    size_t i;
a1c947
+
a1c947
+    *blockers = NULL;
a1c947
+    if (!(cmd = qemuMonitorJSONMakeCommand("query-migrate", NULL)))
a1c947
+        return -1;
a1c947
+
a1c947
+    if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0)
a1c947
+        return -1;
a1c947
+
a1c947
+    if (qemuMonitorJSONCheckReply(cmd, reply, VIR_JSON_TYPE_OBJECT) < 0)
a1c947
+        return -1;
a1c947
+
a1c947
+    data = virJSONValueObjectGetObject(reply, "return");
a1c947
+
a1c947
+    if (!(jblockers = virJSONValueObjectGetArray(data, "blocked-reasons")))
a1c947
+        return 0;
a1c947
+
a1c947
+    *blockers = g_new0(char *, virJSONValueArraySize(jblockers) + 1);
a1c947
+    for (i = 0; i < virJSONValueArraySize(jblockers); i++) {
a1c947
+        virJSONValue *jblocker = virJSONValueArrayGet(jblockers, i);
a1c947
+        const char *blocker = virJSONValueGetString(jblocker);
a1c947
+
a1c947
+        (*blockers)[i] = g_strdup(blocker);
a1c947
+    }
a1c947
+
a1c947
+    return 0;
a1c947
+}
a1c947
+
a1c947
+
a1c947
 int qemuMonitorJSONMigrateCancel(qemuMonitor *mon)
a1c947
 {
a1c947
     g_autoptr(virJSONValue) cmd = qemuMonitorJSONMakeCommand("migrate_cancel", NULL);
a1c947
diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h
a1c947
index ad3853ae69..4e7d6a1a8d 100644
a1c947
--- a/src/qemu/qemu_monitor_json.h
a1c947
+++ b/src/qemu/qemu_monitor_json.h
a1c947
@@ -199,6 +199,9 @@ qemuMonitorJSONMigrate(qemuMonitor *mon,
a1c947
                        unsigned int flags,
a1c947
                        const char *uri);
a1c947
 int
a1c947
+qemuMonitorJSONGetMigrationBlockers(qemuMonitor *mon,
a1c947
+                                    char ***blockers);
a1c947
+int
a1c947
 qemuMonitorJSONGetSpiceMigrationStatus(qemuMonitor *mon,
a1c947
                                        bool *spice_migrated);
a1c947
 
a1c947
-- 
a1c947
2.35.1
a1c947