From patchwork Wed Jun 27 10:34:10 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Orit Wasserman X-Patchwork-Id: 167623 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id ACE08B7004 for ; Wed, 27 Jun 2012 21:18:40 +1000 (EST) Received: from localhost ([::1]:53879 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Sjpan-000544-Qn for incoming@patchwork.ozlabs.org; Wed, 27 Jun 2012 06:35:25 -0400 Received: from eggs.gnu.org ([208.118.235.92]:45618) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Sjpa8-0003NF-0Q for qemu-devel@nongnu.org; Wed, 27 Jun 2012 06:34:50 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Sjpa2-0006l9-5B for qemu-devel@nongnu.org; Wed, 27 Jun 2012 06:34:43 -0400 Received: from mx1.redhat.com ([209.132.183.28]:1027) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Sjpa1-0006kd-Qe for qemu-devel@nongnu.org; Wed, 27 Jun 2012 06:34:38 -0400 Received: from int-mx12.intmail.prod.int.phx2.redhat.com (int-mx12.intmail.prod.int.phx2.redhat.com [10.5.11.25]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id q5RAYV6k023776 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 27 Jun 2012 06:34:31 -0400 Received: from dhcp-1-120.tlv.redhat.com (vpn-200-91.tlv.redhat.com [10.35.200.91]) by int-mx12.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id q5RAYHqG013602; Wed, 27 Jun 2012 06:34:28 -0400 From: Orit Wasserman To: qemu-devel@nongnu.org Date: Wed, 27 Jun 2012 13:34:10 +0300 Message-Id: <1340793261-11400-3-git-send-email-owasserm@redhat.com> In-Reply-To: <1340793261-11400-1-git-send-email-owasserm@redhat.com> References: <1340793261-11400-1-git-send-email-owasserm@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.25 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.132.183.28 Cc: peter.maydell@linaro.org, aliguori@us.ibm.com, quintela@redhat.com, stefanha@gmail.com, mdroth@linux.vnet.ibm.com, blauwirbel@gmail.com, Orit Wasserman , chegu_vinod@hp.com, avi@redhat.com, pbonzini@redhat.com, eblake@redhat.com Subject: [Qemu-devel] [PATCH v13 02/13] Add migration capabilites X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Add migration capabilites that can be queried by the management. The management can query the source QEMU and the destination QEMU in order to verify both support some migration capability (currently only XBZRLE). The managment can enable a capability for the next migration by using migrate_set_parameter command. Signed-off-by: Orit Wasserman --- hmp-commands.hx | 16 ++++++++++++ hmp.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++ hmp.h | 2 + migration.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++- migration.h | 2 + monitor.c | 7 +++++ qapi-schema.json | 46 +++++++++++++++++++++++++++++++++++- qmp-commands.hx | 50 +++++++++++++++++++++++++++++++++++++++ 8 files changed, 252 insertions(+), 3 deletions(-) diff --git a/hmp-commands.hx b/hmp-commands.hx index f5d9d91..a0c8df2 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -861,6 +861,20 @@ Set maximum tolerated downtime (in seconds) for migration. ETEXI { + .name = "migrate_set_parameter", + .args_type = "capability:s,state:b", + .params = "", + .help = "Enable the usage of a capability for migration", + .mhandler.cmd = hmp_migrate_set_parameter, + }, + +STEXI +@item migrate_set_parameter @var{capability} @var{state} +@findex migrate_set_parameter +Enable/Disable the usage of a capability @var{capability} for migration. +ETEXI + + { .name = "client_migrate_info", .args_type = "protocol:s,hostname:s,port:i?,tls-port:i?,cert-subject:s?", .params = "protocol hostname port tls-port cert-subject", @@ -1419,6 +1433,8 @@ show CPU statistics show user network stack connection states @item info migrate show migration status +@item info migration_capabilities +show migration capabilities @item info balloon show balloon information @item info qtree diff --git a/hmp.c b/hmp.c index b9cec1d..c275fab 100644 --- a/hmp.c +++ b/hmp.c @@ -131,9 +131,19 @@ void hmp_info_mice(Monitor *mon) void hmp_info_migrate(Monitor *mon) { MigrationInfo *info; + MigrationCapabilityInfoList *cap; info = qmp_query_migrate(NULL); + if (info->has_params && info->params) { + monitor_printf(mon, "params: "); + for (cap = info->params; cap; cap = cap->next) { + monitor_printf(mon, "%s: %s ", + MigrationCapability_lookup[cap->value->capability], + cap->value->state ? "on" : "off"); + } + monitor_printf(mon, "\n"); + } if (info->has_status) { monitor_printf(mon, "Migration status: %s\n", info->status); } @@ -159,6 +169,24 @@ void hmp_info_migrate(Monitor *mon) qapi_free_MigrationInfo(info); } +void hmp_info_migration_capabilities(Monitor *mon) +{ + MigrationCapabilityInfoList *caps_list, *cap; + + caps_list = qmp_query_migration_capabilities(NULL); + if (!caps_list) { + monitor_printf(mon, "No migration capabilities found\n"); + return; + } + + for (cap = caps_list; cap; cap = cap->next) { + monitor_printf(mon, "%s ", + MigrationCapability_lookup[cap->value->capability]); + } + + qapi_free_MigrationCapabilityInfoList(caps_list); +} + void hmp_info_cpus(Monitor *mon) { CpuInfoList *cpu_list, *cpu; @@ -733,6 +761,41 @@ void hmp_migrate_set_speed(Monitor *mon, const QDict *qdict) qmp_migrate_set_speed(value, NULL); } +void hmp_migrate_set_parameter(Monitor *mon, const QDict *qdict) +{ + const char *cap = qdict_get_str(qdict, "capability"); + bool state = qdict_get_bool(qdict, "state"); + Error *err = NULL; + MigrationCapabilityInfoList *params = NULL; + int i; + + for (i = 0; i < MIGRATION_CAPABILITY_MAX; i++) { + if (strcmp(cap, MigrationCapability_lookup[i]) == 0) { + if (!params) { + params = g_malloc0(sizeof(*params)); + } + params->value = g_malloc0(sizeof(*params->value)); + params->value->capability = i; + params->value->state = state; + params->next = NULL; + qmp_migrate_set_parameters(params, &err); + break; + } + } + + if (i == MIGRATION_CAPABILITY_MAX) { + error_set(&err, QERR_INVALID_PARAMETER, cap); + } + + qapi_free_MigrationCapabilityInfoList(params); + + if (err) { + monitor_printf(mon, "migrate_set_parameter: %s\n", + error_get_pretty(err)); + error_free(err); + } +} + void hmp_set_password(Monitor *mon, const QDict *qdict) { const char *protocol = qdict_get_str(qdict, "protocol"); diff --git a/hmp.h b/hmp.h index 79d138d..09ba198 100644 --- a/hmp.h +++ b/hmp.h @@ -25,6 +25,7 @@ void hmp_info_uuid(Monitor *mon); void hmp_info_chardev(Monitor *mon); void hmp_info_mice(Monitor *mon); void hmp_info_migrate(Monitor *mon); +void hmp_info_migration_capabilities(Monitor *mon); void hmp_info_cpus(Monitor *mon); void hmp_info_block(Monitor *mon); void hmp_info_blockstats(Monitor *mon); @@ -51,6 +52,7 @@ void hmp_snapshot_blkdev(Monitor *mon, const QDict *qdict); void hmp_migrate_cancel(Monitor *mon, const QDict *qdict); void hmp_migrate_set_downtime(Monitor *mon, const QDict *qdict); void hmp_migrate_set_speed(Monitor *mon, const QDict *qdict); +void hmp_migrate_set_parameter(Monitor *mon, const QDict *qdict); void hmp_set_password(Monitor *mon, const QDict *qdict); void hmp_expire_password(Monitor *mon, const QDict *qdict); void hmp_eject(Monitor *mon, const QDict *qdict); diff --git a/migration.c b/migration.c index 810727f..c113111 100644 --- a/migration.c +++ b/migration.c @@ -117,12 +117,34 @@ MigrationInfo *qmp_query_migrate(Error **errp) { MigrationInfo *info = g_malloc0(sizeof(*info)); MigrationState *s = migrate_get_current(); + int i; switch (s->state) { case MIG_STATE_SETUP: - /* no migration has happened ever */ + /* no migration has happened ever show enabled capabilities */ + for (i = 0; i < MIGRATION_CAPABILITY_MAX; i++) { + if (!info->has_params) { + info->params = g_malloc0(sizeof(*info->params)); + info->has_params = true; + } + info->params->value = g_malloc(sizeof(*info->params->value)); + info->params->value->capability = i; + info->params->value->state = s->enabled_capabilities[i]; + info->params->next = NULL; + } break; case MIG_STATE_ACTIVE: + for (i = 0; i < MIGRATION_CAPABILITY_MAX; i++) { + if (!info->has_params) { + info->params = g_malloc0(sizeof(*info->params)); + info->has_params = true; + } + info->params->value = g_malloc(sizeof(*info->params->value)); + info->params->value->capability = i; + info->params->value->state = s->enabled_capabilities[i]; + info->params->next = NULL; + } + info->has_status = true; info->status = g_strdup("active"); @@ -141,6 +163,17 @@ MigrationInfo *qmp_query_migrate(Error **errp) } break; case MIG_STATE_COMPLETED: + for (i = 0; i < MIGRATION_CAPABILITY_MAX; i++) { + if (!info->has_params) { + info->params = g_malloc0(sizeof(*info->params)); + info->has_params = true; + } + info->params->value = g_malloc(sizeof(*info->params->value)); + info->params->value->capability = i; + info->params->value->state = s->enabled_capabilities[i]; + info->params->next = NULL; + } + info->has_status = true; info->status = g_strdup("completed"); break; @@ -157,6 +190,33 @@ MigrationInfo *qmp_query_migrate(Error **errp) return info; } +MigrationCapabilityInfoList *qmp_query_migration_capabilities(Error **errp) +{ + MigrationCapabilityInfoList *caps_list = g_malloc0(sizeof(*caps_list)); + + caps_list->value = g_malloc(sizeof(*caps_list->value)); + caps_list->value->capability = MIGRATION_CAPABILITY_XBZRLE; + caps_list->next = NULL; + + return caps_list; +} + +void qmp_migrate_set_parameters(MigrationCapabilityInfoList *params, + Error **errp) +{ + MigrationState *s = migrate_get_current(); + MigrationCapabilityInfoList *cap; + + if (s->state == MIG_STATE_ACTIVE) { + error_set(errp, QERR_MIGRATION_ACTIVE); + return; + } + + for (cap = params; cap; cap = cap->next) { + s->enabled_capabilities[cap->value->capability] = cap->value->state; + } +} + /* shared migration helpers */ static int migrate_fd_cleanup(MigrationState *s) @@ -365,12 +425,17 @@ static MigrationState *migrate_init(const MigrationParams *params) { MigrationState *s = migrate_get_current(); int64_t bandwidth_limit = s->bandwidth_limit; + bool enabled_capabilities[MIGRATION_CAPABILITY_MAX]; + + memcpy(enabled_capabilities, s->enabled_capabilities, + sizeof(enabled_capabilities)); memset(s, 0, sizeof(*s)); s->bandwidth_limit = bandwidth_limit; s->params = *params; + memcpy(s->enabled_capabilities, enabled_capabilities, + sizeof(enabled_capabilities)); - s->bandwidth_limit = bandwidth_limit; s->state = MIG_STATE_SETUP; return s; diff --git a/migration.h b/migration.h index 35207bd..1ae99f1 100644 --- a/migration.h +++ b/migration.h @@ -18,6 +18,7 @@ #include "qemu-common.h" #include "notify.h" #include "error.h" +#include "qapi-types.h" struct MigrationParams { bool blk; @@ -37,6 +38,7 @@ struct MigrationState int (*write)(MigrationState *s, const void *buff, size_t size); void *opaque; MigrationParams params; + bool enabled_capabilities[MIGRATION_CAPABILITY_MAX]; }; void process_incoming_migration(QEMUFile *f); diff --git a/monitor.c b/monitor.c index f6107ba..e2be6cd 100644 --- a/monitor.c +++ b/monitor.c @@ -2687,6 +2687,13 @@ static mon_cmd_t info_cmds[] = { .mhandler.info = hmp_info_migrate, }, { + .name = "migration_capabilities", + .args_type = "", + .params = "", + .help = "show migration capabilities", + .mhandler.info = hmp_info_migration_capabilities, + }, + { .name = "balloon", .args_type = "", .params = "", diff --git a/qapi-schema.json b/qapi-schema.json index 3b6e346..ccc5eb3 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -286,7 +286,7 @@ ## { 'type': 'MigrationInfo', 'data': {'*status': 'str', '*ram': 'MigrationStats', - '*disk': 'MigrationStats'} } + '*disk': 'MigrationStats', '*params': ['MigrationCapabilityInfo']} } ## # @query-migrate @@ -300,6 +300,50 @@ { 'command': 'query-migrate', 'returns': 'MigrationInfo' } ## +# @MigrationCapability +# +# Migration capabilities enumaration +# +# @xbzrle: current migration supports xbzrle +# +# Since: 1.2 +## +{ 'enum': 'MigrationCapability', + 'data': ['xbzrle'] } + +## +# @MigrationCapabilityInfo +# +# Migration capability information +# +# @capability: capability enum +# +# Since: 1.2 +## +{ 'type': 'MigrationCapabilityInfo', + 'data': { 'capability' : 'MigrationCapability', 'state' : 'bool' } } + +## +# @query-migration-capabilities +# +# Returns information about current migration process capabilties. +# +# Returns: @MigrationCapabilityInfo list +# +# Since: 1.2 +## +{ 'command': 'query-migration-capabilities', 'returns': ['MigrationCapabilityInfo'] } + +## +# @migrate_set_parameters +# +# Set the following migration parameters (like xbzrle) +## +# Since: 1.2 +## +{ 'command': 'migrate-set-parameters', 'data': { 'parameters': ['MigrationCapabilityInfo'] } } + +## # @MouseInfo: # # Information about a mouse device. diff --git a/qmp-commands.hx b/qmp-commands.hx index 2e1a38e..85b5920 100644 --- a/qmp-commands.hx +++ b/qmp-commands.hx @@ -2135,6 +2135,56 @@ EQMP }, SQMP +query-migration-capabilities +------- + +Query migration capabilities + +- "xbzrle": xbzrle support + +Arguments: + +Example: + +-> { "execute": "query-migration-capabilities"} +<- { "return": [ { "capability": "xbzrle", "state": true }, + { "capability": "foobar", "state": false } ] } + +EQMP + + { + .name = "query-migration-capabilities", + .args_type = "", + .mhandler.cmd_new = qmp_marshal_input_query_migration_capabilities, + }, + +SQMP +migrate_set_parameters +------- + +Enable migration capabilities + +- "xbzrle": xbzrle support + +Arguments: + +Example: + +-> { "execute": "migrate_set_parameters" , "arguments": + { "parameters": { "capability": "xbzrle", "state": true } ] } } + +EQMP + + { + .name = "migrate_set_parameters", + .args_type = "parameters:O", + .params = "capability:s,state:b", + .mhandler.cmd_new = qmp_marshal_input_migrate_set_parameters, + }, + + + +SQMP query-balloon -------------