Add monitor API to tune and query the parameters used in live
migration.
* src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h,
src/qemu/qemu_monitor_json.c, src/qemu/qemu_monitor_json.h,
src/qemu/qemu_monitor_text.c, src/qemu/qemu_monitor_text.h:
Add monitor API for get/set migration parameters
Signed-off-by: Eli Qiao <liyong.qiao(a)intel.com>
Signed-off-by: ShaoHe Feng <shaohe.feng(a)intel.com>
---
src/qemu/qemu_monitor.c | 38 ++++++++++++++++++
src/qemu/qemu_monitor.h | 10 +++++
src/qemu/qemu_monitor_json.c | 93 +++++++++++++++++++++++++++++++++++++++++++
src/qemu/qemu_monitor_json.h | 9 +++++
src/qemu/qemu_monitor_text.c | 95 ++++++++++++++++++++++++++++++++++++++++++++
src/qemu/qemu_monitor_text.h | 10 +++++
6 files changed, 255 insertions(+)
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index a10e94f..244bb3e 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -2112,6 +2112,44 @@ qemuMonitorSetMigrationCacheSize(qemuMonitorPtr mon,
int
+qemuMonitorGetMigrationParameters(qemuMonitorPtr mon,
+ unsigned int *level,
+ unsigned int *threads,
+ unsigned int *dthreads)
+{
+ VIR_DEBUG("level=%p threads=%p dthreads=%p", level, threads, dthreads);
+
+ QEMU_CHECK_MONITOR_JSON(mon);
+
+ if (mon->json)
+ return qemuMonitorJSONGetMigrationParameters(mon, level,
+ threads, dthreads);
+ else
+ return qemuMonitorTextGetMigrationParameters(mon, level,
+ threads, dthreads);
+}
+
+
+int
+qemuMonitorSetMigrationParameters(qemuMonitorPtr mon,
+ int level,
+ int threads,
+ int dthreads)
+{
+ VIR_DEBUG("level=%d threads=%d dthreads=%d", level, threads, dthreads);
+
+ QEMU_CHECK_MONITOR_JSON(mon);
+
+ if (mon->json)
+ return qemuMonitorJSONSetMigrationParameters(mon, level,
+ threads, dthreads);
+ else
+ return qemuMonitorTextSetMigrationParameters(mon, level,
+ threads, dthreads);
+}
+
+
+int
qemuMonitorGetMigrationStatus(qemuMonitorPtr mon,
qemuMonitorMigrationStatusPtr status)
{
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index 8bf1058..8f09e76 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -453,6 +453,16 @@ int qemuMonitorGetMigrationCacheSize(qemuMonitorPtr mon,
int qemuMonitorSetMigrationCacheSize(qemuMonitorPtr mon,
unsigned long long cacheSize);
+int qemuMonitorGetMigrationParameters(qemuMonitorPtr mon,
+ unsigned int *level,
+ unsigned int *threads,
+ unsigned int *dthreads);
+
+int qemuMonitorSetMigrationParameters(qemuMonitorPtr mon,
+ int level,
+ int threads,
+ int dthreads);
+
enum {
QEMU_MONITOR_MIGRATION_STATUS_INACTIVE,
QEMU_MONITOR_MIGRATION_STATUS_ACTIVE,
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index ff568d9..6679a9f 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -2424,6 +2424,99 @@ qemuMonitorJSONSetMigrationCacheSize(qemuMonitorPtr mon,
}
+int
+qemuMonitorJSONGetMigrationParameters(qemuMonitorPtr mon,
+ unsigned int *level,
+ unsigned int *threads,
+ unsigned int *dthreads)
+{
+ int ret = -1;
+ virJSONValuePtr result;
+ virJSONValuePtr cmd;
+ virJSONValuePtr reply = NULL;
+
+ *level = 0;
+ *threads = 0;
+ *dthreads = 0;
+
+ cmd = qemuMonitorJSONMakeCommand("query-migrate-parameters", NULL);
+ if (!cmd)
+ return -1;
+
+ ret = qemuMonitorJSONCommand(mon, cmd, &reply);
+
+ if (ret == 0)
+ ret = qemuMonitorJSONCheckError(cmd, reply);
+
+ if (ret < 0)
+ goto cleanup;
+
+ if (!(result = virJSONValueObjectGet(reply, "return"))) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("query-migrate-parameters reply was missing "
+ "'return' data"));
+ goto cleanup;
+ }
+
+ virJSONValueObjectGetNumberUint(result, "compress-level", level);
+ virJSONValueObjectGetNumberUint(result, "compress-threads", threads);
+ virJSONValueObjectGetNumberUint(result, "decompress-threads", dthreads);
+
+ ret = 0;
+ cleanup:
+ virJSONValueFree(cmd);
+ virJSONValueFree(reply);
+ return ret;
+}
+
+
+int qemuMonitorJSONSetMigrationParameters(qemuMonitorPtr mon,
+ int level,
+ int threads,
+ int dthreads)
+{
+ int ret = -1;
+ virJSONValuePtr cmd = NULL;
+ virJSONValuePtr arguments = NULL;
+ virJSONValuePtr reply = NULL;
+
+ if ((level < 0) && (threads < 0) && (dthreads < 0))
+ return 1;
+
+ if (!(arguments = virJSONValueNewObject()))
+ return -1;
+
+ if (level > 0)
+ if (virJSONValueObjectAdd(arguments, "U:compress-level", level, NULL)
< 0)
+ goto error;
+
+ if (threads > 0)
+ if (virJSONValueObjectAdd(arguments, "U:compress-threads", threads,
NULL) < 0)
+ goto error;
+
+ if (dthreads > 0)
+ if (virJSONValueObjectAdd(arguments, "U:decompress-threads", dthreads,
NULL) < 0)
+ goto error;
+
+ if (!(cmd = qemuMonitorJSONMakeCommand("migrate-set-parameters", NULL)))
+ goto error;
+
+ if (arguments)
+ if (virJSONValueObjectAppend(cmd, "arguments", arguments) < 0)
+ goto error;
+
+ ret = qemuMonitorJSONCommand(mon, cmd, &reply);
+
+ if (ret == 0)
+ ret = qemuMonitorJSONCheckError(cmd, reply);
+
+ error:
+ virJSONValueFree(arguments);
+ virJSONValueFree(cmd);
+ virJSONValueFree(reply);
+ return ret;
+}
+
static int
qemuMonitorJSONGetMigrationStatusReply(virJSONValuePtr reply,
qemuMonitorMigrationStatusPtr status)
diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h
index b76d85b..29bf14f 100644
--- a/src/qemu/qemu_monitor_json.h
+++ b/src/qemu/qemu_monitor_json.h
@@ -123,6 +123,15 @@ int qemuMonitorJSONGetMigrationCacheSize(qemuMonitorPtr mon,
int qemuMonitorJSONSetMigrationCacheSize(qemuMonitorPtr mon,
unsigned long long cacheSize);
+int qemuMonitorJSONGetMigrationParameters(qemuMonitorPtr mon,
+ unsigned int *level,
+ unsigned int *threads,
+ unsigned int *dthreads);
+int qemuMonitorJSONSetMigrationParameters(qemuMonitorPtr mon,
+ int level,
+ int threads,
+ int dthreads);
+
int qemuMonitorJSONGetMigrationStatus(qemuMonitorPtr mon,
qemuMonitorMigrationStatusPtr status);
diff --git a/src/qemu/qemu_monitor_text.c b/src/qemu/qemu_monitor_text.c
index 2aa0460..0f02730 100644
--- a/src/qemu/qemu_monitor_text.c
+++ b/src/qemu/qemu_monitor_text.c
@@ -1348,6 +1348,101 @@ int qemuMonitorTextSetMigrationDowntime(qemuMonitorPtr mon,
}
+#define MIGRATION_PARAMETER_PRIFIX "parameters: "
+#define MIGRATION_PARAMETER_COMPRESS_LEVEL "compress-level: "
+#define MIGRATION_PARAMETER_COMPRESS_THREADS "compress-threads: "
+#define MIGRATION_PARAMETER_DECOMPRESS_THREADS "decompress-threads: "
+
+int qemuMonitorTextGetMigrationParameters(qemuMonitorPtr mon,
+ unsigned int *level,
+ unsigned int *threads,
+ unsigned int *dthreads)
+{
+ char *reply = NULL;
+ int ret = -1;
+ char *tmp;
+ char *end;
+ const char *cmd_name = "info migrate_parameters";
+
+ if (qemuMonitorHMPCommand(mon, cmd_name, &reply) < 0)
+ goto cleanup;
+
+ if (qemuMonitorTextCommandNotFound(cmd_name, reply)) {
+ virReportError(VIR_ERR_OPERATION_INVALID,
+ _("Command '%s' is not found"), cmd_name);
+ goto cleanup;
+ }
+
+ if ((tmp = strstr(reply, MIGRATION_PARAMETER_PRIFIX)) != NULL) {
+ tmp += strlen(MIGRATION_PARAMETER_PRIFIX);
+ tmp += strlen(MIGRATION_PARAMETER_COMPRESS_LEVEL);
+ end = strchr(tmp, ' ');
+ if (virStrToLong_ui(tmp, &end, 10, level) == -1) {
+ VIR_WARN("Unable to parse compress level '%s'", tmp);
+ return -1;
+ }
+ tmp = end + 1 + strlen(MIGRATION_PARAMETER_COMPRESS_THREADS);
+ end = strchr(tmp, ' ');
+ if (virStrToLong_ui(tmp, &end, 10, threads) == -1) {
+ VIR_WARN("Unable to parse compress threads'%s'", tmp);
+ return -1;
+ }
+ tmp = end + 1 + strlen(MIGRATION_PARAMETER_DECOMPRESS_THREADS);
+ end = strchr(tmp, '\0');
+ if (virStrToLong_ui(tmp, &end, 10, dthreads) == -1) {
+ VIR_WARN("Unable to parse compress threads'%s'", tmp);
+ return -1;
+ }
+ ret = 0;
+ }
+
+ cleanup:
+ VIR_FREE(reply);
+ return ret;
+}
+
+int qemuMonitorTextSetMigrationParameters(qemuMonitorPtr mon,
+ int level,
+ int threads,
+ int dthreads)
+{
+ char *cmd = NULL;
+ char *info = NULL;
+ int ret = -1;
+
+ if (level > 0) {
+ if (virAsprintf(&cmd, "migrate_set_parameter compress-level %d",
+ level) < 0)
+ goto cleanup;
+
+ if (qemuMonitorHMPCommand(mon, cmd, &info) < 0)
+ goto cleanup;
+ }
+ if (threads > 0) {
+ if (virAsprintf(&cmd, "migrate_set_parameter compress-threads %d",
+ threads) < 0)
+ goto cleanup;
+
+ if (qemuMonitorHMPCommand(mon, cmd, &info) < 0)
+ goto cleanup;
+ }
+ if (dthreads >= 0) {
+ if (virAsprintf(&cmd, "migrate_set_parameter compress-dthreads
%d",
+ dthreads) < 0)
+ goto cleanup;
+
+ if (qemuMonitorHMPCommand(mon, cmd, &info) < 0)
+ goto cleanup;
+ }
+ ret = 0;
+
+ cleanup:
+ VIR_FREE(info);
+ VIR_FREE(cmd);
+ return ret;
+}
+
+
#define MIGRATION_PREFIX "Migration status: "
#define MIGRATION_TRANSFER_PREFIX "transferred ram: "
#define MIGRATION_REMAINING_PREFIX "remaining ram: "
diff --git a/src/qemu/qemu_monitor_text.h b/src/qemu/qemu_monitor_text.h
index 3fa603b..4b518d5 100644
--- a/src/qemu/qemu_monitor_text.h
+++ b/src/qemu/qemu_monitor_text.h
@@ -106,6 +106,16 @@ int qemuMonitorTextSetMigrationDowntime(qemuMonitorPtr mon,
int qemuMonitorTextGetMigrationStatus(qemuMonitorPtr mon,
qemuMonitorMigrationStatusPtr status);
+int qemuMonitorTextGetMigrationParameters(qemuMonitorPtr mon,
+ unsigned int *level,
+ unsigned int *threads,
+ unsigned int *dthreads);
+
+int qemuMonitorTextSetMigrationParameters(qemuMonitorPtr mon,
+ int level,
+ int threads,
+ int dthreads);
+
int qemuMonitorTextMigrate(qemuMonitorPtr mon,
unsigned int flags,
const char *uri);
--
2.1.4