From: ShaoHe Feng <shaohe.feng(a)intel.com>
Current compression does not use all range of parameter values
so let's use some of them as 'unspecified' values. These
values will be used to mark parameters that were not specified
on migrate command line. Thus we check that qemu does not
use these values when we read parameters.
Signed-off-by: ShaoHe Feng <shaohe.feng(a)intel.com>
Signed-off-by: Nikolay Shirokovskiy <nshirokovskiy(a)virtuozzo.com>
---
src/qemu/qemu_monitor.c | 29 +++++++++++++
src/qemu/qemu_monitor.h | 16 +++++++
src/qemu/qemu_monitor_json.c | 87 +++++++++++++++++++++++++++++++++++++
src/qemu/qemu_monitor_json.h | 5 +++
src/qemu/qemu_monitor_text.c | 100 +++++++++++++++++++++++++++++++++++++++++++
src/qemu/qemu_monitor_text.h | 5 +++
6 files changed, 242 insertions(+)
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index cf1cdfb..e9b1ce4 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -2116,6 +2116,35 @@ qemuMonitorSetMigrationCacheSize(qemuMonitorPtr mon,
int
+qemuMonitorGetMigrationCompressParametersMT(qemuMonitorPtr mon,
+ qemuMonitorMigrationMTParametersPtr params)
+{
+ QEMU_CHECK_MONITOR(mon);
+
+ if (mon->json)
+ return qemuMonitorJSONGetMigrationCompressParametersMT(mon, params);
+ else
+ return qemuMonitorTextGetMigrationCompressParametersMT(mon, params);
+}
+
+int
+qemuMonitorSetMigrationCompressParametersMT(qemuMonitorPtr mon,
+ qemuMonitorMigrationMTParametersPtr params)
+{
+ VIR_DEBUG("level=%d threads=%d dthreads=%d", params->level,
+ params->threads,
+ params->dthreads);
+
+ QEMU_CHECK_MONITOR(mon);
+
+ if (mon->json)
+ return qemuMonitorJSONSetMigrationCompressParametersMT(mon, params);
+ else
+ return qemuMonitorTextSetMigrationCompressParametersMT(mon, params);
+}
+
+
+int
qemuMonitorGetMigrationStats(qemuMonitorPtr mon,
qemuMonitorMigrationStatsPtr stats)
{
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index c2a0ed6..5a5e0e2 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -463,6 +463,22 @@ int qemuMonitorGetMigrationCacheSize(qemuMonitorPtr mon,
int qemuMonitorSetMigrationCacheSize(qemuMonitorPtr mon,
unsigned long long cacheSize);
+typedef struct _qemuMonitorMigrationMTParameters qemuMonitorMigrationMTParameters;
+typedef qemuMonitorMigrationMTParameters *qemuMonitorMigrationMTParametersPtr;
+struct _qemuMonitorMigrationMTParameters {
+ /* -1 is value of unspecified */
+ int level;
+ /* 0 is value of unspecified */
+ unsigned int threads;
+ /* 0 is value of unspecified */
+ unsigned int dthreads;
+};
+
+int qemuMonitorGetMigrationCompressParametersMT(qemuMonitorPtr mon,
+ qemuMonitorMigrationMTParametersPtr
params);
+int qemuMonitorSetMigrationCompressParametersMT(qemuMonitorPtr mon,
+ qemuMonitorMigrationMTParametersPtr
params);
+
typedef enum {
QEMU_MONITOR_MIGRATION_STATUS_INACTIVE,
QEMU_MONITOR_MIGRATION_STATUS_SETUP,
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index 24a8865..62aba88 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -2437,6 +2437,93 @@ qemuMonitorJSONSetMigrationCacheSize(qemuMonitorPtr mon,
}
+int qemuMonitorJSONGetMigrationCompressParametersMT(qemuMonitorPtr mon,
+ qemuMonitorMigrationMTParametersPtr
params)
+{
+ int ret = -1;
+ virJSONValuePtr result;
+ virJSONValuePtr cmd;
+ virJSONValuePtr reply = NULL;
+
+ if ((cmd = qemuMonitorJSONMakeCommand("query-migrate-parameters", NULL)) ==
NULL)
+ return -1;
+
+ if ((ret = qemuMonitorJSONCommand(mon, cmd, &reply)) < 0)
+ goto cleanup;
+
+ if ((ret = qemuMonitorJSONCheckError(cmd, reply)) < 0)
+ goto cleanup;
+
+ if (!(result = virJSONValueObjectGet(reply, "return"))) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("query-migrate-parameters reply was missing "
+ "'return' data"));
+ goto cleanup;
+ }
+
+ if (virJSONValueObjectGetNumberInt(result, "compress-level",
+ ¶ms->level) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("malformed/missing compress-level "
+ "in migrate parameters"));
+ goto cleanup;
+ }
+
+ if (virJSONValueObjectGetNumberUint(result, "compress-threads",
+ ¶ms->threads) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("malformed/missing compress-threads "
+ "in migrate parameters"));
+ goto cleanup;
+ }
+
+ if (virJSONValueObjectGetNumberUint(result, "decompress-threads",
+ ¶ms->dthreads) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("malformed/missing decompress-threads "
+ "in migrate parameters"));
+ goto cleanup;
+ }
+
+ if (params->level < 0 || params->threads < 1 || params->dthreads <
1) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("unexpected compress parameters"));
+ goto cleanup;
+ }
+
+ ret = 0;
+ cleanup:
+ virJSONValueFree(cmd);
+ virJSONValueFree(reply);
+ return ret;
+}
+
+int qemuMonitorJSONSetMigrationCompressParametersMT(qemuMonitorPtr mon,
+ qemuMonitorMigrationMTParametersPtr
params)
+{
+ int ret = -1;
+ virJSONValuePtr cmd;
+ virJSONValuePtr reply = NULL;
+
+ cmd = qemuMonitorJSONMakeCommand("migrate-set-parameters",
+ "i:compress-level", params->level,
+ "u:compress-threads", params->threads,
+ "u:decompress-threads",
params->dthreads,
+ NULL);
+ if (!cmd)
+ return -1;
+
+ if ((ret = qemuMonitorJSONCommand(mon, cmd, &reply)) < 0)
+ goto cleanup;
+
+ ret = qemuMonitorJSONCheckError(cmd, reply);
+
+ cleanup:
+ virJSONValueFree(cmd);
+ virJSONValueFree(reply);
+ return ret;
+}
+
static int
qemuMonitorJSONGetMigrationStatsReply(virJSONValuePtr reply,
qemuMonitorMigrationStatsPtr stats)
diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h
index 2c27c6f..e10f7c7 100644
--- a/src/qemu/qemu_monitor_json.h
+++ b/src/qemu/qemu_monitor_json.h
@@ -123,6 +123,11 @@ int qemuMonitorJSONGetMigrationCacheSize(qemuMonitorPtr mon,
int qemuMonitorJSONSetMigrationCacheSize(qemuMonitorPtr mon,
unsigned long long cacheSize);
+int qemuMonitorJSONGetMigrationCompressParametersMT(qemuMonitorPtr mon,
+ qemuMonitorMigrationMTParametersPtr
params);
+int qemuMonitorJSONSetMigrationCompressParametersMT(qemuMonitorPtr mon,
+ qemuMonitorMigrationMTParametersPtr
params);
+
int qemuMonitorJSONGetMigrationStats(qemuMonitorPtr mon,
qemuMonitorMigrationStatsPtr stats);
diff --git a/src/qemu/qemu_monitor_text.c b/src/qemu/qemu_monitor_text.c
index bb87397..a3768df 100644
--- a/src/qemu/qemu_monitor_text.c
+++ b/src/qemu/qemu_monitor_text.c
@@ -1345,6 +1345,106 @@ int qemuMonitorTextSetMigrationDowntime(qemuMonitorPtr mon,
}
+int qemuMonitorTextGetMigrationCompressParametersMT(qemuMonitorPtr mon,
+ qemuMonitorMigrationMTParametersPtr
params)
+{
+ char *reply = NULL;
+ int ret = -1;
+ char *end;
+ char *p;
+
+ if (qemuMonitorHMPCommand(mon, "info migrate_parameters", &reply) <
0)
+ goto cleanup;
+
+ if (STRPREFIX(reply, "unknown command:")) {
+ virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+ _("Command 'info migrate_parameters' is not
found"));
+ goto cleanup;
+ }
+
+ /* reply is like:
+ * parameters: compress-level: 1 compress-threads: 8 decompress-threads: 2
+ */
+
+#define parseCompressionParameter(name, parse, value) \
+ if ((p = strstr(reply, name)) == NULL) \
+ goto cleanup; \
+ if (parse(p + strlen(name), &end, 10, &value) < 0) \
+ goto cleanup;
+
+ parseCompressionParameter("compress-level: ",
+ virStrToLong_i, params->level)
+ parseCompressionParameter("compress-threads: ",
+ virStrToLong_ui, params->threads)
+ parseCompressionParameter("decompress-threads: ",
+ virStrToLong_ui, params->dthreads)
+
+#undef parseCompressionParameter
+
+ if (params->level < 0 || params->threads < 1 || params->dthreads <
1) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("unexpected compress parameters"));
+ goto cleanup;
+ }
+
+ ret = 0;
+
+ cleanup:
+ VIR_FREE(reply);
+ return ret;
+}
+
+/* frees cmd */
+static
+int executeHMPCommand(qemuMonitorPtr mon, char *cmd)
+{
+ char *reply = NULL;
+ int ret = -1;
+
+ if (qemuMonitorHMPCommand(mon, cmd, &reply) < 0)
+ goto cleanup;
+
+ if (STRPREFIX(reply, "unknown command:")) {
+ virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+ _("Command 'migrate_set_parameter' is not
found"));
+ goto cleanup;
+ }
+
+ ret = 0;
+
+ cleanup:
+ VIR_FREE(reply);
+ VIR_FREE(cmd);
+ return ret;
+}
+
+int qemuMonitorTextSetMigrationCompressParametersMT(qemuMonitorPtr mon,
+ qemuMonitorMigrationMTParametersPtr
params)
+{
+ char *cmd = NULL;
+
+ if (virAsprintf(&cmd, "migrate_set_parameter compress-level %d",
+ params->level) < 0)
+ return -1;
+ if (executeHMPCommand(mon, cmd) < 0)
+ return -1;
+
+ if (virAsprintf(&cmd, "migrate_set_parameter compress-threads %u",
+ params->threads) < 0)
+ return -1;
+ if (executeHMPCommand(mon, cmd) < 0)
+ return -1;
+
+ if (virAsprintf(&cmd, "migrate_set_parameter compress-dthreads %u",
+ params->dthreads) < 0)
+ return -1;
+ if (executeHMPCommand(mon, cmd) < 0)
+ return -1;
+
+ return 0;
+}
+
+
#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 44a5330..e6022a9 100644
--- a/src/qemu/qemu_monitor_text.h
+++ b/src/qemu/qemu_monitor_text.h
@@ -106,6 +106,11 @@ int qemuMonitorTextSetMigrationDowntime(qemuMonitorPtr mon,
int qemuMonitorTextGetMigrationStats(qemuMonitorPtr mon,
qemuMonitorMigrationStatsPtr stats);
+int qemuMonitorTextGetMigrationCompressParametersMT(qemuMonitorPtr mon,
+ qemuMonitorMigrationMTParametersPtr
params);
+int qemuMonitorTextSetMigrationCompressParametersMT(qemuMonitorPtr mon,
+ qemuMonitorMigrationMTParametersPtr
params);
+
int qemuMonitorTextMigrate(qemuMonitorPtr mon,
unsigned int flags,
const char *uri);
--
1.8.3.1