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