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@xxxxxxxxx> Signed-off-by: ShaoHe Feng <shaohe.feng@xxxxxxxxx> --- 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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list