On 7/20/22 12:05 PM, Eugenio Pérez wrote:
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 blocking
migration, etc.
Enable qemu monitor to send this query. This will allow
qemuMigrationSrcIsAllowed to dynamically ask for migration blockers,
reducing duplication.
I reworded this commit log a bit - see the branch I linked in my
response to the cover letter and let me know if you approve.
Signed-off-by: Eugenio Pérez <eperezma@xxxxxxxxxx>
Reviewed-by: Jiri Denemark <jdenemar@xxxxxxxxxx>
---
v4:
* Separate return type into its own line
v3:
* Squash some patches
* Return ok in qemuMonitorJSONGetMigrationBlockers is there are no
blockers.
* Move note to function doc.
---
src/qemu/qemu_monitor.c | 11 +++++++++
src/qemu/qemu_monitor.h | 4 ++++
src/qemu/qemu_monitor_json.c | 44 ++++++++++++++++++++++++++++++++++++
src/qemu/qemu_monitor_json.h | 3 +++
4 files changed, 62 insertions(+)
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index 109107eaae..e0939beecd 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -4486,3 +4486,14 @@ qemuMonitorMigrateRecover(qemuMonitor *mon,
return qemuMonitorJSONMigrateRecover(mon, uri);
}
+
+int
+qemuMonitorGetMigrationBlockers(qemuMonitor *mon,
+ char ***blockers)
We try to keep 2 blank lines between each function. I added in the extra
blank lines before and after this function.
+{
+ 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 cc1a0bc8c9..b82f198285 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -1543,3 +1543,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 5e4a86e5ad..6b26dfcb54 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -3338,6 +3338,50 @@ 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 2759566892..e4c65e250e 100644
--- a/src/qemu/qemu_monitor_json.h
+++ b/src/qemu/qemu_monitor_json.h
@@ -184,6 +184,9 @@ qemuMonitorJSONMigrate(qemuMonitor *mon,
unsigned int flags,
const char *uri);
int
+qemuMonitorJSONGetMigrationBlockers(qemuMonitor *mon,
+ char ***blockers);
+int
qemuMonitorJSONGetSpiceMigrationStatus(qemuMonitor *mon,
bool *spice_migrated);