First, we need get migration thread info, implement the related
interface to obtain migration threadinfo from qemu using qmp command.
Implementation of the Interface for Obtaining Thread Information
Signed-off-by: zhengchuan<zhengchuan(a)huawei.com>
Signed-off-by: Jiang Jiacheng <jiangjiacheng(a)huawei.com>
---
src/qemu/qemu_domain.c | 24 ++++++++++++++
src/qemu/qemu_domain.h | 11 +++++++
src/qemu/qemu_monitor.c | 25 +++++++++++++++
src/qemu/qemu_monitor.h | 11 +++++++
src/qemu/qemu_monitor_json.c | 62 ++++++++++++++++++++++++++++++++++++
src/qemu/qemu_monitor_json.h | 5 +++
6 files changed, 138 insertions(+)
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index aa567f652a..ba8d1055ae 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -797,6 +797,28 @@ qemuDomainSecretInfoDestroy(qemuDomainSecretInfo *secinfo)
qemuDomainSecretInfoClear(secinfo, true);
}
+static void
+qemuDomainMigThreadInfoFree(qemuDomainMigThreadInfo *migthread)
+{
+ if (!migthread)
+ return;
+
+ g_free(migthread->thread_name);
+}
+
+void
+qemuDomainMigThreadsInfoFree(qemuDomainMigThreadInfo **migthreads,
+ int nmigthreads)
+{
+ size_t i;
+ if (!migthreads)
+ return;
+
+ for (i = 0; i < nmigthreads; i++) {
+ g_clear_pointer(&migthreads[i], qemuDomainMigThreadInfoFree);
+ }
+ g_free(migthreads);
+}
static virClass *qemuDomainDiskPrivateClass;
static void qemuDomainDiskPrivateDispose(void *obj);
@@ -1842,6 +1864,8 @@ qemuDomainObjPrivateDataClear(qemuDomainObjPrivate *priv)
priv->allowReboot = VIR_TRISTATE_BOOL_ABSENT;
g_clear_pointer(&priv->migrationCaps, virBitmapFree);
+ qemuDomainMigThreadsInfoFree(priv->migThreadsInfo, priv->migThreadCount);
+ priv->migThreadCount = 0;
virHashRemoveAll(priv->blockjobs);
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index 550397ee50..42115a20ef 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -97,6 +97,12 @@ struct _qemuDomainSecretInfo {
char *ciphertext; /* encoded/encrypted secret */
};
+typedef struct _qemuDomainMigThreadInfo qemuDomainMigThreadInfo;
+struct _qemuDomainMigThreadInfo {
+ char *thread_name;
+ int thread_id;
+};
+
typedef struct _qemuDomainObjPrivate qemuDomainObjPrivate;
struct _qemuDomainObjPrivate {
virQEMUDriver *driver;
@@ -138,6 +144,8 @@ struct _qemuDomainObjPrivate {
unsigned long migMaxBandwidth;
char *origname;
int nbdPort; /* Port used for migration with NBD */
+ int migThreadCount;
+ qemuDomainMigThreadInfo **migThreadsInfo;
unsigned short migrationPort;
int preMigrationState;
unsigned long long preMigrationMemlock; /* Original RLIMIT_MEMLOCK in case
@@ -925,6 +933,9 @@ int qemuDomainSecretChardevPrepare(virQEMUDriverConfig *cfg,
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3)
ATTRIBUTE_NONNULL(4);
+void qemuDomainMigThreadsInfoFree(qemuDomainMigThreadInfo **migthreads,
+ int nmigthreads);
+
void qemuDomainCleanupStorageSourceFD(virStorageSource *src);
void qemuDomainStartupCleanup(virDomainObj *vm);
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index 1fa35f03cc..ad35034db2 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -2222,6 +2222,31 @@ qemuMonitorGetMigrationStats(qemuMonitor *mon,
return qemuMonitorJSONGetMigrationStats(mon, stats, error);
}
+void qemuMonitorMigThreadsInfoFree(qemuMonitorMigThreadInfo **migthreads,
+ int nmigthreads)
+{
+ size_t i;
+
+ if (!migthreads)
+ return;
+
+ for (i = 0; i < nmigthreads; i++) {
+ g_free(migthreads[i]->thread_name);
+ g_free(migthreads[i]);
+ }
+
+ g_free(migthreads);
+}
+
+int
+qemuMonitorGetMigThreadsInfo(qemuMonitor *mon,
+ qemuMonitorMigThreadInfo ***migthreads,
+ int *nmigthreads)
+{
+ QEMU_CHECK_MONITOR(mon);
+
+ return qemuMonitorJSONGetMigThreadsInfo(mon, migthreads, nmigthreads);
+}
int
qemuMonitorMigrateToFd(qemuMonitor *mon,
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index 72db0c0838..076e32bdd3 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -823,6 +823,17 @@ int qemuMonitorGetMigrationCapabilities(qemuMonitor *mon,
int qemuMonitorSetMigrationCapabilities(qemuMonitor *mon,
virJSONValue **caps);
+typedef struct _qemuMonitorMigThreadInfo qemuMonitorMigThreadInfo;
+struct _qemuMonitorMigThreadInfo {
+ char *thread_name;
+ int thread_id;
+};
+int qemuMonitorGetMigThreadsInfo(qemuMonitor *mon,
+ qemuMonitorMigThreadInfo ***migthreads,
+ int *nmigthreads);
+void qemuMonitorMigThreadsInfoFree(qemuMonitorMigThreadInfo **migthreads,
+ int nmigthreads);
+
int qemuMonitorGetGICCapabilities(qemuMonitor *mon,
virGICCapability **capabilities);
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index ee2ea68acb..4fd381859f 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -3124,6 +3124,68 @@ int qemuMonitorJSONGetMigrationStats(qemuMonitor *mon,
return 0;
}
+int
+qemuMonitorJSONGetMigThreadsInfo(qemuMonitor *mon,
+ qemuMonitorMigThreadInfo ***migthreads,
+ int *nmigthreads)
+{
+ int ret = -1;
+ g_autoptr(virJSONValue) cmd = NULL;
+ g_autoptr(virJSONValue) reply = NULL;
+ virJSONValue *data = NULL;
+ qemuMonitorMigThreadInfo **infolist = NULL;
+ size_t n = 0;
+ size_t i;
+
+ *migthreads = NULL;
+
+ if (!(cmd = qemuMonitorJSONMakeCommand("query-migrationthreads", NULL)))
+ return ret;
+
+ if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0)
+ goto cleanup;
+
+ if (qemuMonitorJSONCheckReply(cmd, reply, VIR_JSON_TYPE_ARRAY) < 0)
+ goto cleanup;
+
+ data = virJSONValueObjectGetArray(reply, "return");
+ n = virJSONValueArraySize(data);
+
+ infolist = g_new0(qemuMonitorMigThreadInfo *, n + 1);
+
+ for (i = 0; i < n; i++) {
+ virJSONValue *child = virJSONValueArrayGet(data, i);
+ const char *tmp;
+ qemuMonitorMigThreadInfo *info;
+
+ info = g_new0(qemuMonitorMigThreadInfo, 1);
+
+ infolist[i] = info;
+
+ if (!(tmp = virJSONValueObjectGetString(child, "name"))) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("query-migrationthreads reply data was missing
'name'"));
+ goto cleanup;
+ }
+ info->thread_name = g_strdup(tmp);
+
+ if (virJSONValueObjectGetNumberInt(child, "thread-id",
+ &info->thread_id) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("query-migrationthreads reply has malformed "
+ "'thread-id' data"));
+ goto cleanup;
+ }
+ }
+
+ *nmigthreads = n;
+ *migthreads = g_steal_pointer(&infolist);
+ ret = 0;
+
+ cleanup:
+ qemuMonitorMigThreadsInfoFree(infolist, n);
+ return ret;
+}
int qemuMonitorJSONMigrate(qemuMonitor *mon,
unsigned int flags,
diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h
index 6f376cf9b7..1a0875bd2c 100644
--- a/src/qemu/qemu_monitor_json.h
+++ b/src/qemu/qemu_monitor_json.h
@@ -156,6 +156,11 @@ int
qemuMonitorJSONSetMigrationCapabilities(qemuMonitor *mon,
virJSONValue **caps);
+int
+qemuMonitorJSONGetMigThreadsInfo(qemuMonitor *mon,
+ qemuMonitorMigThreadInfo ***migthreads,
+ int *nmigthreads);
+
int
qemuMonitorJSONGetGICCapabilities(qemuMonitor *mon,
virGICCapability **capabilities);
--
2.33.0